Merge "Remove unnecessary spaces" into androidx-platform-dev
diff --git a/.idea/misc.xml b/.idea/misc.xml
index fa7a06b..fbe0221 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -49,7 +49,7 @@
</value>
</option>
</component>
- <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
diff --git a/activity/activity-ktx/api/1.2.0-alpha02.txt b/activity/activity-ktx/api/1.2.0-alpha02.txt
index 3db7798..81717a8 100644
--- a/activity/activity-ktx/api/1.2.0-alpha02.txt
+++ b/activity/activity-ktx/api/1.2.0-alpha02.txt
@@ -1,6 +1,17 @@
// Signature format: 3.0
package androidx.activity {
+ public final class ActivityResultCallerKt {
+ method public static inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> prepareCall(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 inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> prepareCall(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 ActivityResultLauncherKt {
+ method public static operator <I> void invoke(androidx.activity.result.ActivityResultLauncher<I>, I? input);
+ method public static operator void invoke(androidx.activity.result.ActivityResultLauncher<java.lang.Void>);
+ method public static operator void invokeUnit(androidx.activity.result.ActivityResultLauncher<kotlin.Unit>);
+ }
+
public final class ActivityViewModelLazyKt {
method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> viewModels(androidx.activity.ComponentActivity, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
}
diff --git a/activity/activity-ktx/api/current.txt b/activity/activity-ktx/api/current.txt
index 3db7798..81717a8 100644
--- a/activity/activity-ktx/api/current.txt
+++ b/activity/activity-ktx/api/current.txt
@@ -1,6 +1,17 @@
// Signature format: 3.0
package androidx.activity {
+ public final class ActivityResultCallerKt {
+ method public static inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> prepareCall(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 inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> prepareCall(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 ActivityResultLauncherKt {
+ method public static operator <I> void invoke(androidx.activity.result.ActivityResultLauncher<I>, I? input);
+ method public static operator void invoke(androidx.activity.result.ActivityResultLauncher<java.lang.Void>);
+ method public static operator void invokeUnit(androidx.activity.result.ActivityResultLauncher<kotlin.Unit>);
+ }
+
public final class ActivityViewModelLazyKt {
method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> viewModels(androidx.activity.ComponentActivity, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
}
diff --git a/activity/activity-ktx/api/public_plus_experimental_1.2.0-alpha02.txt b/activity/activity-ktx/api/public_plus_experimental_1.2.0-alpha02.txt
index 3db7798..81717a8 100644
--- a/activity/activity-ktx/api/public_plus_experimental_1.2.0-alpha02.txt
+++ b/activity/activity-ktx/api/public_plus_experimental_1.2.0-alpha02.txt
@@ -1,6 +1,17 @@
// Signature format: 3.0
package androidx.activity {
+ public final class ActivityResultCallerKt {
+ method public static inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> prepareCall(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 inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> prepareCall(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 ActivityResultLauncherKt {
+ method public static operator <I> void invoke(androidx.activity.result.ActivityResultLauncher<I>, I? input);
+ method public static operator void invoke(androidx.activity.result.ActivityResultLauncher<java.lang.Void>);
+ method public static operator void invokeUnit(androidx.activity.result.ActivityResultLauncher<kotlin.Unit>);
+ }
+
public final class ActivityViewModelLazyKt {
method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> viewModels(androidx.activity.ComponentActivity, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
}
diff --git a/activity/activity-ktx/api/public_plus_experimental_current.txt b/activity/activity-ktx/api/public_plus_experimental_current.txt
index 3db7798..81717a8 100644
--- a/activity/activity-ktx/api/public_plus_experimental_current.txt
+++ b/activity/activity-ktx/api/public_plus_experimental_current.txt
@@ -1,6 +1,17 @@
// Signature format: 3.0
package androidx.activity {
+ public final class ActivityResultCallerKt {
+ method public static inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> prepareCall(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 inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> prepareCall(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 ActivityResultLauncherKt {
+ method public static operator <I> void invoke(androidx.activity.result.ActivityResultLauncher<I>, I? input);
+ method public static operator void invoke(androidx.activity.result.ActivityResultLauncher<java.lang.Void>);
+ method public static operator void invokeUnit(androidx.activity.result.ActivityResultLauncher<kotlin.Unit>);
+ }
+
public final class ActivityViewModelLazyKt {
method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> viewModels(androidx.activity.ComponentActivity, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
}
diff --git a/activity/activity-ktx/api/restricted_1.2.0-alpha02.txt b/activity/activity-ktx/api/restricted_1.2.0-alpha02.txt
index 3db7798..81717a8 100644
--- a/activity/activity-ktx/api/restricted_1.2.0-alpha02.txt
+++ b/activity/activity-ktx/api/restricted_1.2.0-alpha02.txt
@@ -1,6 +1,17 @@
// Signature format: 3.0
package androidx.activity {
+ public final class ActivityResultCallerKt {
+ method public static inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> prepareCall(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 inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> prepareCall(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 ActivityResultLauncherKt {
+ method public static operator <I> void invoke(androidx.activity.result.ActivityResultLauncher<I>, I? input);
+ method public static operator void invoke(androidx.activity.result.ActivityResultLauncher<java.lang.Void>);
+ method public static operator void invokeUnit(androidx.activity.result.ActivityResultLauncher<kotlin.Unit>);
+ }
+
public final class ActivityViewModelLazyKt {
method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> viewModels(androidx.activity.ComponentActivity, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
}
diff --git a/activity/activity-ktx/api/restricted_current.txt b/activity/activity-ktx/api/restricted_current.txt
index 3db7798..81717a8 100644
--- a/activity/activity-ktx/api/restricted_current.txt
+++ b/activity/activity-ktx/api/restricted_current.txt
@@ -1,6 +1,17 @@
// Signature format: 3.0
package androidx.activity {
+ public final class ActivityResultCallerKt {
+ method public static inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> prepareCall(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 inline <I, O> kotlin.jvm.functions.Function0<kotlin.Unit> prepareCall(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 ActivityResultLauncherKt {
+ method public static operator <I> void invoke(androidx.activity.result.ActivityResultLauncher<I>, I? input);
+ method public static operator void invoke(androidx.activity.result.ActivityResultLauncher<java.lang.Void>);
+ method public static operator void invokeUnit(androidx.activity.result.ActivityResultLauncher<kotlin.Unit>);
+ }
+
public final class ActivityViewModelLazyKt {
method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> viewModels(androidx.activity.ComponentActivity, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
}
diff --git a/activity/activity-ktx/src/main/java/androidx/activity/ActivityResultCaller.kt b/activity/activity-ktx/src/main/java/androidx/activity/ActivityResultCaller.kt
new file mode 100644
index 0000000..aed0651
--- /dev/null
+++ b/activity/activity-ktx/src/main/java/androidx/activity/ActivityResultCaller.kt
@@ -0,0 +1,52 @@
+/*
+ * 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.activity
+
+import androidx.activity.result.ActivityResultCaller
+import androidx.activity.result.ActivityResultRegistry
+import androidx.activity.result.contract.ActivityResultContract
+
+/**
+ * A version of [ActivityResultCaller.prepareCall]
+ * that additionally takes an input right away, producing a launcher that doesn't take any
+ * additional input when called.
+ *
+ * @see ActivityResultCaller.prepareCall
+ */
+inline fun <I, O> ActivityResultCaller.prepareCall(
+ contract: ActivityResultContract<I, O>,
+ input: I,
+ registry: ActivityResultRegistry,
+ crossinline callback: (O) -> Unit
+): () -> Unit {
+ return { prepareCall(contract, registry) { callback(it) }.launch(input) }
+}
+
+/**
+ * A version of [ActivityResultCaller.prepareCall]
+ * that additionally takes an input right away, producing a launcher that doesn't take any
+ * additional input when called.
+ *
+ * @see ActivityResultCaller.prepareCall
+ */
+inline fun <I, O> ActivityResultCaller.prepareCall(
+ contract: ActivityResultContract<I, O>,
+ input: I,
+ crossinline callback: (O) -> Unit
+): () -> Unit {
+ return { prepareCall(contract) { callback(it) }.launch(input) }
+}
\ No newline at end of file
diff --git a/activity/activity-ktx/src/main/java/androidx/activity/ActivityResultLauncher.kt b/activity/activity-ktx/src/main/java/androidx/activity/ActivityResultLauncher.kt
new file mode 100644
index 0000000..87118c5
--- /dev/null
+++ b/activity/activity-ktx/src/main/java/androidx/activity/ActivityResultLauncher.kt
@@ -0,0 +1,37 @@
+/*
+ * 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.activity
+
+import androidx.activity.result.ActivityResultLauncher
+
+/**
+ * Convenience method to launch a prepared call using an invoke operator.
+ */
+operator fun <I> ActivityResultLauncher<I>.invoke(input: I) = launch(input)
+
+/**
+ * Convenience method to launch a no-argument prepared call using an invoke operator
+ * without arguments.
+ */
+operator fun ActivityResultLauncher<Void?>.invoke() = launch(null)
+
+/**
+ * Convenience method to launch a no-argument prepared call using an invoke operator
+ * without arguments.
+ */
+@JvmName("invokeUnit")
+operator fun ActivityResultLauncher<Unit>.invoke() = launch(null)
\ No newline at end of file
diff --git a/activity/activity/api/1.2.0-alpha02.txt b/activity/activity/api/1.2.0-alpha02.txt
index 641c0b5..5d2f72c 100644
--- a/activity/activity/api/1.2.0-alpha02.txt
+++ b/activity/activity/api/1.2.0-alpha02.txt
@@ -1,9 +1,10 @@
// Signature format: 3.0
package androidx.activity {
- public class ComponentActivity extends android.app.Activity implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+ public class ComponentActivity extends android.app.Activity implements androidx.activity.result.ActivityResultCaller androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
ctor public ComponentActivity();
ctor @ContentView public ComponentActivity(@LayoutRes int);
+ method public androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
method @Deprecated public Object? getLastCustomNonConfigurationInstance();
method public androidx.lifecycle.Lifecycle getLifecycle();
@@ -12,6 +13,8 @@
method public androidx.lifecycle.ViewModelStore getViewModelStore();
method @Deprecated public Object? onRetainCustomNonConfigurationInstance();
method public final Object? onRetainNonConfigurationInstance();
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
}
public abstract class OnBackPressedCallback {
@@ -37,3 +40,88 @@
}
+package androidx.activity.result {
+
+ public final class ActivityResult implements android.os.Parcelable {
+ ctor public ActivityResult(int, android.content.Intent?);
+ method public int describeContents();
+ method public android.content.Intent? getData();
+ method public int getResultCode();
+ method public static String resultCodeToString(int);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<androidx.activity.result.ActivityResult!> CREATOR;
+ }
+
+ public interface ActivityResultCallback<O> {
+ method public void onActivityResult(O!);
+ }
+
+ public interface ActivityResultCaller {
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+ }
+
+ public interface ActivityResultLauncher<I> {
+ method public void dispose();
+ method public void launch(I!);
+ }
+
+ public abstract class ActivityResultRegistry {
+ ctor public ActivityResultRegistry();
+ method @MainThread public boolean dispatchResult(int, int, android.content.Intent?);
+ method @MainThread public abstract <I, O> void invoke(int, androidx.activity.result.contract.ActivityResultContract<I!,O!>, I!);
+ method public void onRestoreInstanceState(android.os.Bundle?);
+ method public void onSaveInstanceState(android.os.Bundle);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerActivityResultCallback(String, androidx.lifecycle.LifecycleOwner, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerActivityResultCallback(String, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method @MainThread public void unregisterActivityResultCallback(String);
+ }
+
+}
+
+package androidx.activity.result.contract {
+
+ public abstract class ActivityResultContract<I, O> {
+ ctor public ActivityResultContract();
+ method public abstract android.content.Intent createIntent(I!);
+ method public abstract O! parseResult(int, android.content.Intent?);
+ }
+
+ public class ActivityResultContracts {
+ }
+
+ public static class ActivityResultContracts.Dial extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.lang.Boolean> {
+ ctor public ActivityResultContracts.Dial();
+ method public android.content.Intent createIntent(String);
+ method public Boolean parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.RequestPermission extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.lang.Boolean> {
+ ctor public ActivityResultContracts.RequestPermission();
+ method public android.content.Intent createIntent(String);
+ method public Boolean parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.RequestPermissions extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],java.util.Map<java.lang.String,java.lang.Boolean>> {
+ ctor public ActivityResultContracts.RequestPermissions();
+ method public android.content.Intent createIntent(String![]);
+ method public java.util.Map<java.lang.String!,java.lang.Boolean!> parseResult(int, android.content.Intent?);
+ field public static final String ACTION_REQUEST_PERMISSIONS = "androidx.activity.result.contract.action.REQUEST_PERMISSIONS";
+ field public static final String EXTRA_PERMISSIONS = "androidx.activity.result.contract.extra.PERMISSIONS";
+ field public static final String EXTRA_PERMISSION_GRANT_RESULTS = "androidx.activity.result.contract.extra.PERMISSION_GRANT_RESULTS";
+ }
+
+ public static class ActivityResultContracts.StartActivityForResult extends androidx.activity.result.contract.ActivityResultContract<android.content.Intent,androidx.activity.result.ActivityResult> {
+ ctor public ActivityResultContracts.StartActivityForResult();
+ method public android.content.Intent createIntent(android.content.Intent);
+ method public androidx.activity.result.ActivityResult parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.TakePicture extends androidx.activity.result.contract.ActivityResultContract<java.lang.Void,android.graphics.Bitmap> {
+ ctor public ActivityResultContracts.TakePicture();
+ method public android.content.Intent createIntent(Void?);
+ method public android.graphics.Bitmap? parseResult(int, android.content.Intent?);
+ }
+
+}
+
diff --git a/activity/activity/api/current.txt b/activity/activity/api/current.txt
index 641c0b5..5d2f72c 100644
--- a/activity/activity/api/current.txt
+++ b/activity/activity/api/current.txt
@@ -1,9 +1,10 @@
// Signature format: 3.0
package androidx.activity {
- public class ComponentActivity extends android.app.Activity implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+ public class ComponentActivity extends android.app.Activity implements androidx.activity.result.ActivityResultCaller androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
ctor public ComponentActivity();
ctor @ContentView public ComponentActivity(@LayoutRes int);
+ method public androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
method @Deprecated public Object? getLastCustomNonConfigurationInstance();
method public androidx.lifecycle.Lifecycle getLifecycle();
@@ -12,6 +13,8 @@
method public androidx.lifecycle.ViewModelStore getViewModelStore();
method @Deprecated public Object? onRetainCustomNonConfigurationInstance();
method public final Object? onRetainNonConfigurationInstance();
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
}
public abstract class OnBackPressedCallback {
@@ -37,3 +40,88 @@
}
+package androidx.activity.result {
+
+ public final class ActivityResult implements android.os.Parcelable {
+ ctor public ActivityResult(int, android.content.Intent?);
+ method public int describeContents();
+ method public android.content.Intent? getData();
+ method public int getResultCode();
+ method public static String resultCodeToString(int);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<androidx.activity.result.ActivityResult!> CREATOR;
+ }
+
+ public interface ActivityResultCallback<O> {
+ method public void onActivityResult(O!);
+ }
+
+ public interface ActivityResultCaller {
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+ }
+
+ public interface ActivityResultLauncher<I> {
+ method public void dispose();
+ method public void launch(I!);
+ }
+
+ public abstract class ActivityResultRegistry {
+ ctor public ActivityResultRegistry();
+ method @MainThread public boolean dispatchResult(int, int, android.content.Intent?);
+ method @MainThread public abstract <I, O> void invoke(int, androidx.activity.result.contract.ActivityResultContract<I!,O!>, I!);
+ method public void onRestoreInstanceState(android.os.Bundle?);
+ method public void onSaveInstanceState(android.os.Bundle);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerActivityResultCallback(String, androidx.lifecycle.LifecycleOwner, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerActivityResultCallback(String, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method @MainThread public void unregisterActivityResultCallback(String);
+ }
+
+}
+
+package androidx.activity.result.contract {
+
+ public abstract class ActivityResultContract<I, O> {
+ ctor public ActivityResultContract();
+ method public abstract android.content.Intent createIntent(I!);
+ method public abstract O! parseResult(int, android.content.Intent?);
+ }
+
+ public class ActivityResultContracts {
+ }
+
+ public static class ActivityResultContracts.Dial extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.lang.Boolean> {
+ ctor public ActivityResultContracts.Dial();
+ method public android.content.Intent createIntent(String);
+ method public Boolean parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.RequestPermission extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.lang.Boolean> {
+ ctor public ActivityResultContracts.RequestPermission();
+ method public android.content.Intent createIntent(String);
+ method public Boolean parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.RequestPermissions extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],java.util.Map<java.lang.String,java.lang.Boolean>> {
+ ctor public ActivityResultContracts.RequestPermissions();
+ method public android.content.Intent createIntent(String![]);
+ method public java.util.Map<java.lang.String!,java.lang.Boolean!> parseResult(int, android.content.Intent?);
+ field public static final String ACTION_REQUEST_PERMISSIONS = "androidx.activity.result.contract.action.REQUEST_PERMISSIONS";
+ field public static final String EXTRA_PERMISSIONS = "androidx.activity.result.contract.extra.PERMISSIONS";
+ field public static final String EXTRA_PERMISSION_GRANT_RESULTS = "androidx.activity.result.contract.extra.PERMISSION_GRANT_RESULTS";
+ }
+
+ public static class ActivityResultContracts.StartActivityForResult extends androidx.activity.result.contract.ActivityResultContract<android.content.Intent,androidx.activity.result.ActivityResult> {
+ ctor public ActivityResultContracts.StartActivityForResult();
+ method public android.content.Intent createIntent(android.content.Intent);
+ method public androidx.activity.result.ActivityResult parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.TakePicture extends androidx.activity.result.contract.ActivityResultContract<java.lang.Void,android.graphics.Bitmap> {
+ ctor public ActivityResultContracts.TakePicture();
+ method public android.content.Intent createIntent(Void?);
+ method public android.graphics.Bitmap? parseResult(int, android.content.Intent?);
+ }
+
+}
+
diff --git a/activity/activity/api/public_plus_experimental_1.2.0-alpha02.txt b/activity/activity/api/public_plus_experimental_1.2.0-alpha02.txt
index 2a6b68b..f424b4f 100644
--- a/activity/activity/api/public_plus_experimental_1.2.0-alpha02.txt
+++ b/activity/activity/api/public_plus_experimental_1.2.0-alpha02.txt
@@ -1,9 +1,10 @@
// Signature format: 3.0
package androidx.activity {
- public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+ public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.activity.result.ActivityResultCaller androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
ctor public ComponentActivity();
ctor @ContentView public ComponentActivity(@LayoutRes int);
+ method public androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
method @Deprecated public Object? getLastCustomNonConfigurationInstance();
method public final androidx.activity.OnBackPressedDispatcher getOnBackPressedDispatcher();
@@ -11,6 +12,8 @@
method public androidx.lifecycle.ViewModelStore getViewModelStore();
method @Deprecated public Object? onRetainCustomNonConfigurationInstance();
method public final Object? onRetainNonConfigurationInstance();
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
}
public abstract class OnBackPressedCallback {
@@ -36,3 +39,88 @@
}
+package androidx.activity.result {
+
+ public final class ActivityResult implements android.os.Parcelable {
+ ctor public ActivityResult(int, android.content.Intent?);
+ method public int describeContents();
+ method public android.content.Intent? getData();
+ method public int getResultCode();
+ method public static String resultCodeToString(int);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<androidx.activity.result.ActivityResult!> CREATOR;
+ }
+
+ public interface ActivityResultCallback<O> {
+ method public void onActivityResult(O!);
+ }
+
+ public interface ActivityResultCaller {
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+ }
+
+ public interface ActivityResultLauncher<I> {
+ method public void dispose();
+ method public void launch(I!);
+ }
+
+ public abstract class ActivityResultRegistry {
+ ctor public ActivityResultRegistry();
+ method @MainThread public boolean dispatchResult(int, int, android.content.Intent?);
+ method @MainThread public abstract <I, O> void invoke(int, androidx.activity.result.contract.ActivityResultContract<I!,O!>, I!);
+ method public void onRestoreInstanceState(android.os.Bundle?);
+ method public void onSaveInstanceState(android.os.Bundle);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerActivityResultCallback(String, androidx.lifecycle.LifecycleOwner, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerActivityResultCallback(String, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method @MainThread public void unregisterActivityResultCallback(String);
+ }
+
+}
+
+package androidx.activity.result.contract {
+
+ public abstract class ActivityResultContract<I, O> {
+ ctor public ActivityResultContract();
+ method public abstract android.content.Intent createIntent(I!);
+ method public abstract O! parseResult(int, android.content.Intent?);
+ }
+
+ public class ActivityResultContracts {
+ }
+
+ public static class ActivityResultContracts.Dial extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.lang.Boolean> {
+ ctor public ActivityResultContracts.Dial();
+ method public android.content.Intent createIntent(String);
+ method public Boolean parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.RequestPermission extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.lang.Boolean> {
+ ctor public ActivityResultContracts.RequestPermission();
+ method public android.content.Intent createIntent(String);
+ method public Boolean parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.RequestPermissions extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],java.util.Map<java.lang.String,java.lang.Boolean>> {
+ ctor public ActivityResultContracts.RequestPermissions();
+ method public android.content.Intent createIntent(String![]);
+ method public java.util.Map<java.lang.String!,java.lang.Boolean!> parseResult(int, android.content.Intent?);
+ field public static final String ACTION_REQUEST_PERMISSIONS = "androidx.activity.result.contract.action.REQUEST_PERMISSIONS";
+ field public static final String EXTRA_PERMISSIONS = "androidx.activity.result.contract.extra.PERMISSIONS";
+ field public static final String EXTRA_PERMISSION_GRANT_RESULTS = "androidx.activity.result.contract.extra.PERMISSION_GRANT_RESULTS";
+ }
+
+ public static class ActivityResultContracts.StartActivityForResult extends androidx.activity.result.contract.ActivityResultContract<android.content.Intent,androidx.activity.result.ActivityResult> {
+ ctor public ActivityResultContracts.StartActivityForResult();
+ method public android.content.Intent createIntent(android.content.Intent);
+ method public androidx.activity.result.ActivityResult parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.TakePicture extends androidx.activity.result.contract.ActivityResultContract<java.lang.Void,android.graphics.Bitmap> {
+ ctor public ActivityResultContracts.TakePicture();
+ method public android.content.Intent createIntent(Void?);
+ method public android.graphics.Bitmap? parseResult(int, android.content.Intent?);
+ }
+
+}
+
diff --git a/activity/activity/api/public_plus_experimental_current.txt b/activity/activity/api/public_plus_experimental_current.txt
index 2a6b68b..f424b4f 100644
--- a/activity/activity/api/public_plus_experimental_current.txt
+++ b/activity/activity/api/public_plus_experimental_current.txt
@@ -1,9 +1,10 @@
// Signature format: 3.0
package androidx.activity {
- public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+ public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.activity.result.ActivityResultCaller androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
ctor public ComponentActivity();
ctor @ContentView public ComponentActivity(@LayoutRes int);
+ method public androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
method @Deprecated public Object? getLastCustomNonConfigurationInstance();
method public final androidx.activity.OnBackPressedDispatcher getOnBackPressedDispatcher();
@@ -11,6 +12,8 @@
method public androidx.lifecycle.ViewModelStore getViewModelStore();
method @Deprecated public Object? onRetainCustomNonConfigurationInstance();
method public final Object? onRetainNonConfigurationInstance();
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
}
public abstract class OnBackPressedCallback {
@@ -36,3 +39,88 @@
}
+package androidx.activity.result {
+
+ public final class ActivityResult implements android.os.Parcelable {
+ ctor public ActivityResult(int, android.content.Intent?);
+ method public int describeContents();
+ method public android.content.Intent? getData();
+ method public int getResultCode();
+ method public static String resultCodeToString(int);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<androidx.activity.result.ActivityResult!> CREATOR;
+ }
+
+ public interface ActivityResultCallback<O> {
+ method public void onActivityResult(O!);
+ }
+
+ public interface ActivityResultCaller {
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+ }
+
+ public interface ActivityResultLauncher<I> {
+ method public void dispose();
+ method public void launch(I!);
+ }
+
+ public abstract class ActivityResultRegistry {
+ ctor public ActivityResultRegistry();
+ method @MainThread public boolean dispatchResult(int, int, android.content.Intent?);
+ method @MainThread public abstract <I, O> void invoke(int, androidx.activity.result.contract.ActivityResultContract<I!,O!>, I!);
+ method public void onRestoreInstanceState(android.os.Bundle?);
+ method public void onSaveInstanceState(android.os.Bundle);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerActivityResultCallback(String, androidx.lifecycle.LifecycleOwner, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerActivityResultCallback(String, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method @MainThread public void unregisterActivityResultCallback(String);
+ }
+
+}
+
+package androidx.activity.result.contract {
+
+ public abstract class ActivityResultContract<I, O> {
+ ctor public ActivityResultContract();
+ method public abstract android.content.Intent createIntent(I!);
+ method public abstract O! parseResult(int, android.content.Intent?);
+ }
+
+ public class ActivityResultContracts {
+ }
+
+ public static class ActivityResultContracts.Dial extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.lang.Boolean> {
+ ctor public ActivityResultContracts.Dial();
+ method public android.content.Intent createIntent(String);
+ method public Boolean parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.RequestPermission extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.lang.Boolean> {
+ ctor public ActivityResultContracts.RequestPermission();
+ method public android.content.Intent createIntent(String);
+ method public Boolean parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.RequestPermissions extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],java.util.Map<java.lang.String,java.lang.Boolean>> {
+ ctor public ActivityResultContracts.RequestPermissions();
+ method public android.content.Intent createIntent(String![]);
+ method public java.util.Map<java.lang.String!,java.lang.Boolean!> parseResult(int, android.content.Intent?);
+ field public static final String ACTION_REQUEST_PERMISSIONS = "androidx.activity.result.contract.action.REQUEST_PERMISSIONS";
+ field public static final String EXTRA_PERMISSIONS = "androidx.activity.result.contract.extra.PERMISSIONS";
+ field public static final String EXTRA_PERMISSION_GRANT_RESULTS = "androidx.activity.result.contract.extra.PERMISSION_GRANT_RESULTS";
+ }
+
+ public static class ActivityResultContracts.StartActivityForResult extends androidx.activity.result.contract.ActivityResultContract<android.content.Intent,androidx.activity.result.ActivityResult> {
+ ctor public ActivityResultContracts.StartActivityForResult();
+ method public android.content.Intent createIntent(android.content.Intent);
+ method public androidx.activity.result.ActivityResult parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.TakePicture extends androidx.activity.result.contract.ActivityResultContract<java.lang.Void,android.graphics.Bitmap> {
+ ctor public ActivityResultContracts.TakePicture();
+ method public android.content.Intent createIntent(Void?);
+ method public android.graphics.Bitmap? parseResult(int, android.content.Intent?);
+ }
+
+}
+
diff --git a/activity/activity/api/restricted_1.2.0-alpha02.txt b/activity/activity/api/restricted_1.2.0-alpha02.txt
index 2a6b68b..f424b4f 100644
--- a/activity/activity/api/restricted_1.2.0-alpha02.txt
+++ b/activity/activity/api/restricted_1.2.0-alpha02.txt
@@ -1,9 +1,10 @@
// Signature format: 3.0
package androidx.activity {
- public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+ public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.activity.result.ActivityResultCaller androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
ctor public ComponentActivity();
ctor @ContentView public ComponentActivity(@LayoutRes int);
+ method public androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
method @Deprecated public Object? getLastCustomNonConfigurationInstance();
method public final androidx.activity.OnBackPressedDispatcher getOnBackPressedDispatcher();
@@ -11,6 +12,8 @@
method public androidx.lifecycle.ViewModelStore getViewModelStore();
method @Deprecated public Object? onRetainCustomNonConfigurationInstance();
method public final Object? onRetainNonConfigurationInstance();
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
}
public abstract class OnBackPressedCallback {
@@ -36,3 +39,88 @@
}
+package androidx.activity.result {
+
+ public final class ActivityResult implements android.os.Parcelable {
+ ctor public ActivityResult(int, android.content.Intent?);
+ method public int describeContents();
+ method public android.content.Intent? getData();
+ method public int getResultCode();
+ method public static String resultCodeToString(int);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<androidx.activity.result.ActivityResult!> CREATOR;
+ }
+
+ public interface ActivityResultCallback<O> {
+ method public void onActivityResult(O!);
+ }
+
+ public interface ActivityResultCaller {
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+ }
+
+ public interface ActivityResultLauncher<I> {
+ method public void dispose();
+ method public void launch(I!);
+ }
+
+ public abstract class ActivityResultRegistry {
+ ctor public ActivityResultRegistry();
+ method @MainThread public boolean dispatchResult(int, int, android.content.Intent?);
+ method @MainThread public abstract <I, O> void invoke(int, androidx.activity.result.contract.ActivityResultContract<I!,O!>, I!);
+ method public void onRestoreInstanceState(android.os.Bundle?);
+ method public void onSaveInstanceState(android.os.Bundle);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerActivityResultCallback(String, androidx.lifecycle.LifecycleOwner, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerActivityResultCallback(String, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method @MainThread public void unregisterActivityResultCallback(String);
+ }
+
+}
+
+package androidx.activity.result.contract {
+
+ public abstract class ActivityResultContract<I, O> {
+ ctor public ActivityResultContract();
+ method public abstract android.content.Intent createIntent(I!);
+ method public abstract O! parseResult(int, android.content.Intent?);
+ }
+
+ public class ActivityResultContracts {
+ }
+
+ public static class ActivityResultContracts.Dial extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.lang.Boolean> {
+ ctor public ActivityResultContracts.Dial();
+ method public android.content.Intent createIntent(String);
+ method public Boolean parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.RequestPermission extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.lang.Boolean> {
+ ctor public ActivityResultContracts.RequestPermission();
+ method public android.content.Intent createIntent(String);
+ method public Boolean parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.RequestPermissions extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],java.util.Map<java.lang.String,java.lang.Boolean>> {
+ ctor public ActivityResultContracts.RequestPermissions();
+ method public android.content.Intent createIntent(String![]);
+ method public java.util.Map<java.lang.String!,java.lang.Boolean!> parseResult(int, android.content.Intent?);
+ field public static final String ACTION_REQUEST_PERMISSIONS = "androidx.activity.result.contract.action.REQUEST_PERMISSIONS";
+ field public static final String EXTRA_PERMISSIONS = "androidx.activity.result.contract.extra.PERMISSIONS";
+ field public static final String EXTRA_PERMISSION_GRANT_RESULTS = "androidx.activity.result.contract.extra.PERMISSION_GRANT_RESULTS";
+ }
+
+ public static class ActivityResultContracts.StartActivityForResult extends androidx.activity.result.contract.ActivityResultContract<android.content.Intent,androidx.activity.result.ActivityResult> {
+ ctor public ActivityResultContracts.StartActivityForResult();
+ method public android.content.Intent createIntent(android.content.Intent);
+ method public androidx.activity.result.ActivityResult parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.TakePicture extends androidx.activity.result.contract.ActivityResultContract<java.lang.Void,android.graphics.Bitmap> {
+ ctor public ActivityResultContracts.TakePicture();
+ method public android.content.Intent createIntent(Void?);
+ method public android.graphics.Bitmap? parseResult(int, android.content.Intent?);
+ }
+
+}
+
diff --git a/activity/activity/api/restricted_current.txt b/activity/activity/api/restricted_current.txt
index 2a6b68b..f424b4f 100644
--- a/activity/activity/api/restricted_current.txt
+++ b/activity/activity/api/restricted_current.txt
@@ -1,9 +1,10 @@
// Signature format: 3.0
package androidx.activity {
- public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+ public class ComponentActivity extends androidx.core.app.ComponentActivity implements androidx.activity.result.ActivityResultCaller androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.activity.OnBackPressedDispatcherOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
ctor public ComponentActivity();
ctor @ContentView public ComponentActivity(@LayoutRes int);
+ method public androidx.activity.result.ActivityResultRegistry getActivityResultRegistry();
method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
method @Deprecated public Object? getLastCustomNonConfigurationInstance();
method public final androidx.activity.OnBackPressedDispatcher getOnBackPressedDispatcher();
@@ -11,6 +12,8 @@
method public androidx.lifecycle.ViewModelStore getViewModelStore();
method @Deprecated public Object? onRetainCustomNonConfigurationInstance();
method public final Object? onRetainNonConfigurationInstance();
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
}
public abstract class OnBackPressedCallback {
@@ -36,3 +39,88 @@
}
+package androidx.activity.result {
+
+ public final class ActivityResult implements android.os.Parcelable {
+ ctor public ActivityResult(int, android.content.Intent?);
+ method public int describeContents();
+ method public android.content.Intent? getData();
+ method public int getResultCode();
+ method public static String resultCodeToString(int);
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<androidx.activity.result.ActivityResult!> CREATOR;
+ }
+
+ public interface ActivityResultCallback<O> {
+ method public void onActivityResult(O!);
+ }
+
+ public interface ActivityResultCaller {
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
+ }
+
+ public interface ActivityResultLauncher<I> {
+ method public void dispose();
+ method public void launch(I!);
+ }
+
+ public abstract class ActivityResultRegistry {
+ ctor public ActivityResultRegistry();
+ method @MainThread public boolean dispatchResult(int, int, android.content.Intent?);
+ method @MainThread public abstract <I, O> void invoke(int, androidx.activity.result.contract.ActivityResultContract<I!,O!>, I!);
+ method public void onRestoreInstanceState(android.os.Bundle?);
+ method public void onSaveInstanceState(android.os.Bundle);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerActivityResultCallback(String, androidx.lifecycle.LifecycleOwner, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> registerActivityResultCallback(String, androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method @MainThread public void unregisterActivityResultCallback(String);
+ }
+
+}
+
+package androidx.activity.result.contract {
+
+ public abstract class ActivityResultContract<I, O> {
+ ctor public ActivityResultContract();
+ method public abstract android.content.Intent createIntent(I!);
+ method public abstract O! parseResult(int, android.content.Intent?);
+ }
+
+ public class ActivityResultContracts {
+ }
+
+ public static class ActivityResultContracts.Dial extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.lang.Boolean> {
+ ctor public ActivityResultContracts.Dial();
+ method public android.content.Intent createIntent(String);
+ method public Boolean parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.RequestPermission extends androidx.activity.result.contract.ActivityResultContract<java.lang.String,java.lang.Boolean> {
+ ctor public ActivityResultContracts.RequestPermission();
+ method public android.content.Intent createIntent(String);
+ method public Boolean parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.RequestPermissions extends androidx.activity.result.contract.ActivityResultContract<java.lang.String[],java.util.Map<java.lang.String,java.lang.Boolean>> {
+ ctor public ActivityResultContracts.RequestPermissions();
+ method public android.content.Intent createIntent(String![]);
+ method public java.util.Map<java.lang.String!,java.lang.Boolean!> parseResult(int, android.content.Intent?);
+ field public static final String ACTION_REQUEST_PERMISSIONS = "androidx.activity.result.contract.action.REQUEST_PERMISSIONS";
+ field public static final String EXTRA_PERMISSIONS = "androidx.activity.result.contract.extra.PERMISSIONS";
+ field public static final String EXTRA_PERMISSION_GRANT_RESULTS = "androidx.activity.result.contract.extra.PERMISSION_GRANT_RESULTS";
+ }
+
+ public static class ActivityResultContracts.StartActivityForResult extends androidx.activity.result.contract.ActivityResultContract<android.content.Intent,androidx.activity.result.ActivityResult> {
+ ctor public ActivityResultContracts.StartActivityForResult();
+ method public android.content.Intent createIntent(android.content.Intent);
+ method public androidx.activity.result.ActivityResult parseResult(int, android.content.Intent?);
+ }
+
+ public static class ActivityResultContracts.TakePicture extends androidx.activity.result.contract.ActivityResultContract<java.lang.Void,android.graphics.Bitmap> {
+ ctor public ActivityResultContracts.TakePicture();
+ method public android.content.Intent createIntent(Void?);
+ method public android.graphics.Bitmap? parseResult(int, android.content.Intent?);
+ }
+
+}
+
diff --git a/activity/activity/src/main/java/androidx/activity/ComponentActivity.java b/activity/activity/src/main/java/androidx/activity/ComponentActivity.java
index 2fc4c5e..db2589a 100644
--- a/activity/activity/src/main/java/androidx/activity/ComponentActivity.java
+++ b/activity/activity/src/main/java/androidx/activity/ComponentActivity.java
@@ -18,7 +18,14 @@
import static android.os.Build.VERSION.SDK_INT;
+import static androidx.activity.result.contract.ActivityResultContracts.RequestPermissions.ACTION_REQUEST_PERMISSIONS;
+import static androidx.activity.result.contract.ActivityResultContracts.RequestPermissions.EXTRA_PERMISSIONS;
+import static androidx.activity.result.contract.ActivityResultContracts.RequestPermissions.EXTRA_PERMISSION_GRANT_RESULTS;
+
import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
@@ -26,6 +33,11 @@
import android.view.ViewGroup;
import android.view.Window;
+import androidx.activity.result.ActivityResultCallback;
+import androidx.activity.result.ActivityResultCaller;
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.ActivityResultRegistry;
+import androidx.activity.result.contract.ActivityResultContract;
import androidx.annotation.CallSuper;
import androidx.annotation.ContentView;
import androidx.annotation.LayoutRes;
@@ -47,6 +59,10 @@
import androidx.savedstate.SavedStateRegistryController;
import androidx.savedstate.SavedStateRegistryOwner;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
/**
* Base class for activities that enables composition of higher level components.
* <p>
@@ -59,7 +75,8 @@
ViewModelStoreOwner,
HasDefaultViewModelProviderFactory,
SavedStateRegistryOwner,
- OnBackPressedDispatcherOwner {
+ OnBackPressedDispatcherOwner,
+ ActivityResultCaller {
static final class NonConfigurationInstances {
Object custom;
@@ -95,6 +112,42 @@
@LayoutRes
private int mContentLayoutId;
+ private final AtomicInteger mNextLocalRequestCode = new AtomicInteger();
+
+ private ActivityResultRegistry mActivityResultRegistry = new ActivityResultRegistry() {
+
+ @Override
+ public <I, O> void invoke(
+ final int requestCode,
+ @NonNull ActivityResultContract<I, O> contract,
+ I input) {
+ Intent intent = contract.createIntent(input);
+ if (ACTION_REQUEST_PERMISSIONS.equals(intent.getAction())) {
+ String[] permissions = intent.getStringArrayExtra(EXTRA_PERMISSIONS);
+
+ if (SDK_INT < Build.VERSION_CODES.M || permissions == null) {
+ return;
+ }
+
+ List<String> nonGrantedPermissions = new ArrayList<>();
+ for (String permission : permissions) {
+ if (checkPermission(permission,
+ android.os.Process.myPid(), android.os.Process.myUid())
+ != PackageManager.PERMISSION_GRANTED) {
+ nonGrantedPermissions.add(permission);
+ }
+ }
+
+ if (!nonGrantedPermissions.isEmpty()) {
+ requestPermissions(nonGrantedPermissions.toArray(
+ new String[nonGrantedPermissions.size()]), requestCode);
+ }
+ } else {
+ ComponentActivity.this.startActivityForResult(intent, requestCode);
+ }
+ }
+ };
+
/**
* Default constructor for ComponentActivity. All Activities must have a default constructor
* for API 27 and lower devices or when using the default
@@ -167,6 +220,7 @@
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSavedStateRegistryController.performRestore(savedInstanceState);
+ mActivityResultRegistry.onRestoreInstanceState(savedInstanceState);
ReportFragment.injectIfNeededIn(this);
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
@@ -182,6 +236,7 @@
}
super.onSaveInstanceState(outState);
mSavedStateRegistryController.performSave(outState);
+ mActivityResultRegistry.onSaveInstanceState(outState);
}
/**
@@ -382,4 +437,53 @@
public final SavedStateRegistry getSavedStateRegistry() {
return mSavedStateRegistryController.getSavedStateRegistry();
}
+
+ @CallSuper
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
+ if (!mActivityResultRegistry.dispatchResult(requestCode, resultCode, data)) {
+ super.onActivityResult(requestCode, resultCode, data);
+ }
+ }
+
+ @CallSuper
+ @Override
+ public void onRequestPermissionsResult(
+ int requestCode,
+ @NonNull String[] permissions,
+ @NonNull int[] grantResults) {
+ if (!mActivityResultRegistry.dispatchResult(requestCode, Activity.RESULT_OK, new Intent()
+ .putExtra(EXTRA_PERMISSIONS, permissions)
+ .putExtra(EXTRA_PERMISSION_GRANT_RESULTS, grantResults))) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ }
+ }
+
+ @NonNull
+ @Override
+ public <I, O> ActivityResultLauncher<I> prepareCall(
+ @NonNull final ActivityResultContract<I, O> contract,
+ @NonNull final ActivityResultRegistry registry,
+ @NonNull final ActivityResultCallback<O> callback) {
+ return registry.registerActivityResultCallback(
+ "activity_rq#" + mNextLocalRequestCode.getAndIncrement(), this, contract, callback);
+ }
+
+ @NonNull
+ @Override
+ public <I, O> ActivityResultLauncher<I> prepareCall(
+ @NonNull ActivityResultContract<I, O> contract,
+ @NonNull ActivityResultCallback<O> callback) {
+ return prepareCall(contract, mActivityResultRegistry, callback);
+ }
+
+ /**
+ * Get the {@link ActivityResultRegistry} associated with this activity.
+ *
+ * @return the {@link ActivityResultRegistry}
+ */
+ @NonNull
+ public ActivityResultRegistry getActivityResultRegistry() {
+ return mActivityResultRegistry;
+ }
}
diff --git a/activity/activity/src/main/java/androidx/activity/result/ActivityResult.java b/activity/activity/src/main/java/androidx/activity/result/ActivityResult.java
new file mode 100644
index 0000000..d283d33
--- /dev/null
+++ b/activity/activity/src/main/java/androidx/activity/result/ActivityResult.java
@@ -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.activity.result;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * A container for an activity result as obtained form {@link Activity#onActivityResult}
+ *
+ * @see Activity#onActivityResult
+ */
+@SuppressLint("BanParcelableUsage")
+public final class ActivityResult implements Parcelable {
+ private final int mResultCode;
+ @Nullable
+ private final Intent mData;
+
+ /**
+ * Create a new instance
+ *
+ * @param resultCode status to indicate the success of the operation
+ * @param data an intent that carries the result data
+ */
+ public ActivityResult(int resultCode, @Nullable Intent data) {
+ mResultCode = resultCode;
+ mData = data;
+ }
+
+ ActivityResult(Parcel in) {
+ mResultCode = in.readInt();
+ mData = in.readInt() == 0 ? null : Intent.CREATOR.createFromParcel(in);
+ }
+
+ /**
+ * @return the resultCode
+ */
+ public int getResultCode() {
+ return mResultCode;
+ }
+
+ /**
+ * @return the intent
+ */
+ @Nullable
+ public Intent getData() {
+ return mData;
+ }
+
+ @Override
+ public String toString() {
+ return "ActivityResult{"
+ + "resultCode=" + resultCodeToString(mResultCode)
+ + ", data=" + mData
+ + '}';
+ }
+
+ /**
+ * A readable representation of standard activity result codes
+ *
+ * @param resultCode the result code
+ *
+ * @return RESULT_OK, RESULT_CANCELED, or the number otherwise
+ */
+ @NonNull
+ public static String resultCodeToString(int resultCode) {
+ switch (resultCode) {
+ case Activity.RESULT_OK: return "RESULT_OK";
+ case Activity.RESULT_CANCELED: return "RESULT_CANCELED";
+ default: return String.valueOf(resultCode);
+ }
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeInt(mResultCode);
+ dest.writeInt(mData == null ? 0 : 1);
+ if (mData != null) {
+ mData.writeToParcel(dest, flags);
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @NonNull
+ public static final Creator<ActivityResult> CREATOR = new Creator<ActivityResult>() {
+ @Override
+ public ActivityResult createFromParcel(@NonNull Parcel in) {
+ return new ActivityResult(in);
+ }
+
+ @Override
+ public ActivityResult[] newArray(int size) {
+ return new ActivityResult[size];
+ }
+ };
+}
diff --git a/activity/activity/src/main/java/androidx/activity/result/ActivityResultCallback.java b/activity/activity/src/main/java/androidx/activity/result/ActivityResultCallback.java
new file mode 100644
index 0000000..fde2497
--- /dev/null
+++ b/activity/activity/src/main/java/androidx/activity/result/ActivityResultCallback.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 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.activity.result;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+
+/**
+ * A type-safe callback to be called when an {@link Activity#onActivityResult activity result}
+ * is available.
+ *
+ * @param <O> result type
+ */
+public interface ActivityResultCallback<O> {
+
+ /**
+ * Called when result is available
+ */
+ void onActivityResult(@SuppressLint("UnknownNullness") O result);
+}
diff --git a/activity/activity/src/main/java/androidx/activity/result/ActivityResultCaller.java b/activity/activity/src/main/java/androidx/activity/result/ActivityResultCaller.java
new file mode 100644
index 0000000..33486aa
--- /dev/null
+++ b/activity/activity/src/main/java/androidx/activity/result/ActivityResultCaller.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 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.activity.result;
+
+import android.app.Activity;
+import android.content.Intent;
+
+import androidx.activity.result.contract.ActivityResultContract;
+import androidx.annotation.NonNull;
+
+/**
+ * A class that can call {@link Activity#startActivityForResult}-style APIs without having to manage
+ * request codes, and converting request/response to an {@link Intent}
+ */
+public interface ActivityResultCaller {
+
+ /**
+ * Prepare to {@link Activity#startActivityForResult start an activity for result}, designated
+ * by the given {@link ActivityResultContract contract}.
+ *
+ * This creates a record in the {@link ActivityResultRegistry registry} associated wit this
+ * caller, managing request code, as well as conversions to/from {@link Intent} under the hood.
+ *
+ * This *must* be called unconditionally, as part of initialization path, typically as a field
+ * initializer of an Activity or Fragment.
+ *
+ * @param <I> the type of the input(if any) required to call the activity
+ * @param <O> the type of output returned as an activity result
+ *
+ * @param contract the contract, specifying conversions to/from {@link Intent}s
+ * @param callback the callback to be called on the main thread when activity result
+ * is available
+ *
+ * @return the launcher that can be used to start the activity or dispose of the prepared call.
+ */
+ @NonNull
+ <I, O> ActivityResultLauncher<I> prepareCall(
+ @NonNull ActivityResultContract<I, O> contract,
+ @NonNull ActivityResultCallback<O> callback);
+
+ /**
+ * Prepare to {@link Activity#startActivityForResult start an activity for result}, designated
+ * by the given {@link ActivityResultContract contract}.
+ *
+ * This creates a record in the given {@link ActivityResultRegistry registry}, managing request
+ * code, as well as conversions to/from {@link Intent} under the hood.
+ *
+ * This *must* be called unconditionally, as part of initialization path, typically as a field
+ * initializer of an Activity or Fragment.
+ *
+ * @param <I> the type of the input(if any) required to call the activity
+ * @param <O> the type of output returned as an activity result
+ *
+ * @param contract the contract, specifying conversions to/from {@link Intent}s
+ * @param registry the registry where to hold the record.
+ * @param callback the callback to be called on the main thread when activity result
+ * is available
+ *
+ * @return the launcher that can be used to start the activity or dispose of the prepared call.
+ */
+ @NonNull
+ <I, O> ActivityResultLauncher<I> prepareCall(
+ @NonNull ActivityResultContract<I, O> contract,
+ @NonNull ActivityResultRegistry registry,
+ @NonNull ActivityResultCallback<O> callback);
+}
diff --git a/activity/activity/src/main/java/androidx/activity/result/ActivityResultLauncher.java b/activity/activity/src/main/java/androidx/activity/result/ActivityResultLauncher.java
new file mode 100644
index 0000000..f056c1aa
--- /dev/null
+++ b/activity/activity/src/main/java/androidx/activity/result/ActivityResultLauncher.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 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.activity.result;
+
+import android.annotation.SuppressLint;
+
+import androidx.activity.result.contract.ActivityResultContract;
+
+/**
+ * A launcher for a prevoiusly-{@link ActivityResultCaller#prepareCall prepared call} to start
+ * the process of executing an {@link ActivityResultContract}.
+ *
+ * @param <I> type of the input required to launch
+ */
+public interface ActivityResultLauncher<I> {
+
+ /**
+ * Executes an {@link ActivityResultContract}.
+ *
+ * @param input the input required to execute an {@link ActivityResultContract}.
+ */
+ void launch(@SuppressLint("UnknownNullness") I input);
+
+ /**
+ * Disposes of this launcher, releasing the underlying result callback, and any references
+ * captured within it.
+ *
+ * You should call this if the registry may live longer than the callback registered for this
+ * launcher.
+ */
+ void dispose();
+}
diff --git a/activity/activity/src/main/java/androidx/activity/result/ActivityResultRegistry.java b/activity/activity/src/main/java/androidx/activity/result/ActivityResultRegistry.java
new file mode 100644
index 0000000..bc65179
--- /dev/null
+++ b/activity/activity/src/main/java/androidx/activity/result/ActivityResultRegistry.java
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 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.activity.result;
+
+import static androidx.annotation.RestrictTo.Scope.LIBRARY;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.util.Log;
+
+import androidx.activity.result.contract.ActivityResultContract;
+import androidx.annotation.MainThread;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.RestrictTo;
+import androidx.lifecycle.Lifecycle;
+import androidx.lifecycle.LifecycleEventObserver;
+import androidx.lifecycle.LifecycleOwner;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * A registry that stores {@link ActivityResultCallback activity result callbacks} for
+ * {@link ActivityResultCaller#prepareCall prepared calls}.
+ *
+ * You can create your own instance for testing by overriding {@link #invoke} and calling
+ * {@link #dispatchResult} immediately within it, thus skipping the actual
+ * {@link Activity#startActivityForResult} call.
+ *
+ * When testing, make sure to explicitly provide a registry instance whenever calling
+ * {@link ActivityResultCaller#prepareCall}, to be able to inject a test instance.
+ */
+public abstract class ActivityResultRegistry {
+ private static final String KEY_COMPONENT_ACTIVITY_REGISTERED_RCS =
+ "KEY_COMPONENT_ACTIVITY_REGISTERED_RCS";
+ private static final String KEY_COMPONENT_ACTIVITY_REGISTERED_KEYS =
+ "KEY_COMPONENT_ACTIVITY_REGISTERED_KEYS";
+ private static final String KEY_COMPONENT_ACTIVITY_PENDING_RESULTS =
+ "KEY_COMPONENT_ACTIVITY_PENDING_RESULT";
+
+ private static final String LOG_TAG = "ActivityResultRegistry";
+
+ private final AtomicInteger mNextRc = new AtomicInteger(0);
+ private final Map<Integer, String> mRcToKey = new HashMap<Integer, String>();
+ private final Map<String, Integer> mKeyToRc = new HashMap<String, Integer>();
+
+ private final transient Map<String, CallbackAndContract<?>> mKeyToCallback =
+ new HashMap<String, CallbackAndContract<?>>();
+
+ private final Bundle/*<String, ActivityResult>*/ mPendingResults = new Bundle();
+
+ /**
+ * Start the process of executing an {@link ActivityResultContract} in a type-safe way,
+ * using the provided {@link ActivityResultContract contract}.
+ *
+ * @param requestCode request code to use
+ * @param contract contract to use for type conversions
+ * @param input input required to execute an ActivityResultContract.
+ */
+ @MainThread
+ public abstract <I, O> void invoke(
+ int requestCode,
+ @NonNull ActivityResultContract<I, O> contract,
+ @SuppressLint("UnknownNullness") I input);
+
+ /**
+ * Register a new callback with this registry.
+ *
+ * This is normally called by a higher level convenience methods like
+ * {@link ActivityResultCaller#prepareCall}.
+ *
+ * @param key a unique string key identifying this call
+ * @param lifecycleOwner a {@link LifecycleOwner} that makes this call.
+ * @param contract the contract specifying input/output types of the call
+ * @param callback the activity result callback
+ *
+ * @return a launcher that can be used to execute an ActivityResultContract.
+ */
+ @NonNull
+ public <I, O> ActivityResultLauncher<I> registerActivityResultCallback(
+ @NonNull final String key,
+ @NonNull final LifecycleOwner lifecycleOwner,
+ @NonNull final ActivityResultContract<I, O> contract,
+ @NonNull final ActivityResultCallback<O> callback) {
+
+ final int requestCode = registerKey(key);
+ mKeyToCallback.put(key, new CallbackAndContract<O>(callback, contract));
+
+ Lifecycle lifecycle = lifecycleOwner.getLifecycle();
+
+ final ActivityResult pendingResult = mPendingResults.getParcelable(key);
+ if (pendingResult != null) {
+ mPendingResults.remove(key);
+ if (lifecycle.getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
+ callback.onActivityResult(contract.parseResult(
+ pendingResult.getResultCode(),
+ pendingResult.getData()));
+ } else {
+ lifecycle.addObserver(new LifecycleEventObserver() {
+ @Override
+ public void onStateChanged(
+ @NonNull LifecycleOwner lifecycleOwner,
+ @NonNull Lifecycle.Event event) {
+ if (Lifecycle.Event.ON_CREATE.equals(event)) {
+ callback.onActivityResult(contract.parseResult(
+ pendingResult.getResultCode(),
+ pendingResult.getData()));
+ }
+ }
+ });
+ }
+ }
+
+ lifecycle.addObserver(new LifecycleEventObserver() {
+ @Override
+ public void onStateChanged(@NonNull LifecycleOwner lifecycleOwner,
+ @NonNull Lifecycle.Event event) {
+ if (Lifecycle.Event.ON_DESTROY.equals(event)) {
+ unregisterActivityResultCallback(key);
+ }
+ }
+ });
+
+ return new ActivityResultLauncher<I>() {
+ @Override
+ public void launch(I input) {
+ invoke(requestCode, contract, input);
+ }
+
+ @Override
+ public void dispose() {
+ unregisterActivityResultCallback(key);
+ }
+ };
+ }
+
+ /**
+ * Register a new callback with this registry.
+ *
+ * This is normally called by a higher level convenience methods like
+ * {@link ActivityResultCaller#prepareCall}.
+ *
+ * When calling this, make sure to call {@link #unregisterActivityResultCallback} when the
+ * launcher is no longer needed to release any values that might be captured in the
+ * registered callback.
+ *
+ * @param key a unique string key identifying this call
+ * @param contract the contract specifying input/output types of the call
+ * @param callback the activity result callback
+ *
+ * @return a launcher that can be used to execute an ActivityResultContract.
+ */
+ @NonNull
+ public <I, O> ActivityResultLauncher<I> registerActivityResultCallback(
+ @NonNull final String key,
+ @NonNull final ActivityResultContract<I, O> contract,
+ @NonNull final ActivityResultCallback<O> callback) {
+ final int requestCode = registerKey(key);
+ mKeyToCallback.put(key, new CallbackAndContract<O>(callback, contract));
+
+ final ActivityResult pendingResult = mPendingResults.getParcelable(key);
+ if (pendingResult != null) {
+ mPendingResults.remove(key);
+ callback.onActivityResult(contract.parseResult(
+ pendingResult.getResultCode(),
+ pendingResult.getData()));
+ }
+
+ return new ActivityResultLauncher<I>() {
+ @Override
+ public void launch(I input) {
+ invoke(requestCode, contract, input);
+ }
+
+ @Override
+ public void dispose() {
+ unregisterActivityResultCallback(key);
+ }
+ };
+ }
+
+ /**
+ * Unregister a callback previously registered with {@link #registerActivityResultCallback}
+ *
+ * @param key the unique key used when registering a callback.
+ */
+ @MainThread
+ public void unregisterActivityResultCallback(@NonNull String key) {
+ Integer rc = mKeyToRc.remove(key);
+ if (rc != null) {
+ mRcToKey.remove(rc);
+ }
+ mKeyToCallback.remove(key);
+ if (mPendingResults.containsKey(key)) {
+ Log.w(LOG_TAG, "Dropping pending result for request " + key + ": "
+ + mPendingResults.<ActivityResult>getParcelable(key));
+ }
+ }
+
+ /**
+ * Save the state of this registry in the given {@link Bundle}
+ *
+ * @param outState the place to put state into
+ */
+ public void onSaveInstanceState(@NonNull Bundle outState) {
+ outState.putIntegerArrayList(KEY_COMPONENT_ACTIVITY_REGISTERED_RCS,
+ new ArrayList<Integer>(mRcToKey.keySet()));
+ outState.putStringArrayList(KEY_COMPONENT_ACTIVITY_REGISTERED_KEYS,
+ new ArrayList<String>(mRcToKey.values()));
+ outState.putBundle(KEY_COMPONENT_ACTIVITY_PENDING_RESULTS, mPendingResults);
+ }
+
+ /**
+ * Restore the state of this registry from the given {@link Bundle}
+ *
+ * @param savedInstanceState the place to restore from
+ */
+ public void onRestoreInstanceState(@Nullable Bundle savedInstanceState) {
+ if (savedInstanceState == null) {
+ return;
+ }
+ ArrayList<Integer> rcs =
+ savedInstanceState.getIntegerArrayList(KEY_COMPONENT_ACTIVITY_REGISTERED_RCS);
+ ArrayList<String> keys =
+ savedInstanceState.getStringArrayList(KEY_COMPONENT_ACTIVITY_REGISTERED_KEYS);
+ int numKeys = keys.size();
+ for (int i = 0; i < numKeys; i++) {
+ bindRcKey(rcs.get(i), keys.get(i));
+ }
+ mNextRc.set(numKeys);
+ mPendingResults.putAll(
+ savedInstanceState.getBundle(KEY_COMPONENT_ACTIVITY_PENDING_RESULTS));
+ }
+
+ /**
+ * Dispatch a result received via {@link Activity#onActivityResult} to the callback on record,
+ * or store the result if callback was not yet registered.
+ *
+ * @param requestCode request code to identify the callback
+ * @param resultCode status to indicate the success of the operation
+ * @param data an intent that carries the result data
+ *
+ * @return whether there was a callback was registered for the given request code which was
+ * or will be called.
+ */
+ @MainThread
+ public boolean dispatchResult(int requestCode, int resultCode, @Nullable Intent data) {
+ String key = mRcToKey.get(requestCode);
+ if (key == null) {
+ return false;
+ }
+ doDispatch(key, resultCode, data, mKeyToCallback.get(key));
+ return true;
+ }
+
+ private <O> void doDispatch(String key, int resultCode, @Nullable Intent data,
+ CallbackAndContract<O> callbackAndContract) {
+ ActivityResultCallback<O> callback = callbackAndContract.mCallback;
+ ActivityResultContract<?, O> contract = callbackAndContract.mContract;
+ if (callback != null) {
+ callback.onActivityResult(contract.parseResult(resultCode, data));
+ } else {
+ mPendingResults.putParcelable(key, new ActivityResult(resultCode, data));
+ }
+ }
+
+ /** @hide */
+ @RestrictTo(LIBRARY)
+ public void clearCallbacks() {
+ mKeyToCallback.clear();
+ }
+
+ private int registerKey(String key) {
+ Integer existing = mKeyToRc.get(key);
+ if (existing != null) {
+ return existing;
+ }
+ int rc = mNextRc.getAndIncrement();
+ bindRcKey(rc, key);
+ return rc;
+ }
+
+ private void bindRcKey(int rc, String key) {
+ mRcToKey.put(rc, key);
+ mKeyToRc.put(key, rc);
+ }
+
+ private static class CallbackAndContract<O> {
+ final ActivityResultCallback<O> mCallback;
+ final ActivityResultContract<?, O> mContract;
+
+ CallbackAndContract(
+ ActivityResultCallback<O> callback,
+ ActivityResultContract<?, O> contract) {
+ mCallback = callback;
+ mContract = contract;
+ }
+ }
+}
diff --git a/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContract.java b/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContract.java
new file mode 100644
index 0000000..292d330
--- /dev/null
+++ b/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContract.java
@@ -0,0 +1,48 @@
+/*
+ * 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.activity.result.contract;
+
+import android.annotation.SuppressLint;
+import android.app.Activity;
+import android.content.Intent;
+
+import androidx.activity.result.ActivityResultCaller;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+/**
+ * A contract specifying that an activity can be called with an input of type I
+ * and produce an output of type O
+ *
+ * Makes calling an activity for result type-safe.
+ *
+ * @param <I> input type
+ * @param <O> output type
+ *
+ * @see ActivityResultCaller
+ */
+public abstract class ActivityResultContract<I, O> {
+
+ /** Create an intent that can be used for {@link Activity#startActivityForResult} */
+ public abstract @NonNull Intent createIntent(@SuppressLint("UnknownNullness") I input);
+
+ /** Convert result obtained from {@link Activity#onActivityResult} to O */
+ public abstract @SuppressLint("UnknownNullness") O parseResult(
+ int resultCode,
+ @Nullable Intent intent);
+}
diff --git a/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.java b/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.java
new file mode 100644
index 0000000..b8ca510
--- /dev/null
+++ b/activity/activity/src/main/java/androidx/activity/result/contract/ActivityResultContracts.java
@@ -0,0 +1,194 @@
+/*
+ * 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.activity.result.contract;
+
+import static androidx.activity.result.contract.ActivityResultContracts.RequestPermissions.ACTION_REQUEST_PERMISSIONS;
+import static androidx.activity.result.contract.ActivityResultContracts.RequestPermissions.EXTRA_PERMISSIONS;
+import static androidx.activity.result.contract.ActivityResultContracts.RequestPermissions.EXTRA_PERMISSION_GRANT_RESULTS;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.provider.MediaStore;
+
+import androidx.activity.result.ActivityResult;
+import androidx.activity.result.ActivityResultCaller;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A collection of some standard activity call contracts, as provided by android.
+ */
+public class ActivityResultContracts {
+ private ActivityResultContracts() {}
+
+ /**
+ * An {@link ActivityResultContract} that doesn't do any type conversion, taking raw
+ * {@link Intent} as an input and {@link ActivityResult} as an output.
+ *
+ * Can be used with {@link ActivityResultCaller#prepareCall} to avoid
+ * having to manage request codes when calling an activity API for which a type-safe contract is
+ * not available.
+ */
+ public static class StartActivityForResult
+ extends ActivityResultContract<Intent, ActivityResult> {
+
+ @NonNull
+ @Override
+ public Intent createIntent(@NonNull Intent input) {
+ return input;
+ }
+
+ @NonNull
+ @Override
+ public ActivityResult parseResult(int resultCode, @Nullable Intent intent) {
+ return new ActivityResult(resultCode, intent);
+ }
+ }
+
+ /**
+ * An {@link ActivityResultContract} to {@link Activity#requestPermissions request permissions}
+ */
+ public static class RequestPermissions
+ extends ActivityResultContract<String[], java.util.Map<String, Boolean>> {
+
+
+ /**
+ * An {@link Intent} action for making a permission request via a regular
+ * {@link Activity#startActivityForResult} API.
+ *
+ * Caller must provide a {@code String[]} extra {@link #EXTRA_PERMISSIONS}
+ *
+ * Result will be delivered via {@link Activity#onActivityResult(int, int, Intent)} with
+ * {@code String[]} {@link #EXTRA_PERMISSIONS} and {@code int[]}
+ * {@link #EXTRA_PERMISSION_GRANT_RESULTS}, similar to
+ * {@link Activity#onRequestPermissionsResult(int, String[], int[])}
+ *
+ * @see Activity#requestPermissions(String[], int)
+ * @see Activity#onRequestPermissionsResult(int, String[], int[])
+ */
+ public static final String ACTION_REQUEST_PERMISSIONS =
+ "androidx.activity.result.contract.action.REQUEST_PERMISSIONS";
+
+ /**
+ * Key for the extra containing all the requested permissions.
+ *
+ * @see #ACTION_REQUEST_PERMISSIONS
+ */
+ public static final String EXTRA_PERMISSIONS =
+ "androidx.activity.result.contract.extra.PERMISSIONS";
+
+ /**
+ * Key for the extra containing whether permissions were granted.
+ *
+ * @see #ACTION_REQUEST_PERMISSIONS
+ */
+ public static final String EXTRA_PERMISSION_GRANT_RESULTS =
+ "androidx.activity.result.contract.extra.PERMISSION_GRANT_RESULTS";
+
+ @NonNull
+ @Override
+ public Intent createIntent(@NonNull String[] input) {
+ return new Intent(ACTION_REQUEST_PERMISSIONS).putExtra(EXTRA_PERMISSIONS, input);
+ }
+
+ @NonNull
+ @Override
+ public Map<String, Boolean> parseResult(int resultCode, @Nullable Intent intent) {
+ if (resultCode != Activity.RESULT_OK) return Collections.emptyMap();
+ if (intent == null) return Collections.emptyMap();
+
+ String[] permissions = intent.getStringArrayExtra(EXTRA_PERMISSIONS);
+ int[] grantResults = intent.getIntArrayExtra(EXTRA_PERMISSION_GRANT_RESULTS);
+ if (grantResults == null || permissions == null) return Collections.emptyMap();
+
+ Map<String, Boolean> result = new HashMap<String, Boolean>();
+ for (int i = 0, size = permissions.length; i < size; i++) {
+ result.put(permissions[i], grantResults[i] == PackageManager.PERMISSION_GRANTED);
+ }
+ return result;
+ }
+ }
+
+ /**
+ * An {@link ActivityResultContract} to {@link Intent#ACTION_DIAL dial a number}
+ */
+ public static class Dial extends ActivityResultContract<String, Boolean> {
+
+ @NonNull
+ @Override
+ public Intent createIntent(@NonNull String input) {
+ return new Intent(Intent.ACTION_DIAL).setData(Uri.parse("tel:" + input));
+ }
+
+ @NonNull
+ @Override
+ public Boolean parseResult(int resultCode, @Nullable Intent intent) {
+ return resultCode == Activity.RESULT_OK;
+ }
+ }
+
+ /**
+ * An {@link ActivityResultContract} to {@link Activity#requestPermissions request a permission}
+ */
+ public static class RequestPermission extends ActivityResultContract<String, Boolean> {
+
+ @NonNull
+ @Override
+ public Intent createIntent(@NonNull String input) {
+ return new Intent(ACTION_REQUEST_PERMISSIONS)
+ .putExtra(EXTRA_PERMISSIONS, new String[] { input });
+ }
+
+ @NonNull
+ @Override
+ public Boolean parseResult(int resultCode, @Nullable Intent intent) {
+ if (resultCode != Activity.RESULT_OK) return false;
+ if (intent == null) return false;
+ int[] grantResults = intent.getIntArrayExtra(EXTRA_PERMISSION_GRANT_RESULTS);
+ if (grantResults == null) return false;
+ return grantResults[0] == PackageManager.PERMISSION_GRANTED;
+ }
+ }
+
+ /**
+ * An {@link ActivityResultContract} to
+ * {@link MediaStore#ACTION_IMAGE_CAPTURE take a small picture} as a {@link Bitmap}
+ */
+ public static class TakePicture extends ActivityResultContract<Void, Bitmap> {
+
+ @NonNull
+ @Override
+ public Intent createIntent(@Nullable Void input) {
+ return new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
+ }
+
+ @Nullable
+ @Override
+ public Bitmap parseResult(int resultCode, @Nullable Intent intent) {
+ if (resultCode != Activity.RESULT_OK) return null;
+ if (intent == null) return null;
+ return intent.getParcelableExtra("data");
+ }
+ }
+}
diff --git a/activity/integration-tests/testapp/build.gradle b/activity/integration-tests/testapp/build.gradle
index 24872da..6216bf8 100644
--- a/activity/integration-tests/testapp/build.gradle
+++ b/activity/integration-tests/testapp/build.gradle
@@ -14,9 +14,30 @@
* limitations under the License.
*/
+import static androidx.build.dependencies.DependenciesKt.*
plugins {
id("AndroidXPlugin")
- id("com.android.library")
+ id("com.android.application")
id("org.jetbrains.kotlin.android")
}
+
+android {
+ defaultConfig {
+ testInstrumentationRunnerArgument "listener", "com.squareup.leakcanary.FailTestOnLeakRunListener"
+
+ applicationId "androidx.activity.integration.testapp"
+ }
+}
+
+dependencies {
+ implementation(project(":activity:activity-ktx"))
+ androidTestImplementation(KOTLIN_STDLIB)
+ androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
+ androidTestImplementation(ANDROIDX_TEST_CORE)
+ androidTestImplementation(ANDROIDX_TEST_RUNNER)
+ androidTestImplementation(ANDROIDX_TEST_RULES)
+ androidTestImplementation(ESPRESSO_CORE)
+ androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
+ androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it's own MockMaker
+}
diff --git a/activity/integration-tests/testapp/src/main/AndroidManifest.xml b/activity/integration-tests/testapp/src/main/AndroidManifest.xml
index 01374bf5..c5e34d0 100644
--- a/activity/integration-tests/testapp/src/main/AndroidManifest.xml
+++ b/activity/integration-tests/testapp/src/main/AndroidManifest.xml
@@ -15,6 +15,18 @@
~ limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="androidx.activity.integration.testapp">
+ xmlns:tools="http://schemas.android.com/tools"
+ package="androidx.activity.integration.testapp">
+
+ <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+
+ <application tools:ignore="AllowBackup,GoogleAppIndexingWarning,MissingApplicationIcon">
+ <activity android:name="androidx.activity.integration.testapp.MainActivity">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN"/>
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+ </application>
</manifest>
diff --git a/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/MainActivity.kt b/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/MainActivity.kt
new file mode 100644
index 0000000..6c3e93b
--- /dev/null
+++ b/activity/integration-tests/testapp/src/main/java/androidx/activity/integration/testapp/MainActivity.kt
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2019 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.activity.integration.testapp
+
+import android.Manifest.permission.ACCESS_FINE_LOCATION
+import android.app.Activity
+import android.content.Context
+import android.os.Bundle
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewGroup.LayoutParams.MATCH_PARENT
+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
+import android.view.ViewManager
+import android.widget.Button
+import android.widget.LinearLayout
+import android.widget.LinearLayout.VERTICAL
+import android.widget.Toast
+import androidx.activity.ComponentActivity
+import androidx.activity.invoke
+import androidx.activity.prepareCall
+import androidx.activity.result.contract.ActivityResultContracts.Dial
+import androidx.activity.result.contract.ActivityResultContracts.RequestPermission
+import androidx.activity.result.contract.ActivityResultContracts.TakePicture
+
+class MainActivity : ComponentActivity() {
+
+ val requestLocation = prepareCall(RequestPermission(), ACCESS_FINE_LOCATION) { isGranted ->
+ toast("Location granted: $isGranted")
+ }
+
+ val takePicture = prepareCall(TakePicture()) { bitmap ->
+ toast("Got picture: $bitmap")
+ }
+
+ val dial = prepareCall(Dial()) { success ->
+ toast("Dial success: $success")
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ setContentView {
+ add(::LinearLayout) {
+ orientation = VERTICAL
+
+ button("Request location permission") {
+ requestLocation()
+ }
+ button("Take pic") {
+ takePicture()
+ }
+ button("Dial 111111111") {
+ dial("111111111")
+ }
+ }
+ }
+ }
+}
+
+fun Context.toast(msg: String) {
+ Toast.makeText(this, msg, Toast.LENGTH_LONG).show()
+}
+
+inline fun Activity.setContentView(ui: ViewManager.() -> Unit) =
+ ActivityViewManager(this).apply(ui)
+
+class ActivityViewManager(val activity: Activity) : ViewManager {
+ override fun addView(p0: View?, p1: ViewGroup.LayoutParams?) {
+ activity.setContentView(p0)
+ }
+
+ override fun updateViewLayout(p0: View?, p1: ViewGroup.LayoutParams?) {
+ TODO("not implemented")
+ }
+
+ override fun removeView(p0: View?) {
+ TODO("not implemented")
+ }
+}
+val ViewManager.context get() = when (this) {
+ is View -> context
+ is ActivityViewManager -> activity
+ else -> TODO()
+}
+
+fun <VM : ViewManager, V : View> VM.add(construct: (Context) -> V, init: V.() -> Unit) {
+ construct(context).apply(init).also {
+ addView(it, ViewGroup.LayoutParams(MATCH_PARENT, WRAP_CONTENT))
+ }
+}
+
+fun ViewManager.button(txt: String, listener: (View) -> Unit) {
+ add(::Button) {
+ text = txt
+ setOnClickListener(listener)
+ }
+}
\ No newline at end of file
diff --git a/annotation/annotation-experimental-lint/build.gradle b/annotation/annotation-experimental-lint/build.gradle
index 9fae7f7..b7add4d 100644
--- a/annotation/annotation-experimental-lint/build.gradle
+++ b/annotation/annotation-experimental-lint/build.gradle
@@ -44,7 +44,7 @@
androidx {
name = "Experimental annotation lint checks"
toolingProject = true
- publish = Publish.SNAPSHOT_AND_RELEASE
+ publish = Publish.NONE
mavenVersion = LibraryVersions.ANNOTATION_EXPERIMENTAL
mavenGroup = LibraryGroups.ANNOTATION
inceptionYear = "2019"
diff --git a/annotation/annotation-sampled/src/main/java/androidx/annotation/Sampled.kt b/annotation/annotation-sampled/src/main/java/androidx/annotation/Sampled.kt
index f03f55f..8b15edfc 100644
--- a/annotation/annotation-sampled/src/main/java/androidx/annotation/Sampled.kt
+++ b/annotation/annotation-sampled/src/main/java/androidx/annotation/Sampled.kt
@@ -18,7 +18,19 @@
/**
* Denotes that the annotated function is considered a sample function, and is linked to from the
- * KDoc of a source module.
+ * KDoc of a source module that matches one of the two permitted directory structures:
+ *
+ * 1. The source module is an ancestor of the sample module, for example:
+ * ```
+ * library/src/.. // Source file here that links to a sample
+ * library/integration-tests/samples/src/.. // Sample file here that is linked to by the source file
+ * ```
+ *
+ * 2. The source module is a sibling to the sample module, for example:
+ * ```
+ * library/library-subfeature/src/.. // Source file here that links to a sample
+ * library/integration-tests/samples/src/.. // Sample file here that is linked to by the source file
+ * ```
*
* There are corresponding lint checks ensuring that functions referred to from KDoc with a @sample
* tag are annotated with this annotation, and also to ensure that any functions annotated with this
diff --git a/appcompat/appcompat/api/1.2.0-alpha04.txt b/appcompat/appcompat/api/1.2.0-alpha04.txt
index edfddd3..53d14d4 100644
--- a/appcompat/appcompat/api/1.2.0-alpha04.txt
+++ b/appcompat/appcompat/api/1.2.0-alpha04.txt
@@ -221,7 +221,6 @@
ctor @ContentView public AppCompatActivity(@LayoutRes int);
method public androidx.appcompat.app.AppCompatDelegate getDelegate();
method public androidx.appcompat.app.ActionBarDrawerToggle.Delegate? getDrawerToggleDelegate();
- method public androidx.lifecycle.Lifecycle getLifecycle();
method public androidx.appcompat.app.ActionBar? getSupportActionBar();
method public android.content.Intent? getSupportParentActivityIntent();
method public void onCreateSupportNavigateUpTaskStack(androidx.core.app.TaskStackBuilder);
diff --git a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/EmptyOptionsPanelTest.java b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/EmptyOptionsPanelTest.java
index 3c61a48..b7fe329 100644
--- a/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/EmptyOptionsPanelTest.java
+++ b/appcompat/appcompat/src/androidTest/java/androidx/appcompat/app/EmptyOptionsPanelTest.java
@@ -16,14 +16,12 @@
package androidx.appcompat.app;
-import static androidx.appcompat.testutils.TestUtils.executeShellCommandAndFind;
-
-import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertEquals;
import android.app.Instrumentation;
import android.view.KeyEvent;
+import android.view.inspector.WindowInspector;
-import androidx.appcompat.testutils.TestUtils.Predicate;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.MediumTest;
import androidx.test.filters.SdkSuppress;
@@ -53,9 +51,7 @@
mActivity = mActivityTestRule.getActivity();
}
- // executeShellCommandAndFind() is only available on API 21+ and for some reason the shell
- // command doesn't execute correctly below API 26, so suppress everything below that.
- @SdkSuppress(minSdkVersion = 26)
+ @SdkSuppress(minSdkVersion = 29)
@Test
@MediumTest
public void testEmptyOptionsPanelNotShown() throws Exception {
@@ -64,23 +60,16 @@
mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_MENU);
mInstrumentation.waitForIdleSync();
- assertFalse("Sub-panel was added after first KEYCODE_MENU",
- executeShellCommandAndFind("wm dump", new Predicate<String>() {
- public boolean test(String t) {
- return t.contains(
- "SubPanel:" + mActivity.getComponentName().flattenToString());
- }
- }));
+ // UiAutomator is flaky, so instead we'll just check how many windows are showing. This
+ // is... not a great way to test this behavior, but we don't have any other way to hook
+ // into an empty options panel.
+ assertEquals("Sub-panel should not be added after first KEYCODE_MENU",
+ 1, WindowInspector.getGlobalWindowViews().size());
mInstrumentation.sendKeyDownUpSync(KeyEvent.KEYCODE_MENU);
mInstrumentation.waitForIdleSync();
- assertFalse("Sub-panel was added after second KEYCODE_MENU",
- executeShellCommandAndFind("wm dump", new Predicate<String>() {
- public boolean test(String t) {
- return t.contains(
- "SubPanel:" + mActivity.getComponentName().flattenToString());
- }
- }));
+ assertEquals("Sub-panel should not be added after second KEYCODE_MENU",
+ 1, WindowInspector.getGlobalWindowViews().size());
}
}
diff --git a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
index 2b3a487..cd5c5c79 100644
--- a/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
+++ b/appcompat/appcompat/src/main/java/androidx/appcompat/app/AppCompatDelegateImpl.java
@@ -1650,8 +1650,7 @@
return;
}
- final WindowManager wm = (WindowManager) mContext.getApplicationContext()
- .getSystemService(Context.WINDOW_SERVICE);
+ final WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
if (wm == null) {
return;
}
@@ -1970,8 +1969,7 @@
return;
}
- final WindowManager wm = (WindowManager) mContext.getApplicationContext()
- .getSystemService(Context.WINDOW_SERVICE);
+ final WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
if (wm != null && st.isOpen && st.decorView != null) {
wm.removeView(st.decorView);
diff --git a/benchmark/gradle-plugin/build.gradle b/benchmark/gradle-plugin/build.gradle
index c357a51..9201821 100644
--- a/benchmark/gradle-plugin/build.gradle
+++ b/benchmark/gradle-plugin/build.gradle
@@ -34,7 +34,7 @@
dependencies {
implementation findGradleKotlinDsl()
implementation gradleApi()
- implementation("com.android.tools.build:gradle:3.6.0")
+ implementation("com.android.tools.build:gradle:3.6.1")
implementation(KOTLIN_STDLIB)
testImplementation gradleTestKit()
diff --git a/buildSrc/build_dependencies.gradle b/buildSrc/build_dependencies.gradle
index bc8dba6..aeafc41 100644
--- a/buildSrc/build_dependencies.gradle
+++ b/buildSrc/build_dependencies.gradle
@@ -25,8 +25,14 @@
build_versions.lint = "27.0.0-alpha01"
} else {
build_versions.kotlin = "1.3.60"
- build_versions.agp = '3.6.0'
- build_versions.lint = '26.6.0'
+ build_versions.agp = '3.6.1'
+ build_versions.lint = '26.6.1'
+}
+
+def agpOverride = System.getenv("GRADLE_PLUGIN_VERSION")
+if (agpOverride != null) {
+ logger.warn("Using custom version ${agpOverride} of AGP due to GRADLE_PLUGIN_VERSION being set.")
+ build_versions.agp = agpOverride
}
build_versions.dokka = '0.9.17-g007'
diff --git a/buildSrc/repos.gradle b/buildSrc/repos.gradle
index 5074d22..661dc80 100644
--- a/buildSrc/repos.gradle
+++ b/buildSrc/repos.gradle
@@ -89,6 +89,9 @@
handler.maven {
url androidPluginRepoOverride
}
+ handler.maven {
+ url "${repos.prebuiltsRoot}/tools/common/m2/repository"
+ }
}
}
diff --git a/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt b/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
index ff81d56..e02dc949 100644
--- a/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/AndroidXPlugin.kt
@@ -130,7 +130,6 @@
project.tasks.withType(JavaCompile::class.java) { task ->
project.configureCompilationWarnings(task)
- project.configureCompilationVerbosity(task)
}
project.hideJavadocTask()
@@ -192,7 +191,6 @@
libraryVariant.javaCompileProvider.configure { task ->
project.configureCompilationWarnings(task)
- project.configureCompilationVerbosity(task)
}
}
project.configureLint(extension.lintOptions, androidXExtension)
@@ -206,9 +204,6 @@
configureAndroidCommonOptions(project, androidXExtension)
configureAndroidApplicationOptions(project)
}
- project.tasks.withType(JavaCompile::class.java) { task ->
- project.configureCompilationVerbosity(task)
- }
}
is KotlinBasePluginWrapper -> {
project.tasks.withType(KotlinCompile::class.java).configureEach { task ->
@@ -433,7 +428,7 @@
defaultConfig.minSdkVersion(DEFAULT_MIN_SDK_VERSION)
project.afterEvaluate {
- val minSdkVersion = defaultConfig.minSdkVersion.apiLevel
+ val minSdkVersion = defaultConfig.minSdkVersion!!.apiLevel
check(minSdkVersion >= DEFAULT_MIN_SDK_VERSION) {
"minSdkVersion $minSdkVersion lower than the default of $DEFAULT_MIN_SDK_VERSION"
}
@@ -503,7 +498,8 @@
private fun hasAndroidTestSourceCode(project: Project, extension: TestedExtension): Boolean {
// check Java androidTest source set
extension.sourceSets.findByName("androidTest")?.let { sourceSet ->
- if (!sourceSet.java.sourceFiles.isEmpty) return true
+ // using getSourceFiles() instead of sourceFiles due to b/150800094
+ if (!sourceSet.java.getSourceFiles().isEmpty) return true
}
// check kotlin-android androidTest source set
@@ -621,7 +617,8 @@
val buildTestApksTask = project.rootProject.tasks.named(BUILD_TEST_APKS)
applicationVariants.all { variant ->
- if (variant.buildType.name == "debug") {
+ // Using getName() instead of name due to b/150427408
+ if (variant.buildType.getName() == "debug") {
buildTestApksTask.configure {
it.dependsOn(variant.assembleProvider)
}
@@ -902,16 +899,6 @@
}
}
-// TODO(146217083): remove this when the gradle daemons stop dying intermittently
-private fun Project.configureCompilationVerbosity(task: JavaCompile) {
- if (isRunningOnBuildServer()) {
- if (project.name.contains("room")) {
- var compilerArgs = task.options.compilerArgs
- compilerArgs.plusAssign(listOf("-verbose"))
- }
- }
-}
-
private fun Project.setDependencyVersions() {
val buildVersions = (project.rootProject.property("ext") as ExtraPropertiesExtension)
.let { it.get("build_versions") as Map<*, *> }
diff --git a/buildSrc/src/main/kotlin/androidx/build/DiffAndDocs.kt b/buildSrc/src/main/kotlin/androidx/build/DiffAndDocs.kt
index 1dad9cc..304e824 100644
--- a/buildSrc/src/main/kotlin/androidx/build/DiffAndDocs.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/DiffAndDocs.kt
@@ -242,7 +242,8 @@
appExtension.applicationVariants.all { appVariant ->
val taskProvider = docsTasks[appVariant.flavorName]
- if (appVariant.buildType.name == "release" && taskProvider != null) {
+ // Using getName() instead of name due to b/150427408
+ if (appVariant.buildType.getName() == "release" && taskProvider != null) {
registerAndroidProjectForDocsTask(taskProvider, appVariant)
// Exclude the R.java file from documentation.
diff --git a/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt b/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt
index 772a59e..e6571c3 100644
--- a/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/ErrorProneConfiguration.kt
@@ -43,7 +43,8 @@
fun Project.configureErrorProneForAndroid(variants: DomainObjectSet<out BaseVariant>) {
val toolChain = createErrorProneToolChain()
variants.all { variant ->
- if (variant.buildType.name == BuilderConstants.DEBUG) {
+ // Using getName() instead of name due to b/150427408
+ if (variant.buildType.getName() == BuilderConstants.DEBUG) {
val task = variant.javaCompileProvider
log.info("Configuring error-prone for ${variant.name}'s java compile")
diff --git a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
index 01d200e..d156fae 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
@@ -26,7 +26,7 @@
val ANIMATION_TESTING = Version("1.1.0-alpha01")
val ANNOTATION = Version("1.2.0-alpha01")
val ANNOTATION_EXPERIMENTAL = Version("1.1.0-alpha01")
- val APPCOMPAT = Version("1.2.0-alpha03")
+ val APPCOMPAT = Version("1.2.0-alpha04")
val APPSEARCH = Version("1.0.0-alpha01")
val ARCH_CORE = Version("2.2.0-alpha01")
val ARCH_CORE_TESTING = ARCH_CORE
@@ -47,19 +47,19 @@
val COMPOSE = Version("0.1.0-dev07")
val CONTENTACCESS = Version("1.0.0-alpha01")
val COORDINATORLAYOUT = Version("1.2.0-alpha01")
- val CORE = Version("1.3.0-alpha02")
+ val CORE = Version("1.3.0-alpha03")
val CORE_ROLE = Version("1.0.0-beta01")
val CURSORADAPTER = Version("1.1.0-alpha01")
- val CUSTOMVIEW = Version("1.1.0-alpha02")
+ val CUSTOMVIEW = Version("1.1.0-alpha03")
val DATASTORE = Version("1.0.0-alpha01")
val DOCUMENTFILE = Version("1.1.0-alpha01")
- val DRAWERLAYOUT = Version("1.1.0-alpha04")
+ val DRAWERLAYOUT = Version("1.1.0-alpha05")
val DYNAMICANIMATION = Version("1.1.0-alpha04")
val DYNAMICANIMATION_KTX = Version("1.0.0-alpha04")
val EMOJI = Version("1.1.0-alpha02")
val ENTERPRISE = Version("1.1.0-alpha01")
val EXIFINTERFACE = Version("1.3.0-alpha02")
- val FRAGMENT = Version("1.3.0-alpha01")
+ val FRAGMENT = Version("1.3.0-alpha02")
val FUTURES = Version("1.1.0-beta01")
val GRIDLAYOUT = Version("1.1.0-alpha01")
val HEIFWRITER = Version("1.1.0-alpha01")
@@ -70,14 +70,14 @@
val LEANBACK_PREFERENCE = Version("1.1.0-alpha04")
val LEGACY = Version("1.1.0-alpha01")
val LOCALBROADCASTMANAGER = Version("1.1.0-alpha02")
- val LIFECYCLE = Version("2.3.0-alpha01")
- val LIFECYCLE_EXTENSIONS = LIFECYCLE
+ val LIFECYCLE = Version("2.3.0-alpha02")
+ val LIFECYCLE_EXTENSIONS = Version("2.2.0")
val LOADER = Version("1.2.0-alpha01")
val MEDIA = Version("1.2.0-alpha02")
val MEDIA2 = Version("1.1.0-alpha01")
val MEDIAROUTER = Version("1.2.0-alpha01")
val MESSAGEBROWSER_BROWSER = Version("1.0.0-alpha01")
- val NAVIGATION = Version("2.3.0-alpha03")
+ val NAVIGATION = Version("2.3.0-alpha04")
val PAGING = Version("3.0.0-alpha01")
val PALETTE = Version("1.1.0-alpha01")
val PRINT = Version("1.1.0-alpha01")
@@ -101,7 +101,7 @@
val STARTUP = Version("1.0.0-alpha01")
val SQLITE = Version("2.1.0-rc01")
val SQLITE_INSPECTOR = Version("2.1.0-alpha01")
- val SWIPEREFRESHLAYOUT = Version("1.1.0-beta01")
+ val SWIPEREFRESHLAYOUT = Version("1.1.0-beta02")
val TESTSCREENSHOT = Version("1.0.0-alpha01")
val TEXTCLASSIFIER = Version("1.0.0-alpha03")
val TRANSITION = Version("1.4.0-alpha01")
@@ -117,5 +117,5 @@
val WEBKIT = Version("1.3.0-alpha01")
val WINDOW = Version("1.0.0-alpha01")
val WINDOW_SIDECAR = Version("0.1.0-alpha01")
- val WORK = Version("2.4.0-alpha01")
+ val WORK = Version("2.4.0-alpha02")
}
diff --git a/buildSrc/src/main/kotlin/androidx/build/LintConfiguration.kt b/buildSrc/src/main/kotlin/androidx/build/LintConfiguration.kt
index df43614..6f7333f 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LintConfiguration.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LintConfiguration.kt
@@ -113,7 +113,7 @@
// Only override if not set explicitly.
// Some Kotlin projects may wish to disable this.
- if (lintOptions.severityOverrides["SyntheticAccessor"] == null) {
+ if (severityOverrides!!["SyntheticAccessor"] == null) {
fatal("SyntheticAccessor")
}
diff --git a/buildSrc/src/main/kotlin/androidx/build/dokka/DokkaPublicDocs.kt b/buildSrc/src/main/kotlin/androidx/build/dokka/DokkaPublicDocs.kt
index b5e4eae..adf4953 100644
--- a/buildSrc/src/main/kotlin/androidx/build/dokka/DokkaPublicDocs.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/dokka/DokkaPublicDocs.kt
@@ -62,6 +62,7 @@
"androidx.ui.layout.samples",
"androidx.ui.material.samples",
"androidx.ui.text.samples",
+ "androidx.ui.unit.samples",
"androidx.wear.internal.widget.drawer",
"androidx.webkit.internal",
"androidx.work.impl",
diff --git a/buildSrc/src/main/kotlin/androidx/build/studio/StudioVersions.kt b/buildSrc/src/main/kotlin/androidx/build/studio/StudioVersions.kt
index d1d56f1..c583820 100644
--- a/buildSrc/src/main/kotlin/androidx/build/studio/StudioVersions.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/studio/StudioVersions.kt
@@ -51,9 +51,9 @@
}
private object RootStudioVersions : StudioVersions() {
- override val studioVersion = "3.6.0.21"
+ override val studioVersion = "3.6.1.0"
override val ideaMajorVersion = "192"
- override val studioBuildNumber = "6200805"
+ override val studioBuildNumber = "6241897"
}
private object UiStudioVersions : StudioVersions() {
diff --git a/busytown/impl/parse_profile_html.py b/busytown/impl/parse_profile_html.py
index 9b069ffc..0ce5cae 100755
--- a/busytown/impl/parse_profile_html.py
+++ b/busytown/impl/parse_profile_html.py
@@ -31,7 +31,7 @@
def summarize(inputProfilePath, outputSummaryPath):
# mapping from the key in the Gradle report to the key in the summary that we generate
- mapping = {"Total Build Time": "task_execution_duration", "Task Execution": "total_cpu", "Settings and buildSrc": "configuration_duration"}
+ mapping = {"Total Build Time": "task_execution_duration", "Task Execution": "total_cpu", "Configuring Projects": "configuration_duration"}
parsedValues = parse(inputProfilePath, mapping.keys())
outputValues = dict()
for k in mapping:
@@ -53,15 +53,15 @@
line = line.strip()
lineText = line.replace("<td>", "").replace('<td class="numeric">', "").replace("</td>", "")
if currentKey is not None:
- values[currentKey] = parseDuration(lineText)
+ values[currentKey] = parseDurationSeconds(lineText) * 1000
if lineText in interestingKeys:
currentKey = lineText
else:
currentKey = None
return values
-# Given a duration such as 1h20m02.5s, returns a number like ((1*60)+20)*60+2=4802.5
-def parseDuration(durationText):
+# Given a duration such as 1h20m02.5s, returns a number of seconds like ((1*60)+20)*60+2=4802.5
+def parseDurationSeconds(durationText):
originalDurationText = durationText
secondsText = "0"
minutesText = "0"
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/UseCaseSurfaceOccupancyManagerTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/UseCaseSurfaceOccupancyManagerTest.java
deleted file mode 100644
index 1dac134..0000000
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/UseCaseSurfaceOccupancyManagerTest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright 2019 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.internal;
-
-import android.content.Context;
-
-import androidx.camera.camera2.Camera2Config;
-import androidx.camera.core.CameraX;
-import androidx.camera.core.CameraXConfig;
-import androidx.camera.core.ImageCapture;
-import androidx.camera.core.VideoCapture;
-import androidx.camera.core.impl.VideoCaptureConfig;
-import androidx.test.core.app.ApplicationProvider;
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Collections;
-import java.util.concurrent.ExecutionException;
-
-/** JUnit test cases for UseCaseSurfaceOccupancyManager class. */
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public final class UseCaseSurfaceOccupancyManagerTest {
-
- @Before
- public void setUp() {
- Context context = ApplicationProvider.getApplicationContext();
- CameraXConfig cameraXConfig = Camera2Config.defaultConfig();
- CameraX.initialize(context, cameraXConfig);
- }
-
- @After
- public void tearDown() throws ExecutionException, InterruptedException {
- CameraX.shutdown().get();
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void failedWhenBindTooManyImageCapture() {
- ImageCapture.Builder builder = new ImageCapture.Builder();
- ImageCapture useCase1 = builder.build();
- ImageCapture useCase2 = builder.build();
-
- // Should throw IllegalArgumentException
- UseCaseSurfaceOccupancyManager.checkUseCaseLimitNotExceeded(
- Collections.singletonList(useCase1),
- Collections.singletonList(useCase2));
- }
-
- @Test(expected = IllegalArgumentException.class)
- public void failedWhenBindTooManyVideoCapture() {
- VideoCaptureConfig config = new VideoCaptureConfig.Builder().getUseCaseConfig();
- VideoCapture useCase1 = new VideoCapture(config);
- VideoCapture useCase2 = new VideoCapture(config);
-
- // Should throw IllegalArgumentException
- UseCaseSurfaceOccupancyManager.checkUseCaseLimitNotExceeded(
- Collections.singletonList(useCase1),
- Collections.singletonList(useCase2));
- }
-
- @Test
- public void passWhenNotBindTooManyImageVideoCapture() {
- ImageCapture imageCapture = new ImageCapture.Builder().build();
- VideoCapture videoCapture = new VideoCaptureConfig.Builder().build();
-
- UseCaseSurfaceOccupancyManager.checkUseCaseLimitNotExceeded(
- Collections.singletonList(imageCapture),
- Collections.singletonList(videoCapture));
- }
-}
diff --git a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/compat/CameraDeviceCompatDeviceTest.java b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/compat/CameraDeviceCompatDeviceTest.java
index a6372d6..bc553f9 100644
--- a/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/compat/CameraDeviceCompatDeviceTest.java
+++ b/camera/camera-camera2/src/androidTest/java/androidx/camera/camera2/internal/compat/CameraDeviceCompatDeviceTest.java
@@ -148,7 +148,9 @@
mSurfaceTexture.release();
}
- mCompatHandlerThread.quitSafely();
+ if (mCompatHandlerThread != null) {
+ mCompatHandlerThread.quitSafely();
+ }
}
@Test
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CaptureRequestBuilder.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CaptureRequestBuilder.java
index 24f5b4a..7173cd5 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CaptureRequestBuilder.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2CaptureRequestBuilder.java
@@ -129,6 +129,13 @@
CaptureConfig.OPTION_ROTATION));
}
+ if (captureConfig.getImplementationOptions().containsOption(
+ CaptureConfig.OPTION_JPEG_QUALITY)) {
+ builder.set(CaptureRequest.JPEG_QUALITY,
+ captureConfig.getImplementationOptions().retrieveOption(
+ CaptureConfig.OPTION_JPEG_QUALITY).byteValue());
+ }
+
for (Surface surface : surfaceList) {
builder.addTarget(surface);
}
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2DeviceSurfaceManager.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2DeviceSurfaceManager.java
index 8f5d66d..e36c774 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2DeviceSurfaceManager.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/Camera2DeviceSurfaceManager.java
@@ -162,8 +162,6 @@
Preconditions.checkNotNull(newUseCases, "No new use cases to be bound.");
Preconditions.checkArgument(!newUseCases.isEmpty(), "No new use cases to be bound.");
- UseCaseSurfaceOccupancyManager.checkUseCaseLimitNotExceeded(originalUseCases, newUseCases);
-
// Use the small size (640x480) for new use cases to check whether there is any possible
// supported combination first
List<SurfaceConfig> surfaceConfigs = new ArrayList<>();
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/UseCaseSurfaceOccupancyManager.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/UseCaseSurfaceOccupancyManager.java
deleted file mode 100644
index a845e3f..0000000
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/internal/UseCaseSurfaceOccupancyManager.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright 2019 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.internal;
-
-import androidx.camera.core.ImageCapture;
-import androidx.camera.core.UseCase;
-import androidx.camera.core.VideoCapture;
-
-import java.util.List;
-
-/**
- * Collect the use case surface occupancy customization rules in this class to make
- * Camera2DeviceSurfaceManager independent from use case type.
- */
-final class UseCaseSurfaceOccupancyManager {
- private UseCaseSurfaceOccupancyManager() {
- }
-
- static void checkUseCaseLimitNotExceeded(
- List<UseCase> originalUseCases, List<UseCase> newUseCases) {
- int imageCaptureCount = 0;
- int videoCaptureCount = 0;
-
- if (newUseCases == null || newUseCases.isEmpty()) {
- throw new IllegalArgumentException("No new use cases to be bound.");
- }
-
- if (originalUseCases != null) {
- for (UseCase useCase : originalUseCases) {
- if (useCase instanceof ImageCapture) {
- imageCaptureCount++;
- } else if (useCase instanceof VideoCapture) {
- videoCaptureCount++;
- }
- }
- }
-
- for (UseCase useCase : newUseCases) {
- if (useCase instanceof ImageCapture) {
- imageCaptureCount++;
- } else if (useCase instanceof VideoCapture) {
- videoCaptureCount++;
- }
- }
-
- if (imageCaptureCount > 1) {
- throw new IllegalArgumentException(
- "Exceeded max simultaneously bound image capture use cases.");
- }
-
- if (videoCaptureCount > 1) {
- throw new IllegalArgumentException(
- "Exceeded max simultaneously bound video capture use cases.");
- }
- }
-}
diff --git a/camera/camera-camera2/src/main/java/androidx/camera/camera2/interop/Camera2Interop.java b/camera/camera-camera2/src/main/java/androidx/camera/camera2/interop/Camera2Interop.java
index b7e0699..87d213a 100644
--- a/camera/camera-camera2/src/main/java/androidx/camera/camera2/interop/Camera2Interop.java
+++ b/camera/camera-camera2/src/main/java/androidx/camera/camera2/interop/Camera2Interop.java
@@ -58,6 +58,11 @@
/**
* Sets a {@link CaptureRequest.Key} and Value on the configuration.
*
+ * <p>Any values which are in conflict with values already set by CameraX, such as by
+ * {@link androidx.camera.core.CameraControl}, will result in a thrown
+ * exception. The exception will typically be thrown on an internal thread which will
+ * lead to an uncaught exception.
+ *
* @param key The {@link CaptureRequest.Key} which will be set.
* @param value The value for the key.
* @param <ValueT> The type of the value.
@@ -78,6 +83,9 @@
* <p>See {@link CameraDevice} for valid template types. For example, {@link
* CameraDevice#TEMPLATE_PREVIEW}.
*
+ * <p>Only used by {@link androidx.camera.core.ImageCapture} to set the template type
+ * used. For all other {@link androidx.camera.core.UseCase} this value is ignored.
+ *
* @param templateType The template type to set.
* @return The current Extender.
* @hide
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/ImageCaptureTest.java b/camera/camera-core/src/androidTest/java/androidx/camera/core/ImageCaptureTest.java
index fb7c0e5..0aa6a88 100644
--- a/camera/camera-core/src/androidTest/java/androidx/camera/core/ImageCaptureTest.java
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/ImageCaptureTest.java
@@ -26,6 +26,7 @@
import android.content.Context;
import android.util.Size;
+import androidx.camera.core.impl.CaptureConfig;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
import androidx.camera.testing.fakes.FakeAppConfig;
import androidx.camera.testing.fakes.FakeCamera;
@@ -41,8 +42,12 @@
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
+import java.util.List;
import java.util.concurrent.ExecutionException;
+/**
+ * Instrument tests for {@link ImageCapture}.
+ */
@MediumTest
@RunWith(AndroidJUnit4.class)
public class ImageCaptureTest {
@@ -118,12 +123,50 @@
ImageCapture.ERROR_CAPTURE_FAILED);
}
+ // TODO(b/149336664): add a test to verify jpeg quality is 100 when CaptureMode is MAX_QUALITY.
+ @Test
+ public void captureWithMinLatency_jpegQualityIs95() throws InterruptedException {
+ // Arrange.
+ ImageCapture imageCapture = createImageCapture();
+ mInstrumentation.runOnMainSync(() -> bind(imageCapture));
+ FakeCameraControl fakeCameraControl =
+ ((FakeCameraControl) mFakeCamera.getCameraControlInternal());
+
+ FakeCameraControl.OnNewCaptureRequestListener mockCaptureRequestListener =
+ mock(FakeCameraControl.OnNewCaptureRequestListener.class);
+ fakeCameraControl.setOnNewCaptureRequestListener(mockCaptureRequestListener);
+
+ // Act.
+ mInstrumentation.runOnMainSync(
+ () -> imageCapture.takePicture(CameraXExecutors.mainThreadExecutor(),
+ mock(ImageCapture.OnImageCapturedCallback.class)));
+
+ // Assert.
+ ArgumentCaptor<List<CaptureConfig>> argumentCaptor =
+ ArgumentCaptor.forClass(List.class);
+ verify(mockCaptureRequestListener,
+ timeout(1000).times(1)).onNewCaptureRequests(argumentCaptor.capture());
+ assertThat(hasJpegQuality(argumentCaptor.getValue(), (byte) 95)).isTrue();
+ }
+
+ private boolean hasJpegQuality(List<CaptureConfig> captureConfigs, byte jpegQuality) {
+ for (CaptureConfig captureConfig : captureConfigs) {
+ if (jpegQuality == captureConfig.getImplementationOptions().retrieveOption(
+ CaptureConfig.OPTION_JPEG_QUALITY)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private ImageCapture createImageCapture() {
return new ImageCapture.Builder()
.setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
.setFlashMode(ImageCapture.FLASH_MODE_OFF)
- .setCaptureOptionUnpacker((config, builder) -> { })
- .setSessionOptionUnpacker((config, builder) -> { })
+ .setCaptureOptionUnpacker((config, builder) -> {
+ })
+ .setSessionOptionUnpacker((config, builder) -> {
+ })
.build();
}
diff --git a/camera/camera-core/src/androidTest/java/androidx/camera/core/internal/UseCaseOccupancyTest.java b/camera/camera-core/src/androidTest/java/androidx/camera/core/internal/UseCaseOccupancyTest.java
new file mode 100644
index 0000000..88772c1
--- /dev/null
+++ b/camera/camera-core/src/androidTest/java/androidx/camera/core/internal/UseCaseOccupancyTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.camera.core.internal;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.Context;
+
+import androidx.camera.core.CameraX;
+import androidx.camera.core.CameraXConfig;
+import androidx.camera.core.ImageCapture;
+import androidx.camera.core.VideoCapture;
+import androidx.camera.core.impl.VideoCaptureConfig;
+import androidx.camera.testing.fakes.FakeAppConfig;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Collections;
+import java.util.concurrent.ExecutionException;
+
+/** JUnit test cases for {@link UseCaseOccupancy} class. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class UseCaseOccupancyTest {
+
+ @Before
+ public void setUp() {
+ Context context = ApplicationProvider.getApplicationContext();
+ CameraXConfig cameraXConfig = CameraXConfig.Builder.fromConfig(
+ FakeAppConfig.create()).build();
+ CameraX.initialize(context, cameraXConfig);
+ }
+
+ @After
+ public void tearDown() throws ExecutionException, InterruptedException {
+ CameraX.shutdown().get();
+ }
+
+ @Test
+ public void failedWhenBindTooManyImageCapture() {
+ ImageCapture useCase1 = createImageCapture();
+ ImageCapture useCase2 = createImageCapture();
+
+ assertThat(UseCaseOccupancy.checkUseCaseLimitNotExceeded(
+ Collections.singletonList(useCase1),
+ Collections.singletonList(useCase2))).isFalse();
+ }
+
+ @Test
+ public void failedWhenBindTooManyVideoCapture() {
+ VideoCaptureConfig config = new VideoCaptureConfig.Builder().getUseCaseConfig();
+ VideoCapture useCase1 = new VideoCapture(config);
+ VideoCapture useCase2 = new VideoCapture(config);
+
+ assertThat(UseCaseOccupancy.checkUseCaseLimitNotExceeded(
+ Collections.singletonList(useCase1),
+ Collections.singletonList(useCase2))).isFalse();
+ }
+
+ @Test
+ public void passWhenNotBindTooManyImageVideoCapture() {
+ ImageCapture imageCapture = createImageCapture();
+ VideoCapture videoCapture = new VideoCaptureConfig.Builder().build();
+
+ assertThat(UseCaseOccupancy.checkUseCaseLimitNotExceeded(
+ Collections.singletonList(imageCapture),
+ Collections.singletonList(videoCapture))).isTrue();
+ }
+
+ // TODO remove when UseCase does not require
+ private ImageCapture createImageCapture() {
+ return new ImageCapture.Builder()
+ .setCaptureMode(ImageCapture.CAPTURE_MODE_MINIMIZE_LATENCY)
+ .setFlashMode(ImageCapture.FLASH_MODE_OFF)
+ .setCaptureOptionUnpacker((config, builder) -> { })
+ .setSessionOptionUnpacker((config, builder) -> { })
+ .build();
+ }
+}
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/CameraX.java b/camera/camera-core/src/main/java/androidx/camera/core/CameraX.java
index fd19410..50ea799 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/CameraX.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/CameraX.java
@@ -43,6 +43,7 @@
import androidx.camera.core.impl.utils.futures.FutureCallback;
import androidx.camera.core.impl.utils.futures.FutureChain;
import androidx.camera.core.impl.utils.futures.Futures;
+import androidx.camera.core.internal.UseCaseOccupancy;
import androidx.concurrent.futures.CallbackToFutureAdapter;
import androidx.core.util.Preconditions;
import androidx.lifecycle.Lifecycle;
@@ -280,21 +281,43 @@
}
String newCameraId = CameraX.getCameraWithCameraSelector(selectorBuilder.build());
+ if (newCameraId == null) {
+ throw new IllegalArgumentException("Unable to find a camera with the given selector.");
+ }
- // Try to get the camera before bind to the use case, and throw the IllegalArgumentException
+ // Try to get the camera before binding to the use case, and throw IllegalArgumentException
// if the camera not found.
CameraInternal camera = cameraX.getCameraRepository().getCamera(newCameraId);
+ List<UseCase> originalUseCases = new ArrayList<>();
+
+ // Collect original use cases bound to the camera
+ for (UseCase useCase : useCaseGroupToBind.getUseCases()) {
+ CameraInternal boundCamera = useCase.getBoundCamera();
+ if (boundCamera != null) {
+ if (newCameraId.equals(boundCamera.getCameraInfoInternal().getCameraId())) {
+ originalUseCases.add(useCase);
+ }
+ }
+ }
+
+ if (!UseCaseOccupancy.checkUseCaseLimitNotExceeded(originalUseCases,
+ Arrays.asList(useCases))) {
+ throw new IllegalArgumentException("Attempting to bind too many ImageCapture or "
+ + "VideoCapture instances");
+ }
+
for (UseCase useCase : useCases) {
// Sets bound camera to use case.
useCase.onBind(camera);
}
- Map<UseCase, Size> suggestResolutionsMap = calculateSuggestedResolutions(useCaseGroupToBind,
- newCameraId,
- useCases);
+ Map<UseCase, Size> suggestedResolutionsMap = calculateSuggestedResolutions(
+ camera.getCameraInfoInternal(),
+ originalUseCases,
+ Arrays.asList(useCases));
- updateSuggestedResolutions(suggestResolutionsMap, useCases);
+ updateSuggestedResolutions(suggestedResolutionsMap, useCases);
for (UseCase useCase : useCases) {
useCaseGroupToBind.addUseCase(useCase);
@@ -907,24 +930,12 @@
}
private static Map<UseCase, Size> calculateSuggestedResolutions(
- @NonNull UseCaseGroup useCaseGroupToBind,
- @NonNull String cameraId, @NonNull UseCase... useCases) {
- List<UseCase> originalUseCases = new ArrayList<>();
- List<UseCase> newUseCases = Arrays.asList(useCases);
-
- // Collect original use cases for different camera devices
- for (UseCase useCase : useCaseGroupToBind.getUseCases()) {
- CameraInternal boundCamera = useCase.getBoundCamera();
- if (boundCamera != null) {
- if (cameraId.equals(boundCamera.getCameraInfoInternal().getCameraId())) {
- originalUseCases.add(useCase);
- }
- }
- }
+ @NonNull CameraInfoInternal cameraInfo,
+ @NonNull List<UseCase> originalUseCases, @NonNull List<UseCase> newUseCases) {
// Get suggested resolutions and update the use case session configuration
return getSurfaceManager()
- .getSuggestedResolutions(cameraId, originalUseCases, newUseCases);
+ .getSuggestedResolutions(cameraInfo.getCameraId(), originalUseCases, newUseCases);
}
private static void updateSuggestedResolutions(Map<UseCase, Size> suggestResolutionsMap,
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 48fd7c3..ff59cfd 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
@@ -60,6 +60,7 @@
import androidx.annotation.GuardedBy;
import androidx.annotation.IntDef;
+import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RestrictTo;
@@ -203,6 +204,9 @@
private static final String TAG = "ImageCapture";
private static final long CHECK_3A_TIMEOUT_IN_MS = 1000L;
private static final int MAX_IMAGES = 2;
+ // TODO(b/149336664) Move the quality to a compatibility class when there is a per device case.
+ private static final byte JPEG_QUALITY_MAXIMIZE_QUALITY_MODE = 100;
+ private static final byte JPEG_QUALITY_MINIMIZE_LATENCY_MODE = 95;
@NonNull
@SuppressWarnings("WeakerAccess") /* synthetic accessor */
@@ -749,11 +753,31 @@
targetRatio = ImageUtil.rotate(targetRatio, relativeRotation);
mPendingImageCaptureRequests.offer(
- new ImageCaptureRequest(relativeRotation, targetRatio, listenerExecutor, callback));
+ new ImageCaptureRequest(relativeRotation, getJpegQuality(), targetRatio,
+ listenerExecutor, callback));
issueImageCaptureRequests();
}
+ /**
+ * Gets the JPEG quality based on {@link #mCaptureMode}.
+ *
+ * <p> Range is 1-100; larger is higher quality.
+ *
+ * @return Compression quality of the captured JPEG image.
+ */
+ @IntRange(from = 1, to = 100)
+ private int getJpegQuality() {
+ switch (mCaptureMode) {
+ case CAPTURE_MODE_MAXIMIZE_QUALITY:
+ return JPEG_QUALITY_MAXIMIZE_QUALITY_MODE;
+ case CAPTURE_MODE_MINIMIZE_LATENCY:
+ return JPEG_QUALITY_MINIMIZE_LATENCY_MODE;
+ default:
+ throw new IllegalStateException("CaptureMode " + mCaptureMode + " is invalid");
+ }
+ }
+
/** Issues saved ImageCaptureRequest. */
@UiThread
@SuppressWarnings("WeakerAccess") /* synthetic accessor */
@@ -1210,6 +1234,8 @@
// Add the dynamic implementation options of ImageCapture
builder.addImplementationOption(CaptureConfig.OPTION_ROTATION,
imageCaptureRequest.mRotationDegrees);
+ builder.addImplementationOption(CaptureConfig.OPTION_JPEG_QUALITY,
+ imageCaptureRequest.mJpegQuality);
// Add the implementation options required by the CaptureStage
builder.addImplementationOptions(
@@ -1837,6 +1863,9 @@
private static final class ImageCaptureRequest {
@RotationValue
final int mRotationDegrees;
+ @IntRange(from = 1, to = 100)
+ final int mJpegQuality;
+
private final Rational mTargetRatio;
@NonNull
private final Executor mListenerExecutor;
@@ -1847,10 +1876,13 @@
ImageCaptureRequest(
@RotationValue int rotationDegrees,
+ @IntRange(from = 1, to = 100)
+ int jpegQuality,
Rational targetRatio,
@NonNull Executor executor,
@NonNull OnImageCapturedCallback callback) {
mRotationDegrees = rotationDegrees;
+ mJpegQuality = jpegQuality;
mTargetRatio = targetRatio;
mListenerExecutor = executor;
mCallback = callback;
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/impl/CaptureConfig.java b/camera/camera-core/src/main/java/androidx/camera/core/impl/CaptureConfig.java
index 547a9bb..eb92ce5 100644
--- a/camera/camera-core/src/main/java/androidx/camera/core/impl/CaptureConfig.java
+++ b/camera/camera-core/src/main/java/androidx/camera/core/impl/CaptureConfig.java
@@ -49,6 +49,16 @@
public static final Config.Option<Integer> OPTION_ROTATION =
Config.Option.create("camerax.core.captureConfig.rotation", int.class);
+ /**
+ * Sets the compression quality of the captured JPEG image.
+ *
+ * See {@link CaptureRequest#JPEG_QUALITY}.
+ *
+ * Option: camerax.core.captureConfig.jpegQuality
+ */
+ public static final Config.Option<Integer> OPTION_JPEG_QUALITY =
+ Config.Option.create("camerax.core.captureConfig.jpegQuality", Integer.class);
+
/** The set of {@link Surface} that data from the camera will be put into. */
final List<DeferrableSurface> mSurfaces;
diff --git a/camera/camera-core/src/main/java/androidx/camera/core/internal/UseCaseOccupancy.java b/camera/camera-core/src/main/java/androidx/camera/core/internal/UseCaseOccupancy.java
new file mode 100644
index 0000000..c25f413
--- /dev/null
+++ b/camera/camera-core/src/main/java/androidx/camera/core/internal/UseCaseOccupancy.java
@@ -0,0 +1,81 @@
+/*
+ * 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.camera.core.internal;
+
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.camera.core.ImageCapture;
+import androidx.camera.core.UseCase;
+import androidx.camera.core.VideoCapture;
+
+import java.util.List;
+
+/**
+ * Checks to see if the number of specific {@link UseCase} exceeds the supported number.
+ */
+public final class UseCaseOccupancy {
+ private static final String TAG = "UseCaseOccupancy";
+ private UseCaseOccupancy() {
+ }
+
+ /**
+ * Check to see if CameraX supports running the set of use cases.
+ *
+ * @param originalUseCases the currently existing use cases
+ * @param newUseCases the use cases to be added
+ * @return true if the set of use cases is supported, otherwise false
+ */
+ public static boolean checkUseCaseLimitNotExceeded(
+ @NonNull List<UseCase> originalUseCases,
+ @NonNull List<UseCase> newUseCases) {
+ int imageCaptureCount = 0;
+ int videoCaptureCount = 0;
+
+ if (newUseCases.isEmpty()) {
+ throw new IllegalArgumentException("No new use cases to be bound.");
+ }
+
+ for (UseCase useCase : originalUseCases) {
+ if (useCase instanceof ImageCapture) {
+ imageCaptureCount++;
+ } else if (useCase instanceof VideoCapture) {
+ videoCaptureCount++;
+ }
+ }
+
+ for (UseCase useCase : newUseCases) {
+ if (useCase instanceof ImageCapture) {
+ imageCaptureCount++;
+ } else if (useCase instanceof VideoCapture) {
+ videoCaptureCount++;
+ }
+ }
+
+ if (imageCaptureCount > 1) {
+ Log.e(TAG, "Exceeded max simultaneously bound image capture use cases.");
+ return false;
+ }
+
+ if (videoCaptureCount > 1) {
+ Log.e(TAG, "Exceeded max simultaneously bound video capture use cases.");
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/camera/camera-view/build.gradle b/camera/camera-view/build.gradle
index f98b2f0..d9ec121 100644
--- a/camera/camera-view/build.gradle
+++ b/camera/camera-view/build.gradle
@@ -38,6 +38,8 @@
testImplementation(MOCKITO_CORE)
testImplementation(ROBOLECTRIC)
testImplementation(TRUTH)
+ testImplementation(ANDROIDX_TEST_CORE)
+ testImplementation project(":camera:camera-testing")
androidTestImplementation(project(":camera:camera-testing"))
androidTestImplementation(MOCKITO_CORE)
diff --git a/camera/camera-view/src/androidTest/java/androidx/camera/view/preview/transform/PreviewTransformTest.java b/camera/camera-view/src/androidTest/java/androidx/camera/view/preview/transform/PreviewTransformTest.java
index 15594bf..9c37e86 100644
--- a/camera/camera-view/src/androidTest/java/androidx/camera/view/preview/transform/PreviewTransformTest.java
+++ b/camera/camera-view/src/androidTest/java/androidx/camera/view/preview/transform/PreviewTransformTest.java
@@ -16,8 +16,6 @@
package androidx.camera.view.preview.transform;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-
import static com.google.common.truth.Truth.assertThat;
import android.content.Context;
@@ -27,6 +25,7 @@
import androidx.camera.testing.fakes.FakeActivity;
import androidx.camera.view.PreviewView;
+import androidx.core.content.ContextCompat;
import androidx.test.annotation.UiThreadTest;
import androidx.test.rule.ActivityTestRule;
@@ -36,6 +35,7 @@
public class PreviewTransformTest {
+ private static final Size CONTAINER = new Size(800, 450);
private static final Size BUFFER = new Size(400, 300);
@Rule
@@ -49,57 +49,54 @@
public void setUp() throws Throwable {
mActivityTestRule.runOnUiThread(() -> {
final Context context = mActivityTestRule.getActivity();
+
+ final FrameLayout root = new FrameLayout(context);
+
mContainer = new FrameLayout(context);
- mContainer.setLayoutParams(new FrameLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
+ mContainer.setLayoutParams(
+ new FrameLayout.LayoutParams(CONTAINER.getWidth(), CONTAINER.getHeight()));
mView = new View(context);
mView.setLayoutParams(
new FrameLayout.LayoutParams(BUFFER.getWidth(), BUFFER.getHeight()));
+ mView.setBackgroundColor(
+ ContextCompat.getColor(context, android.R.color.holo_blue_dark));
mContainer.addView(mView);
- mActivityTestRule.getActivity().setContentView(mContainer);
+ root.addView(mContainer);
+ mActivityTestRule.getActivity().setContentView(root);
});
}
@Test
@UiThreadTest
public void fillStart() {
- PreviewTransform.transform(mContainer, mView, BUFFER, PreviewView.ScaleType.FILL_START);
+ PreviewTransform.applyScaleType(mContainer, mView, BUFFER,
+ PreviewView.ScaleType.FILL_START);
// Assert the preview fills its container
assertThat(mView.getWidth() * mView.getScaleX()).isAtLeast(mContainer.getWidth());
assertThat(mView.getHeight() * mView.getScaleY()).isAtLeast(mContainer.getHeight());
-
- // Assert the preview is at the start (top left) of its container
- assertThat(mView.getX()).isEqualTo(0);
- assertThat(mView.getY()).isEqualTo(0);
}
@Test
@UiThreadTest
public void fillCenter() {
- PreviewTransform.transform(mContainer, mView, BUFFER, PreviewView.ScaleType.FILL_CENTER);
+ PreviewTransform.applyScaleType(mContainer, mView, BUFFER,
+ PreviewView.ScaleType.FILL_CENTER);
// Assert the preview fills its container
assertThat(mView.getWidth() * mView.getScaleX()).isAtLeast(mContainer.getWidth());
assertThat(mView.getHeight() * mView.getScaleY()).isAtLeast(mContainer.getHeight());
-
- // Assert the preview is centered in its container
- assertThat(mView.getX() + mView.getWidth() / 2).isEqualTo(mContainer.getWidth() / 2);
- assertThat(mView.getY() + mView.getHeight() / 2).isEqualTo(mContainer.getHeight() / 2);
}
@Test
@UiThreadTest
public void fillEnd() {
- PreviewTransform.transform(mContainer, mView, BUFFER, PreviewView.ScaleType.FILL_END);
+ PreviewTransform.applyScaleType(mContainer, mView, BUFFER, PreviewView.ScaleType.FILL_END);
// Assert the preview fills its container
assertThat(mView.getWidth() * mView.getScaleX()).isAtLeast(mContainer.getWidth());
assertThat(mView.getHeight() * mView.getScaleY()).isAtLeast(mContainer.getHeight());
-
- // Assert the preview is at the end (bottom right) of its container
- assertThat(mView.getX() + mView.getWidth()).isEqualTo(mContainer.getWidth());
- assertThat(mView.getY() + mView.getHeight()).isEqualTo(mContainer.getHeight());
}
}
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/CameraView.java b/camera/camera-view/src/main/java/androidx/camera/view/CameraView.java
index 6a2461a..fa524da 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/CameraView.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/CameraView.java
@@ -46,7 +46,6 @@
import androidx.annotation.RestrictTo.Scope;
import androidx.camera.core.Camera;
import androidx.camera.core.CameraSelector;
-import androidx.camera.core.DisplayOrientedMeteringPointFactory;
import androidx.camera.core.FocusMeteringAction;
import androidx.camera.core.FocusMeteringResult;
import androidx.camera.core.ImageCapture;
@@ -54,6 +53,7 @@
import androidx.camera.core.ImageCapture.OnImageSavedCallback;
import androidx.camera.core.ImageProxy;
import androidx.camera.core.MeteringPoint;
+import androidx.camera.core.MeteringPointFactory;
import androidx.camera.core.VideoCapture.OnVideoSavedCallback;
import androidx.camera.core.impl.LensFacingConverter;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
@@ -577,8 +577,7 @@
new CameraSelector.Builder().requireLensFacing(
mCameraModule.getLensFacing()).build();
- DisplayOrientedMeteringPointFactory pointFactory = new DisplayOrientedMeteringPointFactory(
- getDisplay(), cameraSelector, mPreviewView.getWidth(), mPreviewView.getHeight());
+ MeteringPointFactory pointFactory = mPreviewView.createMeteringPointFactory(cameraSelector);
float afPointWidth = 1.0f / 6.0f; // 1/6 total area
float aePointWidth = afPointWidth * 1.5f;
MeteringPoint afPoint = pointFactory.createPoint(x, y, afPointWidth);
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/PreviewView.java b/camera/camera-view/src/main/java/androidx/camera/view/PreviewView.java
index 87bf85b..083ae98 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/PreviewView.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/PreviewView.java
@@ -21,10 +21,14 @@
import android.hardware.display.DisplayManager;
import android.os.Build;
import android.util.AttributeSet;
+import android.util.Size;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.camera.core.CameraSelector;
+import androidx.camera.core.MeteringPoint;
+import androidx.camera.core.MeteringPointFactory;
import androidx.camera.core.Preview;
import java.util.concurrent.Executor;
@@ -43,20 +47,23 @@
private ImplementationMode mImplementationMode;
+ private ScaleType mScaleType = ScaleType.FILL_CENTER;
+
private final DisplayManager.DisplayListener mDisplayListener =
new DisplayManager.DisplayListener() {
- @Override
- public void onDisplayAdded(int displayId) {
- }
+ @Override
+ public void onDisplayAdded(int displayId) {
+ }
- @Override
- public void onDisplayRemoved(int displayId) {
- }
- @Override
- public void onDisplayChanged(int displayId) {
- mImplementation.onDisplayChanged();
- }
- };
+ @Override
+ public void onDisplayRemoved(int displayId) {
+ }
+
+ @Override
+ public void onDisplayChanged(int displayId) {
+ mImplementation.onDisplayChanged();
+ }
+ };
public PreviewView(@NonNull Context context) {
this(context, null);
@@ -162,6 +169,21 @@
}
/**
+ * Creates a {@link MeteringPointFactory} by a given {@link CameraSelector}
+ *
+ * <p>This {@link MeteringPointFactory} is capable of creating a {@link MeteringPoint} by a
+ * (x, y) in the {@link PreviewView}. It converts the points by current scaleType.
+ *
+ * @param cameraSelector the CameraSelector which the {@link Preview} is bound to.
+ * @return a {@link MeteringPointFactory}
+ */
+ @NonNull
+ public MeteringPointFactory createMeteringPointFactory(@NonNull CameraSelector cameraSelector) {
+ return new PreviewViewMeteringPointFactory(getDisplay(), cameraSelector,
+ mImplementation.getResolution(), mScaleType, getWidth(), getHeight());
+ }
+
+ /**
* Implements this interface to create PreviewView implementation.
*/
interface Implementation {
@@ -180,12 +202,18 @@
Preview.SurfaceProvider getSurfaceProvider();
/**
- * Notifies that the display properties have changed.
+ * Notifies that the display properties have changed.
*
- * <p>Implementation might need to adjust transform by latest display properties such as
- * display orientation in order to show the preview correctly.
+ * <p>Implementation might need to adjust transform by latest display properties such as
+ * display orientation in order to show the preview correctly.
*/
void onDisplayChanged();
+
+ /**
+ * Returns current surface resolution.
+ */
+ @Nullable
+ Size getResolution();
}
/**
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/PreviewViewMeteringPointFactory.java b/camera/camera-view/src/main/java/androidx/camera/view/PreviewViewMeteringPointFactory.java
new file mode 100644
index 0000000..e24c5eb
--- /dev/null
+++ b/camera/camera-view/src/main/java/androidx/camera/view/PreviewViewMeteringPointFactory.java
@@ -0,0 +1,164 @@
+/*
+ * 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.camera.view;
+
+import android.graphics.Point;
+import android.graphics.PointF;
+import android.util.Size;
+import android.view.Display;
+import android.view.Surface;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.camera.core.CameraSelector;
+import androidx.camera.core.DisplayOrientedMeteringPointFactory;
+import androidx.camera.core.MeteringPoint;
+import androidx.camera.core.MeteringPointFactory;
+import androidx.camera.view.PreviewView.ScaleType;
+
+/**
+ * Implement the MeteringPointFactory for PreviewView by DisplayOrientedMeteringPointFactory.
+ *
+ * <p>The width / height in DisplayOrientedMeteringPointFactory defines area (0, 0) - (width,
+ * height) which represents the full preview surface. The (x, y) passed to createPoint()
+ * must be in this coordinate system.
+ *
+ * However, in PreviewView, the preview could be cropped or letterbox/pillarbox depending on
+ * the scaleType. Thus we need to adjust two things for DisplayOrientedMeteringPointFactory.
+ * (1) Calculate the new width/height of factory based on the FIT/FULL scaleType to make it
+ * represent the full preview
+ * (2) Add offset to the (x, y) in convertPoint based on the BEGIN/CENTER/END scaleType.
+ *
+ */
+class PreviewViewMeteringPointFactory extends MeteringPointFactory {
+ private DisplayOrientedMeteringPointFactory mDisplayOrientedMeteringPointFactory;
+ private final float mViewWidth;
+ private final float mViewHeight;
+ private float mFactoryWidth;
+ private float mFactoryHeight;
+ private final ScaleType mScaleType;
+ private final boolean mIsValid;
+
+ // TODO(b/150916047): Use Previewview scaleType transform to implement instead.
+ PreviewViewMeteringPointFactory(@NonNull Display display,
+ @NonNull CameraSelector cameraSelector, @Nullable Size resolution,
+ @NonNull ScaleType scaleType, int viewWidth, int viewHeight) {
+ mViewWidth = viewWidth;
+ mViewHeight = viewHeight;
+ mScaleType = scaleType;
+
+ // invalid condition
+ if (resolution == null || mViewWidth <= 0 || mViewHeight <= 0) {
+ mIsValid = false;
+ return;
+ }
+ mIsValid = true;
+
+ boolean needReverse = false;
+
+ if (isNaturalPortrait(display)) {
+ if (display.getRotation() == Surface.ROTATION_0
+ || display.getRotation() == Surface.ROTATION_180) {
+ needReverse = true;
+ }
+ } else {
+ if (display.getRotation() == Surface.ROTATION_90
+ || display.getRotation() == Surface.ROTATION_270) {
+ needReverse = true;
+ }
+ }
+
+ int bufferRotatedWidth;
+ int bufferRotatedHeight;
+ if (needReverse) {
+ bufferRotatedWidth = resolution.getHeight();
+ bufferRotatedHeight = resolution.getWidth();
+ } else {
+ bufferRotatedWidth = resolution.getWidth();
+ bufferRotatedHeight = resolution.getHeight();
+ }
+
+ final float scale;
+ if (mScaleType == ScaleType.FILL_CENTER
+ || mScaleType == ScaleType.FILL_START
+ || mScaleType == ScaleType.FILL_END) {
+ scale = Math.max((float) viewWidth / bufferRotatedWidth,
+ (float) viewHeight / bufferRotatedHeight);
+ } else if (mScaleType == ScaleType.FIT_START
+ || mScaleType == ScaleType.FIT_CENTER
+ || mScaleType == ScaleType.FIT_END) {
+ scale = Math.min((float) viewWidth / bufferRotatedWidth,
+ (float) viewHeight / bufferRotatedHeight);
+ } else {
+ throw new IllegalArgumentException("Unknown scale type " + scaleType);
+ }
+ mFactoryWidth = bufferRotatedWidth * scale;
+ mFactoryHeight = bufferRotatedHeight * scale;
+ mDisplayOrientedMeteringPointFactory =
+ new DisplayOrientedMeteringPointFactory(display, cameraSelector, mFactoryWidth,
+ mFactoryHeight);
+ }
+
+ @NonNull
+ @Override
+ protected PointF convertPoint(float x, float y) {
+ if (!mIsValid) {
+ // Returns a invalid point whose value is out of range [0..1]
+ return new PointF(2.0f, 2.0f);
+ }
+ float offsetX = 0f;
+ float offsetY = 0f;
+
+ if (mScaleType == ScaleType.FILL_START
+ || mScaleType == ScaleType.FIT_START) {
+ offsetX = 0;
+ offsetY = 0;
+ } else if (mScaleType == ScaleType.FILL_CENTER
+ || mScaleType == ScaleType.FIT_CENTER) {
+ offsetX = (mFactoryWidth - mViewWidth) / 2;
+ offsetY = (mFactoryHeight - mViewHeight) / 2;
+ } else if (mScaleType == ScaleType.FILL_END
+ || mScaleType == ScaleType.FIT_END) {
+ offsetX = (mFactoryWidth - mViewWidth);
+ offsetY = (mFactoryHeight - mViewHeight);
+ }
+
+ float adjustedX = x + offsetX;
+ float adjustedY = y + offsetY;
+
+ // DisplayOrientedMeteringPointFactory#convertPoint is not public, thus we cannot use
+ // it to convert the point. A alternative approach is using createPoint() to create a
+ // MeteringPoint and get X, Y from it.
+ MeteringPoint pt = mDisplayOrientedMeteringPointFactory.createPoint(adjustedX,
+ adjustedY);
+ return new PointF(pt.getX(), pt.getY());
+ }
+
+
+ private boolean isNaturalPortrait(Display display) {
+ final Point deviceSize = new Point();
+ display.getRealSize(deviceSize);
+ int rotation = display.getRotation();
+
+ final int width = deviceSize.x;
+ final int height = deviceSize.y;
+ return ((rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180)
+ && width < height) || (
+ (rotation == Surface.ROTATION_90 || rotation == Surface.ROTATION_270)
+ && width >= height);
+ }
+}
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/SurfaceViewImplementation.java b/camera/camera-view/src/main/java/androidx/camera/view/SurfaceViewImplementation.java
index b8c6316..8f0a518 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/SurfaceViewImplementation.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/SurfaceViewImplementation.java
@@ -39,6 +39,7 @@
// Synthetic Accessor
@SuppressWarnings("WeakerAccess")
TransformableSurfaceView mSurfaceView;
+ private Size mResolution;
// Synthetic Accessor
@SuppressWarnings("WeakerAccess")
@@ -46,14 +47,13 @@
new SurfaceRequestCallback();
private Preview.SurfaceProvider mSurfaceProvider =
- new Preview.SurfaceProvider() {
- @Override
- public void onSurfaceRequested(@NonNull SurfaceRequest surfaceRequest) {
- mSurfaceView.post(
- () -> mSurfaceRequestCallback.setSurfaceRequest(surfaceRequest));
- }
+ surfaceRequest -> {
+ mResolution = surfaceRequest.getResolution();
+ mSurfaceView.post(
+ () -> mSurfaceRequestCallback.setSurfaceRequest(surfaceRequest));
};
+
/**
* {@inheritDoc}
*/
@@ -68,6 +68,12 @@
mSurfaceView.getHolder().addCallback(mSurfaceRequestCallback);
}
+ @Nullable
+ @Override
+ public Size getResolution() {
+ return mResolution;
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/TextureViewImplementation.java b/camera/camera-view/src/main/java/androidx/camera/view/TextureViewImplementation.java
index 430b5a3..8287399 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/TextureViewImplementation.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/TextureViewImplementation.java
@@ -32,6 +32,7 @@
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import androidx.camera.core.Preview;
import androidx.camera.core.SurfaceRequest;
import androidx.camera.core.impl.utils.executor.CameraXExecutors;
@@ -85,6 +86,12 @@
};
}
+ @Nullable
+ @Override
+ public Size getResolution() {
+ return mResolution;
+ }
+
@Override
public void onDisplayChanged() {
if (mParent == null || mTextureView == null || mResolution == null) {
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/GravityTransform.java b/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/GravityTransform.java
deleted file mode 100644
index b60bac2..0000000
--- a/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/GravityTransform.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.camera.view.preview.transform;
-
-import android.graphics.Point;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-
-/**
- * Computes the x and y coordinates of the top left corner of the preview in order to position it
- * at the start (top left), center or end (bottom right) of its parent.
- */
-final class GravityTransform {
-
- private GravityTransform() {
- }
-
- /**
- * Computes the x and y coordinates of the top left corner of {@code view} so that it's
- * aligned to the top left corner of its parent {@code container}.
- */
- static Point start() {
- return new Point(0, 0);
- }
-
- /**
- * Computes the x and y coordinates of the top left corner of {@code view} so that it's
- * centered in its parent {@code container}.
- */
- static Point center(@NonNull final View container, @NonNull final View view) {
- final int offsetX = (container.getWidth() - view.getWidth()) / 2;
- final int offsetY = (container.getHeight() - view.getHeight()) / 2;
- return new Point(offsetX, offsetY);
- }
-
- /**
- * Computes the x and y coordinates of the top left corner of {@code view} so that it's
- * aligned to the bottom right corner of its parent {@code container}.
- */
- static Point end(@NonNull final View container, @NonNull final View view) {
- final int offsetX = container.getWidth() - view.getWidth();
- final int offsetY = container.getHeight() - view.getHeight();
- return new Point(offsetX, offsetY);
- }
-}
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/PreviewTransform.java b/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/PreviewTransform.java
index 3b3d733..0c16cb7 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/PreviewTransform.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/PreviewTransform.java
@@ -16,6 +16,8 @@
package androidx.camera.view.preview.transform;
+import static androidx.camera.view.preview.transform.transformation.Transformation.getTransformation;
+
import android.util.Size;
import android.view.View;
@@ -35,30 +37,44 @@
private PreviewTransform() {
}
- /**
- * Transforms a preview using a supported {@link PreviewView.ScaleType}.
- *
- * @param container A parent {@link View} that wraps {@code view}.
- * @param view A {@link View} that wraps the camera preview.
- * @param aspectRatio A {@link Size} whose aspect ratio must be maintained when scaling the
- * preview.
- * @param scaleType A supported {@link PreviewView.ScaleType} to apply on the camera preview.
- */
- public static void transform(@NonNull final View container, @NonNull final View view,
- @NonNull final Size aspectRatio, @NonNull final PreviewView.ScaleType scaleType) {
- final Transformation transformation = ScaleTypeTransform.getTransformation(container,
- view, aspectRatio, scaleType);
- applyTransformationToPreview(transformation, view);
+ /** Applies the specified {@link PreviewView.ScaleType} on the passed in preview. */
+ public static void applyScaleType(@NonNull final View container, @NonNull final View view,
+ @NonNull final Size bufferSize, @NonNull PreviewView.ScaleType scaleType) {
+ resetPreview(view);
+ correctPreview(container, view, bufferSize);
+ applyScaleTypeInternal(container, view, scaleType);
+ }
+
+ private static void resetPreview(@NonNull View view) {
+ final Transformation reset = new Transformation();
+ applyTransformation(view, reset);
+ }
+
+ /** Corrects the preview. */
+ private static void correctPreview(@NonNull final View container, @NonNull final View view,
+ @NonNull final Size bufferSize) {
+ final Transformation correct = PreviewCorrector.getCorrectionTransformation(container, view,
+ bufferSize);
+ applyTransformation(view, correct);
+ }
+
+ /** Applies the specified {@link PreviewView.ScaleType} on top of the corrected preview. */
+ private static void applyScaleTypeInternal(@NonNull final View container,
+ @NonNull final View view, @NonNull final PreviewView.ScaleType scaleType) {
+ final Transformation current = getTransformation(view);
+ final Transformation transformation = ScaleTypeTransform.getTransformation(container, view,
+ scaleType);
+ applyTransformation(view, current.add(transformation));
}
/**
- * Applies a {@link Transformation} to a preview.
- *
- * @param transformation A transformation to apply on the preview.
- * @param view A {@link View} that wraps the camera preview.
+ * Applies a {@link Transformation} on the passed in preview while overriding any previous
+ * preview {@linkplain Transformation transformations}
*/
- private static void applyTransformationToPreview(@NonNull final Transformation transformation,
- @NonNull final View view) {
+ private static void applyTransformation(@NonNull final View view,
+ @NonNull final Transformation transformation) {
+ view.setX(0);
+ view.setY(0);
view.setScaleX(transformation.getScaleX());
view.setScaleY(transformation.getScaleY());
view.setTranslationX(transformation.getTransX());
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/ScaleTransform.java b/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/ScaleTransform.java
index c05be26..e496680 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/ScaleTransform.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/ScaleTransform.java
@@ -16,124 +16,62 @@
package androidx.camera.view.preview.transform;
-import android.graphics.Point;
-import android.util.Pair;
-import android.util.Size;
-import android.view.Display;
import android.view.View;
import androidx.annotation.NonNull;
+import androidx.camera.view.preview.transform.transformation.ScaleTransformation;
+/**
+ * Computes the scale on both the x and y axes to uniformly scale up or down a view inside its
+ * container, so that it entirely fills it, or is entirely container within it.
+ */
final class ScaleTransform {
private ScaleTransform() {
}
/**
- * Computes the scales on both the x and y axes so that the preview can fill its container,
- * while maintaining the camera output size's aspect ratio.
- *
- * @param container A parent {@link View} that wraps {@code view}.
- * @param view A {@link View} that wraps the camera preview.
- * @param bufferSize A {@link Size} whose aspect ratio must be maintained when
- * scaling the preview.
- * @return The scales on both the x and y axes so that the preview can entirely fill its
- * container, while maintaining the camera output size's aspect ratio
+ * Computes the scale on both the x and y axes so that the view can uniformly fill its
+ * container.
*/
- @SuppressWarnings("SuspiciousNameCombination")
- static Pair<Float, Float> fill(@NonNull final View container, @NonNull final View view,
- @NonNull final Size bufferSize) {
+ static ScaleTransformation fill(@NonNull final View container, @NonNull final View view) {
+ return computeScale(container, view, Math::max);
+ }
+
+ /**
+ * Computes the scale on both the x and y axes so that the view can uniformly fit inside its
+ * container.
+ */
+ static ScaleTransformation fit(@NonNull final View container, @NonNull final View view) {
+ return computeScale(container, view, Math::min);
+ }
+
+ private static ScaleTransformation computeScale(@NonNull final View container,
+ @NonNull final View view, @NonNull final FloatBiFunction function) {
// Scaling only makes sense when none of the dimensions are equal to zero. In the
// opposite case, a default scale of 1 is returned,
if (container.getWidth() == 0 || container.getHeight() == 0 || view.getWidth() == 0
- || view.getHeight() == 0 || bufferSize.getWidth() == 0
- || bufferSize.getHeight() == 0) {
- return new Pair<>(1F, 1F);
+ || view.getHeight() == 0) {
+ return new ScaleTransformation(1);
}
final int viewRotationDegrees = (int) RotationTransform.getRotationDegrees(view);
- final boolean isNaturalPortrait = isNaturalPortrait(view, viewRotationDegrees);
-
- final int bufferWidth;
- final int bufferHeight;
- if (isNaturalPortrait) {
- bufferWidth = bufferSize.getHeight();
- bufferHeight = bufferSize.getWidth();
- } else {
- bufferWidth = bufferSize.getWidth();
- bufferHeight = bufferSize.getHeight();
- }
-
- // Scale the buffers back to the original output size.
- float scaleX = bufferWidth / (float) view.getWidth();
- float scaleY = bufferHeight / (float) view.getHeight();
-
- int bufferRotatedWidth;
- int bufferRotatedHeight;
+ float bufferRotatedWidth;
+ float bufferRotatedHeight;
if (viewRotationDegrees == 0 || viewRotationDegrees == 180) {
- bufferRotatedWidth = bufferWidth;
- bufferRotatedHeight = bufferHeight;
+ bufferRotatedWidth = view.getWidth() * view.getScaleX();
+ bufferRotatedHeight = view.getHeight() * view.getScaleY();
} else {
- bufferRotatedWidth = bufferHeight;
- bufferRotatedHeight = bufferWidth;
+ bufferRotatedWidth = view.getHeight() * view.getScaleY();
+ bufferRotatedHeight = view.getWidth() * view.getScaleX();
}
- // Scale the buffer so that it completely fills the container.
- final float scale = Math.max(container.getWidth() / (float) bufferRotatedWidth,
- container.getHeight() / (float) bufferRotatedHeight);
- scaleX *= scale;
- scaleY *= scale;
-
- return new Pair<>(scaleX, scaleY);
+ final float scale = function.apply(container.getWidth() / bufferRotatedWidth,
+ container.getHeight() / bufferRotatedHeight);
+ return new ScaleTransformation(scale);
}
- /**
- * Computes the scales on both the x and y axes so that the preview is entirely contained within
- * its container, while maintaining the camera output size's aspect ratio.
- *
- * @param container A parent {@link View} that wraps {@code view}.
- * @param view A {@link View} that wraps the camera preview.
- * @param bufferSize A {@link Size} whose aspect ratio must be maintained when
- * scaling the preview.
- * @return The scales on both the x and y axes so that the preview is entirely contained within
- * its container, while maintaining the camera output size's aspect ratio.
- */
- static Pair<Float, Float> fit(@NonNull final View container, @NonNull final View view,
- @NonNull final Size bufferSize) {
- return new Pair<>(1F, 1F);
- }
-
- /**
- * Determines whether the current device is a natural portrait-oriented device
- *
- * <p>
- * Using the current app's window to determine whether the device is a natural
- * portrait-oriented device doesn't work in all scenarios, one example of this is multi-window
- * mode.
- * Taking a natural portrait-oriented device in multi-window mode, rotating it 90 degrees (so
- * that it's in landscape), with the app open, and its window's width being smaller than its
- * height. Using the app's width and height would determine that the device isn't
- * naturally portrait-oriented, where in fact it is, which is why it is important to use the
- * size of the device instead.
- * </p>
- *
- * @param view A {@link View} used to get the current {@link Display}.
- * @param rotationDegrees The device's rotation in degrees from its natural orientation.
- * @return Whether the device is naturally portrait-oriented.
- */
- private static boolean isNaturalPortrait(@NonNull final View view,
- final int rotationDegrees) {
- final Display display = view.getDisplay();
- if (display == null) {
- return true;
- }
-
- final Point deviceSize = new Point();
- display.getRealSize(deviceSize);
-
- final int width = deviceSize.x;
- final int height = deviceSize.y;
- return ((rotationDegrees == 0 || rotationDegrees == 180) && width < height) || (
- (rotationDegrees == 90 || rotationDegrees == 270) && width >= height);
+ private interface FloatBiFunction {
+ float apply(float a, float b);
}
}
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/ScaleTypeTransform.java b/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/ScaleTypeTransform.java
index 840dfcc..53b736a 100644
--- a/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/ScaleTypeTransform.java
+++ b/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/ScaleTypeTransform.java
@@ -16,60 +16,65 @@
package androidx.camera.view.preview.transform;
-import android.graphics.Point;
import android.util.Pair;
-import android.util.Size;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.camera.view.PreviewView;
+import androidx.camera.view.preview.transform.transformation.ScaleTransformation;
import androidx.camera.view.preview.transform.transformation.Transformation;
+import androidx.camera.view.preview.transform.transformation.TranslationTransformation;
final class ScaleTypeTransform {
private ScaleTypeTransform() {
}
- /**
- * Converts a {@link PreviewView.ScaleType} to a {@link Transformation}.
- */
+ /** Converts a {@link PreviewView.ScaleType} to a {@link Transformation} */
static Transformation getTransformation(@NonNull final View container, @NonNull final View view,
- @NonNull final Size bufferSize, @NonNull final PreviewView.ScaleType scaleType) {
- final Pair<Float, Float> scaleXY = getScaleXY(container, view, bufferSize, scaleType);
- final Point origin = getGravityOrigin(container, view, scaleType);
- final float rotation = -RotationTransform.getRotationDegrees(view);
- return new Transformation(scaleXY.first, scaleXY.second, origin.x, origin.y, rotation);
+ @NonNull final PreviewView.ScaleType scaleType) {
+ final Transformation scale = getScale(container, view, scaleType);
+
+ // Use the current preview scale AND the scale that's about to be applied to it to figure
+ // out how to position the preview in its container
+ final Pair<Float, Float> scaleXY = new Pair<>(view.getScaleX() * scale.getScaleX(),
+ view.getScaleY() * scale.getScaleY());
+ final Transformation translation = getScaledTranslation(container, view, scaleType,
+ scaleXY);
+
+ return scale.add(translation);
}
- private static Pair<Float, Float> getScaleXY(@NonNull final View container,
- @NonNull final View view, @NonNull final Size bufferSize,
+ private static ScaleTransformation getScale(@NonNull final View container,
+ @NonNull final View view,
final PreviewView.ScaleType scaleType) {
switch (scaleType) {
case FILL_START:
case FILL_CENTER:
case FILL_END:
- return ScaleTransform.fill(container, view, bufferSize);
+ return ScaleTransform.fill(container, view);
case FIT_START:
case FIT_CENTER:
case FIT_END:
- return ScaleTransform.fit(container, view, bufferSize);
+ return ScaleTransform.fit(container, view);
default:
throw new IllegalArgumentException("Unknown scale type " + scaleType);
}
}
- private static Point getGravityOrigin(@NonNull final View container, @NonNull final View view,
- @NonNull final PreviewView.ScaleType scaleType) {
+ private static TranslationTransformation getScaledTranslation(@NonNull final View container,
+ @NonNull final View view, @NonNull final PreviewView.ScaleType scaleType,
+ @NonNull final Pair<Float, Float> scaleXY) {
switch (scaleType) {
case FILL_START:
case FIT_START:
- return GravityTransform.start();
+ return TranslationTransform.start(view, scaleXY);
case FILL_CENTER:
case FIT_CENTER:
- return GravityTransform.center(container, view);
+ return TranslationTransform.center(container, view);
case FILL_END:
case FIT_END:
- return GravityTransform.end(container, view);
+ return TranslationTransform.end(container, view, scaleXY);
default:
throw new IllegalArgumentException("Unknown scale type " + scaleType);
}
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/TranslationTransform.java b/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/TranslationTransform.java
new file mode 100644
index 0000000..b7a3788
--- /dev/null
+++ b/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/TranslationTransform.java
@@ -0,0 +1,134 @@
+/*
+ * 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.camera.view.preview.transform;
+
+import android.util.Pair;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.camera.view.preview.transform.transformation.TranslationTransformation;
+
+/**
+ * Computes the x and y coordinates of the top left corner of the preview in order to position it
+ * at the start (top left), center or end (bottom right) of its parent.
+ */
+final class TranslationTransform {
+
+ private TranslationTransform() {
+ }
+
+ /**
+ * Computes the x and y coordinates of the top left corner of {@code view} so that it's
+ * aligned to the top left corner of its parent {@code container}.
+ */
+ static TranslationTransformation start(@NonNull final View view,
+ @NonNull final Pair<Float, Float> scaleXY) {
+ if (view.getWidth() == 0 || view.getHeight() == 0) {
+ return new TranslationTransformation(0, 0);
+ }
+
+ // Scaled width and height of the view
+ final int scaledWidth = (int) (view.getWidth() * scaleXY.first);
+ final int scaledHeight = (int) (view.getHeight() * scaleXY.second);
+
+ final int viewRotationDegrees = (int) RotationTransform.getRotationDegrees(view);
+ final boolean isPortrait = viewRotationDegrees == 0 || viewRotationDegrees == 180;
+
+ // Coordinates of the view's center after the `start` translation
+ final int targetCenterX;
+ final int targetCenterY;
+ if (isPortrait) {
+ targetCenterX = scaledWidth / 2;
+ targetCenterY = scaledHeight / 2;
+ } else {
+ targetCenterX = scaledHeight / 2;
+ targetCenterY = scaledWidth / 2;
+ }
+
+ // Current coordinates of the view's center
+ final int currentCenterX = view.getWidth() / 2;
+ final int currentCenterY = view.getHeight() / 2;
+
+ final int transX = targetCenterX - currentCenterX;
+ final int transY = targetCenterY - currentCenterY;
+ return new TranslationTransformation(transX, transY);
+ }
+
+ /**
+ * Computes the x and y coordinates of the top left corner of {@code view} so that it's
+ * centered in its parent {@code container}.
+ */
+ static TranslationTransformation center(@NonNull final View container,
+ @NonNull final View view) {
+ if (view.getWidth() == 0 || view.getHeight() == 0) {
+ return new TranslationTransformation(0, 0);
+ }
+
+ // Coordinates of the view's center after the `center` translation
+ final int targetCenterX = container.getWidth() / 2;
+ final int targetCenterY = container.getHeight() / 2;
+
+ // Current coordinates of the view's center
+ final int currentCenterX = view.getWidth() / 2;
+ final int currentCenterY = view.getHeight() / 2;
+
+ final int transX = targetCenterX - currentCenterX;
+ final int transY = targetCenterY - currentCenterY;
+ return new TranslationTransformation(transX, transY);
+ }
+
+ /**
+ * Computes the x and y coordinates of the top left corner of {@code view} so that it's
+ * aligned to the bottom right corner of its parent {@code container}.
+ */
+ static TranslationTransformation end(@NonNull final View container, @NonNull final View view,
+ @NonNull final Pair<Float, Float> scaleXY) {
+ if (view.getWidth() == 0 || view.getHeight() == 0) {
+ return new TranslationTransformation(0, 0);
+ }
+
+ // Coordinates of the bottom right corner of the container
+ final int endX = container.getWidth();
+ final int endY = container.getHeight();
+
+ // Scaled width and height of the view
+ final int scaledWidth = (int) (view.getWidth() * scaleXY.first);
+ final int scaledHeight = (int) (view.getHeight() * scaleXY.second);
+
+ final int viewRotationDegrees = (int) RotationTransform.getRotationDegrees(view);
+ final boolean isPortrait = viewRotationDegrees == 0 || viewRotationDegrees == 180;
+
+ // Coordinates of the view's center after the `end` translation
+ final int targetCenterX;
+ final int targetCenterY;
+ if (isPortrait) {
+ targetCenterX = endX - (scaledWidth / 2);
+ targetCenterY = endY - (scaledHeight / 2);
+ } else {
+ targetCenterX = endX - (scaledHeight / 2);
+ targetCenterY = endY - (scaledWidth / 2);
+ }
+
+ // Current coordinates of the view's center
+ final int currentCenterX = view.getWidth() / 2;
+ final int currentCenterY = view.getHeight() / 2;
+
+ final int transX = targetCenterX - currentCenterX;
+ final int transY = targetCenterY - currentCenterY;
+ return new TranslationTransformation(transX, transY);
+ }
+}
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/transformation/ScaleTransformation.java b/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/transformation/ScaleTransformation.java
new file mode 100644
index 0000000..da113f0
--- /dev/null
+++ b/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/transformation/ScaleTransformation.java
@@ -0,0 +1,32 @@
+/*
+ * 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.camera.view.preview.transform.transformation;
+
+import androidx.annotation.RestrictTo;
+
+/**
+ * A {@link Transformation} used for scaling on the x and y axes.
+ *
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+public final class ScaleTransformation extends Transformation {
+
+ public ScaleTransformation(float scale) {
+ super(scale, scale, 0, 0, 0);
+ }
+}
diff --git a/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/transformation/TranslationTransformation.java b/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/transformation/TranslationTransformation.java
new file mode 100644
index 0000000..4b214ab
--- /dev/null
+++ b/camera/camera-view/src/main/java/androidx/camera/view/preview/transform/transformation/TranslationTransformation.java
@@ -0,0 +1,33 @@
+/*
+ * 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.camera.view.preview.transform.transformation;
+
+
+import androidx.annotation.RestrictTo;
+
+/**
+ * A {@link Transformation} used for positioning.
+ *
+ * @hide
+ */
+@RestrictTo(RestrictTo.Scope.LIBRARY)
+public final class TranslationTransformation extends Transformation {
+
+ public TranslationTransformation(float transX, float transY) {
+ super(1, 1, transX, transY, 0);
+ }
+}
diff --git a/camera/camera-view/src/test/java/androidx/camera/view/PreviewViewMeteringPointFactoryTest.java b/camera/camera-view/src/test/java/androidx/camera/view/PreviewViewMeteringPointFactoryTest.java
new file mode 100644
index 0000000..385afa2
--- /dev/null
+++ b/camera/camera-view/src/test/java/androidx/camera/view/PreviewViewMeteringPointFactoryTest.java
@@ -0,0 +1,490 @@
+/*
+ * 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.camera.view;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.when;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.util.Size;
+import android.view.Display;
+import android.view.Surface;
+
+import androidx.annotation.NonNull;
+import androidx.camera.core.CameraSelector;
+import androidx.camera.core.CameraX;
+import androidx.camera.core.CameraXConfig;
+import androidx.camera.core.DisplayOrientedMeteringPointFactory;
+import androidx.camera.core.MeteringPoint;
+import androidx.camera.core.impl.CameraDeviceSurfaceManager;
+import androidx.camera.core.impl.ExtendableUseCaseConfigFactory;
+import androidx.camera.core.impl.UseCaseConfigFactory;
+import androidx.camera.testing.fakes.FakeCamera;
+import androidx.camera.testing.fakes.FakeCameraDeviceSurfaceManager;
+import androidx.camera.testing.fakes.FakeCameraFactory;
+import androidx.camera.testing.fakes.FakeCameraInfoInternal;
+import androidx.camera.testing.fakes.FakeUseCaseConfig;
+import androidx.test.core.app.ApplicationProvider;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.robolectric.ParameterizedRobolectricTestRunner;
+import org.robolectric.annotation.internal.DoNotInstrument;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+@RunWith(ParameterizedRobolectricTestRunner.class)
+@DoNotInstrument
+public class PreviewViewMeteringPointFactoryTest {
+ private static final Size RESOLUTION = new Size(2000, 1000);
+ private static final int VIEW_WIDTH = 100;
+ private static final int VIEW_HEIGHT = 100;
+ private static final String FRONT_CAMERA_ID = "1";
+ private static final String BACK_CAMERA_ID = "0";
+ private static final String BACK_CAMERA_FOR_TABLET_ID = "2";
+
+ @ParameterizedRobolectricTestRunner.Parameter(0)
+ public CameraSelector mCameraSelector;
+
+ // Useless, just for showing parameter name during test.
+ @ParameterizedRobolectricTestRunner.Parameter(1)
+ public String mName;
+
+ @ParameterizedRobolectricTestRunner.Parameters(name = "{1}")
+ public static Collection<Object[]> getParameters() {
+ List<Object[]> result = new ArrayList<>();
+ result.add(new Object[]{CameraSelector.DEFAULT_BACK_CAMERA, "Back camera"});
+ result.add(new Object[]{CameraSelector.DEFAULT_FRONT_CAMERA, "Front camera"});
+ return result;
+ }
+
+ private Display mDisplay;
+
+ @Before
+ public void setUp() throws Exception {
+ Context context = ApplicationProvider.getApplicationContext();
+
+ // Init CameraX to inject our FakeCamera with FakeCameraInfo.
+ FakeCameraFactory fakeCameraFactory = new FakeCameraFactory();
+ fakeCameraFactory.insertDefaultBackCamera(BACK_CAMERA_ID,
+ () -> new FakeCamera(null,
+ new FakeCameraInfoInternal(90, CameraSelector.LENS_FACING_BACK)));
+ fakeCameraFactory.insertDefaultFrontCamera(FRONT_CAMERA_ID,
+ () -> new FakeCamera(null,
+ new FakeCameraInfoInternal(270, CameraSelector.LENS_FACING_FRONT)));
+
+ fakeCameraFactory.insertDefaultFrontCamera(BACK_CAMERA_FOR_TABLET_ID,
+ () -> new FakeCamera(null,
+ new FakeCameraInfoInternal(270, CameraSelector.LENS_FACING_FRONT)));
+
+ CameraDeviceSurfaceManager.Provider surfaceManagerProvider =
+ ignored -> new FakeCameraDeviceSurfaceManager();
+ UseCaseConfigFactory.Provider configFactoryProvider = ignored -> {
+ ExtendableUseCaseConfigFactory defaultConfigFactory =
+ new ExtendableUseCaseConfigFactory();
+ defaultConfigFactory.installDefaultProvider(FakeUseCaseConfig.class,
+ cameraInfo -> new FakeUseCaseConfig.Builder().getUseCaseConfig());
+ return defaultConfigFactory;
+ };
+
+ CameraXConfig cameraXConfig =
+ new CameraXConfig.Builder()
+ .setCameraFactoryProvider(ignored -> fakeCameraFactory)
+ .setDeviceSurfaceManagerProvider(surfaceManagerProvider)
+ .setUseCaseConfigFactoryProvider(configFactoryProvider)
+ .build();
+ CameraX.initialize(context, cameraXConfig);
+
+ mDisplay = Mockito.mock(Display.class);
+
+ mockDisplay(Surface.ROTATION_0, 1080, 1920);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ CameraX.shutdown().get();
+ }
+
+ @Test
+ public void fillCenter_rotation0() {
+ final int adjustedViewWidth = 100;
+ final int adjustedViewHeight = 200;
+ PreviewViewMeteringPointFactory factory = new PreviewViewMeteringPointFactory(mDisplay,
+ mCameraSelector, RESOLUTION, PreviewView.ScaleType.FILL_CENTER, VIEW_WIDTH,
+ VIEW_HEIGHT);
+
+ DisplayOrientedMeteringPointFactory displayFactory =
+ new DisplayOrientedMeteringPointFactory(mDisplay, mCameraSelector,
+ adjustedViewWidth,
+ adjustedViewHeight);
+
+ assertEqual(
+ factory.createPoint(0, 0),
+ displayFactory.createPoint(0, 50));
+ assertEqual(
+ factory.createPoint(VIEW_WIDTH, 0),
+ displayFactory.createPoint(adjustedViewWidth, 50));
+ assertEqual(
+ factory.createPoint(0, VIEW_HEIGHT),
+ displayFactory.createPoint(0, adjustedViewHeight - 50));
+ assertEqual(
+ factory.createPoint(VIEW_WIDTH, VIEW_HEIGHT),
+ displayFactory.createPoint(adjustedViewWidth, adjustedViewHeight - 50));
+ }
+
+ @Test
+ public void fillStart_rotation0() {
+ final int adjustedViewWidth = 100;
+ final int adjustedViewHeight = 200;
+ PreviewViewMeteringPointFactory factory = new PreviewViewMeteringPointFactory(mDisplay,
+ mCameraSelector, RESOLUTION, PreviewView.ScaleType.FILL_START, VIEW_WIDTH,
+ VIEW_HEIGHT);
+
+ DisplayOrientedMeteringPointFactory displayFactory =
+ new DisplayOrientedMeteringPointFactory(mDisplay, mCameraSelector,
+ adjustedViewWidth,
+ adjustedViewHeight);
+
+ assertEqual(
+ factory.createPoint(0, 0),
+ displayFactory.createPoint(0, 0));
+ assertEqual(
+ factory.createPoint(VIEW_WIDTH, 0),
+ displayFactory.createPoint(adjustedViewWidth, 0));
+ assertEqual(
+ factory.createPoint(0, VIEW_HEIGHT),
+ displayFactory.createPoint(0, adjustedViewHeight - 100));
+ assertEqual(
+ factory.createPoint(VIEW_WIDTH, VIEW_HEIGHT),
+ displayFactory.createPoint(adjustedViewWidth, adjustedViewHeight - 100));
+ }
+
+ @Test
+ public void fillEnd_rotation0() {
+ final int adjustedViewWidth = 100;
+ final int adjustedViewHeight = 200;
+ PreviewViewMeteringPointFactory factory = new PreviewViewMeteringPointFactory(mDisplay,
+ mCameraSelector, RESOLUTION, PreviewView.ScaleType.FILL_END, VIEW_WIDTH,
+ VIEW_HEIGHT);
+
+ DisplayOrientedMeteringPointFactory displayFactory =
+ new DisplayOrientedMeteringPointFactory(mDisplay, mCameraSelector,
+ adjustedViewWidth,
+ adjustedViewHeight);
+
+ assertEqual(
+ factory.createPoint(0, 0),
+ displayFactory.createPoint(0, 100));
+ assertEqual(
+ factory.createPoint(VIEW_WIDTH, 0),
+ displayFactory.createPoint(adjustedViewWidth, 100));
+ assertEqual(
+ factory.createPoint(0, VIEW_HEIGHT),
+ displayFactory.createPoint(0, adjustedViewHeight));
+ assertEqual(
+ factory.createPoint(VIEW_WIDTH, VIEW_HEIGHT),
+ displayFactory.createPoint(adjustedViewWidth, adjustedViewHeight));
+ }
+
+ @Test
+ public void fillCenter_rotation90() {
+ mockDisplay(Surface.ROTATION_90, 1920, 1080);
+
+ final int adjustedViewWidth = 200;
+ final int adjustedViewHeight = 100;
+ PreviewViewMeteringPointFactory factory = new PreviewViewMeteringPointFactory(mDisplay,
+ mCameraSelector, RESOLUTION, PreviewView.ScaleType.FILL_CENTER, VIEW_WIDTH,
+ VIEW_HEIGHT);
+
+ DisplayOrientedMeteringPointFactory displayFactory =
+ new DisplayOrientedMeteringPointFactory(mDisplay, mCameraSelector,
+ adjustedViewWidth,
+ adjustedViewHeight);
+
+ assertEqual(
+ factory.createPoint(0, 0),
+ displayFactory.createPoint(50, 0));
+ assertEqual(
+ factory.createPoint(VIEW_WIDTH, 0),
+ displayFactory.createPoint(adjustedViewWidth - 50, 0));
+ assertEqual(
+ factory.createPoint(0, VIEW_HEIGHT),
+ displayFactory.createPoint(50, adjustedViewHeight));
+ assertEqual(
+ factory.createPoint(VIEW_WIDTH, VIEW_HEIGHT),
+ displayFactory.createPoint(adjustedViewWidth - 50, adjustedViewHeight));
+ }
+
+ @Test
+ public void fillStart_rotation90() {
+ mockDisplay(Surface.ROTATION_90, 1920, 1080);
+
+ final int adjustedViewWidth = 200;
+ final int adjustedViewHeight = 100;
+ PreviewViewMeteringPointFactory factory = new PreviewViewMeteringPointFactory(mDisplay,
+ mCameraSelector, RESOLUTION, PreviewView.ScaleType.FILL_START, VIEW_WIDTH,
+ VIEW_HEIGHT);
+
+ DisplayOrientedMeteringPointFactory displayFactory =
+ new DisplayOrientedMeteringPointFactory(mDisplay, mCameraSelector,
+ adjustedViewWidth,
+ adjustedViewHeight);
+
+ assertEqual(
+ factory.createPoint(0, 0),
+ displayFactory.createPoint(0, 0));
+ assertEqual(
+ factory.createPoint(VIEW_WIDTH, 0),
+ displayFactory.createPoint(adjustedViewWidth - 100, 0));
+ assertEqual(
+ factory.createPoint(0, VIEW_HEIGHT),
+ displayFactory.createPoint(0, adjustedViewHeight));
+ assertEqual(
+ factory.createPoint(VIEW_WIDTH, VIEW_HEIGHT),
+ displayFactory.createPoint(adjustedViewWidth - 100, adjustedViewHeight));
+ }
+
+ @Test
+ public void fillEnd_rotation90() {
+ mockDisplay(Surface.ROTATION_90, 1920, 1080);
+
+ final int adjustedViewWidth = 200;
+ final int adjustedViewHeight = 100;
+ PreviewViewMeteringPointFactory factory = new PreviewViewMeteringPointFactory(mDisplay,
+ mCameraSelector, RESOLUTION, PreviewView.ScaleType.FILL_END, VIEW_WIDTH,
+ VIEW_HEIGHT);
+
+ DisplayOrientedMeteringPointFactory displayFactory =
+ new DisplayOrientedMeteringPointFactory(mDisplay, mCameraSelector,
+ adjustedViewWidth,
+ adjustedViewHeight);
+
+ assertEqual(
+ factory.createPoint(0, 0),
+ displayFactory.createPoint(100, 0));
+ assertEqual(
+ factory.createPoint(VIEW_WIDTH, 0),
+ displayFactory.createPoint(adjustedViewWidth, 0));
+ assertEqual(
+ factory.createPoint(0, VIEW_HEIGHT),
+ displayFactory.createPoint(100, adjustedViewHeight));
+ assertEqual(
+ factory.createPoint(VIEW_WIDTH, VIEW_HEIGHT),
+ displayFactory.createPoint(adjustedViewWidth, adjustedViewHeight));
+ }
+
+ @Test
+ public void fitCenter_rotation0() {
+ final int adjustedViewWidth = 50;
+ final int adjustedViewHeight = 100;
+ PreviewViewMeteringPointFactory factory = new PreviewViewMeteringPointFactory(mDisplay,
+ mCameraSelector, RESOLUTION, PreviewView.ScaleType.FIT_CENTER, VIEW_WIDTH,
+ VIEW_HEIGHT);
+
+ DisplayOrientedMeteringPointFactory displayFactory =
+ new DisplayOrientedMeteringPointFactory(mDisplay, mCameraSelector,
+ adjustedViewWidth,
+ adjustedViewHeight);
+
+ assertEqual(
+ displayFactory.createPoint(0, 0),
+ factory.createPoint(25, 0));
+ assertEqual(
+ displayFactory.createPoint(adjustedViewWidth, 0),
+ factory.createPoint(VIEW_WIDTH - 25, 0));
+ assertEqual(
+ displayFactory.createPoint(0, adjustedViewHeight),
+ factory.createPoint(25, VIEW_HEIGHT));
+ assertEqual(
+ displayFactory.createPoint(adjustedViewWidth, adjustedViewHeight),
+ factory.createPoint(VIEW_WIDTH - 25, VIEW_HEIGHT)
+ );
+ }
+
+ @Test
+ public void fitStart_rotation0() {
+ final int adjustedViewWidth = 50;
+ final int adjustedViewHeight = 100;
+ PreviewViewMeteringPointFactory factory = new PreviewViewMeteringPointFactory(mDisplay,
+ mCameraSelector, RESOLUTION, PreviewView.ScaleType.FIT_START, VIEW_WIDTH,
+ VIEW_HEIGHT);
+
+ DisplayOrientedMeteringPointFactory displayFactory =
+ new DisplayOrientedMeteringPointFactory(mDisplay, mCameraSelector,
+ adjustedViewWidth,
+ adjustedViewHeight);
+
+ assertEqual(
+ displayFactory.createPoint(0, 0),
+ factory.createPoint(0, 0));
+ assertEqual(
+ displayFactory.createPoint(adjustedViewWidth, 0),
+ factory.createPoint(VIEW_WIDTH - 50, 0));
+ assertEqual(
+ displayFactory.createPoint(0, adjustedViewHeight),
+ factory.createPoint(0, VIEW_HEIGHT));
+ assertEqual(
+ displayFactory.createPoint(adjustedViewWidth, adjustedViewHeight),
+ factory.createPoint(VIEW_WIDTH - 50, VIEW_HEIGHT));
+ }
+
+ @Test
+ public void fitEnd_rotation0() {
+ final int adjustedViewWidth = 50;
+ final int adjustedViewHeight = 100;
+ PreviewViewMeteringPointFactory factory = new PreviewViewMeteringPointFactory(mDisplay,
+ mCameraSelector, RESOLUTION, PreviewView.ScaleType.FIT_END, VIEW_WIDTH,
+ VIEW_HEIGHT);
+
+ DisplayOrientedMeteringPointFactory displayFactory =
+ new DisplayOrientedMeteringPointFactory(mDisplay, mCameraSelector,
+ adjustedViewWidth,
+ adjustedViewHeight);
+
+ assertEqual(
+ displayFactory.createPoint(0, 0),
+ factory.createPoint(50, 0));
+ assertEqual(
+ displayFactory.createPoint(adjustedViewWidth, 0),
+ factory.createPoint(VIEW_WIDTH, 0));
+ assertEqual(
+ displayFactory.createPoint(0, adjustedViewHeight),
+ factory.createPoint(50, VIEW_HEIGHT));
+ assertEqual(
+ displayFactory.createPoint(adjustedViewWidth, adjustedViewHeight),
+ factory.createPoint(VIEW_WIDTH, VIEW_HEIGHT));
+ }
+
+ @Test
+ public void fitCenter_rotation90() {
+ mockDisplay(Surface.ROTATION_90, 1920, 1080);
+
+ final int adjustedViewWidth = 100;
+ final int adjustedViewHeight = 50;
+ PreviewViewMeteringPointFactory factory = new PreviewViewMeteringPointFactory(mDisplay,
+ mCameraSelector, RESOLUTION, PreviewView.ScaleType.FIT_CENTER, VIEW_WIDTH,
+ VIEW_HEIGHT);
+
+ DisplayOrientedMeteringPointFactory displayFactory =
+ new DisplayOrientedMeteringPointFactory(mDisplay, mCameraSelector,
+ adjustedViewWidth,
+ adjustedViewHeight);
+
+ assertEqual(
+ displayFactory.createPoint(0, 0),
+ factory.createPoint(0, 25));
+ assertEqual(
+ displayFactory.createPoint(adjustedViewWidth, 0),
+ factory.createPoint(VIEW_WIDTH, 25));
+ assertEqual(
+ displayFactory.createPoint(0, adjustedViewHeight),
+ factory.createPoint(0, VIEW_HEIGHT - 25));
+ assertEqual(
+ displayFactory.createPoint(adjustedViewWidth, adjustedViewHeight),
+ factory.createPoint(VIEW_WIDTH, VIEW_HEIGHT - 25)
+ );
+ }
+
+ @Test
+ public void fitStart_rotation90() {
+ mockDisplay(Surface.ROTATION_90, 1920, 1080);
+
+ final int adjustedViewWidth = 100;
+ final int adjustedViewHeight = 50;
+ PreviewViewMeteringPointFactory factory = new PreviewViewMeteringPointFactory(mDisplay,
+ mCameraSelector, RESOLUTION, PreviewView.ScaleType.FIT_START, VIEW_WIDTH,
+ VIEW_HEIGHT);
+
+ DisplayOrientedMeteringPointFactory displayFactory =
+ new DisplayOrientedMeteringPointFactory(mDisplay, mCameraSelector,
+ adjustedViewWidth,
+ adjustedViewHeight);
+
+ assertEqual(
+ displayFactory.createPoint(0, 0),
+ factory.createPoint(0, 0));
+ assertEqual(
+ displayFactory.createPoint(adjustedViewWidth, 0),
+ factory.createPoint(VIEW_WIDTH, 0));
+ assertEqual(
+ displayFactory.createPoint(0, adjustedViewHeight),
+ factory.createPoint(0, VIEW_HEIGHT - 50));
+ assertEqual(
+ displayFactory.createPoint(adjustedViewWidth, adjustedViewHeight),
+ factory.createPoint(VIEW_WIDTH, VIEW_HEIGHT - 50)
+ );
+ }
+
+ @Test
+ public void fitEnd_rotation90() {
+ mockDisplay(Surface.ROTATION_90, 1920, 1080);
+
+ final int adjustedViewWidth = 100;
+ final int adjustedViewHeight = 50;
+ PreviewViewMeteringPointFactory factory = new PreviewViewMeteringPointFactory(mDisplay,
+ mCameraSelector, RESOLUTION, PreviewView.ScaleType.FIT_END, VIEW_WIDTH,
+ VIEW_HEIGHT);
+
+ DisplayOrientedMeteringPointFactory displayFactory =
+ new DisplayOrientedMeteringPointFactory(mDisplay, mCameraSelector,
+ adjustedViewWidth,
+ adjustedViewHeight);
+
+ assertEqual(
+ displayFactory.createPoint(0, 0),
+ factory.createPoint(0, 50));
+ assertEqual(
+ displayFactory.createPoint(adjustedViewWidth, 0),
+ factory.createPoint(VIEW_WIDTH, 50));
+ assertEqual(
+ displayFactory.createPoint(0, adjustedViewHeight),
+ factory.createPoint(0, VIEW_HEIGHT));
+ assertEqual(
+ displayFactory.createPoint(adjustedViewWidth, adjustedViewHeight),
+ factory.createPoint(VIEW_WIDTH, VIEW_HEIGHT)
+ );
+ }
+
+ private void mockDisplay(int rotation, int displayWidth, int displayHeight) {
+ when(mDisplay.getRotation()).thenReturn(rotation);
+ doAnswer(new Answer() {
+ @Override
+ public Void answer(InvocationOnMock invocation) throws Throwable {
+ Point point = invocation.getArgument(0);
+ point.x = displayWidth;
+ point.y = displayHeight;
+ return null;
+ }
+ }).when(mDisplay).getRealSize(any(Point.class));
+ }
+
+ private void assertEqual(@NonNull MeteringPoint point1, @NonNull MeteringPoint point2) {
+ assertThat(point1.getX()).isEqualTo(point2.getX());
+ assertThat(point1.getY()).isEqualTo(point2.getY());
+ }
+}
diff --git a/camera/camera-view/src/test/java/androidx/camera/view/preview/transform/GravityTransformTest.java b/camera/camera-view/src/test/java/androidx/camera/view/preview/transform/GravityTransformTest.java
deleted file mode 100644
index 6b0627d5..0000000
--- a/camera/camera-view/src/test/java/androidx/camera/view/preview/transform/GravityTransformTest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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.camera.view.preview.transform;
-
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import android.graphics.Point;
-import android.graphics.Rect;
-import android.view.View;
-
-import androidx.annotation.NonNull;
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.RobolectricTestRunner;
-import org.robolectric.annotation.internal.DoNotInstrument;
-
-@SmallTest
-@RunWith(RobolectricTestRunner.class)
-@DoNotInstrument
-public class GravityTransformTest {
-
- private static final Rect BIG_RECT = new Rect(0, 0, 400, 600);
- private static final Rect SMALL_RECT = new Rect(0, 0, 100, 200);
-
- @Test
- public void start() {
- final Point point = GravityTransform.start();
- assertThat(point).isEqualTo(new Point(0, 0));
- }
-
- @Test
- public void center_whenContainerLargerThanView() {
- final View container = mock(View.class);
- setUpView(container, BIG_RECT);
-
- final View view = mock(View.class);
- setUpView(view, SMALL_RECT);
-
- final Point point = GravityTransform.center(container, view);
- assertThat(point).isEqualTo(new Point(150, 200));
- }
-
- @Test
- public void center_whenContainerSmallerThanView() {
- final View container = mock(View.class);
- setUpView(container, SMALL_RECT);
-
- final View view = mock(View.class);
- setUpView(view, BIG_RECT);
-
- final Point point = GravityTransform.center(container, view);
- assertThat(point).isEqualTo(new Point(-150, -200));
- }
-
- @Test
- public void end_whenContainerLargerThanView() {
- final View container = mock(View.class);
- setUpView(container, BIG_RECT);
-
- final View view = mock(View.class);
- setUpView(view, SMALL_RECT);
-
- final Point point = GravityTransform.end(container, view);
- assertThat(point).isEqualTo(new Point(300, 400));
- }
-
- @Test
- public void end_whenContainerSmallerThanView() {
- final View container = mock(View.class);
- setUpView(container, SMALL_RECT);
-
- final View view = mock(View.class);
- setUpView(view, BIG_RECT);
-
- final Point point = GravityTransform.end(container, view);
- assertThat(point).isEqualTo(new Point(-300, -400));
- }
-
- private void setUpView(@NonNull final View container, @NonNull final Rect size) {
- when(container.getWidth()).thenReturn(size.width());
- when(container.getHeight()).thenReturn(size.height());
- }
-}
diff --git a/camera/camera-view/src/test/java/androidx/camera/view/preview/transform/ScaleTransformTest.java b/camera/camera-view/src/test/java/androidx/camera/view/preview/transform/ScaleTransformTest.java
index 2637ac9..2a5d0df 100644
--- a/camera/camera-view/src/test/java/androidx/camera/view/preview/transform/ScaleTransformTest.java
+++ b/camera/camera-view/src/test/java/androidx/camera/view/preview/transform/ScaleTransformTest.java
@@ -18,23 +18,18 @@
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import android.graphics.Point;
-import android.graphics.Rect;
import android.os.Build;
-import android.util.Pair;
-import android.util.Size;
import android.view.Display;
import android.view.Surface;
import android.view.View;
+import androidx.annotation.NonNull;
+import androidx.camera.view.preview.transform.transformation.ScaleTransformation;
import androidx.test.filters.SmallTest;
-import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
@@ -47,96 +42,146 @@
@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
public class ScaleTransformTest {
- private static final Rect CONTAINER = new Rect(0, 0, 400, 600);
- private static final Size BUFFER = new Size(400, 300);
+ @Test
+ public void fill_viewNotScaled_rotation0() {
+ final View container = setUpContainer(300, 400);
+ final View view = setUpView(200, 400, 1F, 1F, Surface.ROTATION_0);
- private Display mDisplay;
- private View mView;
+ final ScaleTransformation scale = ScaleTransform.fill(container, view);
- @Before
- public void setUp() {
- mDisplay = mock(Display.class);
- mView = mock(View.class);
- when(mView.getDisplay()).thenReturn(mDisplay);
- when(mView.getWidth()).thenReturn(BUFFER.getWidth());
- when(mView.getHeight()).thenReturn(BUFFER.getHeight());
+ assertThat(scale.getScaleX()).isEqualTo(scale.getScaleY());
+ assertThat(getScaledWidth(view) * scale.getScaleX()).isAtLeast(container.getWidth());
+ assertThat(getScaledHeight(view) * scale.getScaleY()).isAtLeast(container.getHeight());
+ assertThat(getScaledWidth(view) * scale.getScaleX() == container.getWidth()
+ || getScaledHeight(view) * scale.getScaleY() == container.getHeight()).isTrue();
}
@Test
- public void fill_naturalPortraitOrientedDevice_portrait() {
- final View container = mock(View.class);
- when(container.getWidth()).thenReturn(CONTAINER.width());
- when(container.getHeight()).thenReturn(CONTAINER.height());
+ public void fill_viewNotScaled_rotation90() {
+ final View container = setUpContainer(300, 400);
+ final View view = setUpView(200, 400, 1F, 1F, Surface.ROTATION_90);
- setDeviceNaturalPortraitOriented_portrait();
+ final ScaleTransformation scale = ScaleTransform.fill(container, view);
- final Pair<Float, Float> scaleXY = ScaleTransform.fill(container, mView, BUFFER);
- assertThat(mView.getWidth() * scaleXY.first).isAtLeast(container.getWidth());
- assertThat(mView.getHeight() * scaleXY.second).isAtLeast(container.getHeight());
+ assertThat(scale.getScaleX()).isEqualTo(scale.getScaleY());
+ assertThat(getScaledWidth(view) * scale.getScaleX()).isAtLeast(container.getHeight());
+ assertThat(getScaledHeight(view) * scale.getScaleY()).isAtLeast(container.getWidth());
+ assertThat(getScaledWidth(view) * scale.getScaleX() == container.getHeight()
+ || getScaledHeight(view) * scale.getScaleY() == container.getWidth()).isTrue();
}
@Test
- public void fill_naturalPortraitOrientedDevice_landscape() {
- final View container = mock(View.class);
- when(container.getWidth()).thenReturn(CONTAINER.height());
- when(container.getHeight()).thenReturn(CONTAINER.width());
+ public void fill_viewScaled_rotation0() {
+ final View container = setUpContainer(300, 400);
+ final View view = setUpView(200, 400, 2F, 1.5F, Surface.ROTATION_0);
- setDeviceNaturalPortraitOriented_landscape();
+ final ScaleTransformation scale = ScaleTransform.fill(container, view);
- final Pair<Float, Float> scaleXY = ScaleTransform.fill(container, mView, BUFFER);
- assertThat(mView.getWidth() * scaleXY.first).isAtLeast(container.getHeight());
- assertThat(mView.getHeight() * scaleXY.second).isAtLeast(container.getWidth());
+ assertThat(scale.getScaleX()).isEqualTo(scale.getScaleY());
+ assertThat(getScaledWidth(view) * scale.getScaleX()).isAtLeast(container.getWidth());
+ assertThat(getScaledHeight(view) * scale.getScaleY()).isAtLeast(container.getHeight());
+ assertThat(getScaledWidth(view) * scale.getScaleX() == container.getWidth()
+ || getScaledHeight(view) * scale.getScaleY() == container.getHeight()).isTrue();
}
@Test
- public void fill_naturalLandscapeOrientedDevice_portrait() {
- final View container = mock(View.class);
- when(container.getWidth()).thenReturn(CONTAINER.width());
- when(container.getHeight()).thenReturn(CONTAINER.height());
+ public void fill_viewScaled_rotation90() {
+ final View container = setUpContainer(300, 400);
+ final View view = setUpView(200, 400, 2F, 1.5F, Surface.ROTATION_90);
- setDeviceNaturalLandscapeOriented_portrait();
+ final ScaleTransformation scale = ScaleTransform.fill(container, view);
- final Pair<Float, Float> scaleXY = ScaleTransform.fill(container, mView, BUFFER);
- assertThat(mView.getWidth() * scaleXY.first).isAtLeast(container.getHeight());
- assertThat(mView.getHeight() * scaleXY.second).isAtLeast(container.getWidth());
+ assertThat(scale.getScaleX()).isEqualTo(scale.getScaleY());
+ assertThat(getScaledWidth(view) * scale.getScaleX()).isAtLeast(container.getHeight());
+ assertThat(getScaledHeight(view) * scale.getScaleY()).isAtLeast(container.getWidth());
+ assertThat(getScaledWidth(view) * scale.getScaleX() == container.getHeight()
+ || getScaledHeight(view) * scale.getScaleY() == container.getWidth()).isTrue();
}
@Test
- public void fill_naturalLandscapeOrientedDevice_landscape() {
+ public void fit_viewNotScaled_rotation0() {
+ final View container = setUpContainer(200, 500);
+ final View view = setUpView(500, 1000, 1F, 1F, Surface.ROTATION_0);
+
+ final ScaleTransformation scale = ScaleTransform.fit(container, view);
+
+ assertThat(scale.getScaleX()).isEqualTo(scale.getScaleY());
+ assertThat(getScaledWidth(view) * scale.getScaleX()).isAtMost(container.getWidth());
+ assertThat(getScaledHeight(view) * scale.getScaleY()).isAtMost(container.getHeight());
+ assertThat(getScaledWidth(view) * scale.getScaleX() == container.getWidth()
+ || getScaledHeight(view) * scale.getScaleY() == container.getHeight()).isTrue();
+ }
+
+ @Test
+ public void fit_viewNotScaled_rotation90() {
+ final View container = setUpContainer(200, 500);
+ final View view = setUpView(500, 1000, 1F, 1F, Surface.ROTATION_90);
+
+ final ScaleTransformation scale = ScaleTransform.fit(container, view);
+
+ assertThat(scale.getScaleX()).isEqualTo(scale.getScaleY());
+ assertThat(getScaledWidth(view) * scale.getScaleX()).isAtMost(container.getHeight());
+ assertThat(getScaledHeight(view) * scale.getScaleY()).isAtMost(container.getWidth());
+ assertThat(getScaledWidth(view) * scale.getScaleX() == container.getHeight()
+ || getScaledHeight(view) * scale.getScaleY() == container.getWidth()).isTrue();
+ }
+
+ @Test
+ public void fit_viewScaled_rotation0() {
+ final View container = setUpContainer(200, 500);
+ final View view = setUpView(500, 1000, 0.5F, 2F, Surface.ROTATION_0);
+
+ final ScaleTransformation scale = ScaleTransform.fit(container, view);
+
+ assertThat(scale.getScaleX()).isEqualTo(scale.getScaleY());
+ assertThat(getScaledWidth(view) * scale.getScaleX()).isAtMost(container.getWidth());
+ assertThat(getScaledHeight(view) * scale.getScaleY()).isAtMost(container.getHeight());
+ assertThat(getScaledWidth(view) * scale.getScaleX() == container.getWidth()
+ || getScaledHeight(view) * scale.getScaleY() == container.getHeight()).isTrue();
+ }
+
+ @Test
+ public void fit_viewScaled_rotation90() {
+ final View container = setUpContainer(200, 500);
+ final View view = setUpView(500, 1000, 0.5F, 2F, Surface.ROTATION_90);
+
+ final ScaleTransformation scale = ScaleTransform.fit(container, view);
+
+ assertThat(scale.getScaleX()).isEqualTo(scale.getScaleY());
+ assertThat(getScaledWidth(view) * scale.getScaleX()).isAtMost(container.getHeight());
+ assertThat(getScaledHeight(view) * scale.getScaleY()).isAtMost(container.getWidth());
+ assertThat(getScaledWidth(view) * scale.getScaleX() == container.getHeight()
+ || getScaledHeight(view) * scale.getScaleY() == container.getWidth()).isTrue();
+ }
+
+ @NonNull
+ private View setUpContainer(int width, int height) {
final View container = mock(View.class);
- when(container.getWidth()).thenReturn(CONTAINER.height());
- when(container.getHeight()).thenReturn(CONTAINER.width());
-
- setDeviceNaturalLandscapeOriented_landscape();
-
- final Pair<Float, Float> scaleXY = ScaleTransform.fill(container, mView, BUFFER);
- assertThat(mView.getWidth() * scaleXY.first).isAtLeast(container.getWidth());
- assertThat(mView.getHeight() * scaleXY.second).isAtLeast(container.getHeight());
+ when(container.getWidth()).thenReturn(width);
+ when(container.getHeight()).thenReturn(height);
+ return container;
}
- private void setDeviceNaturalPortraitOriented_portrait() {
- setUpDeviceNaturalOrientation(Surface.ROTATION_0, 300, 400);
+ @NonNull
+ private View setUpView(int width, int height, float scaleX, float scaleY, int rotation) {
+ final View view = mock(View.class);
+ when(view.getWidth()).thenReturn(width);
+ when(view.getHeight()).thenReturn(height);
+ when(view.getScaleX()).thenReturn(scaleX);
+ when(view.getScaleY()).thenReturn(scaleY);
+
+ final Display display = mock(Display.class);
+ when(view.getDisplay()).thenReturn(display);
+ when(display.getRotation()).thenReturn(rotation);
+
+ return view;
}
- private void setDeviceNaturalPortraitOriented_landscape() {
- setUpDeviceNaturalOrientation(Surface.ROTATION_90, 400, 300);
+ private float getScaledWidth(@NonNull final View view) {
+ return view.getWidth() * view.getScaleX();
}
- private void setDeviceNaturalLandscapeOriented_portrait() {
- setUpDeviceNaturalOrientation(Surface.ROTATION_90, 300, 400);
- }
-
- private void setDeviceNaturalLandscapeOriented_landscape() {
- setUpDeviceNaturalOrientation(Surface.ROTATION_0, 400, 300);
- }
-
- private void setUpDeviceNaturalOrientation(final int rotation, final int width,
- final int height) {
- when(mDisplay.getRotation()).thenReturn(rotation);
- doAnswer(invocation -> {
- final Point point = invocation.getArgument(0);
- point.set(width, height);
- return null;
- }).when(mDisplay).getRealSize(any(Point.class));
+ private float getScaledHeight(@NonNull final View view) {
+ return view.getHeight() * view.getScaleY();
}
}
diff --git a/camera/camera-view/src/test/java/androidx/camera/view/preview/transform/TranslationTransformTest.java b/camera/camera-view/src/test/java/androidx/camera/view/preview/transform/TranslationTransformTest.java
new file mode 100644
index 0000000..699f6db
--- /dev/null
+++ b/camera/camera-view/src/test/java/androidx/camera/view/preview/transform/TranslationTransformTest.java
@@ -0,0 +1,207 @@
+/*
+ * 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.camera.view.preview.transform;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import android.os.Build;
+import android.util.Pair;
+import android.view.Display;
+import android.view.Surface;
+import android.view.View;
+
+import androidx.annotation.NonNull;
+import androidx.camera.view.preview.transform.transformation.TranslationTransformation;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.internal.DoNotInstrument;
+
+@SmallTest
+@RunWith(RobolectricTestRunner.class)
+@DoNotInstrument
+@Config(minSdk = Build.VERSION_CODES.LOLLIPOP)
+public class TranslationTransformTest {
+
+ private static final int CONTAINER_WIDTH = 500;
+ private static final int CONTAINER_HEIGHT = 800;
+ private static final int VIEW_WIDTH = 200;
+ private static final int VIEW_HEIGHT = 300;
+
+ @Test
+ public void start_viewNotScaled_rotation0() {
+ final View view = setUpView(Surface.ROTATION_0);
+ final Pair<Float, Float> scaleXY = new Pair<>(1F, 1F);
+ final TranslationTransformation transformation = TranslationTransform.start(view, scaleXY);
+
+ assertThat(transformation.getTransX()).isEqualTo(0);
+ assertThat(transformation.getTransY()).isEqualTo(0);
+ }
+
+ @Test
+ public void start_viewNotScaled_rotation90() {
+ final View view = setUpView(Surface.ROTATION_90);
+ final Pair<Float, Float> scaleXY = new Pair<>(1F, 1F);
+ final TranslationTransformation transformation = TranslationTransform.start(view, scaleXY);
+
+ assertThat(transformation.getTransX()).isEqualTo(50);
+ assertThat(transformation.getTransY()).isEqualTo(-50);
+ }
+
+ @Test
+ public void start_viewScaled_rotation0() {
+ final View view = setUpView(Surface.ROTATION_0);
+ final Pair<Float, Float> scaleXY = new Pair<>(2F, 0.5F);
+ final TranslationTransformation transformation = TranslationTransform.start(view, scaleXY);
+
+ assertThat(transformation.getTransX()).isEqualTo(100);
+ assertThat(transformation.getTransY()).isEqualTo(-75);
+ }
+
+ @Test
+ public void start_viewScaled_rotation90() {
+ final View view = setUpView(Surface.ROTATION_90);
+ final Pair<Float, Float> scaleXY = new Pair<>(2F, 0.5F);
+ final TranslationTransformation transformation = TranslationTransform.start(view, scaleXY);
+
+ assertThat(transformation.getTransX()).isEqualTo(-25);
+ assertThat(transformation.getTransY()).isEqualTo(50);
+ }
+
+ @Test
+ public void center_viewNotScaled_rotation0() {
+ final View container = setUpContainer();
+ final View view = setUpView(Surface.ROTATION_0);
+ final Pair<Float, Float> scaleXY = new Pair<>(1F, 1F);
+ final TranslationTransformation transformation = TranslationTransform.center(container,
+ view);
+
+ assertThat(transformation.getTransX()).isEqualTo(150);
+ assertThat(transformation.getTransY()).isEqualTo(250);
+ }
+
+ @Test
+ public void center_viewNotScaled_rotation90() {
+ final View container = setUpContainer();
+ final View view = setUpView(Surface.ROTATION_90);
+ final Pair<Float, Float> scaleXY = new Pair<>(1F, 1F);
+ final TranslationTransformation transformation = TranslationTransform.center(container,
+ view);
+
+ assertThat(transformation.getTransX()).isEqualTo(150);
+ assertThat(transformation.getTransY()).isEqualTo(250);
+ }
+
+ @Test
+ public void center_viewScaled_rotation0() {
+ final View container = setUpContainer();
+ final View view = setUpView(Surface.ROTATION_0);
+ final Pair<Float, Float> scaleXY = new Pair<>(2F, 0.5F);
+ final TranslationTransformation transformation = TranslationTransform.center(container,
+ view);
+
+ assertThat(transformation.getTransX()).isEqualTo(150);
+ assertThat(transformation.getTransY()).isEqualTo(250);
+ }
+
+ @Test
+ public void center_viewScaled_rotation90() {
+ final View container = setUpContainer();
+ final View view = setUpView(Surface.ROTATION_90);
+ final Pair<Float, Float> scaleXY = new Pair<>(2F, 0.5F);
+ final TranslationTransformation transformation = TranslationTransform.center(container,
+ view);
+
+ assertThat(transformation.getTransX()).isEqualTo(150);
+ assertThat(transformation.getTransY()).isEqualTo(250);
+ }
+
+ @Test
+ public void end_viewNotScaled_rotation0() {
+ final View container = setUpContainer();
+ final View view = setUpView(Surface.ROTATION_0);
+ final Pair<Float, Float> scaleXY = new Pair<>(1F, 1F);
+ final TranslationTransformation transformation = TranslationTransform.end(container, view,
+ scaleXY);
+
+ assertThat(transformation.getTransX()).isEqualTo(300);
+ assertThat(transformation.getTransY()).isEqualTo(500);
+ }
+
+ @Test
+ public void end_viewNotScaled_rotation90() {
+ final View container = setUpContainer();
+ final View view = setUpView(Surface.ROTATION_90);
+ final Pair<Float, Float> scaleXY = new Pair<>(1F, 1F);
+ final TranslationTransformation transformation = TranslationTransform.end(container, view,
+ scaleXY);
+
+ assertThat(transformation.getTransX()).isEqualTo(250);
+ assertThat(transformation.getTransY()).isEqualTo(550);
+ }
+
+ @Test
+ public void end_viewScaled_rotation0() {
+ final View container = setUpContainer();
+ final View view = setUpView(Surface.ROTATION_0);
+ final Pair<Float, Float> scaleXY = new Pair<>(2F, 0.5F);
+ final TranslationTransformation transformation = TranslationTransform.end(container, view,
+ scaleXY);
+
+ assertThat(transformation.getTransX()).isEqualTo(200);
+ assertThat(transformation.getTransY()).isEqualTo(575);
+ }
+
+ @Test
+ public void end_viewScaled_rotation90() {
+ final View container = setUpContainer();
+ final View view = setUpView(Surface.ROTATION_90);
+ final Pair<Float, Float> scaleXY = new Pair<>(2F, 0.5F);
+ final TranslationTransformation transformation = TranslationTransform.end(container, view,
+ scaleXY);
+
+ assertThat(transformation.getTransX()).isEqualTo(325);
+ assertThat(transformation.getTransY()).isEqualTo(450);
+ }
+
+ @NonNull
+ private View setUpView(final int rotation) {
+ final View view = mock(View.class);
+ when(view.getWidth()).thenReturn(VIEW_WIDTH);
+ when(view.getHeight()).thenReturn(VIEW_HEIGHT);
+
+ final Display display = mock(Display.class);
+ when(view.getDisplay()).thenReturn(display);
+ when(display.getRotation()).thenReturn(rotation);
+
+ return view;
+ }
+
+ @NonNull
+ private View setUpContainer() {
+ final View container = mock(View.class);
+ when(container.getWidth()).thenReturn(CONTAINER_WIDTH);
+ when(container.getHeight()).thenReturn(CONTAINER_HEIGHT);
+ return container;
+ }
+}
diff --git a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
index 22f9027..abefa12 100644
--- a/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
+++ b/camera/integration-tests/coretestapp/src/main/java/androidx/camera/integration/core/CameraXActivity.java
@@ -42,6 +42,7 @@
import android.widget.TextView;
import android.widget.Toast;
+import androidx.annotation.CallSuper;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
@@ -994,6 +995,7 @@
}
}
+ @CallSuper
@Override
public void onRequestPermissionsResult(
int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
@@ -1013,6 +1015,7 @@
default:
// No-op
}
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
@Nullable
diff --git a/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/MainActivity.kt b/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/MainActivity.kt
index 6dc6ca7..3bd621f 100644
--- a/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/MainActivity.kt
+++ b/camera/integration-tests/timingtestapp/src/main/java/androidx/camera/integration/antelope/MainActivity.kt
@@ -275,6 +275,7 @@
}
return
}
+ else -> super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}
}
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/AbstractCodegenSignatureTest.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/AbstractCodegenSignatureTest.kt
index 2fc6ec6a..d0fb46c 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/AbstractCodegenSignatureTest.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/AbstractCodegenSignatureTest.kt
@@ -132,6 +132,7 @@
import androidx.compose.*
import android.widget.LinearLayout
import android.content.Context
+ import androidx.ui.node.UiComposer
$src
@@ -144,7 +145,7 @@
fun makeComposer(): Composer<*> {
val container = LinearLayout(__context!!)
- return ViewComposer(
+ return UiComposer(
__context!!,
container,
SlotTable(),
@@ -154,12 +155,8 @@
fun invokeComposable(composer: Composer<*>?, fn: @Composable() () -> Unit) {
if (composer == null) error("Composer was null")
- val realFn = fn as Function1<Composer<*>, Unit>
- composer.runWithComposing {
- composer.startRoot()
- realFn(composer)
- composer.endRoot()
- }
+ val composition = Composition({ a, b -> composer }, null)
+ composition.compose(fn)
}
class Test {
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/AbstractCodegenTest.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/AbstractCodegenTest.kt
index d67bf8c..f2c15f0c 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/AbstractCodegenTest.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/AbstractCodegenTest.kt
@@ -116,6 +116,87 @@
if (dumpClasses) dumpClasses(loader)
}
+ protected fun testCompileEmittable(source: String, dumpClasses: Boolean = false) = testCompile(
+ """
+ import androidx.compose.Applier
+ import androidx.compose.ApplyAdapter
+ import androidx.compose.Composer
+ import androidx.compose.ComposerUpdater
+ import androidx.compose.FrameManager
+ import androidx.compose.Recomposer
+ import androidx.compose.SlotTable
+ import androidx.compose.Composable
+
+ interface Emittable {
+ fun emitInsertAt(index: Int, instance: Emittable)
+ fun emitRemoveAt(index: Int, count: Int)
+ fun emitMove(from: Int, to: Int, count: Int)
+ }
+
+ internal class EmittableApplyAdapter : ApplyAdapter<Emittable> {
+ override fun Emittable.start(instance: Emittable) {}
+ override fun Emittable.insertAt(index: Int, instance: Emittable) = emitInsertAt(index, instance)
+ override fun Emittable.removeAt(index: Int, count: Int) = emitRemoveAt(index, count)
+ override fun Emittable.move(from: Int, to: Int, count: Int) = emitMove(from, to, count)
+ override fun Emittable.end(instance: Emittable, parent: Emittable) {}
+ }
+
+ class EmittableComposer(
+ val root: Emittable,
+ slotTable: SlotTable,
+ recomposer: Recomposer
+ ) : Composer<Emittable>(
+ slotTable,
+ Applier(
+ root,
+ EmittableApplyAdapter()
+ ),
+ recomposer
+ ) {
+ init {
+ FrameManager.ensureStarted()
+ }
+
+ @Suppress("UNCHECKED_CAST")
+ fun <T : Emittable> emit(
+ key: Any,
+ /*crossinline*/
+ ctor: () -> T,
+ update: ViewUpdater<T>.() -> Unit
+ ) {
+ startNode(key)
+ val node = if (inserting) ctor().also { emitNode(it) }
+ else useNode() as T
+ ViewUpdater(this, node).update()
+ endNode()
+ }
+
+ @Suppress("UNCHECKED_CAST")
+ fun <T : Emittable> emit(
+ key: Any,
+ /*crossinline*/
+ ctor: () -> T,
+ update: ViewUpdater<T>.() -> Unit,
+ children: () -> Unit
+ ) {
+ startNode(key)
+ val node = if (inserting) ctor().also { emitNode(it) }
+ else useNode() as T
+ ViewUpdater(this, node).update()
+ children()
+ endNode()
+ }
+ }
+
+ typealias ViewUpdater<T> = ComposerUpdater<Emittable, T>
+
+ val composer: EmittableComposer get() = error("should not be called")
+
+ $source
+ """,
+ dumpClasses
+ )
+
protected fun sourceFile(name: String, source: String): KtFile {
val result =
createFile(name, source, myEnvironment!!.project)
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallLoweringTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallLoweringTests.kt
index ed61e7a..8d039c2 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallLoweringTests.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallLoweringTests.kt
@@ -205,8 +205,9 @@
codegen(
"""
import androidx.compose.*
+ import androidx.ui.node.UiComposer
- class TextSpanScope internal constructor(val composer: ViewComposer)
+ class TextSpanScope internal constructor(val composer: UiComposer)
@Composable fun TextSpanScope.Foo(children: @Composable TextSpanScope.() -> Unit) {
children()
@@ -324,36 +325,6 @@
}
@Test
- fun testGenericEmittables(): Unit = ensureSetup {
- codegen(
- """
- class FooKey<T>(val name: String)
- class Foo<T>(val key: FooKey<T>, var value: T): Emittable {
- override fun emitInsertAt(index: Int, instance: Emittable) {
-
- }
-
- override fun emitRemoveAt(index: Int, count: Int) {
-
- }
-
- override fun emitMove(from: Int, to: Int, count: Int) {
-
- }
- }
-
- val AnyKey = FooKey<Any>("any")
-
- @Composable fun test(value: Any, children: @Composable() () -> Unit) {
- Foo(key=AnyKey, value=value) {
- children()
- }
- }
- """
- )
- }
-
- @Test
fun testSetViewContentIssue(): Unit = ensureSetup {
codegen(
"""
@@ -363,6 +334,7 @@
import android.view.ViewGroup
import android.widget.*
import androidx.compose.*
+ import androidx.ui.core.setViewContent
import androidx.ui.androidview.adapters.*
class RippleActivity : Activity() {
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallResolutionDiagnosticsTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallResolutionDiagnosticsTests.kt
index 27f203f..c5de69d 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallResolutionDiagnosticsTests.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposeCallResolutionDiagnosticsTests.kt
@@ -63,10 +63,10 @@
"""
import android.widget.FrameLayout
import androidx.compose.Composable
- import androidx.compose.ViewComposer
+ import androidx.ui.node.UiComposer
class SomeScope {
- val composer: ViewComposer get() = error("should not be called")
+ val composer: UiComposer get() = error("should not be called")
}
@Composable fun SomeScope.foo() {
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposerParamSignatureTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposerParamSignatureTests.kt
index c828dc9..f48f340 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposerParamSignatureTests.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/ComposerParamSignatureTests.kt
@@ -90,70 +90,12 @@
"""
val foo = @Composable {}
val bar = @Composable { x: Int -> }
- """, dumpClasses = true
+ """
) {
assert(!it.contains("INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull"))
}
@Test
- fun testParameterLambdasHaveRestartGroups(): Unit = checkApi(
- """
- @Composable fun Foo(children: @Composable() (x: Int) -> Unit) {
- }
- @Composable fun Bar() {
- Foo { x -> print(x) }
- }
- """,
- // We expect 4 lambda classes. One for Foo's restart group. One for Bar's restart group.
- // and one for the children lambda passed into Foo. And then one more for that children
- // lambda's restart group.
- """
- public final class TestKt {
- public final static Foo(Lkotlin/jvm/functions/Function2;Landroidx/compose/Composer;)V
- public final static Bar(Landroidx/compose/Composer;)V
- public final static synthetic Foo(Lkotlin/jvm/functions/Function1;)V
- public final static synthetic Bar()V
- final static INNERCLASS TestKt%Foo%1 null null
- final static INNERCLASS TestKt%Bar%1 null null
- final static INNERCLASS TestKt%Bar%4 null null
- }
- final class TestKt%Foo%1 extends kotlin/jvm/internal/Lambda implements kotlin/jvm/functions/Function1 {
- synthetic <init>(Lkotlin/jvm/functions/Function2;)V
- public final invoke(Landroidx/compose/Composer;)V
- private final synthetic Lkotlin/jvm/functions/Function2; %children
- public synthetic bridge invoke(Ljava/lang/Object;)Ljava/lang/Object;
- final static INNERCLASS TestKt%Foo%1 null null
- OUTERCLASS TestKt Foo (Lkotlin/jvm/functions/Function2;Landroidx/compose/Composer;)V
- }
- final class TestKt%Bar%1 extends kotlin/jvm/internal/Lambda implements kotlin/jvm/functions/Function2 {
- synthetic <init>()V
- public final invoke(ILandroidx/compose/Composer;)V
- public synthetic bridge invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
- final static INNERCLASS TestKt%Bar%1%invoke%1 null null
- final static INNERCLASS TestKt%Bar%1 null null
- OUTERCLASS TestKt Bar (Landroidx/compose/Composer;)V
- }
- final class TestKt%Bar%1%invoke%1 extends kotlin/jvm/internal/Lambda implements kotlin/jvm/functions/Function1 {
- synthetic <init>(LTestKt%Bar%1;I)V
- public final invoke(Landroidx/compose/Composer;)V
- private final synthetic LTestKt%Bar%1; %tmp1_rcvr
- private final synthetic I %x
- public synthetic bridge invoke(Ljava/lang/Object;)Ljava/lang/Object;
- final static INNERCLASS TestKt%Bar%1%invoke%1 null null
- final static INNERCLASS TestKt%Bar%1 null null
- OUTERCLASS TestKt%Bar%1 invoke (ILandroidx/compose/Composer;)V
- }
- final class TestKt%Bar%4 extends kotlin/jvm/internal/Lambda implements kotlin/jvm/functions/Function1 {
- synthetic <init>()V
- public final invoke(Landroidx/compose/Composer;)V
- public synthetic bridge invoke(Ljava/lang/Object;)Ljava/lang/Object;
- final static INNERCLASS TestKt%Bar%4 null null
- OUTERCLASS TestKt Bar (Landroidx/compose/Composer;)V
- }
- """
- )
-
- @Test
fun testAnonymousParamNaming(): Unit = validateBytecode(
"""
@Composable
@@ -182,7 +124,7 @@
public final static synthetic Foo(Ljava/lang/String;Lkotlin/jvm/functions/Function0;)V
public final static synthetic Example()V
final static INNERCLASS TestKt%Foo%1 null null
- final static INNERCLASS TestKt%Example%1%1 null null
+ final static INNERCLASS TestKt%Example%1 null null
final static INNERCLASS TestKt%Example%4 null null
}
final class TestKt%Foo%1 extends kotlin/jvm/internal/Lambda implements kotlin/jvm/functions/Function1 {
@@ -194,12 +136,12 @@
final static INNERCLASS TestKt%Foo%1 null null
OUTERCLASS TestKt Foo (Ljava/lang/String;Lkotlin/jvm/functions/Function0;Landroidx/compose/Composer;)V
}
- final class TestKt%Example%1%1 extends kotlin/jvm/internal/Lambda implements kotlin/jvm/functions/Function0 {
+ final class TestKt%Example%1 extends kotlin/jvm/internal/Lambda implements kotlin/jvm/functions/Function0 {
synthetic <init>()V
public final invoke()V
public synthetic bridge invoke()Ljava/lang/Object;
- final static INNERCLASS TestKt%Example%1%1 null null
- OUTERCLASS TestKt Example%lambda-0 ()Ljava/lang/Object;
+ final static INNERCLASS TestKt%Example%1 null null
+ OUTERCLASS TestKt Example (Landroidx/compose/Composer;)V
}
final class TestKt%Example%4 extends kotlin/jvm/internal/Lambda implements kotlin/jvm/functions/Function1 {
synthetic <init>()V
@@ -284,24 +226,6 @@
)
@Test
- fun testRestartGroupsInComposableVariables(): Unit = validateBytecode(
- """
- val bar: @Composable() () -> Unit = {}
- """
- ) {
- assert(it.contains("INVOKEVIRTUAL androidx/compose/Composer.startRestartGroup"))
- }
-
- @Test
- fun testRestartGroupsInComposableVariables2(): Unit = validateBytecode(
- """
- val bar = @Composable {}
- """
- ) {
- assert(it.contains("INVOKEVIRTUAL androidx/compose/Composer.startRestartGroup"))
- }
-
- @Test
fun testDataClassHashCode(): Unit = validateBytecode(
"""
data class Foo(
@@ -633,20 +557,9 @@
synthetic <init>()V
public final invoke(ILandroidx/compose/Composer;)V
public synthetic bridge invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
- final static INNERCLASS TestKt%foo%1%invoke%1 null null
final static INNERCLASS TestKt%foo%1 null null
OUTERCLASS TestKt <clinit> ()V
}
- final class TestKt%foo%1%invoke%1 extends kotlin/jvm/internal/Lambda implements kotlin/jvm/functions/Function1 {
- synthetic <init>(LTestKt%foo%1;I)V
- public final invoke(Landroidx/compose/Composer;)V
- private final synthetic LTestKt%foo%1; %tmp1_rcvr
- private final synthetic I %x
- public synthetic bridge invoke(Ljava/lang/Object;)Ljava/lang/Object;
- final static INNERCLASS TestKt%foo%1%invoke%1 null null
- final static INNERCLASS TestKt%foo%1 null null
- OUTERCLASS TestKt%foo%1 invoke (ILandroidx/compose/Composer;)V
- }
"""
)
@@ -670,20 +583,9 @@
synthetic <init>()V
public final invoke(ILandroidx/compose/Composer;)V
public synthetic bridge invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
- final static INNERCLASS TestKt%Bar%foo%1%invoke%1 null null
final static INNERCLASS TestKt%Bar%foo%1 null null
OUTERCLASS TestKt Bar (Lkotlin/jvm/functions/Function1;Landroidx/compose/Composer;)V
}
- final class TestKt%Bar%foo%1%invoke%1 extends kotlin/jvm/internal/Lambda implements kotlin/jvm/functions/Function1 {
- synthetic <init>(LTestKt%Bar%foo%1;I)V
- public final invoke(Landroidx/compose/Composer;)V
- private final synthetic LTestKt%Bar%foo%1; %tmp1_rcvr
- private final synthetic I %x
- public synthetic bridge invoke(Ljava/lang/Object;)Ljava/lang/Object;
- final static INNERCLASS TestKt%Bar%foo%1%invoke%1 null null
- final static INNERCLASS TestKt%Bar%foo%1 null null
- OUTERCLASS TestKt%Bar%foo%1 invoke (ILandroidx/compose/Composer;)V
- }
final class TestKt%Bar%5 extends kotlin/jvm/internal/Lambda implements kotlin/jvm/functions/Function1 {
synthetic <init>(Lkotlin/jvm/functions/Function1;)V
public final invoke(Landroidx/compose/Composer;)V
@@ -737,43 +639,17 @@
public final invoke(ILandroidx/compose/Composer;)V
private final synthetic I %x
public synthetic bridge invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
- final static INNERCLASS TestKt%App%1%invoke%1 null null
- final static INNERCLASS TestKt%App%1%invoke%4 null null
+ final static INNERCLASS TestKt%App%1%1 null null
final static INNERCLASS TestKt%App%1 null null
OUTERCLASS TestKt App (ILandroidx/compose/Composer;)V
}
- final class TestKt%App%1%invoke%1 extends kotlin/jvm/internal/Lambda implements kotlin/jvm/functions/Function2 {
+ final class TestKt%App%1%1 extends kotlin/jvm/internal/Lambda implements kotlin/jvm/functions/Function2 {
synthetic <init>(II)V
public final invoke(ILandroidx/compose/Composer;)V
private final synthetic I %x
private final synthetic I %a
public synthetic bridge invoke(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
- final static INNERCLASS TestKt%App%1%invoke%1%invoke%1 null null
- final static INNERCLASS TestKt%App%1%invoke%1 null null
- final static INNERCLASS TestKt%App%1 null null
- OUTERCLASS TestKt%App%1 invoke (ILandroidx/compose/Composer;)V
- }
- final class TestKt%App%1%invoke%1%invoke%1 extends kotlin/jvm/internal/Lambda implements kotlin/jvm/functions/Function1 {
- synthetic <init>(LTestKt%App%1%invoke%1;III)V
- public final invoke(Landroidx/compose/Composer;)V
- private final synthetic LTestKt%App%1%invoke%1; %tmp1_rcvr
- private final synthetic I %b
- private final synthetic I %x
- private final synthetic I %a
- public synthetic bridge invoke(Ljava/lang/Object;)Ljava/lang/Object;
- final static INNERCLASS TestKt%App%1%invoke%1%invoke%1 null null
- final static INNERCLASS TestKt%App%1%invoke%1 null null
- final static INNERCLASS TestKt%App%1 null null
- OUTERCLASS TestKt%App%1%invoke%1 invoke (ILandroidx/compose/Composer;)V
- }
- final class TestKt%App%1%invoke%4 extends kotlin/jvm/internal/Lambda implements kotlin/jvm/functions/Function1 {
- synthetic <init>(LTestKt%App%1;II)V
- public final invoke(Landroidx/compose/Composer;)V
- private final synthetic LTestKt%App%1; %tmp1_rcvr
- private final synthetic I %a
- private final synthetic I %x
- public synthetic bridge invoke(Ljava/lang/Object;)Ljava/lang/Object;
- final static INNERCLASS TestKt%App%1%invoke%4 null null
+ final static INNERCLASS TestKt%App%1%1 null null
final static INNERCLASS TestKt%App%1 null null
OUTERCLASS TestKt%App%1 invoke (ILandroidx/compose/Composer;)V
}
@@ -956,18 +832,6 @@
}
@Test
- fun testStartRestartGroupsInKickoff(): Unit = validateBytecode(
- """
- fun kickoff(block: @Composable() () -> Unit) {}
- fun simpleSquareColorAndSizeTest() {
- kickoff {
- print("abc")
- }
- }
- """
- ) { assert(it.contains("INVOKEVIRTUAL androidx/compose/Composer.startRestartGroup")) }
-
- @Test
fun testCustomComposerCall(): Unit = validateBytecode(
"""
class VectorScope(val composer: VectorComposer)
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/FcsCodegenTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/FcsCodegenTests.kt
index 19209b7..c703974 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/FcsCodegenTests.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/FcsCodegenTests.kt
@@ -992,7 +992,7 @@
val root = ref.value ?: error("Expected a linear")
- Compose.composeInto(root, portal) {
+ composeInto(root, portal) {
DisplayTest(id=$innerId)
}
}
@@ -1120,8 +1120,6 @@
compose(
"""
- import android.view.View
-
var composedSet = mutableSetOf<String>()
var inc = 1
@@ -1195,8 +1193,6 @@
compose(
"""
- import android.view.View
-
inline class InlineInt(val value: Int)
inline class InlineInlineInt(val value: InlineInt)
inline class InlineMutableSet(val value: MutableSet<String>)
@@ -1272,8 +1268,6 @@
compose(
"""
- import android.view.View
-
fun View.setComposed(composed: Set<String>) = setTag($tagId, composed)
val composedSet = mutableSetOf<String>()
@@ -1867,57 +1861,6 @@
}
@Test
- fun testPropertiesAndCtorParamsOnEmittables(): Unit = ensureSetup {
- codegen(
- """
- class SimpleEmittable(label: String? = null) : Emittable {
- var label: String? = null
- override fun emitInsertAt(index: Int, instance: Emittable) {}
- override fun emitMove(from: Int, to: Int, count: Int) {}
- override fun emitRemoveAt(index: Int, count: Int) {}
- }
-
- @Composable
- fun foo() {
- SimpleEmittable(label="Foo")
- }
- """
- )
- }
-
- @Test
- fun testSimpleClassConstructor(): Unit = ensureSetup {
- codegen(
- """
- import androidx.compose.Emittable
-
- class Path2() : Emittable {
-
- private val path99 = Path3()
-
- fun draw(canvas: Canvas2) {
- canvas.drawPath(path99)
- }
-
- override fun emitInsertAt(index: Int, instance: Emittable) { }
- override fun emitMove(from: Int, to: Int, count: Int) { }
- override fun emitRemoveAt(index: Int, count: Int) { }
- override fun toString(): String = ""
- }
-
- class Canvas2() {
- fun drawPath(path: Path3) {
- System.out.println(""+path)
- }
- }
-
- class Path3(private val internalPath: android.graphics.Path = android.graphics.Path()) {
- }
- """
- )
- }
-
- @Test
fun testMovement(): Unit = ensureSetup {
val tvId = 50
val btnIdAdd = 100
@@ -2351,7 +2294,7 @@
}.then {
// Expect only NormalLambda(4) to be called
assertEquals(
- "TestSkipping, Container, NormalLambda(4)",
+ "TestSkipping, NormalLambda(4)",
output.joinToString()
)
}
@@ -2479,8 +2422,7 @@
"""
Button(id=101, text="model ${'$'}{m.count}", onClick={ m.count++ })
InvokeSelfCompose()
- """,
- dumpClasses = true
+ """
).then { activity ->
assertEquals(activity.findViewById<TextView>(100).text, "f1=1, f2=10, m=0")
val button = activity.findViewById<Button>(101)
@@ -2550,6 +2492,7 @@
"""
import android.content.Context
import android.widget.*
+ import android.view.View
import androidx.compose.*
import androidx.ui.androidview.adapters.*
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxTransformationTest.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxTransformationTest.kt
index b4f081b..2cd4833 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxTransformationTest.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/KtxTransformationTest.kt
@@ -17,6 +17,7 @@
package androidx.compose.plugins.kotlin
import org.junit.Before
+import org.junit.Ignore
class KtxTransformationTest : AbstractCodegenTest() {
@@ -703,9 +704,8 @@
)
}
- fun testKtxEmittable() = ensureSetup { testCompile(
+ fun testKtxEmittable() = ensureSetup { testCompileEmittable(
"""
- import androidx.compose.*
open class MockEmittable: Emittable {
override fun emitInsertAt(index: Int, instance: Emittable) {}
@@ -718,18 +718,17 @@
}
class Comp {
- @Composable
- operator fun invoke() {
- MyEmittable(a=2)
- }
+ @Composable
+ fun Example() {
+ MyEmittable(a=2)
+ }
}
"""
) }
- fun testKtxCompoundEmittable() = ensureSetup { testCompile(
+ @Ignore("b/150394471")
+ fun xtestKtxCompoundEmittable() = ensureSetup { testCompileEmittable(
"""
- import androidx.compose.*
-
open class MockEmittable: Emittable {
override fun emitInsertAt(index: Int, instance: Emittable) {}
override fun emitRemoveAt(index: Int, count: Int) {}
@@ -740,16 +739,13 @@
var a: Int = 1
}
- class Comp {
- @Composable
- operator fun invoke() {
+ @Composable fun Test() {
MyEmittable(a=1) {
- MyEmittable(a=2)
- MyEmittable(a=3)
- MyEmittable(a=4)
- MyEmittable(a=5)
+ MyEmittable(a=2)
+ MyEmittable(a=3)
+ MyEmittable(a=4)
+ MyEmittable(a=5)
}
- }
}
"""
) }
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/LambdaMemoizationTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/LambdaMemoizationTests.kt
index ec8ae47..3374011 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/LambdaMemoizationTests.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/LambdaMemoizationTests.kt
@@ -35,6 +35,7 @@
@Composable
fun EventHolder(event: () -> Unit, block: @Composable() () -> Unit) {
+ workToBeAvoided()
block()
}
@@ -71,12 +72,18 @@
fun eventFired() { }
@Composable
- fun EventHolder(event: () -> Unit) {}
+ fun EventHolder(event: () -> Unit, block: @Composable() () -> Unit) {
+ workToBeAvoided()
+ block()
+ }
@Composable
fun Example(model: String) {
workToBeRepeated()
- EventHolder(event = ::eventFired)
+ EventHolder(event = ::eventFired) {
+ workToBeRepeated()
+ ValidateModel(text = model)
+ }
}
""")
@@ -413,7 +420,9 @@
@Composable
fun Wrap(block: @Composable() () -> Unit) {
+ workToBeAvoided()
block()
+ workToBeAvoided()
}
@Composable
@@ -465,6 +474,206 @@
}
""")
+ @Test
+ fun wrapLambaExpressions() = skipping("""
+ @Composable
+ fun Wrapper(block: @Composable() () -> Unit) {
+ workToBeAvoided()
+ block()
+ workToBeAvoided()
+ }
+
+ @Composable
+ fun Example(model: String) {
+ workToBeRepeated()
+ Wrapper {
+ workToBeRepeated()
+ ValidateModel(model)
+ }
+ }
+ """)
+
+ @Test
+ fun nonCapturingComposableLambda() = skipping("""
+ @Composable
+ fun Wrapper1(block: @Composable() () -> Unit) {
+ workToBeAvoided("Wrapper1.1")
+ block()
+ workToBeAvoided("Wrapper1.2")
+ }
+
+ @Composable
+ fun Wrapper2(block: @Composable() () -> Unit) {
+ workToBeAvoided("Wrapper2.1")
+ Wrapper1(block = block)
+ workToBeAvoided("Wrapper2.2")
+ }
+
+ @Composable
+ fun Wrapper3(block: @Composable() () -> Unit) {
+ workToBeAvoided("Wrapper3.1")
+ Wrapper2 {
+ block()
+ }
+ workToBeAvoided("Wrapper3.2")
+ }
+
+ @Composable
+ fun Example(model: String) {
+ Wrapper3 {
+ workToBeRepeated("Example1.1")
+ ValidateModel(model)
+ Wrapper3 {
+ workToBeRepeated("Example1.2")
+ ValidateModel(model)
+ }
+ }
+ }
+ """)
+
+ @Test
+ fun wrappingOneParameter() = skipping("""
+ @Composable
+ fun Wrap(block: @Composable() (p1: String) -> Unit) {
+ workToBeAvoided()
+ block("test")
+ workToBeAvoided()
+ }
+
+ @Composable
+ fun Example(model: String) {
+ workToBeRepeated()
+ Wrap { p1 ->
+ require(p1 == "test")
+ workToBeRepeated()
+ Display(p1)
+ ValidateModel(model)
+ }
+ }
+ """)
+
+ @Test // Selecting 23 as 22 is the maximum number handled by RestartingFunction
+ fun wrapping23Parameters() = skipping("""
+ @Composable
+ fun Wrap(block: @Composable() (
+ p1: String,
+ p2: String,
+ p3: String,
+ p4: String,
+ p5: String,
+ p6: String,
+ p7: String,
+ p8: String,
+ p9: String,
+ p10: String,
+ p11: String,
+ p12: String,
+ p13: String,
+ p14: String,
+ p15: String,
+ p16: String,
+ p17: String,
+ p18: String,
+ p19: String,
+ p20: String,
+ p21: String,
+ p22: String,
+ p23: String
+ ) -> Unit) {
+ workToBeAvoided()
+ block(
+ "test1", "test2", "test3", "test4", "test5",
+ "test6", "test7", "test8", "test9", "test10",
+ "test11", "test12", "test13", "test14", "test15",
+ "test16", "test17", "test18", "test19", "test20",
+ "test21", "test22", "test23"
+ )
+ workToBeAvoided()
+ }
+
+ @Composable
+ fun Example(model: String) {
+ workToBeRepeated()
+ Wrap {
+ p1, p2, p3, p4, p5, p6, p7, p8, p9, p10,
+ p11, p12, p13, p14, p15, p16, p17, p18, p19, p20,
+ p21, p22, p23 ->
+ require(p1 == "test1") { "p1 should be test1 but was ${'$'}p1" }
+ require(p2 == "test2") { "p2 should be test2 but was ${'$'}p2" }
+ require(p3 == "test3") { "p3 should be test3 but was ${'$'}p3" }
+ require(p4 == "test4") { "p4 should be test4 but was ${'$'}p4" }
+ require(p5 == "test5") { "p5 should be test5 but was ${'$'}p5" }
+ require(p6 == "test6") { "p6 should be test6 but was ${'$'}p6" }
+ require(p7 == "test7") { "p7 should be test7 but was ${'$'}p7" }
+ require(p8 == "test8") { "p8 should be test8 but was ${'$'}p8" }
+ require(p9 == "test9") { "p9 should be test9 but was ${'$'}p9" }
+ require(p10 == "test10") { "p10 should be test10 but was ${'$'}p10" }
+ require(p11 == "test11") { "p11 should be test11 but was ${'$'}p11" }
+ require(p12 == "test12") { "p12 should be test12 but was ${'$'}p12" }
+ require(p13 == "test13") { "p13 should be test13 but was ${'$'}p13" }
+ require(p14 == "test14") { "p14 should be test14 but was ${'$'}p14" }
+ require(p15 == "test15") { "p15 should be test15 but was ${'$'}p15" }
+ require(p16 == "test16") { "p16 should be test16 but was ${'$'}p16" }
+ require(p17 == "test17") { "p17 should be test17 but was ${'$'}p17" }
+ require(p18 == "test18") { "p18 should be test18 but was ${'$'}p18" }
+ require(p19 == "test19") { "p19 should be test19 but was ${'$'}p19" }
+ require(p20 == "test20") { "p20 should be test20 but was ${'$'}p20" }
+ require(p21 == "test21") { "p21 should be test21 but was ${'$'}p21" }
+ require(p22 == "test22") { "p22 should be test22 but was ${'$'}p22" }
+ require(p23 == "test23") { "p23 should be test23 but was ${'$'}p23" }
+ workToBeRepeated()
+ Display(p1)
+ ValidateModel(model)
+ }
+ }
+ """)
+
+ @Test
+ fun wrappingReceiverParameter() = skipping("""
+ class Receiver() { }
+
+ @Composable
+ fun Wrapper(block: @Composable() Receiver.() -> Unit) {
+ workToBeAvoided()
+ val receiver = Receiver()
+ receiver.block()
+ workToBeAvoided()
+ }
+
+ @Composable
+ fun Example(model: String) {
+ workToBeRepeated()
+ Wrapper {
+ workToBeRepeated()
+ ValidateModel(model)
+ }
+ }
+ """)
+
+ @Test
+ fun untrackedLambdasShouldNotForceEvaluation() = skipping("""
+ @Composable
+ fun Wrapper(block: @Composable() () -> Unit) {
+ workToBeAvoided()
+ block()
+ workToBeAvoided()
+ }
+
+ @Composable
+ fun Example(model: String) {
+ workToBeRepeated()
+ Wrapper @Untracked {
+ workToBeAvoided()
+ ValidateModel(model)
+ }
+ Wrapper {
+ workToBeRepeated()
+ ValidateModel(model)
+ }
+ workToBeRepeated()
+ }
+ """)
+
private fun skipping(text: String, dumpClasses: Boolean = false) =
ensureSetup {
compose("""
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/RobolectricComposeTester.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/RobolectricComposeTester.kt
index 1ef06c2..a73fede 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/RobolectricComposeTester.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/RobolectricComposeTester.kt
@@ -17,19 +17,14 @@
package androidx.compose.plugins.kotlin
import android.app.Activity
+import android.content.Context
import android.os.Bundle
import android.view.ViewGroup
import android.widget.LinearLayout
-import androidx.compose.Compose
import androidx.compose.Composer
-import androidx.compose.Composition
-import androidx.compose.Recomposer
+import androidx.ui.core.makeCompositionForTesting
import org.robolectric.Robolectric
import org.robolectric.RuntimeEnvironment
-import kotlin.reflect.full.findParameterByName
-import kotlin.reflect.full.functions
-import kotlin.reflect.full.isSubtypeOf
-import kotlin.reflect.full.starProjectedType
const val ROOT_ID = 18284847
@@ -72,19 +67,15 @@
val activity = controller.create().get()
val root = activity.root
scheduler.advanceToLastPostedRunnable()
- val composeInto = Compose::class.java.methods.first {
- if (it.name != "composeInto") false
+ val composition = makeCompositionForTesting(root, activity, null)
+ val composeMethod = composition.javaClass.methods.first {
+ if (it.name != "compose") false
else {
- val param = it.parameters.getOrNull(2)
+ val param = it.parameters.getOrNull(0)
param?.type == Function1::class.java
}
}
- val composition = composeInto.invoke(
- Compose,
- root,
- null,
- composable
- ) as Composition
+ composeMethod.invoke(composition, composable)
scheduler.advanceToLastPostedRunnable()
block(activity)
val advanceFn = advance ?: { composition.compose() }
diff --git a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/ComposableCheckerTests.kt b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/ComposableCheckerTests.kt
index ca27da0..aa28521 100644
--- a/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/ComposableCheckerTests.kt
+++ b/compose/compose-compiler-hosted/integration-tests/src/test/java/androidx/compose/plugins/kotlin/analysis/ComposableCheckerTests.kt
@@ -339,11 +339,12 @@
fun testComposableReporting024() {
check("""
import androidx.compose.*;
+ import androidx.ui.core.setViewContent
import android.widget.TextView;
import android.widget.LinearLayout;
fun foo(ll: LinearLayout) {
- ll.setViewContent({ TextView(text="Hello World!") })
+ ll.setViewContent { TextView(text="Hello World!") }
}
""")
}
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeCallResolutionInterceptorExtension.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeCallResolutionInterceptorExtension.kt
index bd894b6..65cb081 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeCallResolutionInterceptorExtension.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeCallResolutionInterceptorExtension.kt
@@ -298,7 +298,13 @@
.scope
.ownerDescriptor
.module
- .findClassAcrossModuleDependencies(ClassId.topLevel(ComposeFqNames.ViewComposer))
+ .findClassAcrossModuleDependencies(ClassId.topLevel(ComposeFqNames.UiComposer))
+ ?.defaultType
+ ?: context
+ .scope
+ .ownerDescriptor
+ .module
+ .findClassAcrossModuleDependencies(ClassId.topLevel(ComposeFqNames.Composer))
?.defaultType
}
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeFqNames.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeFqNames.kt
index 0f723d0..7d40134 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeFqNames.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeFqNames.kt
@@ -40,7 +40,7 @@
val HiddenAttribute = ComposeUtils.composeFqName("HiddenAttribute")
val Composer = ComposeUtils.composeFqName("Composer")
val Untracked = ComposeUtils.composeFqName("Untracked")
- val ViewComposer = ComposeUtils.composeFqName("ViewComposer")
+ val UiComposer = FqName.fromSegments(listOf("androidx", "ui", "node", "UiComposer"))
val Package = FqName.fromSegments(listOf("androidx", "compose"))
val Function0 = FqName.fromSegments(listOf("kotlin", "jvm", "functions", "Function0"))
val Function1 = FqName.fromSegments(listOf("kotlin", "jvm", "functions", "Function1"))
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeUtils.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeUtils.kt
index 3ab9d97..736511e 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeUtils.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/ComposeUtils.kt
@@ -36,6 +36,10 @@
fun composeFqName(cname: String) = FqName("${generateComposePackageName()}.$cname")
+ fun composeInternalFqName(cname: String? = null) = FqName(
+ "${generateComposePackageName()}.internal${cname?.let { ".$it"} ?: ""}"
+ )
+
fun setterMethodFromPropertyName(name: String): String {
return "set${name[0].toUpperCase()}${name.slice(1 until name.length)}"
}
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposableCallTransformer.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposableCallTransformer.kt
index fa883a0..4f39a02 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposableCallTransformer.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposableCallTransformer.kt
@@ -183,7 +183,7 @@
if (expression.origin == IrStatementOrigin.LAMBDA) {
if (expression.function.valueParameters.lastOrNull()?.isComposerParam() == true) {
return DeclarationIrBuilder(context, declarationStack.last().symbol).irBlock {
- +covertLambdaIfNecessary(expression.transformChildren())
+ +expression.transformChildren()
}
}
}
@@ -515,7 +515,7 @@
({ expr })
else -> {
val temp = irTemporary(
- covertLambdaIfNecessary(expr),
+ value = expr,
irType = expr.type
)
({ irGet(temp) })
@@ -862,147 +862,4 @@
}
}
}
-
- /**
- * Convert a function-reference into a inner class constructor call.
- *
- * This is a transformed copy of the work done in CallableReferenceLowering to allow the
- * [ComposeObservePatcher] access to the this parameter.
- */
- private fun IrBlockBuilder.covertLambdaIfNecessary(expression: IrExpression): IrExpression {
- val functionExpression = expression as? IrFunctionExpression ?: return expression
-
- val function = functionExpression.function
-
- if (!function.isComposable()) return expression
-
- // A temporary node created so the code matches more closely to the
- // CallableReferenceLowering code that was copied.
- val functionReference = IrFunctionReferenceImpl(
- -1,
- -1,
- expression.type,
- function.symbol,
- function.descriptor,
- 0,
- expression.origin
- )
-
- val context = [email protected]
- val superType =
- FakeJvmSymbols(context.state.module, context.irBuiltIns).lambdaClass.typeWith()
- val parameterTypes = (functionExpression.type as IrSimpleType).arguments.map {
- (it as IrTypeProjection).type
- }
- val functionSuperClass = FakeJvmSymbols(context.state.module, context.irBuiltIns)
- .getJvmFunctionClass(
- parameterTypes.size - 1
- )
- val jvmClass = functionSuperClass.typeWith(parameterTypes)
- val boundReceiver = functionReference.getArgumentsWithIr().singleOrNull()
- val typeArgumentsMap = functionReference.typeSubstitutionMap
- val callee = functionReference.symbol.owner
- var constructor: IrConstructor? = null
- val irClass = buildClass {
- setSourceRange(functionReference)
- visibility = Visibilities.LOCAL
- origin = JvmLoweredDeclarationOrigin.LAMBDA_IMPL
- name = Name.special("<function reference to ${callee.fqNameWhenAvailable}>")
- }.apply {
- parent = scope.getLocalDeclarationParent()
- superTypes += superType
- superTypes += jvmClass
- createImplicitParameterDeclarationWithWrappedDescriptor()
- }.also { irClass ->
- // Add constructor
- val superConstructor = superType.getClass()!!.constructors.single {
- it.valueParameters.size == if (boundReceiver != null) 2 else 1
- }
- constructor = irClass.addConstructor {
- setSourceRange(functionReference)
- origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
- returnType = irClass.defaultType
- isPrimary = true
- }.apply {
- boundReceiver?.first?.let { param ->
- valueParameters += param.copyTo(
- irFunction = this,
- index = 0,
- type = param.type.substitute(typeArgumentsMap)
- )
- }
- body = DeclarationIrBuilder(context, symbol).irBlockBody(startOffset, endOffset) {
- +irDelegatingConstructorCall(superConstructor).apply {
- putValueArgument(0, irInt(parameterTypes.size - 1))
- if (boundReceiver != null)
- putValueArgument(1, irGet(valueParameters.first()))
- }
- +IrInstanceInitializerCallImpl(
- startOffset,
- endOffset,
- irClass.symbol,
- context.irBuiltIns.unitType
- )
- }
- }
-
- // Add the invoke method
- val superMethod = functionSuperClass.functions.single {
- it.owner.modality == Modality.ABSTRACT
- }
- irClass.addFunction {
- name = superMethod.owner.name
- returnType = callee.returnType
- isSuspend = callee.isSuspend
- }.apply {
- overriddenSymbols += superMethod
- dispatchReceiverParameter = parentAsClass.thisReceiver!!.copyTo(this)
- annotations += callee.annotations
- if (annotations.findAnnotation(ComposeFqNames.Composable) == null) {
- expression.type.annotations.findAnnotation(ComposeFqNames.Composable)?.let {
- annotations += it
- }
- }
- val valueParameterMap =
- callee.explicitParameters.withIndex().associate { (index, param) ->
- param to param.copyTo(this, index = index)
- }
- valueParameters += valueParameterMap.values
- body = DeclarationIrBuilder(context, symbol).irBlockBody(startOffset, endOffset) {
- callee.body?.statements?.forEach { statement ->
- +statement.transform(object : IrElementTransformerVoid() {
- override fun visitGetValue(expression: IrGetValue): IrExpression {
- val replacement = valueParameterMap[expression.symbol.owner]
- ?: return super.visitGetValue(expression)
-
- at(expression.startOffset, expression.endOffset)
- return irGet(replacement)
- }
-
- override fun visitReturn(expression: IrReturn): IrExpression =
- if (expression.returnTargetSymbol != callee.symbol) {
- super.visitReturn(expression)
- } else {
- at(expression.startOffset, expression.endOffset)
- irReturn(expression.value.transform(this, null))
- }
-
- override fun visitDeclaration(declaration: IrDeclaration): IrStatement {
- if (declaration.parent == callee)
- declaration.parent = this@apply
- return super.visitDeclaration(declaration)
- }
- }, null)
- }
- }
- }
- }
-
- return irBlock {
- +irClass
- +irCall(constructor!!.symbol).apply {
- if (valueArgumentsCount > 0) putValueArgument(0, boundReceiver!!.second)
- }
- }
- }
}
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposableTypeRemapper.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposableTypeRemapper.kt
index efcaaee..18f1d81 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposableTypeRemapper.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposableTypeRemapper.kt
@@ -55,6 +55,7 @@
import org.jetbrains.kotlin.ir.types.IrTypeProjection
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.types.impl.IrTypeAbbreviationImpl
+import org.jetbrains.kotlin.ir.types.impl.IrTypeProjectionImpl
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.types.toKotlinType
import org.jetbrains.kotlin.ir.types.withHasQuestionMark
@@ -72,6 +73,7 @@
import org.jetbrains.kotlin.psi2ir.findFirstFunction
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeProjectionImpl
+import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.types.replace
class DeepCopyIrTreeWithSymbolsPreservingMetadata(
@@ -328,29 +330,32 @@
private fun KotlinType.toIrType(): IrType = typeTranslator.translateType(this)
override fun remapType(type: IrType): IrType {
- // TODO(lmr):
- // This is basically creating the KotlinType and then converting to an IrType. Consider
- // rewriting to just create the IrType directly, which would probably be more efficient.
if (type !is IrSimpleType) return type
if (!type.isFunction()) return underlyingRemapType(type)
if (!type.isComposable()) return underlyingRemapType(type)
if (!shouldTransform) return underlyingRemapType(type)
- val oldArguments = type.toKotlinType().arguments
- val newArguments =
- oldArguments.subList(0, oldArguments.size - 1) +
- TypeProjectionImpl(composerTypeDescriptor.defaultType) +
- oldArguments.last()
+ val oldIrArguments = type.arguments
+ val newIrArguments =
+ oldIrArguments.subList(0, oldIrArguments.size - 1) +
+ makeTypeProjection(composerTypeDescriptor.defaultType.toIrType(),
+ Variance.INVARIANT) +
+ oldIrArguments.last()
- val transformedComposableType = context
- .irBuiltIns
- .builtIns
- .getFunction(oldArguments.size) // return type is an argument, so this is n + 1
- .defaultType
- .replace(newArguments)
- .toIrType()
- .withHasQuestionMark(type.hasQuestionMark) as IrSimpleType
-
- return underlyingRemapType(transformedComposableType)
+ return IrSimpleTypeImpl(
+ null,
+ symbolRemapper.getReferencedClassifier(
+ context.ir.symbols.externalSymbolTable.referenceClass(
+ context
+ .irBuiltIns
+ .builtIns
+ .getFunction(oldIrArguments.size) // return type is an argument, so this is n + 1
+ )
+ ),
+ type.hasQuestionMark,
+ newIrArguments.map { remapTypeArgument(it) },
+ emptyList(),
+ null
+ )
}
private fun underlyingRemapType(type: IrSimpleType): IrType {
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposeObservePatcher.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposeObservePatcher.kt
index 0ba7edc..19e3412 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposeObservePatcher.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposeObservePatcher.kt
@@ -147,8 +147,9 @@
// Check if the descriptor has restart scope calls resolved
if (descriptor is SimpleFunctionDescriptor &&
- // Lambdas that make are not lowered earlier should be ignored.
- // All composable lambdas are already lowered to a class with an invoke() method.
+ // Lambdas should be ignored. All composable lambdas are wrapped by a restartable
+ // function wrapper by ComposerLambdaMemoization which supplies the startRestartGroup/
+ // endRestartGroup pair on behalf of the lambda.
declaration.origin != IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA &&
declaration.origin != IrDeclarationOrigin.LOCAL_FUNCTION_NO_CLOSURE) {
diff --git a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposerLambdaMemoization.kt b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposerLambdaMemoization.kt
index 13091a0..fb9e434 100644
--- a/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposerLambdaMemoization.kt
+++ b/compose/compose-compiler-hosted/src/main/java/androidx/compose/plugins/kotlin/compiler/lower/ComposerLambdaMemoization.kt
@@ -17,6 +17,7 @@
package androidx.compose.plugins.kotlin.compiler.lower
import androidx.compose.plugins.kotlin.ComposeUtils
+import androidx.compose.plugins.kotlin.ComposeUtils.composeInternalFqName
import androidx.compose.plugins.kotlin.analysis.ComposeWritableSlices
import androidx.compose.plugins.kotlin.hasUntrackedAnnotation
import androidx.compose.plugins.kotlin.irTrace
@@ -30,13 +31,16 @@
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.irBlock
+import org.jetbrains.kotlin.ir.builders.irBoolean
import org.jetbrains.kotlin.ir.builders.irCall
import org.jetbrains.kotlin.ir.builders.irGet
+import org.jetbrains.kotlin.ir.builders.irInt
import org.jetbrains.kotlin.ir.builders.irReturn
import org.jetbrains.kotlin.ir.builders.irTemporary
-import org.jetbrains.kotlin.ir.declarations.IrClass
+import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
+import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
import org.jetbrains.kotlin.ir.declarations.IrValueDeclaration
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.declarations.copyAttributes
@@ -47,6 +51,7 @@
import org.jetbrains.kotlin.ir.expressions.IrValueAccessExpression
import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
+import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.toKotlinType
import org.jetbrains.kotlin.ir.util.DeepCopySymbolRemapper
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
@@ -56,6 +61,7 @@
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtFunctionLiteral
import org.jetbrains.kotlin.resolve.BindingTrace
+import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.types.typeUtil.isUnit
@@ -68,18 +74,31 @@
}
}
-private sealed class MemoizationContext {
- open val composable get() = false
- open fun declareLocal(local: IrValueDeclaration?) { }
- open fun recordCapture(local: IrValueDeclaration?) { }
- open fun pushCollector(collector: CaptureCollector) { }
- open fun popCollector(collector: CaptureCollector) { }
+private abstract class DeclarationContext {
+ abstract val composable: Boolean
+ abstract val symbol: IrSymbol
+ abstract fun declareLocal(local: IrValueDeclaration?)
+ abstract fun recordCapture(local: IrValueDeclaration?)
+ abstract fun pushCollector(collector: CaptureCollector)
+ abstract fun popCollector(collector: CaptureCollector)
}
-private class ClassContext : MemoizationContext()
+private class SymbolOwnerContext(val declaration: IrSymbolOwner) : DeclarationContext() {
+ override val composable get() = false
+ override val symbol get() = declaration.symbol
+ override fun declareLocal(local: IrValueDeclaration?) { }
+ override fun recordCapture(local: IrValueDeclaration?) { }
+ override fun pushCollector(collector: CaptureCollector) { }
+ override fun popCollector(collector: CaptureCollector) { }
+}
-private class FunctionContext(val declaration: IrFunction, override val composable: Boolean) :
- MemoizationContext() {
+private class FunctionContext(
+ val declaration: IrFunction,
+ override val composable: Boolean,
+ val canRemember: Boolean
+) : DeclarationContext() {
+ override val symbol get() = declaration.symbol
+
val locals = mutableSetOf<IrValueDeclaration>()
var collectors = mutableListOf<CaptureCollector>()
@@ -113,6 +132,11 @@
}
}
+const val RESTARTABLE_FUNCTION = "restartableFunction"
+const val RESTARTABLE_FUNCTION_N = "restartableFunctionN"
+const val RESTARTABLE_FUNCTION_INSTANCE = "restartableFunctionInstance"
+const val RESTARTABLE_FUNCTION_N_INSTANCE = "restartableFunctionNInstance"
+
class ComposerLambdaMemoization(
context: JvmBackendContext,
symbolRemapper: DeepCopySymbolRemapper,
@@ -121,46 +145,49 @@
AbstractComposeLowering(context, symbolRemapper, bindingTrace),
ModuleLoweringPass {
- private val memoizationContextStack = mutableListOf<MemoizationContext>()
+ private val declarationContextStack = mutableListOf<DeclarationContext>()
override fun lower(module: IrModuleFragment) = module.transformChildrenVoid(this)
- override fun visitClass(declaration: IrClass): IrStatement {
- memoizationContextStack.push(ClassContext())
- val result = super.visitClass(declaration)
- memoizationContextStack.pop()
+ override fun visitDeclaration(declaration: IrDeclaration): IrStatement {
+ if (declaration is IrFunction) return super.visitDeclaration(declaration)
+ val symbolOwner = declaration as? IrSymbolOwner
+ if (symbolOwner != null) declarationContextStack.push(SymbolOwnerContext(declaration))
+ val result = super.visitDeclaration(declaration)
+ if (symbolOwner != null) declarationContextStack.pop()
return result
}
override fun visitFunction(declaration: IrFunction): IrStatement {
val descriptor = declaration.descriptor
- val composable = descriptor.isComposable() &&
- // Don't memoize in an inline function
+ val composable = descriptor.isComposable()
+ val canRemember = composable &&
+ // Don't use remember in an inline function
!descriptor.isInline &&
- // Don't memoize if in a composable that returns a value
- // TODO(b/150390108): Consider allowing memoization in effects
+ // Don't use remember if in a composable that returns a value
+ // TODO(b/150390108): Consider allowing remember in effects
descriptor.returnType.let { it != null && it.isUnit() }
- memoizationContextStack.push(FunctionContext(declaration, composable))
+ declarationContextStack.push(FunctionContext(declaration, composable, canRemember))
val result = super.visitFunction(declaration)
- memoizationContextStack.pop()
+ declarationContextStack.pop()
return result
}
override fun visitVariable(declaration: IrVariable): IrStatement {
- memoizationContextStack.peek()?.declareLocal(declaration)
+ declarationContextStack.peek()?.declareLocal(declaration)
return super.visitVariable(declaration)
}
override fun visitValueAccess(expression: IrValueAccessExpression): IrExpression {
- memoizationContextStack.forEach { it.recordCapture(expression.symbol.owner) }
+ declarationContextStack.forEach { it.recordCapture(expression.symbol.owner) }
return super.visitValueAccess(expression)
}
override fun visitFunctionReference(expression: IrFunctionReference): IrExpression {
- // Memoize the instance created by using the :: prefix
+ // Memoize the instance created by using the :: operator
val result = super.visitFunctionReference(expression)
- val memoizationContext = memoizationContextStack.peek() as? FunctionContext
+ val functionContext = declarationContextStack.peek() as? FunctionContext
?: return result
if (expression.valueArgumentsCount != 0) {
// If this syntax is as a curry syntax in the future, don't memoize.
@@ -172,7 +199,7 @@
// receivers are treated below.
return result
}
- if (memoizationContext.composable) {
+ if (functionContext.canRemember) {
// Memoize the reference for <expr>::<method>
val dispatchReceiver = expression.dispatchReceiver
val extensionReceiver = expression.extensionReceiver
@@ -182,7 +209,7 @@
// Save the receivers into a temporaries and memoize the function reference using
// the resulting temporaries
val builder = context.createIrBuilder(
- memoizationContext.declaration.symbol,
+ functionContext.declaration.symbol,
startOffset = expression.startOffset,
endOffset = expression.endOffset
)
@@ -203,7 +230,7 @@
}
+rememberExpression(
- memoizationContext,
+ functionContext,
IrFunctionReferenceImpl(
startOffset,
endOffset,
@@ -218,18 +245,30 @@
)
}
} else if (dispatchReceiver == null) {
- return rememberExpression(memoizationContext, result, emptyList())
+ return rememberExpression(functionContext, result, emptyList())
}
}
return result
}
- override fun visitFunctionExpression(expression: IrFunctionExpression): IrExpression {
- // Start recording variables captured in this scope
- val composableFunction = memoizationContextStack.peek() as? FunctionContext
+ private fun visitNonComposableFunctionExpression(
+ expression: IrFunctionExpression,
+ declarationContext: DeclarationContext
+ ): IrExpression {
+ val functionContext = declarationContext as? FunctionContext
?: return super.visitFunctionExpression(expression)
- if (!composableFunction.composable) return super.visitFunctionExpression(expression)
+ if (
+ // Only memoize non-composable lambdas in a context we can use remember
+ !functionContext.canRemember ||
+ // Don't memoize inlined lambdas
+ expression.isInlineArgument() ||
+ // Don't memoize untracked function
+ !expression.isTracked()) {
+ return super.visitFunctionExpression(expression)
+ }
+
+ // Record capture variables for this scope
val collector = CaptureCollector()
startCollector(collector)
// Wrap composable functions expressions or memoize non-composable function expressions
@@ -239,45 +278,105 @@
// If the ancestor converted this then return
val functionExpression = result as? IrFunctionExpression ?: return result
- // Ensure we don't transform targets of an inline function
- if (functionExpression.isInlineArgument()) return functionExpression
- if (functionExpression.isComposable()) {
- return functionExpression
- }
-
- if (functionExpression.function.descriptor.hasUntrackedAnnotation())
- return functionExpression
-
return rememberExpression(
- composableFunction,
+ functionContext,
functionExpression,
collector.captures.toList()
)
}
+ private fun visitComposableFunctionExpression(
+ expression: IrFunctionExpression,
+ declarationContext: DeclarationContext
+ ): IrExpression {
+ val result = super.visitFunctionExpression(expression)
+
+ // If the ancestor converted this then return
+ val functionExpression = result as? IrFunctionExpression ?: return result
+
+ // Do not wrap target of an inline function
+ if (expression.isInlineArgument()) return functionExpression
+
+ return wrapFunctionExpression(declarationContext, functionExpression)
+ }
+
+ override fun visitFunctionExpression(expression: IrFunctionExpression): IrExpression {
+ val declarationContext = declarationContextStack.peek()
+ ?: return super.visitFunctionExpression(expression)
+ return if (expression.isComposable())
+ visitComposableFunctionExpression(expression, declarationContext)
+ else
+ visitNonComposableFunctionExpression(expression, declarationContext)
+ }
+
private fun startCollector(collector: CaptureCollector) {
- for (memoizationContext in memoizationContextStack) {
- memoizationContext.pushCollector(collector)
+ for (declarationContext in declarationContextStack) {
+ declarationContext.pushCollector(collector)
}
}
private fun stopCollector(collector: CaptureCollector) {
- for (memoizationContext in memoizationContextStack) {
- memoizationContext.popCollector(collector)
+ for (declarationContext in declarationContextStack) {
+ declarationContext.popCollector(collector)
}
}
+ private fun wrapFunctionExpression(
+ declarationContext: DeclarationContext,
+ expression: IrFunctionExpression
+ ): IrExpression {
+ val function = expression.function
+ val argumentCount = function.descriptor.valueParameters.size
+ val useRestartableFunctionN = argumentCount > MAX_RESTART_ARGUMENT_COUNT
+ val restartFunctionFactory =
+ if (declarationContext.composable)
+ if (useRestartableFunctionN)
+ RESTARTABLE_FUNCTION_N
+ else RESTARTABLE_FUNCTION
+ else if (useRestartableFunctionN)
+ RESTARTABLE_FUNCTION_N_INSTANCE
+ else RESTARTABLE_FUNCTION_INSTANCE
+ val restartFactorySymbol =
+ getTopLevelFunction(composeInternalFqName(restartFunctionFactory))
+ val irBuilder = context.createIrBuilder(
+ symbol = declarationContext.symbol,
+ startOffset = expression.startOffset,
+ endOffset = expression.endOffset
+ )
+
+ return irBuilder.irCall(restartFactorySymbol).apply {
+ var index = 0
+ // key parameter
+ putValueArgument(
+ index++, irBuilder.irInt(
+ descriptor.fqNameSafe.hashCode() xor expression.startOffset
+ )
+ )
+
+ // tracked parameter
+ putValueArgument(index++, irBuilder.irBoolean(expression.isTracked()))
+
+ // RestartableFunctionN requires the arity
+ if (useRestartableFunctionN) {
+ // arity parameter
+ putValueArgument(index++, irBuilder.irInt(argumentCount))
+ }
+
+ // block parameter
+ putValueArgument(index, expression)
+ }.markAsSynthetic(mark = declarationContext.composable)
+ }
+
private fun rememberExpression(
- memoizationContext: FunctionContext,
+ functionContext: FunctionContext,
expression: IrExpression,
captures: List<IrValueDeclaration>
): IrExpression {
-
if (captures.any {
!((it as? IrVariable)?.isVar != true && it.type.toKotlinType().isStable())
}) return expression
val rememberParameterCount = captures.size + 1 // One additional parameter for the lambda
- val declaration = memoizationContext.declaration
+ val declaration = functionContext.declaration
val descriptor = declaration.descriptor
val module = descriptor.module
val rememberFunctions = module
@@ -302,7 +401,7 @@
val rememberFunctionSymbol = referenceSimpleFunction(rememberFunctionDescriptor)
val irBuilder = context.createIrBuilder(
- symbol = declaration.symbol,
+ symbol = functionContext.symbol,
startOffset = expression.startOffset,
endOffset = expression.endOffset
)
@@ -352,16 +451,19 @@
+irReturn(expression)
}
))
- }.patchDeclarationParents(declaration).markAsSynthetic()
+ }.patchDeclarationParents(declaration).markAsSynthetic(mark = true)
}
- private fun <T : IrFunctionAccessExpression> T.markAsSynthetic(): T {
- // Mark it so the ComposableCallTransformer will insert the correct code around this call
- context.state.irTrace.record(
- ComposeWritableSlices.IS_SYNTHETIC_COMPOSABLE_CALL,
- this,
- true
- )
+ private fun <T : IrFunctionAccessExpression> T.markAsSynthetic(mark: Boolean): T {
+ if (mark) {
+ // Mark it so the ComposableCallTransformer will insert the correct code around this
+ // call
+ context.irTrace.record(
+ ComposeWritableSlices.IS_SYNTHETIC_COMPOSABLE_CALL,
+ this,
+ true
+ )
+ }
return this
}
@@ -383,5 +485,9 @@
return false
}
- fun IrExpression?.isNullOrStable() = this == null || type.toKotlinType().isStable()
+ private fun IrExpression?.isNullOrStable() = this == null || type.toKotlinType().isStable()
+ private fun IrFunctionExpression.isTracked() = !function.descriptor.hasUntrackedAnnotation()
}
+
+// This must match the highest value of FunctionXX which is current Function22
+private const val MAX_RESTART_ARGUMENT_COUNT = 22
diff --git a/compose/compose-runtime/api/0.1.0-dev07.txt b/compose/compose-runtime/api/0.1.0-dev07.txt
index 101b78f..faa36af 100644
--- a/compose/compose-runtime/api/0.1.0-dev07.txt
+++ b/compose/compose-runtime/api/0.1.0-dev07.txt
@@ -60,25 +60,9 @@
@kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.PROPERTY}) public @interface Composable {
}
- public final class Compose {
- method @MainThread public androidx.compose.Composition composeInto(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- method @MainThread public androidx.compose.Composition composeInto(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- method @MainThread public void disposeComposition(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null);
- method @MainThread public void disposeComposition(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null);
- method @MainThread public androidx.compose.Composition subcomposeInto(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- field public static final androidx.compose.Compose! INSTANCE;
- }
-
- public final class ComposeAndroidKt {
- method public static void disposeComposition(android.app.Activity);
- method public static androidx.compose.Composition? setViewContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- }
-
public final class ComposeKt {
- method public static void disposeComposition(android.view.ViewGroup);
method public static kotlin.jvm.functions.Function0<kotlin.Unit> emptyContent();
method public static inline kotlin.jvm.functions.Function0<kotlin.Unit> orEmpty(kotlin.jvm.functions.Function0<kotlin.Unit>?);
- method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
}
public class Composer<N> implements androidx.compose.ComposerValidator {
@@ -152,7 +136,12 @@
method public final void compose(kotlin.jvm.functions.Function0<kotlin.Unit> content);
method public final void compose();
method public void dispose();
+ method public final kotlin.jvm.functions.Function0<kotlin.Unit> getComposable();
+ method public final boolean isRoot();
method public final boolean recomposeSync();
+ method public final void setComposable(kotlin.jvm.functions.Function0<kotlin.Unit> p);
+ property public final kotlin.jvm.functions.Function0<kotlin.Unit> composable;
+ property public final boolean isRoot;
}
public final class CompositionKt {
@@ -185,12 +174,6 @@
method @androidx.compose.Composable public static void onPreCommit(Object![]? inputs, kotlin.jvm.functions.Function1<? super androidx.compose.CommitScope,kotlin.Unit> callback);
}
- public interface Emittable {
- method public void emitInsertAt(int index, androidx.compose.Emittable instance);
- method public void emitMove(int from, int to, int count);
- method public void emitRemoveAt(int index, int count);
- }
-
public final class ExpectKt {
}
@@ -427,68 +410,6 @@
@kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.FUNCTION) public @interface Untracked {
}
- public final class ViewAdapters {
- ctor public ViewAdapters();
- method public Object? adapt(Object parent, Object child);
- method public boolean register(kotlin.jvm.functions.Function2<java.lang.Object,java.lang.Object,?> adapter);
- }
-
- public final class ViewComposer extends androidx.compose.Composer<java.lang.Object> {
- ctor public ViewComposer(android.content.Context context, Object root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer, androidx.compose.ViewAdapters? adapters);
- method public inline <T extends android.view.View> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
- method public inline <T extends android.view.ViewGroup> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public inline <T extends androidx.compose.Emittable> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
- method public inline <T extends androidx.compose.Emittable> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public androidx.compose.ViewAdapters? getAdapters();
- method public android.content.Context getContext();
- method public Object getRoot();
- }
-
- public final class ViewComposerCommonKt {
- }
-
- public final class ViewComposerKt {
- method @Deprecated public static androidx.compose.ViewComposer getComposer();
- method public static Boolean? registerAdapter(androidx.compose.ViewComposer, kotlin.jvm.functions.Function2<java.lang.Object,java.lang.Object,?> adapter);
- method public static <T> T! runWithComposing(androidx.compose.Composer<?>, kotlin.jvm.functions.Function0<? extends T> block);
- }
-
-}
-
-package androidx.compose.adapters {
-
- public final class ComposeViewAdapter implements androidx.compose.adapters.ViewAdapter {
- ctor public ComposeViewAdapter();
- method public void didInsert(android.view.View view, android.view.ViewGroup parent);
- method public void didUpdate(android.view.View view, android.view.ViewGroup parent);
- method public inline <T extends androidx.compose.adapters.ViewAdapter> T get(int id, kotlin.jvm.functions.Function0<? extends T> factory);
- method public java.util.List<androidx.compose.adapters.ViewAdapter> getAdapters();
- method public int getId();
- method public void willInsert(android.view.View view, android.view.ViewGroup parent);
- property public final java.util.List<androidx.compose.adapters.ViewAdapter> adapters;
- property public int id;
- }
-
- public interface ViewAdapter {
- method public void didInsert(android.view.View view, android.view.ViewGroup parent);
- method public void didUpdate(android.view.View view, android.view.ViewGroup parent);
- method public int getId();
- method public void willInsert(android.view.View view, android.view.ViewGroup parent);
- property public abstract int id;
- }
-
- public final class ViewAdapterKt {
- method public static inline <T extends androidx.compose.adapters.ViewAdapter> T getOrAddAdapter(android.view.View, int id, kotlin.jvm.functions.Function0<? extends T> factory);
- method public static androidx.compose.adapters.ComposeViewAdapter getViewAdapter(android.view.View);
- }
-
-}
-
-package androidx.compose.annotations {
-
- @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface Hide {
- }
-
}
package androidx.compose.frames {
@@ -623,3 +544,54 @@
}
+package androidx.compose.internal {
+
+ @androidx.compose.Stable public final class RestartableFunction<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, R> implements kotlin.jvm.functions.Function0<R> kotlin.jvm.functions.Function1<androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function10<P1,P2,P3,P4,P5,P6,P7,P8,P9,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function11<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function12<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function13<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function14<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function15<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function16<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function17<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function18<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function19<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function2<P1,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function20<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function21<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,P20,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function22<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,P20,P21,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function3<P1,P2,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function4<P1,P2,P3,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function5<P1,P2,P3,P4,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function6<P1,P2,P3,P4,P5,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function7<P1,P2,P3,P4,P5,P6,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function8<P1,P2,P3,P4,P5,P6,P7,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function9<P1,P2,P3,P4,P5,P6,P7,P8,androidx.compose.Composer<?>,R> {
+ ctor public RestartableFunction(Object key, boolean tracked);
+ method public Object getKey();
+ method public R! invoke();
+ method public R! invoke(androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, P20? p20, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, P20? p20, P21? p21, androidx.compose.Composer<?> c);
+ method public void update(Object block);
+ }
+
+ public final class RestartableFunctionKt {
+ method @androidx.compose.Composable public static androidx.compose.internal.RestartableFunction<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object> restartableFunction(int key, boolean tracked, Object block);
+ method public static androidx.compose.internal.RestartableFunction<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object> restartableFunctionInstance(int key, boolean tracked, Object block);
+ }
+
+ @androidx.compose.Stable public final class RestartableFunctionN<R> implements kotlin.jvm.functions.FunctionN<R> {
+ ctor public RestartableFunctionN(Object key, boolean tracked, int arity);
+ method public int getArity();
+ method public Object getKey();
+ method public R! invoke(java.lang.Object?... args);
+ method public void update(Object block);
+ }
+
+ public final class RestartableFunctionNKt {
+ method @androidx.compose.Composable public static androidx.compose.internal.RestartableFunctionN<?> restartableFunctionN(int key, boolean tracked, int arity, Object block);
+ method public static androidx.compose.internal.RestartableFunctionN<?> restartableFunctionNInstance(int key, boolean tracked, int arity, Object block);
+ }
+
+}
+
diff --git a/compose/compose-runtime/api/api_lint.ignore b/compose/compose-runtime/api/api_lint.ignore
index abf7dda..5fa0a6cd 100644
--- a/compose/compose-runtime/api/api_lint.ignore
+++ b/compose/compose-runtime/api/api_lint.ignore
@@ -25,14 +25,6 @@
Class should be named CompositionLifecycleCallback
-ContextFirst: androidx.compose.Compose#composeInto(androidx.compose.Emittable, android.content.Context, androidx.compose.CompositionReference, kotlin.jvm.functions.Function0<kotlin.Unit>) parameter #1:
- Context is distinct, so it must be the first argument (method `composeInto`)
-ContextFirst: androidx.compose.Compose#disposeComposition(androidx.compose.Emittable, android.content.Context, androidx.compose.CompositionReference) parameter #1:
- Context is distinct, so it must be the first argument (method `disposeComposition`)
-ContextFirst: androidx.compose.Compose#subcomposeInto(androidx.compose.Emittable, android.content.Context, androidx.compose.CompositionReference, kotlin.jvm.functions.Function0<kotlin.Unit>) parameter #1:
- Context is distinct, so it must be the first argument (method `subcomposeInto`)
-
-
DocumentExceptions: androidx.compose.ComposerKt#getCurrentComposer():
Method ComposerKt.getCurrentComposer appears to be throwing kotlin.NotImplementedError; this should be listed in the documentation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
DocumentExceptions: androidx.compose.frames.FramesKt#commit(androidx.compose.frames.Frame):
@@ -55,13 +47,7 @@
Note that adding the `operator` keyword would allow calling this method using operator syntax
KotlinOperator: androidx.compose.SlotEditor#get(int):
Note that adding the `operator` keyword would allow calling this method using operator syntax
-KotlinOperator: androidx.compose.adapters.ComposeViewAdapter#get(int, kotlin.jvm.functions.Function0<? extends T>):
- Note that adding the `operator` keyword would allow calling this method using operator syntax
MissingNullability: androidx.compose.SlotReader#getGroupKey():
Missing nullability on method `getGroupKey` return
-
-
-RegistrationName: androidx.compose.Choreographer#removeFrameCallback(android.view.Choreographer.FrameCallback):
- Callback methods should be named register/unregister; was removeFrameCallback
diff --git a/compose/compose-runtime/api/current.txt b/compose/compose-runtime/api/current.txt
index 101b78f..faa36af 100644
--- a/compose/compose-runtime/api/current.txt
+++ b/compose/compose-runtime/api/current.txt
@@ -60,25 +60,9 @@
@kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.PROPERTY}) public @interface Composable {
}
- public final class Compose {
- method @MainThread public androidx.compose.Composition composeInto(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- method @MainThread public androidx.compose.Composition composeInto(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- method @MainThread public void disposeComposition(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null);
- method @MainThread public void disposeComposition(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null);
- method @MainThread public androidx.compose.Composition subcomposeInto(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- field public static final androidx.compose.Compose! INSTANCE;
- }
-
- public final class ComposeAndroidKt {
- method public static void disposeComposition(android.app.Activity);
- method public static androidx.compose.Composition? setViewContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- }
-
public final class ComposeKt {
- method public static void disposeComposition(android.view.ViewGroup);
method public static kotlin.jvm.functions.Function0<kotlin.Unit> emptyContent();
method public static inline kotlin.jvm.functions.Function0<kotlin.Unit> orEmpty(kotlin.jvm.functions.Function0<kotlin.Unit>?);
- method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
}
public class Composer<N> implements androidx.compose.ComposerValidator {
@@ -152,7 +136,12 @@
method public final void compose(kotlin.jvm.functions.Function0<kotlin.Unit> content);
method public final void compose();
method public void dispose();
+ method public final kotlin.jvm.functions.Function0<kotlin.Unit> getComposable();
+ method public final boolean isRoot();
method public final boolean recomposeSync();
+ method public final void setComposable(kotlin.jvm.functions.Function0<kotlin.Unit> p);
+ property public final kotlin.jvm.functions.Function0<kotlin.Unit> composable;
+ property public final boolean isRoot;
}
public final class CompositionKt {
@@ -185,12 +174,6 @@
method @androidx.compose.Composable public static void onPreCommit(Object![]? inputs, kotlin.jvm.functions.Function1<? super androidx.compose.CommitScope,kotlin.Unit> callback);
}
- public interface Emittable {
- method public void emitInsertAt(int index, androidx.compose.Emittable instance);
- method public void emitMove(int from, int to, int count);
- method public void emitRemoveAt(int index, int count);
- }
-
public final class ExpectKt {
}
@@ -427,68 +410,6 @@
@kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.FUNCTION) public @interface Untracked {
}
- public final class ViewAdapters {
- ctor public ViewAdapters();
- method public Object? adapt(Object parent, Object child);
- method public boolean register(kotlin.jvm.functions.Function2<java.lang.Object,java.lang.Object,?> adapter);
- }
-
- public final class ViewComposer extends androidx.compose.Composer<java.lang.Object> {
- ctor public ViewComposer(android.content.Context context, Object root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer, androidx.compose.ViewAdapters? adapters);
- method public inline <T extends android.view.View> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
- method public inline <T extends android.view.ViewGroup> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public inline <T extends androidx.compose.Emittable> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
- method public inline <T extends androidx.compose.Emittable> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public androidx.compose.ViewAdapters? getAdapters();
- method public android.content.Context getContext();
- method public Object getRoot();
- }
-
- public final class ViewComposerCommonKt {
- }
-
- public final class ViewComposerKt {
- method @Deprecated public static androidx.compose.ViewComposer getComposer();
- method public static Boolean? registerAdapter(androidx.compose.ViewComposer, kotlin.jvm.functions.Function2<java.lang.Object,java.lang.Object,?> adapter);
- method public static <T> T! runWithComposing(androidx.compose.Composer<?>, kotlin.jvm.functions.Function0<? extends T> block);
- }
-
-}
-
-package androidx.compose.adapters {
-
- public final class ComposeViewAdapter implements androidx.compose.adapters.ViewAdapter {
- ctor public ComposeViewAdapter();
- method public void didInsert(android.view.View view, android.view.ViewGroup parent);
- method public void didUpdate(android.view.View view, android.view.ViewGroup parent);
- method public inline <T extends androidx.compose.adapters.ViewAdapter> T get(int id, kotlin.jvm.functions.Function0<? extends T> factory);
- method public java.util.List<androidx.compose.adapters.ViewAdapter> getAdapters();
- method public int getId();
- method public void willInsert(android.view.View view, android.view.ViewGroup parent);
- property public final java.util.List<androidx.compose.adapters.ViewAdapter> adapters;
- property public int id;
- }
-
- public interface ViewAdapter {
- method public void didInsert(android.view.View view, android.view.ViewGroup parent);
- method public void didUpdate(android.view.View view, android.view.ViewGroup parent);
- method public int getId();
- method public void willInsert(android.view.View view, android.view.ViewGroup parent);
- property public abstract int id;
- }
-
- public final class ViewAdapterKt {
- method public static inline <T extends androidx.compose.adapters.ViewAdapter> T getOrAddAdapter(android.view.View, int id, kotlin.jvm.functions.Function0<? extends T> factory);
- method public static androidx.compose.adapters.ComposeViewAdapter getViewAdapter(android.view.View);
- }
-
-}
-
-package androidx.compose.annotations {
-
- @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface Hide {
- }
-
}
package androidx.compose.frames {
@@ -623,3 +544,54 @@
}
+package androidx.compose.internal {
+
+ @androidx.compose.Stable public final class RestartableFunction<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, R> implements kotlin.jvm.functions.Function0<R> kotlin.jvm.functions.Function1<androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function10<P1,P2,P3,P4,P5,P6,P7,P8,P9,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function11<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function12<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function13<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function14<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function15<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function16<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function17<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function18<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function19<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function2<P1,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function20<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function21<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,P20,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function22<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,P20,P21,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function3<P1,P2,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function4<P1,P2,P3,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function5<P1,P2,P3,P4,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function6<P1,P2,P3,P4,P5,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function7<P1,P2,P3,P4,P5,P6,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function8<P1,P2,P3,P4,P5,P6,P7,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function9<P1,P2,P3,P4,P5,P6,P7,P8,androidx.compose.Composer<?>,R> {
+ ctor public RestartableFunction(Object key, boolean tracked);
+ method public Object getKey();
+ method public R! invoke();
+ method public R! invoke(androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, P20? p20, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, P20? p20, P21? p21, androidx.compose.Composer<?> c);
+ method public void update(Object block);
+ }
+
+ public final class RestartableFunctionKt {
+ method @androidx.compose.Composable public static androidx.compose.internal.RestartableFunction<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object> restartableFunction(int key, boolean tracked, Object block);
+ method public static androidx.compose.internal.RestartableFunction<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object> restartableFunctionInstance(int key, boolean tracked, Object block);
+ }
+
+ @androidx.compose.Stable public final class RestartableFunctionN<R> implements kotlin.jvm.functions.FunctionN<R> {
+ ctor public RestartableFunctionN(Object key, boolean tracked, int arity);
+ method public int getArity();
+ method public Object getKey();
+ method public R! invoke(java.lang.Object?... args);
+ method public void update(Object block);
+ }
+
+ public final class RestartableFunctionNKt {
+ method @androidx.compose.Composable public static androidx.compose.internal.RestartableFunctionN<?> restartableFunctionN(int key, boolean tracked, int arity, Object block);
+ method public static androidx.compose.internal.RestartableFunctionN<?> restartableFunctionNInstance(int key, boolean tracked, int arity, Object block);
+ }
+
+}
+
diff --git a/compose/compose-runtime/api/public_plus_experimental_0.1.0-dev07.txt b/compose/compose-runtime/api/public_plus_experimental_0.1.0-dev07.txt
index 101b78f..faa36af 100644
--- a/compose/compose-runtime/api/public_plus_experimental_0.1.0-dev07.txt
+++ b/compose/compose-runtime/api/public_plus_experimental_0.1.0-dev07.txt
@@ -60,25 +60,9 @@
@kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.PROPERTY}) public @interface Composable {
}
- public final class Compose {
- method @MainThread public androidx.compose.Composition composeInto(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- method @MainThread public androidx.compose.Composition composeInto(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- method @MainThread public void disposeComposition(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null);
- method @MainThread public void disposeComposition(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null);
- method @MainThread public androidx.compose.Composition subcomposeInto(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- field public static final androidx.compose.Compose! INSTANCE;
- }
-
- public final class ComposeAndroidKt {
- method public static void disposeComposition(android.app.Activity);
- method public static androidx.compose.Composition? setViewContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- }
-
public final class ComposeKt {
- method public static void disposeComposition(android.view.ViewGroup);
method public static kotlin.jvm.functions.Function0<kotlin.Unit> emptyContent();
method public static inline kotlin.jvm.functions.Function0<kotlin.Unit> orEmpty(kotlin.jvm.functions.Function0<kotlin.Unit>?);
- method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
}
public class Composer<N> implements androidx.compose.ComposerValidator {
@@ -152,7 +136,12 @@
method public final void compose(kotlin.jvm.functions.Function0<kotlin.Unit> content);
method public final void compose();
method public void dispose();
+ method public final kotlin.jvm.functions.Function0<kotlin.Unit> getComposable();
+ method public final boolean isRoot();
method public final boolean recomposeSync();
+ method public final void setComposable(kotlin.jvm.functions.Function0<kotlin.Unit> p);
+ property public final kotlin.jvm.functions.Function0<kotlin.Unit> composable;
+ property public final boolean isRoot;
}
public final class CompositionKt {
@@ -185,12 +174,6 @@
method @androidx.compose.Composable public static void onPreCommit(Object![]? inputs, kotlin.jvm.functions.Function1<? super androidx.compose.CommitScope,kotlin.Unit> callback);
}
- public interface Emittable {
- method public void emitInsertAt(int index, androidx.compose.Emittable instance);
- method public void emitMove(int from, int to, int count);
- method public void emitRemoveAt(int index, int count);
- }
-
public final class ExpectKt {
}
@@ -427,68 +410,6 @@
@kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.FUNCTION) public @interface Untracked {
}
- public final class ViewAdapters {
- ctor public ViewAdapters();
- method public Object? adapt(Object parent, Object child);
- method public boolean register(kotlin.jvm.functions.Function2<java.lang.Object,java.lang.Object,?> adapter);
- }
-
- public final class ViewComposer extends androidx.compose.Composer<java.lang.Object> {
- ctor public ViewComposer(android.content.Context context, Object root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer, androidx.compose.ViewAdapters? adapters);
- method public inline <T extends android.view.View> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
- method public inline <T extends android.view.ViewGroup> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public inline <T extends androidx.compose.Emittable> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
- method public inline <T extends androidx.compose.Emittable> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public androidx.compose.ViewAdapters? getAdapters();
- method public android.content.Context getContext();
- method public Object getRoot();
- }
-
- public final class ViewComposerCommonKt {
- }
-
- public final class ViewComposerKt {
- method @Deprecated public static androidx.compose.ViewComposer getComposer();
- method public static Boolean? registerAdapter(androidx.compose.ViewComposer, kotlin.jvm.functions.Function2<java.lang.Object,java.lang.Object,?> adapter);
- method public static <T> T! runWithComposing(androidx.compose.Composer<?>, kotlin.jvm.functions.Function0<? extends T> block);
- }
-
-}
-
-package androidx.compose.adapters {
-
- public final class ComposeViewAdapter implements androidx.compose.adapters.ViewAdapter {
- ctor public ComposeViewAdapter();
- method public void didInsert(android.view.View view, android.view.ViewGroup parent);
- method public void didUpdate(android.view.View view, android.view.ViewGroup parent);
- method public inline <T extends androidx.compose.adapters.ViewAdapter> T get(int id, kotlin.jvm.functions.Function0<? extends T> factory);
- method public java.util.List<androidx.compose.adapters.ViewAdapter> getAdapters();
- method public int getId();
- method public void willInsert(android.view.View view, android.view.ViewGroup parent);
- property public final java.util.List<androidx.compose.adapters.ViewAdapter> adapters;
- property public int id;
- }
-
- public interface ViewAdapter {
- method public void didInsert(android.view.View view, android.view.ViewGroup parent);
- method public void didUpdate(android.view.View view, android.view.ViewGroup parent);
- method public int getId();
- method public void willInsert(android.view.View view, android.view.ViewGroup parent);
- property public abstract int id;
- }
-
- public final class ViewAdapterKt {
- method public static inline <T extends androidx.compose.adapters.ViewAdapter> T getOrAddAdapter(android.view.View, int id, kotlin.jvm.functions.Function0<? extends T> factory);
- method public static androidx.compose.adapters.ComposeViewAdapter getViewAdapter(android.view.View);
- }
-
-}
-
-package androidx.compose.annotations {
-
- @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface Hide {
- }
-
}
package androidx.compose.frames {
@@ -623,3 +544,54 @@
}
+package androidx.compose.internal {
+
+ @androidx.compose.Stable public final class RestartableFunction<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, R> implements kotlin.jvm.functions.Function0<R> kotlin.jvm.functions.Function1<androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function10<P1,P2,P3,P4,P5,P6,P7,P8,P9,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function11<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function12<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function13<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function14<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function15<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function16<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function17<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function18<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function19<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function2<P1,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function20<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function21<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,P20,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function22<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,P20,P21,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function3<P1,P2,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function4<P1,P2,P3,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function5<P1,P2,P3,P4,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function6<P1,P2,P3,P4,P5,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function7<P1,P2,P3,P4,P5,P6,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function8<P1,P2,P3,P4,P5,P6,P7,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function9<P1,P2,P3,P4,P5,P6,P7,P8,androidx.compose.Composer<?>,R> {
+ ctor public RestartableFunction(Object key, boolean tracked);
+ method public Object getKey();
+ method public R! invoke();
+ method public R! invoke(androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, P20? p20, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, P20? p20, P21? p21, androidx.compose.Composer<?> c);
+ method public void update(Object block);
+ }
+
+ public final class RestartableFunctionKt {
+ method @androidx.compose.Composable public static androidx.compose.internal.RestartableFunction<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object> restartableFunction(int key, boolean tracked, Object block);
+ method public static androidx.compose.internal.RestartableFunction<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object> restartableFunctionInstance(int key, boolean tracked, Object block);
+ }
+
+ @androidx.compose.Stable public final class RestartableFunctionN<R> implements kotlin.jvm.functions.FunctionN<R> {
+ ctor public RestartableFunctionN(Object key, boolean tracked, int arity);
+ method public int getArity();
+ method public Object getKey();
+ method public R! invoke(java.lang.Object?... args);
+ method public void update(Object block);
+ }
+
+ public final class RestartableFunctionNKt {
+ method @androidx.compose.Composable public static androidx.compose.internal.RestartableFunctionN<?> restartableFunctionN(int key, boolean tracked, int arity, Object block);
+ method public static androidx.compose.internal.RestartableFunctionN<?> restartableFunctionNInstance(int key, boolean tracked, int arity, Object block);
+ }
+
+}
+
diff --git a/compose/compose-runtime/api/public_plus_experimental_current.txt b/compose/compose-runtime/api/public_plus_experimental_current.txt
index 101b78f..faa36af 100644
--- a/compose/compose-runtime/api/public_plus_experimental_current.txt
+++ b/compose/compose-runtime/api/public_plus_experimental_current.txt
@@ -60,25 +60,9 @@
@kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.PROPERTY}) public @interface Composable {
}
- public final class Compose {
- method @MainThread public androidx.compose.Composition composeInto(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- method @MainThread public androidx.compose.Composition composeInto(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- method @MainThread public void disposeComposition(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null);
- method @MainThread public void disposeComposition(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null);
- method @MainThread public androidx.compose.Composition subcomposeInto(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- field public static final androidx.compose.Compose! INSTANCE;
- }
-
- public final class ComposeAndroidKt {
- method public static void disposeComposition(android.app.Activity);
- method public static androidx.compose.Composition? setViewContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- }
-
public final class ComposeKt {
- method public static void disposeComposition(android.view.ViewGroup);
method public static kotlin.jvm.functions.Function0<kotlin.Unit> emptyContent();
method public static inline kotlin.jvm.functions.Function0<kotlin.Unit> orEmpty(kotlin.jvm.functions.Function0<kotlin.Unit>?);
- method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
}
public class Composer<N> implements androidx.compose.ComposerValidator {
@@ -152,7 +136,12 @@
method public final void compose(kotlin.jvm.functions.Function0<kotlin.Unit> content);
method public final void compose();
method public void dispose();
+ method public final kotlin.jvm.functions.Function0<kotlin.Unit> getComposable();
+ method public final boolean isRoot();
method public final boolean recomposeSync();
+ method public final void setComposable(kotlin.jvm.functions.Function0<kotlin.Unit> p);
+ property public final kotlin.jvm.functions.Function0<kotlin.Unit> composable;
+ property public final boolean isRoot;
}
public final class CompositionKt {
@@ -185,12 +174,6 @@
method @androidx.compose.Composable public static void onPreCommit(Object![]? inputs, kotlin.jvm.functions.Function1<? super androidx.compose.CommitScope,kotlin.Unit> callback);
}
- public interface Emittable {
- method public void emitInsertAt(int index, androidx.compose.Emittable instance);
- method public void emitMove(int from, int to, int count);
- method public void emitRemoveAt(int index, int count);
- }
-
public final class ExpectKt {
}
@@ -427,68 +410,6 @@
@kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.FUNCTION) public @interface Untracked {
}
- public final class ViewAdapters {
- ctor public ViewAdapters();
- method public Object? adapt(Object parent, Object child);
- method public boolean register(kotlin.jvm.functions.Function2<java.lang.Object,java.lang.Object,?> adapter);
- }
-
- public final class ViewComposer extends androidx.compose.Composer<java.lang.Object> {
- ctor public ViewComposer(android.content.Context context, Object root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer, androidx.compose.ViewAdapters? adapters);
- method public inline <T extends android.view.View> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
- method public inline <T extends android.view.ViewGroup> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public inline <T extends androidx.compose.Emittable> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
- method public inline <T extends androidx.compose.Emittable> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public androidx.compose.ViewAdapters? getAdapters();
- method public android.content.Context getContext();
- method public Object getRoot();
- }
-
- public final class ViewComposerCommonKt {
- }
-
- public final class ViewComposerKt {
- method @Deprecated public static androidx.compose.ViewComposer getComposer();
- method public static Boolean? registerAdapter(androidx.compose.ViewComposer, kotlin.jvm.functions.Function2<java.lang.Object,java.lang.Object,?> adapter);
- method public static <T> T! runWithComposing(androidx.compose.Composer<?>, kotlin.jvm.functions.Function0<? extends T> block);
- }
-
-}
-
-package androidx.compose.adapters {
-
- public final class ComposeViewAdapter implements androidx.compose.adapters.ViewAdapter {
- ctor public ComposeViewAdapter();
- method public void didInsert(android.view.View view, android.view.ViewGroup parent);
- method public void didUpdate(android.view.View view, android.view.ViewGroup parent);
- method public inline <T extends androidx.compose.adapters.ViewAdapter> T get(int id, kotlin.jvm.functions.Function0<? extends T> factory);
- method public java.util.List<androidx.compose.adapters.ViewAdapter> getAdapters();
- method public int getId();
- method public void willInsert(android.view.View view, android.view.ViewGroup parent);
- property public final java.util.List<androidx.compose.adapters.ViewAdapter> adapters;
- property public int id;
- }
-
- public interface ViewAdapter {
- method public void didInsert(android.view.View view, android.view.ViewGroup parent);
- method public void didUpdate(android.view.View view, android.view.ViewGroup parent);
- method public int getId();
- method public void willInsert(android.view.View view, android.view.ViewGroup parent);
- property public abstract int id;
- }
-
- public final class ViewAdapterKt {
- method public static inline <T extends androidx.compose.adapters.ViewAdapter> T getOrAddAdapter(android.view.View, int id, kotlin.jvm.functions.Function0<? extends T> factory);
- method public static androidx.compose.adapters.ComposeViewAdapter getViewAdapter(android.view.View);
- }
-
-}
-
-package androidx.compose.annotations {
-
- @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface Hide {
- }
-
}
package androidx.compose.frames {
@@ -623,3 +544,54 @@
}
+package androidx.compose.internal {
+
+ @androidx.compose.Stable public final class RestartableFunction<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, R> implements kotlin.jvm.functions.Function0<R> kotlin.jvm.functions.Function1<androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function10<P1,P2,P3,P4,P5,P6,P7,P8,P9,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function11<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function12<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function13<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function14<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function15<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function16<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function17<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function18<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function19<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function2<P1,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function20<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function21<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,P20,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function22<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,P20,P21,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function3<P1,P2,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function4<P1,P2,P3,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function5<P1,P2,P3,P4,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function6<P1,P2,P3,P4,P5,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function7<P1,P2,P3,P4,P5,P6,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function8<P1,P2,P3,P4,P5,P6,P7,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function9<P1,P2,P3,P4,P5,P6,P7,P8,androidx.compose.Composer<?>,R> {
+ ctor public RestartableFunction(Object key, boolean tracked);
+ method public Object getKey();
+ method public R! invoke();
+ method public R! invoke(androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, P20? p20, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, P20? p20, P21? p21, androidx.compose.Composer<?> c);
+ method public void update(Object block);
+ }
+
+ public final class RestartableFunctionKt {
+ method @androidx.compose.Composable public static androidx.compose.internal.RestartableFunction<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object> restartableFunction(int key, boolean tracked, Object block);
+ method public static androidx.compose.internal.RestartableFunction<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object> restartableFunctionInstance(int key, boolean tracked, Object block);
+ }
+
+ @androidx.compose.Stable public final class RestartableFunctionN<R> implements kotlin.jvm.functions.FunctionN<R> {
+ ctor public RestartableFunctionN(Object key, boolean tracked, int arity);
+ method public int getArity();
+ method public Object getKey();
+ method public R! invoke(java.lang.Object?... args);
+ method public void update(Object block);
+ }
+
+ public final class RestartableFunctionNKt {
+ method @androidx.compose.Composable public static androidx.compose.internal.RestartableFunctionN<?> restartableFunctionN(int key, boolean tracked, int arity, Object block);
+ method public static androidx.compose.internal.RestartableFunctionN<?> restartableFunctionNInstance(int key, boolean tracked, int arity, Object block);
+ }
+
+}
+
diff --git a/compose/compose-runtime/api/restricted_0.1.0-dev07.txt b/compose/compose-runtime/api/restricted_0.1.0-dev07.txt
index 101b78f..faa36af 100644
--- a/compose/compose-runtime/api/restricted_0.1.0-dev07.txt
+++ b/compose/compose-runtime/api/restricted_0.1.0-dev07.txt
@@ -60,25 +60,9 @@
@kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.PROPERTY}) public @interface Composable {
}
- public final class Compose {
- method @MainThread public androidx.compose.Composition composeInto(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- method @MainThread public androidx.compose.Composition composeInto(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- method @MainThread public void disposeComposition(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null);
- method @MainThread public void disposeComposition(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null);
- method @MainThread public androidx.compose.Composition subcomposeInto(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- field public static final androidx.compose.Compose! INSTANCE;
- }
-
- public final class ComposeAndroidKt {
- method public static void disposeComposition(android.app.Activity);
- method public static androidx.compose.Composition? setViewContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- }
-
public final class ComposeKt {
- method public static void disposeComposition(android.view.ViewGroup);
method public static kotlin.jvm.functions.Function0<kotlin.Unit> emptyContent();
method public static inline kotlin.jvm.functions.Function0<kotlin.Unit> orEmpty(kotlin.jvm.functions.Function0<kotlin.Unit>?);
- method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
}
public class Composer<N> implements androidx.compose.ComposerValidator {
@@ -152,7 +136,12 @@
method public final void compose(kotlin.jvm.functions.Function0<kotlin.Unit> content);
method public final void compose();
method public void dispose();
+ method public final kotlin.jvm.functions.Function0<kotlin.Unit> getComposable();
+ method public final boolean isRoot();
method public final boolean recomposeSync();
+ method public final void setComposable(kotlin.jvm.functions.Function0<kotlin.Unit> p);
+ property public final kotlin.jvm.functions.Function0<kotlin.Unit> composable;
+ property public final boolean isRoot;
}
public final class CompositionKt {
@@ -185,12 +174,6 @@
method @androidx.compose.Composable public static void onPreCommit(Object![]? inputs, kotlin.jvm.functions.Function1<? super androidx.compose.CommitScope,kotlin.Unit> callback);
}
- public interface Emittable {
- method public void emitInsertAt(int index, androidx.compose.Emittable instance);
- method public void emitMove(int from, int to, int count);
- method public void emitRemoveAt(int index, int count);
- }
-
public final class ExpectKt {
}
@@ -427,68 +410,6 @@
@kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.FUNCTION) public @interface Untracked {
}
- public final class ViewAdapters {
- ctor public ViewAdapters();
- method public Object? adapt(Object parent, Object child);
- method public boolean register(kotlin.jvm.functions.Function2<java.lang.Object,java.lang.Object,?> adapter);
- }
-
- public final class ViewComposer extends androidx.compose.Composer<java.lang.Object> {
- ctor public ViewComposer(android.content.Context context, Object root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer, androidx.compose.ViewAdapters? adapters);
- method public inline <T extends android.view.View> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
- method public inline <T extends android.view.ViewGroup> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public inline <T extends androidx.compose.Emittable> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
- method public inline <T extends androidx.compose.Emittable> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public androidx.compose.ViewAdapters? getAdapters();
- method public android.content.Context getContext();
- method public Object getRoot();
- }
-
- public final class ViewComposerCommonKt {
- }
-
- public final class ViewComposerKt {
- method @Deprecated public static androidx.compose.ViewComposer getComposer();
- method public static Boolean? registerAdapter(androidx.compose.ViewComposer, kotlin.jvm.functions.Function2<java.lang.Object,java.lang.Object,?> adapter);
- method public static <T> T! runWithComposing(androidx.compose.Composer<?>, kotlin.jvm.functions.Function0<? extends T> block);
- }
-
-}
-
-package androidx.compose.adapters {
-
- public final class ComposeViewAdapter implements androidx.compose.adapters.ViewAdapter {
- ctor public ComposeViewAdapter();
- method public void didInsert(android.view.View view, android.view.ViewGroup parent);
- method public void didUpdate(android.view.View view, android.view.ViewGroup parent);
- method public inline <T extends androidx.compose.adapters.ViewAdapter> T get(int id, kotlin.jvm.functions.Function0<? extends T> factory);
- method public java.util.List<androidx.compose.adapters.ViewAdapter> getAdapters();
- method public int getId();
- method public void willInsert(android.view.View view, android.view.ViewGroup parent);
- property public final java.util.List<androidx.compose.adapters.ViewAdapter> adapters;
- property public int id;
- }
-
- public interface ViewAdapter {
- method public void didInsert(android.view.View view, android.view.ViewGroup parent);
- method public void didUpdate(android.view.View view, android.view.ViewGroup parent);
- method public int getId();
- method public void willInsert(android.view.View view, android.view.ViewGroup parent);
- property public abstract int id;
- }
-
- public final class ViewAdapterKt {
- method public static inline <T extends androidx.compose.adapters.ViewAdapter> T getOrAddAdapter(android.view.View, int id, kotlin.jvm.functions.Function0<? extends T> factory);
- method public static androidx.compose.adapters.ComposeViewAdapter getViewAdapter(android.view.View);
- }
-
-}
-
-package androidx.compose.annotations {
-
- @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface Hide {
- }
-
}
package androidx.compose.frames {
@@ -623,3 +544,54 @@
}
+package androidx.compose.internal {
+
+ @androidx.compose.Stable public final class RestartableFunction<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, R> implements kotlin.jvm.functions.Function0<R> kotlin.jvm.functions.Function1<androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function10<P1,P2,P3,P4,P5,P6,P7,P8,P9,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function11<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function12<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function13<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function14<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function15<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function16<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function17<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function18<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function19<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function2<P1,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function20<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function21<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,P20,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function22<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,P20,P21,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function3<P1,P2,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function4<P1,P2,P3,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function5<P1,P2,P3,P4,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function6<P1,P2,P3,P4,P5,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function7<P1,P2,P3,P4,P5,P6,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function8<P1,P2,P3,P4,P5,P6,P7,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function9<P1,P2,P3,P4,P5,P6,P7,P8,androidx.compose.Composer<?>,R> {
+ ctor public RestartableFunction(Object key, boolean tracked);
+ method public Object getKey();
+ method public R! invoke();
+ method public R! invoke(androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, P20? p20, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, P20? p20, P21? p21, androidx.compose.Composer<?> c);
+ method public void update(Object block);
+ }
+
+ public final class RestartableFunctionKt {
+ method @androidx.compose.Composable public static androidx.compose.internal.RestartableFunction<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object> restartableFunction(int key, boolean tracked, Object block);
+ method public static androidx.compose.internal.RestartableFunction<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object> restartableFunctionInstance(int key, boolean tracked, Object block);
+ }
+
+ @androidx.compose.Stable public final class RestartableFunctionN<R> implements kotlin.jvm.functions.FunctionN<R> {
+ ctor public RestartableFunctionN(Object key, boolean tracked, int arity);
+ method public int getArity();
+ method public Object getKey();
+ method public R! invoke(java.lang.Object?... args);
+ method public void update(Object block);
+ }
+
+ public final class RestartableFunctionNKt {
+ method @androidx.compose.Composable public static androidx.compose.internal.RestartableFunctionN<?> restartableFunctionN(int key, boolean tracked, int arity, Object block);
+ method public static androidx.compose.internal.RestartableFunctionN<?> restartableFunctionNInstance(int key, boolean tracked, int arity, Object block);
+ }
+
+}
+
diff --git a/compose/compose-runtime/api/restricted_current.txt b/compose/compose-runtime/api/restricted_current.txt
index 101b78f..faa36af 100644
--- a/compose/compose-runtime/api/restricted_current.txt
+++ b/compose/compose-runtime/api/restricted_current.txt
@@ -60,25 +60,9 @@
@kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets={AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.TYPE, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.PROPERTY}) public @interface Composable {
}
- public final class Compose {
- method @MainThread public androidx.compose.Composition composeInto(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- method @MainThread public androidx.compose.Composition composeInto(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- method @MainThread public void disposeComposition(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null);
- method @MainThread public void disposeComposition(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null);
- method @MainThread public androidx.compose.Composition subcomposeInto(androidx.compose.Emittable container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- field public static final androidx.compose.Compose! INSTANCE;
- }
-
- public final class ComposeAndroidKt {
- method public static void disposeComposition(android.app.Activity);
- method public static androidx.compose.Composition? setViewContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
- }
-
public final class ComposeKt {
- method public static void disposeComposition(android.view.ViewGroup);
method public static kotlin.jvm.functions.Function0<kotlin.Unit> emptyContent();
method public static inline kotlin.jvm.functions.Function0<kotlin.Unit> orEmpty(kotlin.jvm.functions.Function0<kotlin.Unit>?);
- method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
}
public class Composer<N> implements androidx.compose.ComposerValidator {
@@ -152,7 +136,12 @@
method public final void compose(kotlin.jvm.functions.Function0<kotlin.Unit> content);
method public final void compose();
method public void dispose();
+ method public final kotlin.jvm.functions.Function0<kotlin.Unit> getComposable();
+ method public final boolean isRoot();
method public final boolean recomposeSync();
+ method public final void setComposable(kotlin.jvm.functions.Function0<kotlin.Unit> p);
+ property public final kotlin.jvm.functions.Function0<kotlin.Unit> composable;
+ property public final boolean isRoot;
}
public final class CompositionKt {
@@ -185,12 +174,6 @@
method @androidx.compose.Composable public static void onPreCommit(Object![]? inputs, kotlin.jvm.functions.Function1<? super androidx.compose.CommitScope,kotlin.Unit> callback);
}
- public interface Emittable {
- method public void emitInsertAt(int index, androidx.compose.Emittable instance);
- method public void emitMove(int from, int to, int count);
- method public void emitRemoveAt(int index, int count);
- }
-
public final class ExpectKt {
}
@@ -427,68 +410,6 @@
@kotlin.annotation.MustBeDocumented @kotlin.annotation.Retention(AnnotationRetention.BINARY) @kotlin.annotation.Target(allowedTargets=AnnotationTarget.FUNCTION) public @interface Untracked {
}
- public final class ViewAdapters {
- ctor public ViewAdapters();
- method public Object? adapt(Object parent, Object child);
- method public boolean register(kotlin.jvm.functions.Function2<java.lang.Object,java.lang.Object,?> adapter);
- }
-
- public final class ViewComposer extends androidx.compose.Composer<java.lang.Object> {
- ctor public ViewComposer(android.content.Context context, Object root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer, androidx.compose.ViewAdapters? adapters);
- method public inline <T extends android.view.View> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
- method public inline <T extends android.view.ViewGroup> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public inline <T extends androidx.compose.Emittable> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
- method public inline <T extends androidx.compose.Emittable> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public androidx.compose.ViewAdapters? getAdapters();
- method public android.content.Context getContext();
- method public Object getRoot();
- }
-
- public final class ViewComposerCommonKt {
- }
-
- public final class ViewComposerKt {
- method @Deprecated public static androidx.compose.ViewComposer getComposer();
- method public static Boolean? registerAdapter(androidx.compose.ViewComposer, kotlin.jvm.functions.Function2<java.lang.Object,java.lang.Object,?> adapter);
- method public static <T> T! runWithComposing(androidx.compose.Composer<?>, kotlin.jvm.functions.Function0<? extends T> block);
- }
-
-}
-
-package androidx.compose.adapters {
-
- public final class ComposeViewAdapter implements androidx.compose.adapters.ViewAdapter {
- ctor public ComposeViewAdapter();
- method public void didInsert(android.view.View view, android.view.ViewGroup parent);
- method public void didUpdate(android.view.View view, android.view.ViewGroup parent);
- method public inline <T extends androidx.compose.adapters.ViewAdapter> T get(int id, kotlin.jvm.functions.Function0<? extends T> factory);
- method public java.util.List<androidx.compose.adapters.ViewAdapter> getAdapters();
- method public int getId();
- method public void willInsert(android.view.View view, android.view.ViewGroup parent);
- property public final java.util.List<androidx.compose.adapters.ViewAdapter> adapters;
- property public int id;
- }
-
- public interface ViewAdapter {
- method public void didInsert(android.view.View view, android.view.ViewGroup parent);
- method public void didUpdate(android.view.View view, android.view.ViewGroup parent);
- method public int getId();
- method public void willInsert(android.view.View view, android.view.ViewGroup parent);
- property public abstract int id;
- }
-
- public final class ViewAdapterKt {
- method public static inline <T extends androidx.compose.adapters.ViewAdapter> T getOrAddAdapter(android.view.View, int id, kotlin.jvm.functions.Function0<? extends T> factory);
- method public static androidx.compose.adapters.ComposeViewAdapter getViewAdapter(android.view.View);
- }
-
-}
-
-package androidx.compose.annotations {
-
- @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) public @interface Hide {
- }
-
}
package androidx.compose.frames {
@@ -623,3 +544,54 @@
}
+package androidx.compose.internal {
+
+ @androidx.compose.Stable public final class RestartableFunction<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18, P19, P20, P21, R> implements kotlin.jvm.functions.Function0<R> kotlin.jvm.functions.Function1<androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function10<P1,P2,P3,P4,P5,P6,P7,P8,P9,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function11<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function12<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function13<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function14<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function15<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function16<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function17<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function18<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function19<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function2<P1,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function20<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function21<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,P20,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function22<P1,P2,P3,P4,P5,P6,P7,P8,P9,P10,P11,P12,P13,P14,P15,P16,P17,P18,P19,P20,P21,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function3<P1,P2,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function4<P1,P2,P3,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function5<P1,P2,P3,P4,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function6<P1,P2,P3,P4,P5,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function7<P1,P2,P3,P4,P5,P6,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function8<P1,P2,P3,P4,P5,P6,P7,androidx.compose.Composer<?>,R> kotlin.jvm.functions.Function9<P1,P2,P3,P4,P5,P6,P7,P8,androidx.compose.Composer<?>,R> {
+ ctor public RestartableFunction(Object key, boolean tracked);
+ method public Object getKey();
+ method public R! invoke();
+ method public R! invoke(androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, P20? p20, androidx.compose.Composer<?> c);
+ method public R! invoke(P1? p1, P2? p2, P3? p3, P4? p4, P5? p5, P6? p6, P7? p7, P8? p8, P9? p9, P10? p10, P11? p11, P12? p12, P13? p13, P14? p14, P15? p15, P16? p16, P17? p17, P18? p18, P19? p19, P20? p20, P21? p21, androidx.compose.Composer<?> c);
+ method public void update(Object block);
+ }
+
+ public final class RestartableFunctionKt {
+ method @androidx.compose.Composable public static androidx.compose.internal.RestartableFunction<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object> restartableFunction(int key, boolean tracked, Object block);
+ method public static androidx.compose.internal.RestartableFunction<java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object,java.lang.Object> restartableFunctionInstance(int key, boolean tracked, Object block);
+ }
+
+ @androidx.compose.Stable public final class RestartableFunctionN<R> implements kotlin.jvm.functions.FunctionN<R> {
+ ctor public RestartableFunctionN(Object key, boolean tracked, int arity);
+ method public int getArity();
+ method public Object getKey();
+ method public R! invoke(java.lang.Object?... args);
+ method public void update(Object block);
+ }
+
+ public final class RestartableFunctionNKt {
+ method @androidx.compose.Composable public static androidx.compose.internal.RestartableFunctionN<?> restartableFunctionN(int key, boolean tracked, int arity, Object block);
+ method public static androidx.compose.internal.RestartableFunctionN<?> restartableFunctionNInstance(int key, boolean tracked, int arity, Object block);
+ }
+
+}
+
diff --git a/compose/compose-runtime/build.gradle b/compose/compose-runtime/build.gradle
index fd83485..d3dc145 100644
--- a/compose/compose-runtime/build.gradle
+++ b/compose/compose-runtime/build.gradle
@@ -40,6 +40,7 @@
}
commonTest.dependencies {
implementation kotlin("test-junit")
+ implementation project(":ui:ui-framework")
}
jvmMain {
@@ -64,6 +65,8 @@
androidAndroidTest.dependencies {
implementation(ANDROIDX_TEST_EXT_JUNIT)
implementation(ANDROIDX_TEST_RULES)
+ implementation project(":ui:ui-framework")
+ implementation project(":ui:ui-platform")
}
all {
languageSettings.useExperimentalAnnotation("kotlin.Experimental")
diff --git a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/HotReloadIntegrationTests.kt b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/HotReloadIntegrationTests.kt
index 8951071..402d55a 100644
--- a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/HotReloadIntegrationTests.kt
+++ b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/HotReloadIntegrationTests.kt
@@ -24,6 +24,7 @@
import androidx.ui.core.Text
import androidx.ui.core.WithConstraints
import androidx.ui.core.setContent
+import androidx.ui.core.simulateHotReload
import androidx.ui.layout.Column
import androidx.ui.material.DrawerState
import androidx.ui.material.ModalDrawerLayout
@@ -55,7 +56,7 @@
activity.uiThread {
activity.setContent {
Column {
- WithConstraints {
+ WithConstraints { _, _ ->
val state = state { DrawerState.Closed }
ModalDrawerLayout(
drawerState = state.value,
@@ -69,7 +70,7 @@
}
activity.onNextFrame {
- Compose.simulateHotReload(activity)
+ simulateHotReload(activity)
}
}
}
diff --git a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/ComposeBenchmarkBase.kt b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/ComposeBenchmarkBase.kt
index 5e32a8d..b8c3443 100644
--- a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/ComposeBenchmarkBase.kt
+++ b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/ComposeBenchmarkBase.kt
@@ -20,9 +20,9 @@
import androidx.benchmark.junit4.measureRepeated
import androidx.compose.Composable
import androidx.compose.Composer
+import androidx.compose.Composition
import androidx.compose.FrameManager
import androidx.compose.currentComposer
-import androidx.compose.disposeComposition
import androidx.test.rule.ActivityTestRule
import androidx.ui.core.setContent
import org.junit.Assert.assertTrue
@@ -37,14 +37,15 @@
fun measureCompose(block: @Composable() () -> Unit) {
val activity = activityRule.activity
+ var composition: Composition? = null
benchmarkRule.measureRepeated {
- activity.setContent(block)
+ composition = activity.setContent(block)
runWithTimingDisabled {
- activity.setContent { }
+ composition = activity.setContent { }
}
}
- activity.disposeComposition()
+ composition?.dispose()
}
fun measureRecompose(block: RecomposeReceiver.() -> Unit) {
@@ -54,7 +55,7 @@
val activity = activityRule.activity
- activity.setContent {
+ val composition = activity.setContent {
activeComposer = currentComposer
receiver.composeCb()
}
@@ -71,7 +72,7 @@
assertTrue(didSomething)
}
- activity.disposeComposition()
+ composition.dispose()
}
}
diff --git a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/realworld4/RealWorld4_Widgets.kt b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/realworld4/RealWorld4_Widgets.kt
index e96f266..1aca5d6 100644
--- a/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/realworld4/RealWorld4_Widgets.kt
+++ b/compose/compose-runtime/compose-runtime-benchmark/src/androidTest/java/androidx/compose/benchmark/realworld4/RealWorld4_Widgets.kt
@@ -50,7 +50,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -120,7 +120,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -168,7 +168,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -265,7 +265,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -368,7 +368,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -456,7 +456,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -567,7 +567,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -633,7 +633,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -712,7 +712,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -759,7 +759,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -814,7 +814,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -852,7 +852,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -889,7 +889,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -952,7 +952,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -991,7 +991,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1036,7 +1036,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1095,7 +1095,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1165,7 +1165,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1219,7 +1219,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1276,7 +1276,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1327,7 +1327,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1360,7 +1360,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1412,7 +1412,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1495,7 +1495,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp5.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1548,7 +1548,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1595,7 +1595,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1656,7 +1656,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1695,7 +1695,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1745,7 +1745,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1788,7 +1788,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1835,7 +1835,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1883,7 +1883,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1924,7 +1924,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp5.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -1963,7 +1963,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2018,7 +2018,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2063,7 +2063,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2102,7 +2102,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2154,7 +2154,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2254,7 +2254,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp5.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2305,7 +2305,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2364,7 +2364,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2411,7 +2411,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2483,7 +2483,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2541,7 +2541,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp5.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2607,7 +2607,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp5.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2693,7 +2693,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp5.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2740,7 +2740,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2781,7 +2781,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2820,7 +2820,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2859,7 +2859,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2920,7 +2920,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2959,7 +2959,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -2998,7 +2998,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3036,7 +3036,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3066,7 +3066,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3141,7 +3141,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3200,7 +3200,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3261,7 +3261,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp5.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3294,7 +3294,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3351,7 +3351,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3389,7 +3389,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3425,7 +3425,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3462,7 +3462,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3523,7 +3523,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3562,7 +3562,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3606,7 +3606,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3649,7 +3649,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3700,7 +3700,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3750,7 +3750,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp5.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3815,7 +3815,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3879,7 +3879,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -3950,7 +3950,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp5.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4019,7 +4019,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4066,7 +4066,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4112,7 +4112,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4151,7 +4151,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4202,7 +4202,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4309,7 +4309,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4361,7 +4361,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4418,7 +4418,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4458,7 +4458,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4538,7 +4538,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp5.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4609,7 +4609,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4668,7 +4668,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4711,7 +4711,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4744,7 +4744,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4802,7 +4802,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4858,7 +4858,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4895,7 +4895,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4942,7 +4942,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -4986,7 +4986,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5023,7 +5023,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5063,7 +5063,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5121,7 +5121,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5194,7 +5194,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp5.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5247,7 +5247,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5292,7 +5292,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5353,7 +5353,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5419,7 +5419,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5472,7 +5472,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5517,7 +5517,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5582,7 +5582,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5645,7 +5645,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5683,7 +5683,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5726,7 +5726,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5765,7 +5765,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5825,7 +5825,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5870,7 +5870,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5909,7 +5909,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5942,7 +5942,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -5993,7 +5993,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6036,7 +6036,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp5.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6069,7 +6069,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6128,7 +6128,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6199,7 +6199,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6250,7 +6250,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6289,7 +6289,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6336,7 +6336,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6375,7 +6375,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6414,7 +6414,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6461,7 +6461,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6506,7 +6506,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6561,7 +6561,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp5.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6606,7 +6606,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6651,7 +6651,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6698,7 +6698,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6737,7 +6737,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6770,7 +6770,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6815,7 +6815,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6854,7 +6854,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6887,7 +6887,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -6934,7 +6934,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -7010,7 +7010,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -7145,7 +7145,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -7207,7 +7207,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -7270,7 +7270,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -7317,7 +7317,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -7384,7 +7384,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -7417,7 +7417,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -7451,7 +7451,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -7512,7 +7512,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -7589,7 +7589,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -7652,7 +7652,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -7744,7 +7744,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -7841,7 +7841,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp5.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -7906,7 +7906,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -7989,7 +7989,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -8072,7 +8072,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp5 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2 + tmp3 + tmp4
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp5.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -8110,7 +8110,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
@@ -8177,7 +8177,7 @@
emptyList<Collection<KCallable<*>>>()
}.map { it.toString().reversed() }.joinToString("-"))
val tmp3 = "lkjzndgke84ts" + tmp0 + tmp1 + tmp2
- WithConstraints(modifier) { constraints ->
+ WithConstraints(modifier) { constraints, _ ->
Box(LayoutPadding(1.dp) + DrawBackground(color = tmp3.toColor())) {
if (constraints.maxHeight > constraints.maxWidth) {
Column {
diff --git a/compose/compose-runtime/integration-tests/samples/src/main/java/androidx/compose/samples/SlotTableSamples.kt b/compose/compose-runtime/integration-tests/samples/src/main/java/androidx/compose/samples/SlotTableSamples.kt
index eaaab06..2144694 100644
--- a/compose/compose-runtime/integration-tests/samples/src/main/java/androidx/compose/samples/SlotTableSamples.kt
+++ b/compose/compose-runtime/integration-tests/samples/src/main/java/androidx/compose/samples/SlotTableSamples.kt
@@ -18,15 +18,13 @@
package androidx.compose.samples
-import android.widget.LinearLayout
-import android.widget.TextView
import androidx.annotation.Sampled
import androidx.compose.Composable
@Sampled
@Composable
fun initialGroup() {
- LinearLayout {
+ Column {
Contact(contact = jim)
Contact(contact = bob)
}
@@ -35,7 +33,7 @@
@Sampled
@Composable
fun reorderedGroup() {
- LinearLayout {
+ Column {
Contact(contact = bob)
Contact(contact = jim)
}
@@ -46,8 +44,8 @@
private fun contactSample() {
@Composable
fun Contact(contact: Contact) {
- TextView(text = contact.name)
- TextView(text = contact.email)
+ Text(text = contact.name)
+ Text(text = contact.email)
}
}
@@ -55,6 +53,14 @@
@Composable
private fun Contact(contact: Contact) {}
+@Suppress("UNUSED_PARAMETER")
+@Composable
+private fun Column(children: @Composable() () -> Unit) {}
+
+@Suppress("UNUSED_PARAMETER")
+@Composable
+private fun Text(text: String) {}
+
private data class Contact(val name: String, val email: String)
private val jim = Contact("", "")
diff --git a/compose/compose-runtime/src/androidAndroidTest/AndroidManifest.xml b/compose/compose-runtime/src/androidAndroidTest/AndroidManifest.xml
index 1cb1e26..e74aed9f 100644
--- a/compose/compose-runtime/src/androidAndroidTest/AndroidManifest.xml
+++ b/compose/compose-runtime/src/androidAndroidTest/AndroidManifest.xml
@@ -17,8 +17,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="androidx.compose">
<application>
<activity
- android:name="androidx.compose.TestActivity"/>
+ android:name="androidx.compose.test.TestActivity"/>
<activity
- android:name="androidx.compose.DisposeTests$DisposeTestActivity"/>
+ android:name="androidx.compose.test.DisposeTests$DisposeTestActivity"/>
</application>
</manifest>
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/HotReloadTests.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/HotReloadTests.kt
deleted file mode 100644
index f951cc0..0000000
--- a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/HotReloadTests.kt
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright 2019 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:Suppress("USELESS_CAST")
-
-package androidx.compose
-
-import android.app.Activity
-import android.content.Context
-import android.view.ViewGroup
-import android.widget.LinearLayout
-import android.widget.TextView
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.MediumTest
-import org.junit.After
-import org.junit.Rule
-import org.junit.Test
-import org.junit.runner.RunWith
-import kotlin.test.assertEquals
-import kotlin.test.assertNotEquals
-
-@MediumTest
-@RunWith(AndroidJUnit4::class)
-class HotReloadTests : BaseComposeTest() {
- @After
- fun teardown() {
- Compose.clearRoots()
- }
-
- @get:Rule
- override val activityRule = makeTestActivityRule()
-
- @Test
- fun composeView() {
- var value = "First value"
-
- compose {
- column {
- text(text = "Hello", id = 101)
- text(text = "World", id = 102)
- text(text = value, id = 103)
- }
- }.then { activity ->
- assertEquals(activity.findViewById<TextView>(103).text, value)
- value = "Second value"
- }.then { activity ->
- assertNotEquals(activity.findViewById<TextView>(103).text, value)
-
- Compose.simulateHotReload(activity)
-
- assertEquals(activity.findViewById<TextView>(103).text, value)
- }
- }
-
- @Test
- fun composeEmittable() {
- var value = "First value"
-
- val activity = activityRule.activity
-
- // Set the content of the view
- activity.uiThread {
- activity.setContent {
- columnNode {
- textNode(text = "Hello")
- textNode(text = "World")
- textNode(text = value)
- }
- }
- }
-
- // Allow the composition to complete
- activity.waitForAFrame()
-
- fun target() = activity.content.children[0].children[2]
-
- // Assert that the composition has the correct value
- assertEquals(target().value, value)
-
- value = "Second value"
-
- // Ensure the composition hasn't changed
- activity.waitForAFrame()
- assertNotEquals(target().value, value)
-
- // Simulate hot-reload
- activity.uiThread {
- Compose.simulateHotReload(activity)
- }
-
- // Detect tha tthe node changed
- assertEquals(target().value, value)
- }
-}
-
-@Composable fun text(text: String, id: Int = -1) {
- TextView(id = id, text = text)
-}
-
-@Composable fun column(children: @Composable() () -> Unit) {
- LinearLayout { children() }
-}
-
-@Composable fun textNode(text: String) {
- Node(name = "Text", value = text)
-}
-
-@Composable fun columnNode(children: @Composable() () -> Unit) {
- Node(name = "Text") {
- children()
- }
-}
-
-class Node(val name: String, var value: String = "") : Emittable {
- val children = mutableListOf<Node>()
-
- override fun emitInsertAt(index: Int, instance: Emittable) {
- children.add(index, instance as Node)
- }
-
- override fun emitRemoveAt(index: Int, count: Int) {
- repeat(count) { children.removeAt(index) }
- }
-
- override fun emitMove(from: Int, to: Int, count: Int) {
- if (from > to) {
- repeat(count) {
- children.add(to + it, children.removeAt(from))
- }
- } else if (from < to) {
- repeat(count) {
- children.add(to - 1, children.removeAt(from))
- }
- }
- }
-}
-
-fun Activity.setContent(content: @Composable() () -> Unit) {
- val composeView = contentView as? ViewEmitWrapper
- ?: ViewEmitWrapper(this).also {
- setContentView(it)
- }
- val root = Node("Root")
- composeView.emittable = root
- Compose.composeInto(root, this, null, content)
-}
-
-val Activity.contentView: View get() =
- window.decorView.findViewById<ViewGroup>(android.R.id.content).getChildAt(0)
-
-val Activity.content: Node get() =
- (contentView as ViewEmitWrapper).emittable as Node
-
-class ViewEmitWrapper(context: Context) : View(context) {
- var emittable: Emittable? = null
-}
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/AmbientTests.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/AmbientTests.kt
similarity index 72%
rename from compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/AmbientTests.kt
rename to compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/AmbientTests.kt
index c3dce9a..a6ef1ef 100644
--- a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/AmbientTests.kt
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/AmbientTests.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * 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.
@@ -14,11 +14,28 @@
* limitations under the License.
*/
-package androidx.compose
+package androidx.compose.test
import android.widget.TextView
+import androidx.compose.Ambient
+import androidx.compose.Composable
+import androidx.compose.CompositionReference
+import androidx.compose.Observe
+import androidx.compose.Providers
+import androidx.compose.Recomposer
+import androidx.compose.StructurallyEqual
+import androidx.compose.Untracked
+import androidx.compose.ambientOf
+import androidx.compose.compositionReference
+import androidx.compose.escapeCompose
+import androidx.compose.invalidate
+import androidx.compose.remember
+import androidx.compose.staticAmbientOf
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import androidx.ui.core.LayoutNode
+import androidx.ui.node.UiComposer
+import androidx.ui.core.subcomposeInto
import org.junit.After
import org.junit.Rule
import org.junit.Test
@@ -37,7 +54,8 @@
private val someOtherIntProvider = ambientOf { 1 }
// Make public the consumer key.
-val someOtherIntAmbient: Ambient<Int> = someOtherIntProvider
+val someOtherIntAmbient: Ambient<Int> =
+ someOtherIntProvider
// Create a static ambient with an int value
val someStaticInt = staticAmbientOf { 40 }
@@ -46,6 +64,18 @@
@RunWith(AndroidJUnit4::class)
class AmbientTests : BaseComposeTest() {
+ val composer: UiComposer get() = error("should not be called")
+
+ @Composable
+ fun Text(value: String, id: Int = 100) {
+ TextView(id = id, text = value)
+ }
+
+ @Composable
+ fun ReadStringAmbient(ambient: Ambient<String>, id: Int = 100) {
+ Text(value = ambient.current, id = id)
+ }
+
@get:Rule
override val activityRule = makeTestActivityRule()
@@ -60,19 +90,43 @@
someOtherIntProvider provides 42,
someStaticInt provides 50
) {
- assertEquals("Test1", someTextAmbient.current)
+ assertEquals(
+ "Test1",
+ someTextAmbient.current
+ )
assertEquals(12, someIntAmbient.current)
- assertEquals(42, someOtherIntAmbient.current)
+ assertEquals(
+ 42,
+ someOtherIntAmbient.current
+ )
assertEquals(50, someStaticInt.current)
- Providers(someTextAmbient provides "Test2", someStaticInt provides 60) {
- assertEquals("Test2", someTextAmbient.current)
- assertEquals(12, someIntAmbient.current)
- assertEquals(42, someOtherIntAmbient.current)
+ Providers(
+ someTextAmbient provides "Test2",
+ someStaticInt provides 60
+ ) {
+ assertEquals(
+ "Test2",
+ someTextAmbient.current
+ )
+ assertEquals(
+ 12,
+ someIntAmbient.current
+ )
+ assertEquals(
+ 42,
+ someOtherIntAmbient.current
+ )
assertEquals(60, someStaticInt.current)
}
- assertEquals("Test1", someTextAmbient.current)
+ assertEquals(
+ "Test1",
+ someTextAmbient.current
+ )
assertEquals(12, someIntAmbient.current)
- assertEquals(42, someOtherIntAmbient.current)
+ assertEquals(
+ 42,
+ someOtherIntAmbient.current
+ )
assertEquals(50, someStaticInt.current)
}
assertEquals("Default", someTextAmbient.current)
@@ -93,7 +147,10 @@
Providers(
someTextAmbient provides someText
) {
- ReadStringAmbient(ambient = someTextAmbient, id = tvId)
+ ReadStringAmbient(
+ ambient = someTextAmbient,
+ id = tvId
+ )
}
}.then { activity ->
assertEquals(someText, activity.findViewById<TextView>(100).text)
@@ -117,7 +174,10 @@
Providers(
staticStringAmbient provides someText
) {
- ReadStringAmbient(ambient = staticStringAmbient, id = tvId)
+ ReadStringAmbient(
+ ambient = staticStringAmbient,
+ id = tvId
+ )
}
}.then { activity ->
assertEquals(someText, activity.findViewById<TextView>(100).text)
@@ -143,15 +203,25 @@
someIntAmbient provides 0
) {
ReadStringAmbient(ambient = someTextAmbient, id = tvId)
+
subCompose {
- assertEquals(someText, someTextAmbient.current)
+ assertEquals(
+ someText,
+ someTextAmbient.current
+ )
assertEquals(0, someIntAmbient.current)
Providers(
someIntAmbient provides 42
) {
- assertEquals(someText, someTextAmbient.current)
- assertEquals(42, someIntAmbient.current)
+ assertEquals(
+ someText,
+ someTextAmbient.current
+ )
+ assertEquals(
+ 42,
+ someIntAmbient.current
+ )
}
}
}
@@ -170,7 +240,8 @@
val tvId = 100
val invalidates = mutableListOf<() -> Unit>()
fun doInvalidate() = invalidates.forEach { it() }.also { invalidates.clear() }
- val staticSomeTextAmbient = staticAmbientOf { "Default" }
+ val staticSomeTextAmbient =
+ staticAmbientOf { "Default" }
val staticSomeIntAmbient = staticAmbientOf { -1 }
var someText = "Unmodified"
compose {
@@ -183,7 +254,10 @@
assertEquals(someText, staticSomeTextAmbient.current)
assertEquals(0, staticSomeIntAmbient.current)
- ReadStringAmbient(ambient = staticSomeTextAmbient, id = tvId)
+ ReadStringAmbient(
+ ambient = staticSomeTextAmbient,
+ id = tvId
+ )
subCompose {
assertEquals(someText, staticSomeTextAmbient.current)
@@ -221,17 +295,29 @@
someTextAmbient provides someText,
someIntAmbient provides 0
) {
- ReadStringAmbient(ambient = someTextAmbient, id = tvId)
+ ReadStringAmbient(
+ ambient = someTextAmbient,
+ id = tvId
+ )
doSubCompose = deferredSubCompose {
- assertEquals(someText, someTextAmbient.current)
+ assertEquals(
+ someText,
+ someTextAmbient.current
+ )
assertEquals(0, someIntAmbient.current)
Providers(
someIntAmbient provides 42
) {
- assertEquals(someText, someTextAmbient.current)
- assertEquals(42, someIntAmbient.current)
+ assertEquals(
+ someText,
+ someTextAmbient.current
+ )
+ assertEquals(
+ 42,
+ someIntAmbient.current
+ )
}
}
}
@@ -255,7 +341,8 @@
fun doInvalidate() = invalidates.forEach { it() }.also { invalidates.clear() }
var someText = "Unmodified"
var doSubCompose: () -> Unit = { error("Sub-compose callback not set") }
- val staticSomeTextAmbient = staticAmbientOf { "Default" }
+ val staticSomeTextAmbient =
+ staticAmbientOf { "Default" }
val staticSomeIntAmbient = staticAmbientOf { -1 }
compose {
invalidates.add(invalidate)
@@ -267,7 +354,10 @@
assertEquals(someText, staticSomeTextAmbient.current)
assertEquals(0, staticSomeIntAmbient.current)
- ReadStringAmbient(ambient = staticSomeTextAmbient, id = tvId)
+ ReadStringAmbient(
+ ambient = staticSomeTextAmbient,
+ id = tvId
+ )
doSubCompose = deferredSubCompose {
@@ -349,7 +439,8 @@
fun insertShouldSeePreviouslyProvidedValues() {
val invalidates = mutableListOf<() -> Unit>()
fun doInvalidate() = invalidates.forEach { it() }.also { invalidates.clear() }
- val someStaticString = staticAmbientOf<String> { "Default" }
+ val someStaticString =
+ staticAmbientOf { "Default" }
var shouldRead = false
compose {
Providers(
@@ -374,10 +465,12 @@
fun providingANewDataClassValueShouldNotRecompose() {
val invalidates = mutableListOf<() -> Unit>()
fun doInvalidate() = invalidates.forEach { it() }.also { invalidates.clear() }
- val someDataAmbient = ambientOf(StructurallyEqual) { SomeData() }
+ val someDataAmbient =
+ ambientOf(StructurallyEqual) { SomeData() }
var composed = false
- @Composable fun ReadSomeDataAmbient(ambient: Ambient<SomeData>, id: Int = 100) {
+ @Composable
+ fun ReadSomeDataAmbient(ambient: Ambient<SomeData>, id: Int = 100) {
composed = true
Text(value = ambient.current.value, id = id)
}
@@ -410,19 +503,32 @@
}
}
- @Composable fun subCompose(block: @Composable() () -> Unit) {
- val container = remember { escapeCompose { Container() } }
+ @Composable
+ fun subCompose(block: @Composable() () -> Unit) {
+ val container =
+ remember { escapeCompose { LayoutNode() } }
val reference = compositionReference()
- Compose.subcomposeInto(container, activityRule.activity, reference) {
+ // TODO(b/150390669): Review use of @Untracked
+ subcomposeInto(container, activityRule.activity, reference) @Untracked {
block()
}
}
+ class Ref<T : Any> {
+ lateinit var value: T
+ }
+
+ @Composable fun narrowInvalidateForReference(ref: Ref<CompositionReference>) {
+ ref.value = compositionReference()
+ }
+
@Composable fun deferredSubCompose(block: @Composable() () -> Unit): () -> Unit {
- val container = remember { escapeCompose { Container() } }
- val reference = compositionReference()
+ val container = remember { escapeCompose { LayoutNode() } }
+ val ref = Ref<CompositionReference>()
+ narrowInvalidateForReference(ref = ref)
return {
- Compose.subcomposeInto(container, activityRule.activity, reference) {
+ // TODO(b/150390669): Review use of @Untracked
+ subcomposeInto(container, activityRule.activity, ref.value) @Untracked {
block()
}
}
@@ -430,33 +536,3 @@
}
private data class SomeData(val value: String = "default")
-
-@Composable
-fun Text(value: String, id: Int = 100) {
- TextView(id = id, text = value)
-}
-
-@Composable
-fun ReadStringAmbient(ambient: Ambient<String>, id: Int = 100) {
- Text(value = ambient.current, id = id)
-}
-
-class Container : Emittable {
- val children = mutableListOf<Emittable>()
-
- override fun emitInsertAt(index: Int, instance: Emittable) {
- children.add(index, instance)
- }
-
- override fun emitRemoveAt(index: Int, count: Int) {
- children.subList(index, index + count).clear()
- }
-
- override fun emitMove(from: Int, to: Int, count: Int) {
- val toMove = children.subList(from, from + count)
- val nodes = toMove.toMutableList()
- toMove.clear()
- if (from < to) children.addAll(to - count, nodes)
- else children.addAll(to, nodes)
- }
-}
\ No newline at end of file
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/BaseComposeTest.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/BaseComposeTest.kt
similarity index 60%
rename from compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/BaseComposeTest.kt
rename to compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/BaseComposeTest.kt
index e2e316b..694460a 100644
--- a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/BaseComposeTest.kt
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/BaseComposeTest.kt
@@ -14,23 +14,8 @@
* limitations under the License.
*/
-/*
- * Copyright 2019 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:Suppress("PLUGIN_ERROR")
-package androidx.compose
+package androidx.compose.test
import android.os.Bundle
import android.widget.LinearLayout
@@ -38,7 +23,15 @@
import java.util.concurrent.TimeUnit
import kotlin.test.assertTrue
import android.app.Activity
+import android.view.ViewGroup
+import androidx.compose.Choreographer
+import androidx.compose.ChoreographerFrameCallback
+import androidx.compose.Composable
+import androidx.compose.Composition
+import androidx.compose.FrameManager
+import androidx.compose.Looper
import androidx.test.rule.ActivityTestRule
+import androidx.ui.core.setViewContent
class TestActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
@@ -83,17 +76,11 @@
}
}
-internal fun Activity.disposeTestComposition() {
- uiThread {
- Compose.disposeComposition(root)
- }
-}
-
internal fun Activity.show(block: @Composable() () -> Unit): Composition {
var composition: Composition? = null
uiThread {
FrameManager.nextFrame()
- composition = Compose.composeInto(container = root, composable = block)
+ composition = setViewContent(block)
}
return composition!!
}
@@ -104,7 +91,8 @@
}
val latch = CountDownLatch(1)
uiThread {
- Choreographer.postFrameCallback(object : ChoreographerFrameCallback {
+ Choreographer.postFrameCallback(object :
+ ChoreographerFrameCallback {
override fun doFrame(frameTimeNanos: Long) = latch.countDown()
})
}
@@ -119,35 +107,63 @@
fun compose(
composable: @Composable() () -> Unit
- ) = ComposeTester(
+ ) = UiTester(
activity,
composable
)
- class ComposeTester(val activity: Activity, val composable: @Composable() () -> Unit) {
- inner class ActiveTest(val activity: Activity, val composition: Composition) {
- fun then(block: ActiveTest.(activity: Activity) -> Unit): ActiveTest {
- activity.waitForAFrame()
- activity.uiThread {
- block(activity)
- }
- return this
- }
+ fun composeEmittables(
+ composable: @Composable() () -> Unit
+ ) = EmittableTester(
+ activity,
+ composable
+ )
+}
- fun done() {
- activity.waitForAFrame()
- }
- }
-
- fun then(block: ComposeTester.(activity: Activity) -> Unit): ActiveTest {
- val composition = activity.show {
- composable()
- }
+sealed class ComposeTester(val activity: Activity, val composable: @Composable() () -> Unit) {
+ inner class ActiveTest(val activity: Activity, val composition: Composition) {
+ fun then(block: ActiveTest.(activity: Activity) -> Unit): ActiveTest {
activity.waitForAFrame()
activity.uiThread {
block(activity)
}
- return ActiveTest(activity, composition)
+ return this
+ }
+
+ fun done() {
+ activity.waitForAFrame()
}
}
+
+ abstract fun initialComposition(composable: @Composable() () -> Unit): Composition
+
+ fun then(block: ComposeTester.(activity: Activity) -> Unit): ActiveTest {
+ val composition = initialComposition(composable)
+ activity.waitForAFrame()
+ activity.uiThread {
+ block(activity)
+ }
+ return ActiveTest(activity, composition)
+ }
}
+
+class EmittableTester(activity: Activity, composable: @Composable() () -> Unit) :
+ ComposeTester(activity, composable) {
+ override fun initialComposition(composable: @Composable() () -> Unit): Composition {
+ var composition: Composition? = null
+ activity.uiThread {
+ FrameManager.nextFrame()
+ composition = activity.setEmittableContent(composable)
+ }
+ return composition!!
+ }
+}
+
+class UiTester(activity: Activity, composable: @Composable() () -> Unit) :
+ ComposeTester(activity, composable) {
+ override fun initialComposition(composable: @Composable() () -> Unit): Composition {
+ return activity.show {
+ composable()
+ }
+ }
+}
\ No newline at end of file
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposeIntoTests.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/ComposeIntoTests.kt
similarity index 88%
rename from compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposeIntoTests.kt
rename to compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/ComposeIntoTests.kt
index 6a3f0a8..245174c 100644
--- a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposeIntoTests.kt
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/ComposeIntoTests.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * 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.
@@ -14,10 +14,14 @@
* limitations under the License.
*/
-package androidx.compose
+package androidx.compose.test
+import androidx.compose.Composable
+import androidx.compose.onActive
+import androidx.compose.onCommit
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import androidx.ui.core.clearRoots
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Rule
@@ -28,7 +32,7 @@
class ComposeIntoTests : BaseComposeTest() {
@After
fun teardown() {
- Compose.clearRoots()
+ clearRoots()
}
@get:Rule
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposeModelTests.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/ComposeModelTests.kt
similarity index 96%
rename from compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposeModelTests.kt
rename to compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/ComposeModelTests.kt
index 6e95c49..df8a593 100644
--- a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/ComposeModelTests.kt
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/ComposeModelTests.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * 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.
@@ -14,9 +14,11 @@
* limitations under the License.
*/
@file:Suppress("PLUGIN_ERROR")
-package androidx.compose
+package androidx.compose.test
import android.widget.TextView
+import androidx.compose.Composable
+import androidx.compose.Observe
import androidx.compose.frames.AbstractRecord
import androidx.compose.frames.Framed
import androidx.compose.frames.Record
@@ -29,6 +31,8 @@
import androidx.compose.frames.open
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import androidx.ui.node.UiComposer
+import androidx.ui.core.clearRoots
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertFalse
import org.junit.After
@@ -122,9 +126,12 @@
@MediumTest
@RunWith(AndroidJUnit4::class)
class ModelViewTests : BaseComposeTest() {
+
+ val composer: UiComposer get() = error("should not be called")
+
@After
fun teardown() {
- Compose.clearRoots()
+ clearRoots()
}
@get:Rule
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/ComposerCompat.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/ComposerCompat.kt
new file mode 100644
index 0000000..d34d799
--- /dev/null
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/ComposerCompat.kt
@@ -0,0 +1,30 @@
+/*
+ * 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.compose.test
+
+// NOTE(lmr): This API is no longer needed in any way by the compiler, but we still need this API
+// to be here to support versions of Android Studio that are still looking for it. Without it,
+// valid composable code will look broken in the IDE. Remove this after we have left some time to
+// get all versions of Studio upgraded.
+@Deprecated(
+ "This property should not be called directly. It is only used by the compiler.",
+ replaceWith = ReplaceWith("currentComposer")
+)
+val composer: EmittableComposer
+ get() = error(
+ "This property should not be called directly. It is only used by the compiler."
+ )
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/DisposeTests.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/DisposeTests.kt
similarity index 84%
rename from compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/DisposeTests.kt
rename to compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/DisposeTests.kt
index 9acd4bb..8e14979 100644
--- a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/DisposeTests.kt
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/DisposeTests.kt
@@ -14,10 +14,15 @@
* limitations under the License.
*/
-package androidx.compose
+package androidx.compose.test
+import androidx.compose.Composable
+import androidx.compose.Composition
+import androidx.compose.onActive
+import androidx.compose.onPreCommit
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import androidx.ui.core.clearRoots
import junit.framework.TestCase
import org.junit.After
import org.junit.Rule
@@ -29,7 +34,7 @@
class DisposeTests : BaseComposeTest() {
@After
fun teardown() {
- Compose.clearRoots()
+ clearRoots()
}
@get:Rule
@@ -60,8 +65,10 @@
TestCase.assertEquals(expected, log.joinToString())
}
+ var composition: Composition? = null
+
assertLog("onPreCommit, onActive") {
- activity.show(composable)
+ composition = activity.show(composable)
activity.waitForAFrame()
}
@@ -71,7 +78,9 @@
}
assertLog("onActiveDispose, onPreCommitDispose") {
- activity.disposeTestComposition()
+ activity.uiThread {
+ composition?.dispose()
+ }
activity.waitForAFrame()
}
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/EffectsTests.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/EffectsTests.kt
similarity index 96%
rename from compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/EffectsTests.kt
rename to compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/EffectsTests.kt
index 7eec133..8204c0e 100644
--- a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/EffectsTests.kt
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/EffectsTests.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * 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.
@@ -14,12 +14,25 @@
* limitations under the License.
*/
@file:Suppress("PLUGIN_ERROR")
-package androidx.compose
+package androidx.compose.test
import android.widget.Button
import android.widget.TextView
+import androidx.compose.Composable
+import androidx.compose.Providers
+import androidx.compose.Recompose
+import androidx.compose.ambientOf
+import androidx.compose.invalidate
+import androidx.compose.mutableStateOf
+import androidx.compose.onCommit
+import androidx.compose.onDispose
+import androidx.compose.onPreCommit
+import androidx.compose.remember
+import androidx.compose.state
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import androidx.ui.node.UiComposer
+import androidx.ui.core.clearRoots
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertTrue
import org.junit.After
@@ -30,9 +43,12 @@
@MediumTest
@RunWith(AndroidJUnit4::class)
class EffectsTests : BaseComposeTest() {
+
+ val composer: UiComposer get() = error("should not be called")
+
@After
fun teardown() {
- Compose.clearRoots()
+ clearRoots()
}
@get:Rule
@@ -474,7 +490,8 @@
val logHistory = mutableListOf<String>()
fun log(x: String) = logHistory.add(x)
- @Composable fun DisposeLogger(msg: String) {
+ @Composable
+ fun DisposeLogger(msg: String) {
onDispose { log(msg) }
}
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/EmittableComposer.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/EmittableComposer.kt
new file mode 100644
index 0000000..f17d071
--- /dev/null
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/EmittableComposer.kt
@@ -0,0 +1,208 @@
+/*
+ * 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.compose.test
+
+import android.app.Activity
+import android.content.Context
+import android.view.View
+import android.view.ViewGroup
+import androidx.compose.Applier
+import androidx.compose.ApplyAdapter
+import androidx.compose.Composable
+import androidx.compose.Composer
+import androidx.compose.ComposerUpdater
+import androidx.compose.Composition
+import androidx.compose.FrameManager
+import androidx.compose.Recomposer
+import androidx.compose.SlotTable
+import androidx.ui.node.UiComposer
+
+interface Emittable {
+ fun emitInsertAt(index: Int, instance: Emittable)
+ fun emitRemoveAt(index: Int, count: Int)
+ fun emitMove(from: Int, to: Int, count: Int)
+}
+
+internal class EmittableApplyAdapter : ApplyAdapter<Any> {
+ override fun Any.start(instance: Any) {}
+ override fun Any.insertAt(index: Int, instance: Any) {
+ when (this) {
+ is ViewGroup -> insertAt(index, instance)
+ is Emittable -> emitInsertAt(index, instance as Emittable)
+ else -> error("unexpected node")
+ }
+ }
+
+ override fun Any.removeAt(index: Int, count: Int) {
+ when (this) {
+ is ViewGroup -> removeViews(index, count)
+ is Emittable -> emitRemoveAt(index, count)
+ else -> error("unexpected node")
+ }
+ }
+
+ override fun Any.move(from: Int, to: Int, count: Int) {
+ when (this) {
+ is ViewGroup -> {
+ if (from > to) {
+ var currentFrom = from
+ var currentTo = to
+ repeat(count) {
+ val view = getChildAt(currentFrom)
+ removeViewAt(currentFrom)
+ addView(view, currentTo)
+ currentFrom++
+ currentTo++
+ }
+ } else {
+ repeat(count) {
+ val view = getChildAt(from)
+ removeViewAt(from)
+ addView(view, to - 1)
+ }
+ }
+ }
+ is Emittable -> {
+ emitMove(from, to, count)
+ }
+ else -> error("unexpected node")
+ }
+ }
+
+ override fun Any.end(instance: Any, parent: Any) {}
+}
+
+class EmittableComposer(
+ val context: Context,
+ val root: Any,
+ slotTable: SlotTable,
+ recomposer: Recomposer
+) : Composer<Any>(
+ slotTable,
+ Applier(
+ root,
+ EmittableApplyAdapter()
+ ),
+ recomposer
+) {
+ init {
+ FrameManager.ensureStarted()
+ }
+
+ @Suppress("UNCHECKED_CAST")
+ fun <T : View> emit(
+ key: Any,
+ /*crossinline*/
+ ctor: (context: Context) -> T,
+ update: ViewUpdater<T>.() -> Unit
+ ) {
+ startNode(key)
+ val node = if (inserting) ctor(context).also { emitNode(it) }
+ else useNode() as T
+ ViewUpdater(this, node).update()
+ endNode()
+ }
+
+ @Suppress("UNCHECKED_CAST")
+ fun <T : ViewGroup> emit(
+ key: Any,
+ /*crossinline*/
+ ctor: (context: Context) -> T,
+ update: ViewUpdater<T>.() -> Unit,
+ children: () -> Unit
+ ) {
+ startNode(key)
+ val node = if (inserting) ctor(context).also { emitNode(it) }
+ else useNode() as T
+ ViewUpdater(this, node).update()
+ children()
+ endNode()
+ }
+
+ @Suppress("UNCHECKED_CAST")
+ fun <T : Emittable> emit(
+ key: Any,
+ /*crossinline*/
+ ctor: () -> T,
+ update: ViewUpdater<T>.() -> Unit
+ ) {
+ startNode(key)
+ val node = if (inserting) ctor().also { emitNode(it) }
+ else useNode() as T
+ ViewUpdater(this, node).update()
+ endNode()
+ }
+
+ @Suppress("UNCHECKED_CAST")
+ fun <T : Emittable> emit(
+ key: Any,
+ /*crossinline*/
+ ctor: () -> T,
+ update: ViewUpdater<T>.() -> Unit,
+ children: () -> Unit
+ ) {
+ startNode(key)
+ val node = if (inserting) ctor().also { emitNode(it) }
+ else useNode() as T
+ ViewUpdater(this, node).update()
+ children()
+ endNode()
+ }
+}
+
+typealias ViewUpdater<T> = ComposerUpdater<Any, T>
+
+class ComponentNodeScope { val composer: UiComposer get() = error("should not get called") }
+class EmittableScope { val composer: EmittableComposer get() = error("should not get called") }
+
+class Node(val name: String, var value: String = "") : Emittable {
+ val children = mutableListOf<Node>()
+
+ override fun emitInsertAt(index: Int, instance: Emittable) {
+ children.add(index, instance as Node)
+ }
+
+ override fun emitRemoveAt(index: Int, count: Int) {
+ repeat(count) { children.removeAt(index) }
+ }
+
+ override fun emitMove(from: Int, to: Int, count: Int) {
+ if (from > to) {
+ repeat(count) {
+ children.add(to + it, children.removeAt(from))
+ }
+ } else if (from < to) {
+ repeat(count) {
+ children.add(to - 1, children.removeAt(from))
+ }
+ }
+ }
+}
+
+fun Activity.setEmittableContent(content: @Composable() () -> Unit): Composition {
+ val root = Node("Root")
+ val composition = Composition({ slotTable, recomposer ->
+ EmittableComposer(
+ this,
+ root,
+ slotTable,
+ recomposer
+ )
+ })
+ composition.compose(content)
+ return composition
+}
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/NewCodeGenTests.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/NewCodeGenTests.kt
similarity index 94%
rename from compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/NewCodeGenTests.kt
rename to compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/NewCodeGenTests.kt
index ca601d8..de6c096 100644
--- a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/NewCodeGenTests.kt
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/NewCodeGenTests.kt
@@ -13,14 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+@file:Suppress("UNUSED_PARAMETER", "UNUSED_VARIABLE", "ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE")
-package androidx.compose
+package androidx.compose.test
import android.content.Context
import android.widget.LinearLayout
import android.widget.TextView
+import androidx.compose.Composable
+import androidx.compose.key
+import androidx.compose.mutableStateOf
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import androidx.ui.node.UiComposer
+import androidx.ui.core.clearRoots
import junit.framework.TestCase
import org.junit.After
import org.junit.Rule
@@ -30,9 +36,12 @@
@MediumTest
@RunWith(AndroidJUnit4::class)
class NewCodeGenTests : BaseComposeTest() {
+
+ val composer: UiComposer get() = error("should not be called")
+
@After
fun teardown() {
- Compose.clearRoots()
+ clearRoots()
}
@get:Rule
@@ -154,7 +163,8 @@
// phoneCalled++
// TextView(text = "...")
// }
- @Composable fun PhoneView(phone: Phone) {
+ @Composable
+ fun PhoneView(phone: Phone) {
phoneCalled++
TextView(
text = "${if (phone.area.isBlank()) ""
@@ -189,7 +199,8 @@
// addCalled++
// <TextView text = "$left + $right = ${left + right}" />
// }
- @Composable fun AddView(left: Int, right: Int) {
+ @Composable
+ fun AddView(left: Int, right: Int) {
addCalled++
TextView(id = tvId, text = "$left + $right = ${left + right}")
}
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/RecomposerTests.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/RecomposerTests.kt
similarity index 89%
rename from compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/RecomposerTests.kt
rename to compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/RecomposerTests.kt
index e4bad1b..7119d02 100644
--- a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/RecomposerTests.kt
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/RecomposerTests.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * 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.
@@ -14,15 +14,20 @@
* limitations under the License.
*/
-package androidx.compose
+package androidx.compose.test
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
+import androidx.compose.Composable
import androidx.compose.frames.currentFrame
+import androidx.compose.invalidate
+import androidx.compose.key
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import androidx.ui.node.UiComposer
+import androidx.ui.core.clearRoots
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertFalse
import junit.framework.TestCase.assertNotSame
@@ -35,9 +40,11 @@
@MediumTest
@RunWith(AndroidJUnit4::class)
class RecomposerTests : BaseComposeTest() {
+ val composer: UiComposer get() = error("should not be called")
+
@After
fun teardown() {
- Compose.clearRoots()
+ clearRoots()
}
@get:Rule
@@ -146,9 +153,9 @@
val counter = Counter()
compose {
- RecomposeTestComponents.A(
+ RecomposeTestComponentsA(
counter,
- RecomposeTestComponents.ClickAction.Recompose
+ ClickAction.Recompose
)
}.then { activity ->
// everything got rendered once
@@ -191,13 +198,13 @@
val trigger = Trigger()
val listener =
- RecomposeTestComponents.ClickAction.PerformOnView {
+ ClickAction.PerformOnView {
trigger.recompose()
}
compose {
trigger.subscribe()
- RecomposeTestComponents.A(
+ RecomposeTestComponentsA(
counter,
listener
)
@@ -236,29 +243,28 @@
}
// components for testing recompose behavior above
- private object RecomposeTestComponents {
- sealed class ClickAction {
- object Recompose : ClickAction()
- class PerformOnView(val action: (View) -> Unit) : ClickAction()
- }
+ sealed class ClickAction {
+ object Recompose : ClickAction()
+ class PerformOnView(val action: (View) -> Unit) : ClickAction()
+ }
- @Composable fun B(counter: Counter, listener: ClickAction, id: Int = 0) {
- counter.inc("$id")
+ @Composable fun RecomposeTestComponentsB(counter: Counter, listener: ClickAction, id: Int = 0) {
+ counter.inc("$id")
- val recompose = invalidate
+ val recompose = invalidate
- TextView(id = id, onClickListener = View.OnClickListener {
- @Suppress("DEPRECATION")
- when (listener) {
- is ClickAction.Recompose -> recompose()
- is ClickAction.PerformOnView -> listener.action.invoke(it)
- }
- })
- }
+ TextView(id = id, onClickListener = View.OnClickListener {
+ @Suppress("DEPRECATION")
+ when (listener) {
+ is ClickAction.Recompose -> recompose()
+ is ClickAction.PerformOnView -> listener.action.invoke(it)
+ }
+ })
+ }
- @Composable fun A(counter: Counter, listener: ClickAction) {
- counter.inc("A")
- val recompose = invalidate
+ @Composable fun RecomposeTestComponentsA(counter: Counter, listener: ClickAction) {
+ counter.inc("A")
+ val recompose = invalidate
LinearLayout(id = 99, onClickListener = View.OnClickListener {
@Suppress("DEPRECATION")
when (listener) {
@@ -268,11 +274,14 @@
}) {
for (id in 100..102) {
key(id) {
- B(counter, listener, id)
+ RecomposeTestComponentsB(
+ counter,
+ listener,
+ id
+ )
}
}
}
- }
}
@Test
diff --git a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/RestartTests.kt b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/RestartTests.kt
similarity index 95%
rename from compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/RestartTests.kt
rename to compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/RestartTests.kt
index ab89396..7b21d1d 100644
--- a/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/RestartTests.kt
+++ b/compose/compose-runtime/src/androidAndroidTest/kotlin/androidx/compose/test/RestartTests.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * 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.
@@ -14,11 +14,15 @@
* limitations under the License.
*/
@file:Suppress("PLUGIN_ERROR")
-package androidx.compose
+package androidx.compose.test
import android.widget.TextView
+import androidx.compose.Composable
+import androidx.compose.mutableStateOf
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
+import androidx.ui.node.UiComposer
+import androidx.ui.core.clearRoots
import junit.framework.TestCase
import org.junit.After
import org.junit.Rule
@@ -30,9 +34,12 @@
@MediumTest
@RunWith(AndroidJUnit4::class)
class RestartTests : BaseComposeTest() {
+
+ val composer: UiComposer get() = error("should not be called")
+
@After
fun teardown() {
- Compose.clearRoots()
+ clearRoots()
}
@get:Rule
diff --git a/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ActualAndroid.kt b/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ActualAndroid.kt
index f8553b9..68e842a 100644
--- a/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ActualAndroid.kt
+++ b/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ActualAndroid.kt
@@ -16,29 +16,6 @@
package androidx.compose
-// TODO(b/137794549): Remove View System-related expect/actuals
-internal actual typealias ViewParent = android.view.ViewParent
-
-// TODO(b/137794549): Remove View System-related expect/actuals
-internal actual typealias View = android.view.View
-
-// TODO(b/137794549): Remove View System-related expect/actuals
-internal actual val View.parent: ViewParent
- get() = parent
-
-// TODO(b/137794549): Remove View System-related expect/actuals
-internal actual val View.context: Context
- get() = context
-
-// TODO(b/137794549): Remove View System-related expect/actuals
-internal actual typealias ViewGroup = android.view.ViewGroup
-
-// TODO(b/137794549): Remove View System-related expect/actuals
-internal actual typealias Context = android.content.Context
-
-// TODO(b/137794549): Remove View System-related expect/actuals
-internal actual typealias FrameLayout = android.widget.FrameLayout
-
// TODO(b/137794558): Create portable abstraction for scheduling
internal actual typealias Looper = android.os.Looper
diff --git a/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ComposeAndroid.kt b/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ComposeAndroid.kt
deleted file mode 100644
index 1516d27..0000000
--- a/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ComposeAndroid.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2019 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
-
-import android.app.Activity
-
-/**
- * Sets the contentView of an activity to a FrameLayout, and composes the contents of the layout
- * with the passed in [composable]. This is a convenience method around [Compose.composeInto].
- *
- * @see Compose.composeInto
- * @see Activity.setContentView
- */
-fun Activity.setViewContent(composable: @Composable() () -> Unit): Composition? {
- // If there is already a FrameLayout in the root, we assume we want to compose
- // into it instead of create a new one. This allows for `setContent` to be
- // called multiple times.
- val root = window
- .decorView
- .findViewById<ViewGroup>(android.R.id.content)
- .getChildAt(0) as? ViewGroup
- ?: FrameLayout(this).also { setContentView(it) }
- return root.setViewContent(composable)
-}
-
-/**
- * Disposes of a composition that was started using [setContent]. This is a convenience method
- * around [Compose.disposeComposition].
- *
- * @see setContent
- * @see Compose.disposeComposition
- */
-fun Activity.disposeComposition() {
- val view = window
- .decorView
- .findViewById<ViewGroup>(android.R.id.content)
- .getChildAt(0) as? ViewGroup
- ?: error("No root view found")
- Compose.disposeComposition(view, null)
-}
\ No newline at end of file
diff --git a/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ViewComposer.kt b/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ViewComposer.kt
deleted file mode 100644
index 6ede3fa..0000000
--- a/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/ViewComposer.kt
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright 2019 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
-
-import android.content.Context
-import android.view.View
-import android.view.ViewGroup
-import androidx.compose.adapters.getViewAdapterIfExists
-
-class ViewAdapters {
- private val adapters = mutableListOf<(parent: Any, child: Any) -> Any?>()
-
- fun register(adapter: (parent: Any, child: Any) -> Any?) = adapters.add(adapter)
- fun adapt(parent: Any, child: Any): Any? =
- adapters.map { it(parent, child) }.filterNotNull().firstOrNull()
-}
-
-private fun invalidNode(node: Any): Nothing =
- error("Unsupported node type ${node.javaClass.simpleName}")
-
-internal class ViewApplyAdapter(private val adapters: ViewAdapters? = null) :
- ApplyAdapter<Any> {
- private data class PendingInsert(val index: Int, val instance: Any)
-
- private val pendingInserts = Stack<PendingInsert>()
-
- override fun Any.start(instance: Any) {}
- override fun Any.insertAt(index: Int, instance: Any) {
- pendingInserts.push(PendingInsert(index, instance))
- }
-
- override fun Any.removeAt(index: Int, count: Int) {
- when (this) {
- is ViewGroup -> removeViews(index, count)
- is Emittable -> emitRemoveAt(index, count)
- else -> invalidNode(this)
- }
- }
-
- override fun Any.move(from: Int, to: Int, count: Int) {
- when (this) {
- is ViewGroup -> {
- if (from > to) {
- var currentFrom = from
- var currentTo = to
- repeat(count) {
- val view = getChildAt(currentFrom)
- removeViewAt(currentFrom)
- addView(view, currentTo)
- currentFrom++
- currentTo++
- }
- } else {
- repeat(count) {
- val view = getChildAt(from)
- removeViewAt(from)
- addView(view, to - 1)
- }
- }
- }
- is Emittable -> {
- emitMove(from, to, count)
- }
- else -> invalidNode(this)
- }
- }
-
- override fun Any.end(instance: Any, parent: Any) {
- val adapter = when (instance) {
- is View -> instance.getViewAdapterIfExists()
- else -> null
- }
- if (pendingInserts.isNotEmpty()) {
- val pendingInsert = pendingInserts.peek()
- if (pendingInsert.instance == instance) {
- val index = pendingInsert.index
- pendingInserts.pop()
-
- when (parent) {
- is ViewGroup ->
- when (instance) {
- is View -> {
- adapter?.willInsert(instance, parent)
- parent.addView(instance, index)
- adapter?.didInsert(instance, parent)
- }
- is Emittable -> {
- val adaptedView = adapters?.adapt(parent, instance) as? View
- ?: error(
- "Could not convert ${
- instance.javaClass.simpleName
- } to a View"
- )
- adapter?.willInsert(adaptedView, parent)
- parent.addView(adaptedView, index)
- adapter?.didInsert(adaptedView, parent)
- }
- else -> invalidNode(instance)
- }
- is Emittable ->
- when (instance) {
- is View -> parent.emitInsertAt(
- index,
- adapters?.adapt(parent, instance) as? Emittable
- ?: error(
- "Could not convert ${
- instance.javaClass.name
- } to an Emittable"
- )
- )
- is Emittable -> parent.emitInsertAt(index, instance)
- else -> invalidNode(instance)
- }
- else -> invalidNode(parent)
- }
- return
- }
- }
- if (parent is ViewGroup)
- adapter?.didUpdate(instance as View, parent)
- }
-}
-
-internal actual fun UiComposer(
- context: Context,
- root: Any,
- slots: SlotTable,
- recomposer: Recomposer
-): Composer<*> = ViewComposer(context, root, slots, recomposer)
-
-class ViewComposer(
- val context: Context,
- val root: Any,
- slotTable: SlotTable,
- recomposer: Recomposer,
- val adapters: ViewAdapters? = ViewAdapters()
-) : Composer<Any>(
- slotTable,
- Applier(root, ViewApplyAdapter(adapters)),
- recomposer
-) {
- init {
- FrameManager.ensureStarted()
- }
-
- @Suppress("UNCHECKED_CAST")
- inline fun <T : View> emit(
- key: Any,
- /*crossinline*/
- ctor: (context: Context) -> T,
- update: ViewUpdater<T>.() -> Unit
- ) {
- startNode(key)
- val node = if (inserting) ctor(context).also { emitNode(it) }
- else useNode() as T
- ViewUpdater<T>(this, node).update()
- endNode()
- }
-
- @Suppress("UNCHECKED_CAST")
- inline fun <T : ViewGroup> emit(
- key: Any,
- /*crossinline*/
- ctor: (context: Context) -> T,
- update: ViewUpdater<T>.() -> Unit,
- children: () -> Unit
- ) {
- startNode(key)
- val node = if (inserting) ctor(context).also { emitNode(it) }
- else useNode() as T
- ViewUpdater<T>(this, node).update()
- children()
- endNode()
- }
-
- @Suppress("UNCHECKED_CAST")
- inline fun <T : Emittable> emit(
- key: Any,
- /*crossinline*/
- ctor: () -> T,
- update: ViewUpdater<T>.() -> Unit
- ) {
- startNode(key)
- val node = if (inserting) ctor().also { emitNode(it) }
- else useNode() as T
- ViewUpdater<T>(this, node).update()
- endNode()
- }
-
- @Suppress("UNCHECKED_CAST")
- inline fun <T : Emittable> emit(
- key: Any,
- /*crossinline*/
- ctor: () -> T,
- update: ViewUpdater<T>.() -> Unit,
- children: () -> Unit
- ) {
- startNode(key)
- val node = if (inserting) ctor().also { emitNode(it) }
- else useNode() as T
- ViewUpdater<T>(this, node).update()
- children()
- endNode()
- }
-}
-
-@Suppress("UNCHECKED_CAST")
-/*inline */ class ComposerUpdater<N, T : N>(val composer: Composer<N>, val node: T) {
- inline fun set(
- value: Int,
- /*crossinline*/
- block: T.(value: Int) -> Unit
- ) = with(composer) {
- if (inserting || nextSlot() != value) {
- updateValue(value)
- node.block(value)
-// val appliedBlock: T.(value: Int) -> Unit = { block(it) }
-// composer.apply(value, appliedBlock)
- } else skipValue()
- }
-
- inline fun <reified V> set(
- value: V,
- /*crossinline*/
- block: T.(value: V) -> Unit
- ) = with(composer) {
- if (inserting || nextSlot() != value) {
- updateValue(value)
- node.block(value)
-// val appliedBlock: T.(value: V) -> Unit = { block(it) }
-// composer.apply(value, appliedBlock)
- } else skipValue()
- }
-
- inline fun update(
- value: Int,
- /*crossinline*/
- block: T.(value: Int) -> Unit
- ) = with(composer) {
- if (inserting || nextSlot() != value) {
- updateValue(value)
- node.block(value)
-// val appliedBlock: T.(value: Int) -> Unit = { block(it) }
-// if (!inserting) composer.apply(value, appliedBlock)
- } else skipValue()
- }
-
- inline fun <reified V> update(
- value: V,
- /*crossinline*/
- block: T.(value: V) -> Unit
- ) = with(composer) {
- if (inserting || nextSlot() != value) {
- updateValue(value)
- node.block(value)
-// val appliedBlock: T.(value: V) -> Unit = { block(it) }
-// if (!inserting) composer.apply(value, appliedBlock)
- } else skipValue()
- }
-}
-
-// NOTE(lmr): This API is no longer needed in any way by the compiler, but we still need this API
-// to be here to support versions of Android Studio that are still looking for it. Without it,
-// valid composable code will look broken in the IDE. Remove this after we have left some time to
-// get all versions of Studio upgraded.
-@Deprecated(
- "This property should not be called directly. It is only used by the compiler.",
- replaceWith = ReplaceWith("currentComposer")
-)
-val composer: ViewComposer get() = error(
- "This property should not be called directly. It is only used by the compiler."
-)
-
-actual fun <T> Composer<*>.runWithComposing(block: () -> T): T {
- val wasComposing = isComposing
- try {
- isComposing = true
- return block()
- } finally {
- isComposing = wasComposing
- }
-}
-
-fun ViewComposer.registerAdapter(
- adapter: (parent: Any, child: Any) -> Any?
-) = adapters?.register(adapter)
-
-typealias ViewUpdater<T> = ComposerUpdater<Any, T>
\ No newline at end of file
diff --git a/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/adapters/ViewAdapter.kt b/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/adapters/ViewAdapter.kt
deleted file mode 100644
index 334558d..0000000
--- a/compose/compose-runtime/src/androidMain/kotlin/androidx/compose/adapters/ViewAdapter.kt
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2019 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.adapters
-
-import android.view.View
-import android.view.ViewGroup
-
-interface ViewAdapter {
- val id: Int
- fun willInsert(view: View, parent: ViewGroup)
- fun didInsert(view: View, parent: ViewGroup)
- fun didUpdate(view: View, parent: ViewGroup)
-}
-
-class ComposeViewAdapter : ViewAdapter {
- override val id = 0
- val adapters = mutableListOf<ViewAdapter>()
-
- inline fun <T : ViewAdapter> get(id: Int, factory: () -> T): T {
- @Suppress("UNCHECKED_CAST")
- val existing = adapters.firstOrNull { it.id == id } as? T
- if (existing != null) return existing
- val next = factory()
- adapters.add(next)
- return next
- }
-
- override fun willInsert(view: View, parent: ViewGroup) {
- for (adapter in adapters) adapter.willInsert(view, parent)
- }
-
- override fun didInsert(view: View, parent: ViewGroup) {
- for (adapter in adapters) adapter.didInsert(view, parent)
- }
-
- override fun didUpdate(view: View, parent: ViewGroup) {
- for (adapter in adapters) adapter.didUpdate(view, parent)
- }
-}
-
-/**
- * This function will take in a string and pass back a valid resource identifier for
- * View.setTag(...). We should eventually move this to a resource id that's actually generated via
- * AAPT but doing that in this project is proving to be complicated, so for now I'm just doing this
- * as a stop-gap.
- */
-internal fun tagKey(key: String): Int {
- return (3 shl 24) or key.hashCode()
-}
-
-private val viewAdaptersKey = tagKey("ViewAdapter")
-
-internal fun View.getViewAdapterIfExists(): ComposeViewAdapter? {
- return getTag(viewAdaptersKey) as? ComposeViewAdapter
-}
-
-fun View.getViewAdapter(): ComposeViewAdapter {
- var adapter = getTag(viewAdaptersKey) as? ComposeViewAdapter
- if (adapter == null) {
- adapter = ComposeViewAdapter()
- setTag(viewAdaptersKey, adapter)
- }
- return adapter
-}
-
-inline fun <T : ViewAdapter> View.getOrAddAdapter(id: Int, factory: () -> T): T {
- return getViewAdapter().get(id, factory)
-}
\ No newline at end of file
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Compose.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Compose.kt
index ec55cd4..0cab57a 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Compose.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Compose.kt
@@ -16,289 +16,6 @@
package androidx.compose
-/**
- * A global namespace to hold some Compose utility methods, such as [Compose.composeInto] and
- * [Compose.disposeComposition].
- */
-object Compose {
- /**
- * Apply Code Changes will invoke the two functions before and after a code swap.
- *
- * This forces the whole view hierarchy to be redrawn to invoke any code change that was
- * introduce in the code swap.
- *
- * All these are private as within JVMTI / JNI accessibility is mostly a formality.
- */
- // NOTE(lmr): right now, this class only takes into account Emittables and Views composed using
- // compose. In reality, there might be more (ie, Vectors), and we should figure out a more
- // holistic way to capture those as well.
- private class HotReloader {
- companion object {
- private var compositions = mutableListOf<Pair<Composition, @Composable() () -> Unit>>()
-
- @TestOnly
- fun clearRoots() {
- EMITTABLE_ROOT_COMPONENT.clear()
- VIEWGROUP_ROOT_COMPONENT.clear()
- }
-
- // Called before Dex Code Swap
- @Suppress("UNUSED_PARAMETER")
- private fun saveStateAndDispose(context: Context) {
- compositions.clear()
-
- val emittableRoots = EMITTABLE_ROOT_COMPONENT.entries.toSet()
-
- for ((_, composition) in emittableRoots) {
- if (composition.isRootComposition) {
- compositions.add(composition to composition.composable)
- composition.dispose()
- }
- }
-
- val viewRoots = VIEWGROUP_ROOT_COMPONENT.entries.toSet()
-
- for ((_, composition) in viewRoots) {
- if (composition.isRootComposition) {
- compositions.add(composition to composition.composable)
- composition.dispose()
- }
- }
- }
-
- // Called after Dex Code Swap
- @Suppress("UNUSED_PARAMETER")
- private fun loadStateAndCompose(context: Context) {
- for ((composition, composable) in compositions) {
- composition.compose(composable)
- }
-
- compositions.clear()
- }
-
- @TestOnly
- internal fun simulateHotReload(context: Context) {
- saveStateAndDispose(context)
- loadStateAndCompose(context)
- }
- }
- }
-
- private val TAG_COMPOSITION_CONTEXT = "androidx.compose.CompositionContext".hashCode()
- private val EMITTABLE_ROOT_COMPONENT = WeakHashMap<Emittable, Composition>()
- private val VIEWGROUP_ROOT_COMPONENT = WeakHashMap<ViewGroup, Composition>()
-
- private fun findComposition(view: View): Composition? {
- return view.getTag(TAG_COMPOSITION_CONTEXT) as? Composition
- }
-
- internal fun storeComposition(view: View, composition: Composition) {
- view.setTag(TAG_COMPOSITION_CONTEXT, composition)
- if (view is ViewGroup)
- VIEWGROUP_ROOT_COMPONENT[view] = composition
- }
-
- internal fun removeRoot(view: View) {
- view.setTag(TAG_COMPOSITION_CONTEXT, null)
- if (view is ViewGroup)
- VIEWGROUP_ROOT_COMPONENT.remove(view)
- }
-
- private fun findComposition(emittable: Emittable): Composition? {
- return EMITTABLE_ROOT_COMPONENT[emittable]
- }
-
- // TODO(b/138254844): Make findRoot/setRoot test-only & Android-only
- private fun storeComposition(emittable: Emittable, context: Composition) {
- EMITTABLE_ROOT_COMPONENT[emittable] = context
- }
-
- /**
- * @suppress
- */
- @TestOnly
- fun simulateHotReload(context: Context) = HotReloader.simulateHotReload(context)
-
- /**
- * @suppress
- */
- @TestOnly
- fun clearRoots() = HotReloader.clearRoots()
-
- /**
- * This method is the way to initiate a composition. The [composable] passed in will be executed
- * to compose the children of the passed in [container]. Optionally, a [parent]
- * [CompositionReference] can be provided to make the composition behave as a sub-composition of
- * the parent. The children of [container] will be updated and maintained by the time this
- * method returns.
- *
- * It is important to call [disposeComposition] whenever this view is no longer needed in order
- * to release resources.
- *
- * @param container The view whose children is being composed.
- * @param parent The parent composition reference, if applicable. Default is null.
- * @param composable The composable function intended to compose the children of [container].
- *
- * @see Compose.disposeComposition
- * @see Composable
- */
- // TODO(lmr): rename to compose?
- @MainThread
- fun composeInto(
- container: ViewGroup,
- parent: CompositionReference? = null,
- composable: @Composable() () -> Unit
- ): Composition {
- val composition = findComposition(container)
- ?: UiComposition(container, container.context, parent).also {
- container.removeAllViews()
- }
- composition.compose(composable)
- return composition
- }
-
- /**
- * Disposes any composition previously run with [container] as the root. This will
- * release any resources that have been built around the composition, including all [onDispose]
- * callbacks that have been registered with [CompositionLifecycleObserver] objects.
- *
- * It is important to call this for any [Compose.composeInto] call that is made, or else you may have
- * memory leaks in your application.
- *
- * @param container The view that was passed into [Compose.composeInto] as the root container of the composition
- * @param parent The parent composition reference, if applicable.
- *
- * @see Compose.composeInto
- * @see CompositionLifecycleObserver
- */
- @MainThread
- fun disposeComposition(container: ViewGroup, parent: CompositionReference? = null) {
- // temporary easy way to call correct lifecycles on everything
- // need to remove compositionContext from context map as well
- composeInto(container, parent, emptyContent())
- removeRoot(container)
- }
-
- /**
- * This method is the way to initiate a composition. The [composable] passed in will be executed
- * to compose the children of the passed in [container]. Optionally, a [parent]
- * [CompositionReference] can be provided to make the composition behave as a sub-composition of
- * the parent. The children of [container] will be updated and maintained by the time this
- * method returns.
- *
- * It is important to call [Compose.disposeComposition] whenever this view is no longer needed in order
- * to release resources.
- *
- * @param container The emittable whose children is being composed.
- * @param context The android [Context] to associate with this composition.
- * @param parent The parent composition reference, if applicable. Default is null.
- * @param composable The composable function intended to compose the children of [container].
- *
- * @see Compose.disposeComposition
- * @see Composable
- */
- // TODO(lmr): rename to compose?
- @MainThread
- fun composeInto(
- container: Emittable,
- context: Context,
- parent: CompositionReference? = null,
- composable: @Composable() () -> Unit
- ): Composition {
- val composition = findComposition(container)
- ?: UiComposition(container, context, parent)
- composition.compose(composable)
- return composition
- }
-
- private class UiComposition(
- private val root: Any,
- private val context: Context,
- parent: CompositionReference? = null
- ) : Composition(
- { slots, recomposer -> UiComposer(context, root, slots, recomposer) },
- parent
- ) {
- init {
- when (root) {
- is ViewGroup -> storeComposition(root, this)
- is Emittable -> storeComposition(root, this)
- }
- }
-
- override fun dispose() {
- super.dispose()
- when (root) {
- is ViewGroup -> disposeComposition(root)
- is Emittable -> disposeComposition(root, context)
- }
- }
- }
-
- // TODO(chuckj): This is a temporary work-around until subframes exist so that
- // nextFrame() inside recompose() doesn't really start a new frame, but a new subframe
- // instead.
- @MainThread
- fun subcomposeInto(
- container: Emittable,
- context: Context,
- parent: CompositionReference? = null,
- composable: @Composable() () -> Unit
- ): Composition {
- val composition = findComposition(container)
- ?: UiComposition(container, context, parent).also { storeComposition(container, it) }
- composition.composer.runWithComposing {
- composition.compose(composable)
- }
- return composition
- }
-
- /**
- * Disposes any composition previously run with [container] as the root. This will
- * release any resources that have been built around the composition, including all [onDispose]
- * callbacks that have been registered with [CompositionLifecycleObserver] objects.
- *
- * It is important to call this for any [Compose.composeInto] call that is made, or else you may have
- * memory leaks in your application.
- *
- * @param container The view that was passed into [Compose.composeInto] as the root container of the composition
- * @param context The android [Context] associated with the composition
- * @param parent The parent composition reference, if applicable.
- *
- * @see Compose.composeInto
- * @see CompositionLifecycleObserver
- */
- @MainThread
- fun disposeComposition(
- container: Emittable,
- context: Context,
- parent: CompositionReference? = null
- ) {
- // temporary easy way to call correct lifecycles on everything
- composeInto(container, context, parent, emptyContent())
- EMITTABLE_ROOT_COMPONENT.remove(container)
- }
-}
-
-/**
- * Composes the children of the view with the passed in [composable]. This is a convenience method
- * around [Compose.composeInto].
- *
- * @see Compose.composeInto
- * @see disposeComposition
- */
-fun ViewGroup.setViewContent(composable: @Composable() () -> Unit): Composition =
- Compose.composeInto(this, null, composable)
-
-/**
- * Disposes of a composition of the children of this view. This is a convenience method around
- * [Compose.disposeComposition].
- *
- * @see Compose.disposeComposition
- * @see Compose.composeInto
- */
-fun ViewGroup.disposeComposition() = Compose.disposeComposition(this, null)
-
private val EmptyComposable: @Composable() () -> Unit = {}
/**
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composer.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composer.kt
index 306f4a0..11a56c0 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composer.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composer.kt
@@ -65,11 +65,13 @@
private val usedKeys = mutableListOf<KeyInfo>()
private val groupInfos = run {
var runningNodeIndex = 0
- keyInfos.withIndex().associateTo(mutableMapOf()) { (index, key) ->
- Pair(key, GroupInfo(index, runningNodeIndex, key.nodes)).also {
- runningNodeIndex += key.nodes
- }
+ val result = hashMapOf<Any?, GroupInfo>()
+ for (index in 0 until keyInfos.size) {
+ val key = keyInfos[index]
+ result[key] = GroupInfo(index, runningNodeIndex, key.nodes)
+ runningNodeIndex += key.nodes
}
+ result
}
/**
@@ -78,7 +80,8 @@
*/
val keyMap by lazy {
multiMap<Any, KeyInfo>().also {
- for (keyInfo in keyInfos) {
+ for (index in 0 until keyInfos.size) {
+ val keyInfo = keyInfos[index]
@Suppress("ReplacePutWithAssignment")
it.put(keyInfo.key, keyInfo)
}
@@ -434,25 +437,31 @@
changes.clear()
}
- for ((anchor, invalidation) in invalidationAnchors) {
+ @Suppress("ReplaceManualRangeWithIndicesCalls") // Avoids allocation of an iterator
+ for (index in 0 until invalidationAnchors.size) {
+ val (anchor, invalidation) = invalidationAnchors[index]
invalidation.location = slotTable.anchorLocation(anchor)
}
trace("Compose:lifecycles") {
// Send lifecycle leaves
- for (holder in leaves.reversed()) {
- // The count of the holder might be greater than 0 here as it might leave one
- // part of the composition and reappear in another. Only send a leave if the
- // count is still 0 after all changes have been applied.
- if (holder.count == 0) {
- holder.instance.onLeave()
- lifecycleObservers.remove(holder)
+ if (leaves.isNotEmpty()) {
+ for (holder in leaves.reversed()) {
+ // The count of the holder might be greater than 0 here as it might leave one
+ // part of the composition and reappear in another. Only send a leave if the
+ // count is still 0 after all changes have been applied.
+ if (holder.count == 0) {
+ holder.instance.onLeave()
+ lifecycleObservers.remove(holder)
+ }
}
}
// Send lifecycle enters
- for (holder in enters) {
- holder.instance.onEnter()
+ if (enters.isNotEmpty()) {
+ for (holder in enters) {
+ holder.instance.onEnter()
+ }
}
}
@@ -1081,11 +1090,12 @@
// increment the node index and the group's node count. If the parent is tracking structural
// changes in pending then restore that too.
val previousPending = pendingStack.pop()
- previousPending?.let { previous ->
+ if (previousPending != null) {
// Update the parent count of nodes
- previous.updateNodeCount(pending?.parentKeyInfo, expectedNodeCount)
- if (!inserting)
- previous.groupIndex++
+ previousPending.updateNodeCount(pending?.parentKeyInfo, expectedNodeCount)
+ if (!inserting) {
+ previousPending.groupIndex++
+ }
}
this.pending = previousPending
this.nodeIndex = nodeIndexStack.pop() + expectedNodeCount
@@ -1371,7 +1381,8 @@
slotsActionStartStack.clear()
record { applier, slots, _ ->
var currentKey = 0
- actions.forEach { action ->
+ for (index in 0 until actions.actionSize) {
+ val action = actions.actions[index]
when (action) {
START_GROUP -> slots.startGroup(actions.getKey(currentKey++))
START_GROUP_SAME_KEY -> slots.startGroup(EMPTY)
@@ -1574,6 +1585,61 @@
}
}
+@Suppress("UNCHECKED_CAST")
+/*inline */ class ComposerUpdater<N, T : N>(val composer: Composer<N>, val node: T) {
+ inline fun set(
+ value: Int,
+ /*crossinline*/
+ block: T.(value: Int) -> Unit
+ ) = with(composer) {
+ if (inserting || nextSlot() != value) {
+ updateValue(value)
+ node.block(value)
+// val appliedBlock: T.(value: Int) -> Unit = { block(it) }
+// composer.apply(value, appliedBlock)
+ } else skipValue()
+ }
+
+ inline fun <reified V> set(
+ value: V,
+ /*crossinline*/
+ block: T.(value: V) -> Unit
+ ) = with(composer) {
+ if (inserting || nextSlot() != value) {
+ updateValue(value)
+ node.block(value)
+// val appliedBlock: T.(value: V) -> Unit = { block(it) }
+// composer.apply(value, appliedBlock)
+ } else skipValue()
+ }
+
+ inline fun update(
+ value: Int,
+ /*crossinline*/
+ block: T.(value: Int) -> Unit
+ ) = with(composer) {
+ if (inserting || nextSlot() != value) {
+ updateValue(value)
+ node.block(value)
+// val appliedBlock: T.(value: Int) -> Unit = { block(it) }
+// if (!inserting) composer.apply(value, appliedBlock)
+ } else skipValue()
+ }
+
+ inline fun <reified V> update(
+ value: V,
+ /*crossinline*/
+ block: T.(value: V) -> Unit
+ ) = with(composer) {
+ if (inserting || nextSlot() != value) {
+ updateValue(value)
+ node.block(value)
+// val appliedBlock: T.(value: V) -> Unit = { block(it) }
+// if (!inserting) composer.apply(value, appliedBlock)
+ } else skipValue()
+ }
+}
+
/**
* Get the next value of the slot table. This will unwrap lifecycle observer holders to return
* lifecycle observer and should be used instead of [Composer.nextSlot].
@@ -1735,11 +1801,6 @@
fun last(): SlotAction = actions[actionSize - 1]
}
-// SlotActions helper
-private inline fun SlotActions.forEach(block: (SlotAction) -> Unit) {
- for (index in 0 until actionSize) block(actions[index])
-}
-
// Mutable list
private fun <K, V> multiMap() = HashMap<K, LinkedHashSet<V>>()
@@ -1822,7 +1883,7 @@
throw NotImplementedError("Implemented as an intrinsic")
}
-// TODO: git rid of the need for this when we merge FrameManager and Recomposer together!
+// TODO: get rid of the need for this when we merge FrameManager and Recomposer together!
internal var currentComposerInternal: Composer<*>? = null
internal fun invokeComposable(composer: Composer<*>, composable: @Composable() () -> Unit) {
@@ -1839,3 +1900,21 @@
val realFn = composable as Function1<Composer<*>, T>
return realFn(composer)
}
+
+@PublishedApi
+internal val invocation = Any()
+
+@PublishedApi
+internal val provider = Any()
+
+@PublishedApi
+internal val providerValues = Any()
+
+@PublishedApi
+internal val providerMaps = Any()
+
+@PublishedApi
+internal val consumer = Any()
+
+@PublishedApi
+internal val reference = Any()
\ No newline at end of file
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composition.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composition.kt
index e44f41c..1230695 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composition.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Composition.kt
@@ -28,7 +28,7 @@
/**
* A Composition is an object that is used to manage the UI created from a Composable from the
* top level. A composition object is usually constructed for you, and returned from an API that
- * is used to initially compose a UI. For instance, [Compose.composeInto] returns a Composition.
+ * is used to initially compose a UI. For instance, [composeInto] returns a Composition.
*
* The Composition object can be used to update the composition by calling the [compose] methods.
* Similarly, the [dispose] method should be used when you would like to dispose of the UI and
@@ -37,7 +37,7 @@
* @param composerFactory A function to create a composer object, for use during composition
* @param parent An optional reference to the parent composition.
*
- * @see Compose.composeInto
+ * @see composeInto
*/
open class Composition(
private val composerFactory: (SlotTable, Recomposer) -> Composer<*>,
@@ -45,7 +45,7 @@
) {
private val slotTable: SlotTable = SlotTable()
internal val composer: Composer<*> = makeComposer(composerFactory, parent, slotTable)
- internal var composable: @Composable() () -> Unit = emptyContent()
+ var composable: @Composable() () -> Unit = emptyContent()
/**
* Update the composition with the content described by the [content] composable
@@ -76,7 +76,7 @@
/**
* Return true if this is a root (non-sub-) composition
*/
- internal val isRootComposition: Boolean get() = parent == null
+ val isRoot: Boolean get() = parent == null
/**
* Recomposes any changes without forcing the [composable] to compose and blocks until
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/CompositionReference.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/CompositionReference.kt
index 6b22bd2..4ed6f8e 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/CompositionReference.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/CompositionReference.kt
@@ -24,7 +24,6 @@
* through the two compositions as if they were not separate.
*
* @see compositionReference
- * @see Compose.composeInto
*/
interface CompositionReference {
fun <T> getAmbient(key: Ambient<T>): T
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Emittable.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Emittable.kt
deleted file mode 100644
index c31302f..0000000
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Emittable.kt
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright 2019 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
-
-/**
- * The Emittable interface tells Compose that the implementing class represents a
- * primitive node/type in the view hierarchy produced as a result of composition.
- * Conceptually similar to a RenderObject in flutter. The result of composition is
- * an updated tree of Emittables, which Compose will maintain/mutate over time as
- * subsequent reconciliations are calculated.
- */
-interface Emittable {
- fun emitInsertAt(index: Int, instance: Emittable)
- fun emitRemoveAt(index: Int, count: Int)
- fun emitMove(from: Int, to: Int, count: Int)
-}
\ No newline at end of file
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Expect.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Expect.kt
index 278752c..4d5ab65 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Expect.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/Expect.kt
@@ -37,23 +37,6 @@
internal expect fun identityHashCode(instance: Any?): Int
-expect interface ViewParent
-
-expect open class View {
- fun getTag(key: Int): Any
- fun setTag(key: Int, tag: Any?)
-}
-internal expect val View.parent: ViewParent
-internal expect val View.context: Context
-
-expect abstract class ViewGroup : View {
- fun removeAllViews()
-}
-
-expect abstract class Context
-
-expect class FrameLayout(context: Context)
-
internal expect inline fun <R> synchronized(lock: Any, block: () -> R): R
expect open class WeakReference<T> : Reference<T> {
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/FrameManager.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/FrameManager.kt
index 16105d7..06f5fa8 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/FrameManager.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/FrameManager.kt
@@ -141,6 +141,15 @@
}
}
+ /**
+ * Records that [value], or one of its fields, read while composing and its values were
+ * used during composition.
+ *
+ * This is the underlying mechanism used by [Model] objects to allow composition to observe
+ * changes made to model objects.
+ */
+ internal fun recordRead(value: Any) = readObserver(value)
+
private val writeObserver: (write: Any, isNew: Boolean) -> Unit = { value, isNew ->
if (!commitPending) {
commitPending = true
@@ -149,17 +158,39 @@
nextFrame()
}
}
+ recordWrite(value, isNew)
+ }
+
+ /**
+ * Records that [value], or one of its fields, was changed and the reads recorded by
+ * [recordRead] might have changed value.
+ *
+ * Calling this method outside of composition is ignored. This is only intended for
+ * invaliding composable lambdas while composing.
+ */
+ internal fun recordWrite(value: Any, isNew: Boolean) {
if (!isNew && composing) {
val currentInvalidations = synchronized(lock) {
invalidations.getValueOf(value)
}
if (currentInvalidations.isNotEmpty()) {
- val results = currentInvalidations.map { scope -> scope.invalidate() }
- val frame = currentFrame()
- if (results.any { result -> result == InvalidationResult.DEFERRED })
- deferredMap.add(frame, value)
- if (results.any { result -> result == InvalidationResult.IMMINENT })
- immediateMap.add(frame, value)
+ var hasDeferred = false
+ var hasImminent = false
+ for (index in 0 until currentInvalidations.size) {
+ val scope = currentInvalidations[index]
+ when (scope.invalidate()) {
+ InvalidationResult.DEFERRED -> hasDeferred = true
+ InvalidationResult.IMMINENT -> hasImminent = true
+ else -> { } // Nothing to do
+ }
+ }
+ if (hasDeferred || hasImminent) {
+ val frame = currentFrame()
+ if (hasDeferred)
+ deferredMap.add(frame, value)
+ if (hasImminent)
+ immediateMap.add(frame, value)
+ }
}
}
}
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/JoinedKey.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/JoinedKey.kt
index aaa79fa..30fc771 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/JoinedKey.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/JoinedKey.kt
@@ -16,11 +16,9 @@
package androidx.compose
-import kotlin.jvm.JvmField
-
internal data class JoinedKey(
- @JvmField val left: Any?,
- @JvmField val right: Any?
+ val left: Any?,
+ val right: Any?
)
fun isJoinedKey(key: Any?) = key is JoinedKey
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/ObserverMap.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/ObserverMap.kt
index 50c3742..5ebe73d 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/ObserverMap.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/ObserverMap.kt
@@ -26,9 +26,9 @@
*/
class ObserverMap<K : Any, V : Any> {
private val keyToValue =
- mutableMapOf<IdentityWeakReference<K>, MutableSet<IdentityWeakReference<V>>>()
+ hashMapOf<IdentityWeakReference<K>, MutableSet<IdentityWeakReference<V>>>()
private val valueToKey =
- mutableMapOf<IdentityWeakReference<V>, MutableSet<IdentityWeakReference<K>>>()
+ hashMapOf<IdentityWeakReference<V>, MutableSet<IdentityWeakReference<K>>>()
private val keyQueue = ReferenceQueue<K>()
private val valueQueue = ReferenceQueue<V>()
@@ -163,7 +163,7 @@
) {
var set = map[key]
if (set == null) {
- set = mutableSetOf()
+ set = hashSetOf()
map.put(key, set)
}
set.add(value)
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/ViewComposerCommon.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/ViewComposerCommon.kt
deleted file mode 100644
index be748af..0000000
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/ViewComposerCommon.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2019 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
-
-internal expect fun UiComposer(
- context: Context,
- root: Any,
- slots: SlotTable,
- recomposer: Recomposer
-): Composer<*>
-
-// TODO(b/147710889): Once composer param work is complete, this API should be removed and
-// replaced with an internal API used for invoking composables.
-/**
- * Execute a block of code with the composer in "composing" mode. After executing, the composer
- * will revert back to it's previous "composing" state. This can be useful for manually starting
- * a composition.
- *
- * @param block the code to execute
- */
-@TestOnly
-expect fun <T> Composer<*>.runWithComposing(block: () -> T): T
-
-@PublishedApi
-internal val invocation = OpaqueKey("invocation")
-
-@PublishedApi
-internal val provider = OpaqueKey("provider")
-
-@PublishedApi
-internal val providerValues = OpaqueKey("providerValues")
-
-@PublishedApi
-internal val providerMaps = OpaqueKey("providerMaps")
-
-@PublishedApi
-internal val consumer = OpaqueKey("consumer")
-
-@PublishedApi
-internal val reference = OpaqueKey("reference")
\ No newline at end of file
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/annotations/Hide.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/annotations/Hide.kt
deleted file mode 100644
index 313a251..0000000
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/annotations/Hide.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package androidx.compose.annotations
-
-/**
- * We will want something like this to remove things from autocomplete. This seems like a generally useful thing, but not sure if
- * something already exists that would do this.
- */
-annotation class Hide
\ No newline at end of file
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/frames/Frames.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/frames/Frames.kt
index 6ff2035..a82e04c 100644
--- a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/frames/Frames.kt
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/frames/Frames.kt
@@ -449,7 +449,12 @@
// invoke the observer associated with the current frame.
frame.readObserver?.invoke(framed)
// invoke the thread local observers.
- frame.threadReadObservers.forEach { it(framed) }
+ val observers = frame.threadReadObservers
+ if (observers.isNotEmpty()) {
+ for (observer in observers) {
+ observer(framed)
+ }
+ }
return readable(this, frame.id, frame.invalid)
}
diff --git a/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/internal/RestartableFunction.kt b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/internal/RestartableFunction.kt
new file mode 100644
index 0000000..dd1a381
--- /dev/null
+++ b/compose/compose-runtime/src/commonMain/kotlin/androidx/compose/internal/RestartableFunction.kt
@@ -0,0 +1,1147 @@
+/*
+ * 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.
+ */
+
+@file:Suppress("UNCHECKED_CAST")
+
+package androidx.compose.internal
+
+import androidx.compose.Composable
+import androidx.compose.Composer
+import androidx.compose.FrameManager
+import androidx.compose.Stable
+import androidx.compose.remember
+
+/**
+ * A Restart is created to hold composable lambdas to track when they are invoked allowing
+ * the invocations to be invalidated when a new composable lambda is created during composition.
+ *
+ * This allows much of the call-graph to be skipped when a composable function is passed through
+ * multiple levels of composable functions.
+ */
+@Stable
+class RestartableFunction<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16,
+ P17, P18, P19, P20, P21, R>(val key: Any, private val tracked: Boolean) : Function0<R>,
+ Function1<Composer<*>, R>,
+ Function2<P1, Composer<*>, R>,
+ Function3<P1, P2, Composer<*>, R>,
+ Function4<P1, P2, P3, Composer<*>, R>,
+ Function5<P1, P2, P3, P4, Composer<*>, R>,
+ Function6<P1, P2, P3, P4, P5, Composer<*>, R>,
+ Function7<P1, P2, P3, P4, P5, P6, Composer<*>, R>,
+ Function8<P1, P2, P3, P4, P5, P6, P7, Composer<*>, R>,
+ Function9<P1, P2, P3, P4, P5, P6, P7, P8, Composer<*>, R>,
+ Function10<P1, P2, P3, P4, P5, P6, P7, P8, P9, Composer<*>, R>,
+ Function11<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, Composer<*>, R>,
+ Function12<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, Composer<*>, R>,
+ Function13<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, Composer<*>, R>,
+ Function14<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, Composer<*>, R>,
+ Function15<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, Composer<*>, R>,
+ Function16<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, Composer<*>, R>,
+ Function17<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16,
+ Composer<*>, R>,
+ Function18<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17,
+ Composer<*>, R>,
+ Function19<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18,
+ Composer<*>, R>,
+ Function20<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18,
+ P19, Composer<*>, R>,
+ Function21<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18,
+ P19, P20, Composer<*>, R>,
+ Function22<P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, P17, P18,
+ P19, P20, P21, Composer<*>, R> {
+ private var _block: Any? = null
+
+ private fun trackWrite() {
+ if (tracked) {
+ FrameManager.recordWrite(this, false)
+ }
+ }
+
+ private fun trackRead() {
+ if (tracked) {
+ FrameManager.recordRead(this)
+ }
+ }
+
+ fun update(block: Any) {
+ if (_block != block) {
+ val oldBlockNull = _block == null
+ _block = block
+ if (!oldBlockNull) {
+ trackWrite()
+ }
+ }
+ }
+
+ override fun invoke(): R = error("Expected a composer")
+
+ override fun invoke(c: Composer<*>): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (c: Composer<*>) -> R)(c)
+ c.endRestartGroup()?.updateScope(this as (Composer<*>) -> Unit)
+ return result
+ }
+
+ override fun invoke(p1: P1, c: Composer<*>): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (p1: P1, c: Composer<*>) -> R)(p1, c)
+ c.endRestartGroup()?.updateScope { nc -> this(p1, nc) }
+ return result
+ }
+
+ override fun invoke(p1: P1, p2: P2, c: Composer<*>): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (p1: P1, p2: P2, c: Composer<*>) -> R)(p1, p2, c)
+ c.endRestartGroup()?.updateScope { nc -> this(p1, p2, nc) }
+ return result
+ }
+
+ override fun invoke(p1: P1, p2: P2, p3: P3, c: Composer<*>): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (p1: P1, p2: P2, p3: P3, c: Composer<*>) -> R)(p1, p2, p3, c)
+ c.endRestartGroup()?.updateScope { nc -> this(p1, p2, p3, nc) }
+ return result
+ }
+
+ override fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, c: Composer<*>): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (p1: P1, p2: P2, p3: P3, p4: P4, c: Composer<*>) -> R)(
+ p1,
+ p2,
+ p3,
+ p4,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc -> this(p1, p2, p3, p4, nc) }
+ return result
+ }
+
+ override fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, c: Composer<*>): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, c: Composer<*>) -> R)(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc -> this(p1, p2, p3, p4, p5,
+ nc) }
+ return result
+ }
+
+ override fun invoke(p1: P1, p2: P2, p3: P3, p4: P4, p5: P5, p6: P6, c: Composer<*>): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ c: Composer<*>
+ ) -> R)(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc ->
+ this(p1, p2, p3, p4, p5, p6, nc)
+ }
+ return result
+ }
+
+ override fun invoke(
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ c: Composer<*>
+ ): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ c: Composer<*>
+ ) -> R)(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc ->
+ this(p1, p2, p3, p4, p5, p6, p7, nc)
+ }
+ return result
+ }
+
+ override fun invoke(
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ c: Composer<*>
+ ): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ c: Composer<*>
+ ) -> R) (
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc ->
+ this(p1, p2, p3, p4, p5, p6, p7, p8, nc)
+ }
+ return result
+ }
+
+ override fun invoke(
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ c: Composer<*>
+ ): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ c: Composer<*>
+ ) -> R)(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ p9,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc ->
+ this(p1, p2, p3, p4, p5, p6, p7, p8, p9, nc)
+ }
+ return result
+ }
+
+ override fun invoke(
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ c: Composer<*>
+ ): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ c: Composer<*>
+ ) -> R)(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ p9,
+ p10,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc ->
+ this(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, nc)
+ }
+ return result
+ }
+
+ override fun invoke(
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ c: Composer<*>
+ ): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ c: Composer<*>
+ ) -> R)(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ p9,
+ p10,
+ p11,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc ->
+ this(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, nc)
+ }
+ return result
+ }
+
+ override fun invoke(
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ c: Composer<*>
+ ): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ c: Composer<*>
+ ) -> R)(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ p9,
+ p10,
+ p11,
+ p12,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc ->
+ this(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, nc)
+ }
+ return result
+ }
+
+ override fun invoke(
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ c: Composer<*>
+ ): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ c: Composer<*>
+ ) -> R)(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ p9,
+ p10,
+ p11,
+ p12,
+ p13,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc ->
+ this(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, nc)
+ }
+ return result
+ }
+
+ override fun invoke(
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ p14: P14,
+ c: Composer<*>
+ ): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ p14: P14,
+ c: Composer<*>
+ ) -> R)(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ p9,
+ p10,
+ p11,
+ p12,
+ p13,
+ p14,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc ->
+ this(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, nc)
+ }
+ return result
+ }
+
+ override fun invoke(
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ p14: P14,
+ p15: P15,
+ c: Composer<*>
+ ): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ p14: P14,
+ p15: P15,
+ c: Composer<*>
+ ) -> R)(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ p9,
+ p10,
+ p11,
+ p12,
+ p13,
+ p14,
+ p15,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc ->
+ this(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, nc)
+ }
+ return result
+ }
+
+ override fun invoke(
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ p14: P14,
+ p15: P15,
+ p16: P16,
+ c: Composer<*>
+ ): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ p14: P14,
+ p15: P15,
+ p16: P16,
+ c: Composer<*>
+ ) -> R)(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ p9,
+ p10,
+ p11,
+ p12,
+ p13,
+ p14,
+ p15,
+ p16,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc ->
+ this(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, nc)
+ }
+ return result
+ }
+
+ override fun invoke(
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ p14: P14,
+ p15: P15,
+ p16: P16,
+ p17: P17,
+ c: Composer<*>
+ ): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ p14: P14,
+ p15: P15,
+ p16: P16,
+ p17: P17,
+ c: Composer<*>
+ ) -> R)(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ p9,
+ p10,
+ p11,
+ p12,
+ p13,
+ p14,
+ p15,
+ p16,
+ p17,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc ->
+ this(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, nc)
+ }
+ return result
+ }
+
+ override fun invoke(
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ p14: P14,
+ p15: P15,
+ p16: P16,
+ p17: P17,
+ p18: P18,
+ c: Composer<*>
+ ): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ p14: P14,
+ p15: P15,
+ p16: P16,
+ p17: P17,
+ p18: P18,
+ c: Composer<*>
+ ) -> R)(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ p9,
+ p10,
+ p11,
+ p12,
+ p13,
+ p14,
+ p15,
+ p16,
+ p17,
+ p18,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc ->
+ this(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ p9,
+ p10,
+ p11,
+ p12,
+ p13,
+ p14,
+ p15,
+ p16,
+ p17,
+ p18,
+ nc
+ )
+ }
+ return result
+ }
+
+ override fun invoke(
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ p14: P14,
+ p15: P15,
+ p16: P16,
+ p17: P17,
+ p18: P18,
+ p19: P19,
+ c: Composer<*>
+ ): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ p14: P14,
+ p15: P15,
+ p16: P16,
+ p17: P17,
+ p18: P18,
+ p19: P19,
+ c: Composer<*>
+ ) -> R)(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ p9,
+ p10,
+ p11,
+ p12,
+ p13,
+ p14,
+ p15,
+ p16,
+ p17,
+ p18,
+ p19,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc ->
+ this(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ p9,
+ p10,
+ p11,
+ p12,
+ p13,
+ p14,
+ p15,
+ p16,
+ p17,
+ p18,
+ p19,
+ nc
+ )
+ }
+ return result
+ }
+
+ override fun invoke(
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ p14: P14,
+ p15: P15,
+ p16: P16,
+ p17: P17,
+ p18: P18,
+ p19: P19,
+ p20: P20,
+ c: Composer<*>
+ ): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ p14: P14,
+ p15: P15,
+ p16: P16,
+ p17: P17,
+ p18: P18,
+ p19: P19,
+ p20: P20,
+ c: Composer<*>
+ ) -> R)(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ p9,
+ p10,
+ p11,
+ p12,
+ p13,
+ p14,
+ p15,
+ p16,
+ p17,
+ p18,
+ p19,
+ p20,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc ->
+ this(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ p9,
+ p10,
+ p11,
+ p12,
+ p13,
+ p14,
+ p15,
+ p16,
+ p17,
+ p18,
+ p19,
+ p20,
+ nc
+ )
+ }
+ return result
+ }
+
+ override fun invoke(
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ p14: P14,
+ p15: P15,
+ p16: P16,
+ p17: P17,
+ p18: P18,
+ p19: P19,
+ p20: P20,
+ p21: P21,
+ c: Composer<*>
+ ): R {
+ c.startRestartGroup(key)
+ trackRead()
+ val result = (_block as (
+ p1: P1,
+ p2: P2,
+ p3: P3,
+ p4: P4,
+ p5: P5,
+ p6: P6,
+ p7: P7,
+ p8: P8,
+ p9: P9,
+ p10: P10,
+ p11: P11,
+ p12: P12,
+ p13: P13,
+ p14: P14,
+ p15: P15,
+ p16: P16,
+ p17: P17,
+ p18: P18,
+ p19: P19,
+ p20: P20,
+ p21: P21,
+ c: Composer<*>
+ ) -> R)(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ p9,
+ p10,
+ p11,
+ p12,
+ p13,
+ p14,
+ p15,
+ p16,
+ p17,
+ p18,
+ p19,
+ p20,
+ p21,
+ c
+ )
+ c.endRestartGroup()?.updateScope { nc ->
+ this(
+ p1,
+ p2,
+ p3,
+ p4,
+ p5,
+ p6,
+ p7,
+ p8,
+ p9,
+ p10,
+ p11,
+ p12,
+ p13,
+ p14,
+ p15,
+ p16,
+ p17,
+ p18,
+ p19,
+ p20,
+ p21,
+ nc
+ )
+ }
+ return result
+ }
+}
+
+@Suppress("unused")
+@Composable
+fun restartableFunction(key: Int, tracked: Boolean, block: Any) =
+ remember {
+ RestartableFunction<Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any,
+ Any, Any, Any, Any, Any, Any, Any, Any>(key, tracked)
+ }.apply { update(block) }
+
+@Suppress("unused")
+fun restartableFunctionInstance(key: Int, tracked: Boolean, block: Any) =
+ RestartableFunction<Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any, Any,
+ Any, Any, Any, Any, Any, Any, Any, Any>(key, tracked).apply { update(block) }
diff --git a/compose/compose-runtime/src/jvmMain/kotlin/androidx/compose/internal/RestartableFunctionN.kt b/compose/compose-runtime/src/jvmMain/kotlin/androidx/compose/internal/RestartableFunctionN.kt
new file mode 100644
index 0000000..a8609a1
--- /dev/null
+++ b/compose/compose-runtime/src/jvmMain/kotlin/androidx/compose/internal/RestartableFunctionN.kt
@@ -0,0 +1,75 @@
+/*
+ * 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.compose.internal
+
+import androidx.compose.Composable
+import androidx.compose.Composer
+import androidx.compose.FrameManager
+import androidx.compose.Stable
+import androidx.compose.remember
+import kotlin.jvm.functions.FunctionN
+
+@Stable
+class RestartableFunctionN<R>(
+ val key: Any,
+ private val tracked: Boolean,
+ override val arity: Int
+) : FunctionN<R> {
+ private var _block: Any? = null
+
+ fun update(block: Any) {
+ if (block != this._block) {
+ if (tracked) {
+ FrameManager.recordWrite(this, false)
+ }
+ this._block = block as FunctionN<*>
+ }
+ }
+
+ override fun invoke(vararg args: Any?): R {
+ val c = args.last() as Composer<*>
+ c.startRestartGroup(key)
+ if (tracked) {
+ FrameManager.recordRead(this)
+ }
+ @Suppress("UNCHECKED_CAST")
+ val result = (_block as FunctionN<*>)(*args) as R
+ c.endRestartGroup()?.updateScope { nc ->
+ this(*(args.slice(0 until args.size - 1) + nc).toTypedArray())
+ }
+ return result
+ }
+}
+
+@Suppress("unused")
+@Composable
+fun restartableFunctionN(
+ key: Int,
+ tracked: Boolean,
+ arity: Int,
+ block: Any
+): RestartableFunctionN<*> = remember {
+ RestartableFunctionN<Any>(key, tracked, arity)
+}.apply { update(block) }
+
+@Suppress("unused")
+fun restartableFunctionNInstance(
+ key: Int,
+ tracked: Boolean,
+ arity: Int,
+ block: Any
+): RestartableFunctionN<*> = RestartableFunctionN<Any>(key, tracked, arity).apply { update(block) }
diff --git a/compose/compose-runtime/src/unitTest/kotlin/androidx/compose/CompositionTests.kt b/compose/compose-runtime/src/unitTest/kotlin/androidx/compose/CompositionTests.kt
index 4630c2f..8334e2ce 100644
--- a/compose/compose-runtime/src/unitTest/kotlin/androidx/compose/CompositionTests.kt
+++ b/compose/compose-runtime/src/unitTest/kotlin/androidx/compose/CompositionTests.kt
@@ -35,6 +35,7 @@
import androidx.compose.mock.skip
import androidx.compose.mock.text
import androidx.compose.mock.validate
+import androidx.ui.core.clearRoots
import org.junit.After
import org.junit.Ignore
import kotlin.test.Test
@@ -46,7 +47,7 @@
@After
fun teardown() {
- Compose.clearRoots()
+ clearRoots()
}
@Test
@@ -358,8 +359,6 @@
@Ignore("b/148896187")
@Test
fun testComponent() {
- val slReportReports = object {}
-
@Composable fun MockComposeScope.Reporter(report: Report? = null) {
if (report != null) {
text(report.from)
@@ -613,7 +612,6 @@
@Ignore("b/148896187")
@Test
fun testComposePartOfTree() {
- val slReportReports = object {}
var recomposeLois: (() -> Unit)? = null
@Composable fun MockComposeScope.Reporter(report: Report? = null) {
@@ -680,18 +678,16 @@
@Ignore("b/148896187")
@Test
fun testRecomposeWithReplace() {
- val slReportReports = object {}
var recomposeLois: (() -> Unit)? = null
var key = 0
@Composable fun MockComposeScope.Reporter(report: Report? = null) {
- val r = report
- if (r != null) {
- if (r.from == "Lois" || r.to == "Lois") recomposeLois = invalidate
+ if (report != null) {
+ if (report.from == "Lois" || report.to == "Lois") recomposeLois = invalidate
key(key) {
- text(r.from)
+ text(report.from)
text("reports to")
- text(r.to)
+ text(report.to)
}
} else {
text("no report to report")
@@ -753,7 +749,6 @@
@Test
fun testInvalidationAfterRemoval() {
- val slReportReports = object {}
var recomposeLois: (() -> Unit)? = null
val key = 0
@@ -1852,23 +1847,23 @@
expectChanges: Boolean = true,
block: @Composable MockComposeScope.() -> Unit
): MockViewComposer {
- val myComposer = myComposer ?: run {
+ val myRealComposer = myComposer ?: run {
val root = View().apply { name = "root" }
MockViewComposer(root)
}
- myComposer.compose {
+ myRealComposer.compose {
block()
}
if (expectChanges) {
- assertNotEquals(0, myComposer.changeCount, "changes were expected")
- myComposer.applyChanges()
+ assertNotEquals(0, myRealComposer.changeCount, "changes were expected")
+ myRealComposer.applyChanges()
} else {
- assertEquals(0, myComposer.changeCount, "no changes were expected")
+ assertEquals(0, myRealComposer.changeCount, "no changes were expected")
}
- return myComposer
+ return myRealComposer
}
private fun compose(
diff --git a/compose/compose-runtime/src/unitTest/kotlin/androidx/compose/frames/FrameIdSetTests.kt b/compose/compose-runtime/src/unitTest/kotlin/androidx/compose/frames/FrameIdSetTests.kt
index 15e0cc0..cbe997b 100644
--- a/compose/compose-runtime/src/unitTest/kotlin/androidx/compose/frames/FrameIdSetTests.kt
+++ b/compose/compose-runtime/src/unitTest/kotlin/androidx/compose/frames/FrameIdSetTests.kt
@@ -16,7 +16,7 @@
package androidx.compose.frames
-import androidx.compose.BitSet
+import java.util.BitSet
import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertEquals
diff --git a/compose/compose-runtime/src/unitTest/kotlin/androidx/compose/mock/ViewComposer.kt b/compose/compose-runtime/src/unitTest/kotlin/androidx/compose/mock/ViewComposer.kt
index 260259a..dff3a1d 100644
--- a/compose/compose-runtime/src/unitTest/kotlin/androidx/compose/mock/ViewComposer.kt
+++ b/compose/compose-runtime/src/unitTest/kotlin/androidx/compose/mock/ViewComposer.kt
@@ -64,6 +64,7 @@
}
}
+ @Suppress("UNCHECKED_CAST")
inline fun <V : View> emit(
key: Any,
ctor: () -> V,
diff --git a/core/core/api/restricted_1.3.0-alpha03.txt b/core/core/api/restricted_1.3.0-alpha03.txt
index a30f3ce..aae1774 100644
--- a/core/core/api/restricted_1.3.0-alpha03.txt
+++ b/core/core/api/restricted_1.3.0-alpha03.txt
@@ -1334,9 +1334,6 @@
@RequiresApi(28) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) public class TypefaceCompatApi28Impl extends androidx.core.graphics.TypefaceCompatApi26Impl {
ctor public TypefaceCompatApi28Impl();
- method public android.graphics.Typeface! createFromFontFamilyFilesResourceEntry(android.content.Context!, androidx.core.content.res.FontResourcesParserCompat.FontFamilyFilesResourceEntry!, android.content.res.Resources!, int);
- method public android.graphics.Typeface! createFromFontInfo(android.content.Context!, android.os.CancellationSignal!, androidx.core.provider.FontsContractCompat.FontInfo![], int);
- method public android.graphics.Typeface? createFromResourcesFontFile(android.content.Context!, android.content.res.Resources!, int, String!, int);
}
@RequiresApi(29) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public class TypefaceCompatApi29Impl {
diff --git a/datastore/OWNERS b/datastore/OWNERS
index 568ad4a..e7a11f3 100644
--- a/datastore/OWNERS
+++ b/datastore/OWNERS
@@ -1,2 +1,3 @@
[email protected]
[email protected]
[email protected]
\ No newline at end of file
diff --git a/development/checkInvalidSuppress.py b/development/checkInvalidSuppress.py
index 5848064..e015483 100755
--- a/development/checkInvalidSuppress.py
+++ b/development/checkInvalidSuppress.py
@@ -67,8 +67,8 @@
if not report:
sys.exit(0)
- print "Invalid, IDEA-specific warning suppression found. These cause warnings during compilation."
- print report
+ print("Invalid, IDEA-specific warning suppression found. These cause warnings during compilation.")
+ print(report)
sys.exit(1)
if __name__ == '__main__':
diff --git a/development/release-notes/AndroidXMarkdown.py b/development/release-notes/AndroidXMarkdown.py
index 9c82ae2..c5ca7f8 100644
--- a/development/release-notes/AndroidXMarkdown.py
+++ b/development/release-notes/AndroidXMarkdown.py
@@ -83,11 +83,7 @@
if ("frameworks/support" in projectDir):
print_e("Gitiles directory should be relative to frameworks/support; received incorrect directory: $projectDir")
exit(1)
- # Remove extra preceeding directory slashes, if they exist
- simplifiedProjectDir = projectDir
- while (simplifiedProjectDir[0] == '/'):
- simplifiedProjectDir = simplifiedProjectDir[1:]
- return GitilesDiffLogLink("Version %s contains these commits." % version, "%s%s..%s/%s" % (baseGitilesUrl, startSHA, endSHA, simplifiedProjectDir))
+ return GitilesDiffLogLink("Version %s contains these commits." % version, "%s%s..%s/%s" % (baseGitilesUrl, startSHA, endSHA, projectDir))
class LibraryHeader(MarkdownHeader):
"""
diff --git a/development/release-notes/GitClient.py b/development/release-notes/GitClient.py
index bb2a4a9..257eee1 100644
--- a/development/release-notes/GitClient.py
+++ b/development/release-notes/GitClient.py
@@ -69,6 +69,11 @@
authorEmailDelimiter = "_Author:"
dateDelimiter = "_Date:"
bodyDelimiter = "_Body:"
+ if subProjectDir[0] == '/':
+ raise RuntimeError("Fatal error: the subproject directory (subProjectDir) passed to " +
+ "GitClient.getGitLog was an absolute filepath. The subproject directory should " +
+ "be a relative filepath to the GitClient.gitRoot")
+
fullProjectDir = os.path.join(self.gitRoot, subProjectDir)
gitLogOptions = "--pretty=format:" + \
diff --git a/development/release-notes/generateReleaseNotes.py b/development/release-notes/generateReleaseNotes.py
index 442f35a..0a92865 100755
--- a/development/release-notes/generateReleaseNotes.py
+++ b/development/release-notes/generateReleaseNotes.py
@@ -84,6 +84,7 @@
fromSHA = artifactId_release_line[4]
untilSHA = artifactId_release_line[5]
path = artifactId_release_line[6]
+ if path[0] == '/': path = path[1:]
requiresSameVersion = False
if artifactId_release_line[7] == "true":
requiresSameVersion = True
diff --git a/development/release-notes/testReleaseNotes.py b/development/release-notes/testReleaseNotes.py
index 2c1a12b..a877008 100755
--- a/development/release-notes/testReleaseNotes.py
+++ b/development/release-notes/testReleaseNotes.py
@@ -430,6 +430,19 @@
)
self.assertEqual(1, len(commitList))
+ def test_gitLogFailsWhenPassedAnAbsolutePath(self):
+ # Tests that you cannot pass an absolute file path to git log
+ gitClient = GitClient(os.getcwd())
+ subProjectDir = os.getcwd().split("frameworks/support/")[1]
+ subProjectDir = '/' + subProjectDir
+ self.assertRaises(RuntimeError, gitClient.getGitLog,
+ fromExclusiveSha = "",
+ untilInclusiveSha = "HEAD",
+ keepMerges = False,
+ subProjectDir = subProjectDir,
+ n = 1
+ )
+
def assertCommitsAreEqual(self, commitA, commitB):
self.assertEqual(commitA.summary, commitB.summary)
self.assertEqual(commitA.files, commitB.files)
diff --git a/fragment/fragment-ktx/api/1.3.0-alpha02.txt b/fragment/fragment-ktx/api/1.3.0-alpha02.txt
new file mode 100644
index 0000000..c8315cb
--- /dev/null
+++ b/fragment/fragment-ktx/api/1.3.0-alpha02.txt
@@ -0,0 +1,27 @@
+// Signature format: 3.0
+package androidx.fragment.app {
+
+ public final class FragmentManagerKt {
+ method public static inline void commit(androidx.fragment.app.FragmentManager, boolean allowStateLoss = false, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
+ method public static inline void commitNow(androidx.fragment.app.FragmentManager, boolean allowStateLoss = false, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
+ method @Deprecated public static inline void transaction(androidx.fragment.app.FragmentManager, boolean now = false, boolean allowStateLoss = false, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
+ }
+
+ public final class FragmentTransactionKt {
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction add(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, String? tag = null, android.os.Bundle? args = null);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction add(androidx.fragment.app.FragmentTransaction, String tag, android.os.Bundle? args = null);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction replace(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, String? tag = null, android.os.Bundle? args = null);
+ }
+
+ public final class FragmentViewModelLazyKt {
+ method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> activityViewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+ method @MainThread public static <VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> createViewModelLazy(androidx.fragment.app.Fragment, kotlin.reflect.KClass<VM> viewModelClass, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStore> storeProducer, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+ method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> viewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner> ownerProducer = { this }, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+ }
+
+ public final class ViewKt {
+ method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
+ }
+
+}
+
diff --git a/fragment/fragment-ktx/api/public_plus_experimental_1.3.0-alpha02.txt b/fragment/fragment-ktx/api/public_plus_experimental_1.3.0-alpha02.txt
new file mode 100644
index 0000000..c8315cb
--- /dev/null
+++ b/fragment/fragment-ktx/api/public_plus_experimental_1.3.0-alpha02.txt
@@ -0,0 +1,27 @@
+// Signature format: 3.0
+package androidx.fragment.app {
+
+ public final class FragmentManagerKt {
+ method public static inline void commit(androidx.fragment.app.FragmentManager, boolean allowStateLoss = false, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
+ method public static inline void commitNow(androidx.fragment.app.FragmentManager, boolean allowStateLoss = false, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
+ method @Deprecated public static inline void transaction(androidx.fragment.app.FragmentManager, boolean now = false, boolean allowStateLoss = false, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
+ }
+
+ public final class FragmentTransactionKt {
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction add(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, String? tag = null, android.os.Bundle? args = null);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction add(androidx.fragment.app.FragmentTransaction, String tag, android.os.Bundle? args = null);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction replace(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, String? tag = null, android.os.Bundle? args = null);
+ }
+
+ public final class FragmentViewModelLazyKt {
+ method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> activityViewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+ method @MainThread public static <VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> createViewModelLazy(androidx.fragment.app.Fragment, kotlin.reflect.KClass<VM> viewModelClass, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStore> storeProducer, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+ method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> viewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner> ownerProducer = { this }, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+ }
+
+ public final class ViewKt {
+ method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
+ }
+
+}
+
diff --git a/fragment/fragment-ktx/api/restricted_1.3.0-alpha02.txt b/fragment/fragment-ktx/api/restricted_1.3.0-alpha02.txt
new file mode 100644
index 0000000..c8315cb
--- /dev/null
+++ b/fragment/fragment-ktx/api/restricted_1.3.0-alpha02.txt
@@ -0,0 +1,27 @@
+// Signature format: 3.0
+package androidx.fragment.app {
+
+ public final class FragmentManagerKt {
+ method public static inline void commit(androidx.fragment.app.FragmentManager, boolean allowStateLoss = false, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
+ method public static inline void commitNow(androidx.fragment.app.FragmentManager, boolean allowStateLoss = false, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
+ method @Deprecated public static inline void transaction(androidx.fragment.app.FragmentManager, boolean now = false, boolean allowStateLoss = false, kotlin.jvm.functions.Function1<? super androidx.fragment.app.FragmentTransaction,kotlin.Unit> body);
+ }
+
+ public final class FragmentTransactionKt {
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction add(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, String? tag = null, android.os.Bundle? args = null);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction add(androidx.fragment.app.FragmentTransaction, String tag, android.os.Bundle? args = null);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.FragmentTransaction replace(androidx.fragment.app.FragmentTransaction, @IdRes int containerViewId, String? tag = null, android.os.Bundle? args = null);
+ }
+
+ public final class FragmentViewModelLazyKt {
+ method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> activityViewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+ method @MainThread public static <VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> createViewModelLazy(androidx.fragment.app.Fragment, kotlin.reflect.KClass<VM> viewModelClass, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStore> storeProducer, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+ method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> viewModels(androidx.fragment.app.Fragment, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelStoreOwner> ownerProducer = { this }, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+ }
+
+ public final class ViewKt {
+ method public static <F extends androidx.fragment.app.Fragment> F findFragment(android.view.View);
+ }
+
+}
+
diff --git a/fragment/fragment-testing/api/1.3.0-alpha02.txt b/fragment/fragment-testing/api/1.3.0-alpha02.txt
new file mode 100644
index 0000000..ac1542b
--- /dev/null
+++ b/fragment/fragment-testing/api/1.3.0-alpha02.txt
@@ -0,0 +1,30 @@
+// Signature format: 3.0
+package androidx.fragment.app.testing {
+
+ public final class FragmentScenario<F extends androidx.fragment.app.Fragment> {
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>, android.os.Bundle?);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>, android.os.Bundle?, androidx.fragment.app.FragmentFactory?);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>, android.os.Bundle?, @StyleRes int, androidx.fragment.app.FragmentFactory?);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>, android.os.Bundle?);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>, android.os.Bundle?, androidx.fragment.app.FragmentFactory?);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>, android.os.Bundle?, @StyleRes int, androidx.fragment.app.FragmentFactory?);
+ method public androidx.fragment.app.testing.FragmentScenario<F!> moveToState(androidx.lifecycle.Lifecycle.State);
+ method public androidx.fragment.app.testing.FragmentScenario<F!> onFragment(androidx.fragment.app.testing.FragmentScenario.FragmentAction<F!>);
+ method public androidx.fragment.app.testing.FragmentScenario<F!> recreate();
+ }
+
+ public static interface FragmentScenario.FragmentAction<F extends androidx.fragment.app.Fragment> {
+ method public void perform(F);
+ }
+
+ public final class FragmentScenarioKt {
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragment(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, androidx.fragment.app.FragmentFactory? factory = null);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragment(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, kotlin.jvm.functions.Function0<? extends F> instantiate);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragmentInContainer(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, androidx.fragment.app.FragmentFactory? factory = null);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragmentInContainer(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, kotlin.jvm.functions.Function0<? extends F> instantiate);
+ }
+
+}
+
diff --git a/fragment/fragment-testing/api/public_plus_experimental_1.3.0-alpha02.txt b/fragment/fragment-testing/api/public_plus_experimental_1.3.0-alpha02.txt
new file mode 100644
index 0000000..ac1542b
--- /dev/null
+++ b/fragment/fragment-testing/api/public_plus_experimental_1.3.0-alpha02.txt
@@ -0,0 +1,30 @@
+// Signature format: 3.0
+package androidx.fragment.app.testing {
+
+ public final class FragmentScenario<F extends androidx.fragment.app.Fragment> {
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>, android.os.Bundle?);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>, android.os.Bundle?, androidx.fragment.app.FragmentFactory?);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>, android.os.Bundle?, @StyleRes int, androidx.fragment.app.FragmentFactory?);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>, android.os.Bundle?);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>, android.os.Bundle?, androidx.fragment.app.FragmentFactory?);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>, android.os.Bundle?, @StyleRes int, androidx.fragment.app.FragmentFactory?);
+ method public androidx.fragment.app.testing.FragmentScenario<F!> moveToState(androidx.lifecycle.Lifecycle.State);
+ method public androidx.fragment.app.testing.FragmentScenario<F!> onFragment(androidx.fragment.app.testing.FragmentScenario.FragmentAction<F!>);
+ method public androidx.fragment.app.testing.FragmentScenario<F!> recreate();
+ }
+
+ public static interface FragmentScenario.FragmentAction<F extends androidx.fragment.app.Fragment> {
+ method public void perform(F);
+ }
+
+ public final class FragmentScenarioKt {
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragment(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, androidx.fragment.app.FragmentFactory? factory = null);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragment(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, kotlin.jvm.functions.Function0<? extends F> instantiate);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragmentInContainer(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, androidx.fragment.app.FragmentFactory? factory = null);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragmentInContainer(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, kotlin.jvm.functions.Function0<? extends F> instantiate);
+ }
+
+}
+
diff --git a/lifecycle/lifecycle-extensions/api/res-2.3.0-alpha02.txt b/fragment/fragment-testing/api/res-1.3.0-alpha02.txt
similarity index 100%
rename from lifecycle/lifecycle-extensions/api/res-2.3.0-alpha02.txt
rename to fragment/fragment-testing/api/res-1.3.0-alpha02.txt
diff --git a/fragment/fragment-testing/api/restricted_1.3.0-alpha02.txt b/fragment/fragment-testing/api/restricted_1.3.0-alpha02.txt
new file mode 100644
index 0000000..ac1542b
--- /dev/null
+++ b/fragment/fragment-testing/api/restricted_1.3.0-alpha02.txt
@@ -0,0 +1,30 @@
+// Signature format: 3.0
+package androidx.fragment.app.testing {
+
+ public final class FragmentScenario<F extends androidx.fragment.app.Fragment> {
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>, android.os.Bundle?);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>, android.os.Bundle?, androidx.fragment.app.FragmentFactory?);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launch(Class<F!>, android.os.Bundle?, @StyleRes int, androidx.fragment.app.FragmentFactory?);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>, android.os.Bundle?);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>, android.os.Bundle?, androidx.fragment.app.FragmentFactory?);
+ method public static <F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F!> launchInContainer(Class<F!>, android.os.Bundle?, @StyleRes int, androidx.fragment.app.FragmentFactory?);
+ method public androidx.fragment.app.testing.FragmentScenario<F!> moveToState(androidx.lifecycle.Lifecycle.State);
+ method public androidx.fragment.app.testing.FragmentScenario<F!> onFragment(androidx.fragment.app.testing.FragmentScenario.FragmentAction<F!>);
+ method public androidx.fragment.app.testing.FragmentScenario<F!> recreate();
+ }
+
+ public static interface FragmentScenario.FragmentAction<F extends androidx.fragment.app.Fragment> {
+ method public void perform(F);
+ }
+
+ public final class FragmentScenarioKt {
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragment(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, androidx.fragment.app.FragmentFactory? factory = null);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragment(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, kotlin.jvm.functions.Function0<? extends F> instantiate);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragmentInContainer(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, androidx.fragment.app.FragmentFactory? factory = null);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> androidx.fragment.app.testing.FragmentScenario<F> launchFragmentInContainer(android.os.Bundle? fragmentArgs = null, @StyleRes int themeResId = R.style.FragmentScenarioEmptyFragmentActivityTheme, kotlin.jvm.functions.Function0<? extends F> instantiate);
+ }
+
+}
+
diff --git a/fragment/fragment-testing/src/androidTest/java/androidx/fragment/app/testing/SimpleDialogFragment.kt b/fragment/fragment-testing/src/androidTest/java/androidx/fragment/app/testing/SimpleDialogFragment.kt
index f5bd569..5de4d78 100644
--- a/fragment/fragment-testing/src/androidTest/java/androidx/fragment/app/testing/SimpleDialogFragment.kt
+++ b/fragment/fragment-testing/src/androidTest/java/androidx/fragment/app/testing/SimpleDialogFragment.kt
@@ -1,19 +1,9 @@
package androidx.fragment.app.testing
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
import androidx.fragment.app.DialogFragment
import androidx.fragment.testing.test.R
/**
* A dialog fragment with a button to demonstrate unit testing.
*/
-class SimpleDialogFragment : DialogFragment() {
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? = inflater.inflate(R.layout.fragment_simple_dialog, container, false)
-}
\ No newline at end of file
+class SimpleDialogFragment : DialogFragment(R.layout.fragment_simple_dialog)
diff --git a/fragment/fragment/api/1.3.0-alpha02.txt b/fragment/fragment/api/1.3.0-alpha02.txt
index 28045cc4..67a8903 100644
--- a/fragment/fragment/api/1.3.0-alpha02.txt
+++ b/fragment/fragment/api/1.3.0-alpha02.txt
@@ -3,6 +3,7 @@
public class DialogFragment extends androidx.fragment.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
ctor public DialogFragment();
+ ctor public DialogFragment(@LayoutRes int);
method public void dismiss();
method public void dismissAllowingStateLoss();
method public android.app.Dialog? getDialog();
@@ -25,7 +26,7 @@
field public static final int STYLE_NO_TITLE = 1; // 0x1
}
- public class Fragment implements android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
+ public class Fragment implements androidx.activity.result.ActivityResultCaller android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
ctor public Fragment();
ctor @ContentView public Fragment(@LayoutRes int);
method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
@@ -114,6 +115,8 @@
method @CallSuper @MainThread public void onViewStateRestored(android.os.Bundle?);
method public void postponeEnterTransition();
method public final void postponeEnterTransition(long, java.util.concurrent.TimeUnit);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
method public void registerForContextMenu(android.view.View);
method public final void requestPermissions(String![], int);
method public final androidx.fragment.app.FragmentActivity requireActivity();
@@ -163,7 +166,6 @@
public class FragmentActivity extends androidx.activity.ComponentActivity implements androidx.core.app.ActivityCompat.OnRequestPermissionsResultCallback androidx.lifecycle.LifecycleOwner {
ctor public FragmentActivity();
ctor @ContentView public FragmentActivity(@LayoutRes int);
- method public androidx.lifecycle.Lifecycle getLifecycle();
method public androidx.fragment.app.FragmentManager getSupportFragmentManager();
method @Deprecated public androidx.loader.app.LoaderManager getSupportLoaderManager();
method public void onAttachFragment(androidx.fragment.app.Fragment);
diff --git a/fragment/fragment/api/current.txt b/fragment/fragment/api/current.txt
index 5610308..67a8903 100644
--- a/fragment/fragment/api/current.txt
+++ b/fragment/fragment/api/current.txt
@@ -3,6 +3,7 @@
public class DialogFragment extends androidx.fragment.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
ctor public DialogFragment();
+ ctor public DialogFragment(@LayoutRes int);
method public void dismiss();
method public void dismissAllowingStateLoss();
method public android.app.Dialog? getDialog();
@@ -25,7 +26,7 @@
field public static final int STYLE_NO_TITLE = 1; // 0x1
}
- public class Fragment implements android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
+ public class Fragment implements androidx.activity.result.ActivityResultCaller android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
ctor public Fragment();
ctor @ContentView public Fragment(@LayoutRes int);
method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
@@ -114,6 +115,8 @@
method @CallSuper @MainThread public void onViewStateRestored(android.os.Bundle?);
method public void postponeEnterTransition();
method public final void postponeEnterTransition(long, java.util.concurrent.TimeUnit);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
method public void registerForContextMenu(android.view.View);
method public final void requestPermissions(String![], int);
method public final androidx.fragment.app.FragmentActivity requireActivity();
diff --git a/fragment/fragment/api/public_plus_experimental_1.3.0-alpha02.txt b/fragment/fragment/api/public_plus_experimental_1.3.0-alpha02.txt
index 24697ad..9b1ce92 100644
--- a/fragment/fragment/api/public_plus_experimental_1.3.0-alpha02.txt
+++ b/fragment/fragment/api/public_plus_experimental_1.3.0-alpha02.txt
@@ -3,6 +3,7 @@
public class DialogFragment extends androidx.fragment.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
ctor public DialogFragment();
+ ctor public DialogFragment(@LayoutRes int);
method public void dismiss();
method public void dismissAllowingStateLoss();
method public android.app.Dialog? getDialog();
@@ -25,7 +26,7 @@
field public static final int STYLE_NO_TITLE = 1; // 0x1
}
- public class Fragment implements android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
+ public class Fragment implements androidx.activity.result.ActivityResultCaller android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
ctor public Fragment();
ctor @ContentView public Fragment(@LayoutRes int);
method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
@@ -114,6 +115,8 @@
method @CallSuper @MainThread public void onViewStateRestored(android.os.Bundle?);
method public void postponeEnterTransition();
method public final void postponeEnterTransition(long, java.util.concurrent.TimeUnit);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
method public void registerForContextMenu(android.view.View);
method public final void requestPermissions(String![], int);
method public final androidx.fragment.app.FragmentActivity requireActivity();
diff --git a/fragment/fragment/api/public_plus_experimental_current.txt b/fragment/fragment/api/public_plus_experimental_current.txt
index 24697ad..9b1ce92 100644
--- a/fragment/fragment/api/public_plus_experimental_current.txt
+++ b/fragment/fragment/api/public_plus_experimental_current.txt
@@ -3,6 +3,7 @@
public class DialogFragment extends androidx.fragment.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
ctor public DialogFragment();
+ ctor public DialogFragment(@LayoutRes int);
method public void dismiss();
method public void dismissAllowingStateLoss();
method public android.app.Dialog? getDialog();
@@ -25,7 +26,7 @@
field public static final int STYLE_NO_TITLE = 1; // 0x1
}
- public class Fragment implements android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
+ public class Fragment implements androidx.activity.result.ActivityResultCaller android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
ctor public Fragment();
ctor @ContentView public Fragment(@LayoutRes int);
method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
@@ -114,6 +115,8 @@
method @CallSuper @MainThread public void onViewStateRestored(android.os.Bundle?);
method public void postponeEnterTransition();
method public final void postponeEnterTransition(long, java.util.concurrent.TimeUnit);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
method public void registerForContextMenu(android.view.View);
method public final void requestPermissions(String![], int);
method public final androidx.fragment.app.FragmentActivity requireActivity();
diff --git a/fragment/fragment/api/restricted_1.3.0-alpha02.txt b/fragment/fragment/api/restricted_1.3.0-alpha02.txt
index ab6560d..c0f920f 100644
--- a/fragment/fragment/api/restricted_1.3.0-alpha02.txt
+++ b/fragment/fragment/api/restricted_1.3.0-alpha02.txt
@@ -3,6 +3,7 @@
public class DialogFragment extends androidx.fragment.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
ctor public DialogFragment();
+ ctor public DialogFragment(@LayoutRes int);
method public void dismiss();
method public void dismissAllowingStateLoss();
method public android.app.Dialog? getDialog();
@@ -26,7 +27,7 @@
field public static final int STYLE_NO_TITLE = 1; // 0x1
}
- public class Fragment implements android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
+ public class Fragment implements androidx.activity.result.ActivityResultCaller android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
ctor public Fragment();
ctor @ContentView public Fragment(@LayoutRes int);
method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
@@ -118,6 +119,8 @@
method @CallSuper @MainThread public void onViewStateRestored(android.os.Bundle?);
method public void postponeEnterTransition();
method public final void postponeEnterTransition(long, java.util.concurrent.TimeUnit);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
method public void registerForContextMenu(android.view.View);
method public final void requestPermissions(String![], int);
method public final androidx.fragment.app.FragmentActivity requireActivity();
diff --git a/fragment/fragment/api/restricted_current.txt b/fragment/fragment/api/restricted_current.txt
index ab6560d..c0f920f 100644
--- a/fragment/fragment/api/restricted_current.txt
+++ b/fragment/fragment/api/restricted_current.txt
@@ -3,6 +3,7 @@
public class DialogFragment extends androidx.fragment.app.Fragment implements android.content.DialogInterface.OnCancelListener android.content.DialogInterface.OnDismissListener {
ctor public DialogFragment();
+ ctor public DialogFragment(@LayoutRes int);
method public void dismiss();
method public void dismissAllowingStateLoss();
method public android.app.Dialog? getDialog();
@@ -26,7 +27,7 @@
field public static final int STYLE_NO_TITLE = 1; // 0x1
}
- public class Fragment implements android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
+ public class Fragment implements androidx.activity.result.ActivityResultCaller android.content.ComponentCallbacks androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner android.view.View.OnCreateContextMenuListener androidx.lifecycle.ViewModelStoreOwner {
ctor public Fragment();
ctor @ContentView public Fragment(@LayoutRes int);
method public void dump(String, java.io.FileDescriptor?, java.io.PrintWriter, String![]?);
@@ -118,6 +119,8 @@
method @CallSuper @MainThread public void onViewStateRestored(android.os.Bundle?);
method public void postponeEnterTransition();
method public final void postponeEnterTransition(long, java.util.concurrent.TimeUnit);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultCallback<O!>);
+ method public <I, O> androidx.activity.result.ActivityResultLauncher<I!> prepareCall(androidx.activity.result.contract.ActivityResultContract<I!,O!>, androidx.activity.result.ActivityResultRegistry, androidx.activity.result.ActivityResultCallback<O!>);
method public void registerForContextMenu(android.view.View);
method public final void requestPermissions(String![], int);
method public final androidx.fragment.app.FragmentActivity requireActivity();
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/DialogFragment.java b/fragment/fragment/src/main/java/androidx/fragment/app/DialogFragment.java
index 43d24a4..a8c1715 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/DialogFragment.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/DialogFragment.java
@@ -18,6 +18,7 @@
import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX;
+import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
@@ -32,6 +33,7 @@
import android.view.WindowManager;
import androidx.annotation.IntDef;
+import androidx.annotation.LayoutRes;
import androidx.annotation.MainThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -92,14 +94,16 @@
private Handler mHandler;
private Runnable mDismissRunnable = new Runnable() {
+ @SuppressLint("SyntheticAccessor")
@Override
public void run() {
mOnDismissListener.onDismiss(mDialog);
}
};
- DialogInterface.OnCancelListener mOnCancelListener =
+ private DialogInterface.OnCancelListener mOnCancelListener =
new DialogInterface.OnCancelListener() {
+ @SuppressLint("SyntheticAccessor")
@Override
public void onCancel(@Nullable DialogInterface dialog) {
if (mDialog != null) {
@@ -108,8 +112,9 @@
}
};
- DialogInterface.OnDismissListener mOnDismissListener =
+ private DialogInterface.OnDismissListener mOnDismissListener =
new DialogInterface.OnDismissListener() {
+ @SuppressLint("SyntheticAccessor")
@Override
public void onDismiss(@Nullable DialogInterface dialog) {
if (mDialog != null) {
@@ -118,18 +123,47 @@
}
};
- int mStyle = STYLE_NORMAL;
- int mTheme = 0;
- boolean mCancelable = true;
- boolean mShowsDialog = true;
- int mBackStackId = -1;
+ private int mStyle = STYLE_NORMAL;
+ private int mTheme = 0;
+ private boolean mCancelable = true;
+ private boolean mShowsDialog = true;
+ private int mBackStackId = -1;
- @Nullable Dialog mDialog;
- boolean mViewDestroyed;
- boolean mDismissed;
- boolean mShownByMe;
+ @Nullable
+ private Dialog mDialog;
+ private boolean mViewDestroyed;
+ private boolean mDismissed;
+ private boolean mShownByMe;
+
+ /**
+ * Constructor used by the default {@link FragmentFactory}. You must
+ * {@link FragmentManager#setFragmentFactory(FragmentFactory) set a custom FragmentFactory}
+ * if you want to use a non-default constructor to ensure that your constructor
+ * is called when the fragment is re-instantiated.
+ *
+ * <p>It is strongly recommended to supply arguments with {@link #setArguments}
+ * and later retrieved by the Fragment with {@link #getArguments}. These arguments
+ * are automatically saved and restored alongside the Fragment.
+ *
+ * <p>Applications should generally not implement a constructor. Prefer
+ * {@link #onAttach(Context)} instead. It is the first place application code can run where
+ * the fragment is ready to be used - the point where the fragment is actually associated with
+ * its context.
+ */
public DialogFragment() {
+ super();
+ }
+
+ /**
+ * Alternate constructor that can be used to provide a default layout
+ * that will be inflated by {@link #onCreateView(LayoutInflater, ViewGroup, Bundle)}.
+ *
+ * @see #DialogFragment()
+ * @see #onCreateView(LayoutInflater, ViewGroup, Bundle)
+ */
+ public DialogFragment(@LayoutRes int contentLayoutId) {
+ super(contentLayoutId);
}
/**
@@ -232,7 +266,7 @@
dismissInternal(true, false);
}
- void dismissInternal(boolean allowStateLoss, boolean fromOnDismiss) {
+ private void dismissInternal(boolean allowStateLoss, boolean fromOnDismiss) {
if (mDismissed) {
return;
}
@@ -402,13 +436,9 @@
mDialog = onCreateDialog(savedInstanceState);
- if (mDialog != null) {
- setupDialog(mDialog, mStyle);
+ setupDialog(mDialog, mStyle);
- return (LayoutInflater) mDialog.getContext().getSystemService(
- Context.LAYOUT_INFLATER_SERVICE);
- }
- return (LayoutInflater) mHost.getContext().getSystemService(
+ return (LayoutInflater) mDialog.getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
}
@@ -417,9 +447,11 @@
public void setupDialog(@NonNull Dialog dialog, int style) {
switch (style) {
case STYLE_NO_INPUT:
- dialog.getWindow().addFlags(
- WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
- WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
+ Window window = dialog.getWindow();
+ if (window != null) {
+ window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+ | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
+ }
// fall through...
case STYLE_NO_FRAME:
case STYLE_NO_TITLE:
@@ -480,24 +512,26 @@
}
View view = getView();
- if (view != null) {
- if (view.getParent() != null) {
- throw new IllegalStateException(
- "DialogFragment can not be attached to a container view");
+ if (mDialog != null) {
+ if (view != null) {
+ if (view.getParent() != null) {
+ throw new IllegalStateException(
+ "DialogFragment can not be attached to a container view");
+ }
+ mDialog.setContentView(view);
}
- mDialog.setContentView(view);
- }
- final Activity activity = getActivity();
- if (activity != null) {
- mDialog.setOwnerActivity(activity);
- }
- mDialog.setCancelable(mCancelable);
- mDialog.setOnCancelListener(mOnCancelListener);
- mDialog.setOnDismissListener(mOnDismissListener);
- if (savedInstanceState != null) {
- Bundle dialogState = savedInstanceState.getBundle(SAVED_DIALOG_STATE_TAG);
- if (dialogState != null) {
- mDialog.onRestoreInstanceState(dialogState);
+ final Activity activity = getActivity();
+ if (activity != null) {
+ mDialog.setOwnerActivity(activity);
+ }
+ mDialog.setCancelable(mCancelable);
+ mDialog.setOnCancelListener(mOnCancelListener);
+ mDialog.setOnDismissListener(mOnDismissListener);
+ if (savedInstanceState != null) {
+ Bundle dialogState = savedInstanceState.getBundle(SAVED_DIALOG_STATE_TAG);
+ if (dialogState != null) {
+ mDialog.onRestoreInstanceState(dialogState);
+ }
}
}
}
@@ -519,9 +553,7 @@
super.onSaveInstanceState(outState);
if (mDialog != null) {
Bundle dialogState = mDialog.onSaveInstanceState();
- if (dialogState != null) {
- outState.putBundle(SAVED_DIALOG_STATE_TAG, dialogState);
- }
+ outState.putBundle(SAVED_DIALOG_STATE_TAG, dialogState);
}
if (mStyle != STYLE_NORMAL) {
outState.putInt(SAVED_STYLE, mStyle);
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java b/fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
index 7caaafa..d185b7c 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/Fragment.java
@@ -47,6 +47,11 @@
import android.view.animation.Animation;
import android.widget.AdapterView;
+import androidx.activity.result.ActivityResultCallback;
+import androidx.activity.result.ActivityResultCaller;
+import androidx.activity.result.ActivityResultLauncher;
+import androidx.activity.result.ActivityResultRegistry;
+import androidx.activity.result.contract.ActivityResultContract;
import androidx.annotation.CallSuper;
import androidx.annotation.ContentView;
import androidx.annotation.LayoutRes;
@@ -80,6 +85,8 @@
import java.lang.reflect.InvocationTargetException;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
/**
* Static library support version of the framework's {@link android.app.Fragment}.
@@ -97,7 +104,8 @@
*
*/
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner,
- ViewModelStoreOwner, HasDefaultViewModelProviderFactory, SavedStateRegistryOwner {
+ ViewModelStoreOwner, HasDefaultViewModelProviderFactory, SavedStateRegistryOwner,
+ ActivityResultCaller {
static final Object USE_DEFAULT_TRANSITION = new Object();
@@ -277,6 +285,8 @@
@LayoutRes
private int mContentLayoutId;
+ private final AtomicInteger mNextLocalRequestCode = new AtomicInteger();
+
/**
* {@inheritDoc}
* <p>
@@ -3096,6 +3106,65 @@
ensureAnimationInfo().mIsHideReplaced = replaced;
}
+ @NonNull
+ @Override
+ public <I, O> ActivityResultLauncher<I> prepareCall(
+ @NonNull final ActivityResultContract<I, O> contract,
+ @NonNull final ActivityResultCallback<O> callback) {
+ final String key = generateActivityResultKey();
+ final AtomicReference<ActivityResultLauncher<I>> ref =
+ new AtomicReference<ActivityResultLauncher<I>>();
+
+ getLifecycle().addObserver(new LifecycleEventObserver() {
+ @Override
+ public void onStateChanged(@NonNull LifecycleOwner lifecycleOwner,
+ @NonNull Lifecycle.Event event) {
+
+ if (Lifecycle.Event.ON_CREATE.equals(event)) {
+ ref.set(getActivity()
+ .getActivityResultRegistry()
+ .registerActivityResultCallback(
+ key, Fragment.this, contract, callback));
+ }
+ }
+ });
+
+ return new ActivityResultLauncher<I>() {
+ @Override
+ public void launch(I input) {
+ ActivityResultLauncher<I> delegate = ref.get();
+ if (delegate == null) {
+ throw new IllegalStateException("Operation cannot be started before fragment "
+ + "is in created state");
+ }
+ delegate.launch(input);
+ }
+
+ @Override
+ public void dispose() {
+ ActivityResultLauncher<I> delegate = ref.getAndSet(null);
+ if (delegate != null) {
+ delegate.dispose();
+ }
+ }
+ };
+ }
+
+ @NonNull
+ private String generateActivityResultKey() {
+ return "fragment_" + mWho + "_rq#" + mNextLocalRequestCode.getAndIncrement();
+ }
+
+ @NonNull
+ @Override
+ public <I, O> ActivityResultLauncher<I> prepareCall(
+ @NonNull final ActivityResultContract<I, O> contract,
+ @NonNull ActivityResultRegistry registry,
+ @NonNull final ActivityResultCallback<O> callback) {
+ return registry.registerActivityResultCallback(
+ generateActivityResultKey(), this, contract, callback);
+ }
+
/**
* Used internally to be notified when {@link #startPostponedEnterTransition()} has
* been called. This listener will only be called once and then be removed from the
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentActivity.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentActivity.java
index 1e98e88..4dcfe51 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentActivity.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentActivity.java
@@ -754,10 +754,12 @@
*
* @see #requestPermissions(String[], int)
*/
+ @CallSuper
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
@NonNull int[] grantResults) {
mFragments.noteStateNotSaved();
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
int index = (requestCode >> 16) & 0xffff;
if (index != 0) {
index--;
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentStateManager.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentStateManager.java
index 84ddff6..17cd180 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentStateManager.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentStateManager.java
@@ -310,6 +310,7 @@
case Fragment.AWAITING_ENTER_EFFECTS:
// There's no enter effects when moving the state downward
mFragment.mState = Fragment.AWAITING_ENTER_EFFECTS;
+ break;
case Fragment.STARTED:
pause();
break;
diff --git a/gradle.properties b/gradle.properties
index 0dbc99d..d27e92a 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -14,7 +14,6 @@
android.useNewJarCreator=false
# Workaround for b/141364941
android.forceJacocoOutOfProcess=true
-android.namespacedRClass=true
# Gradle duplicate detection does not handle :core:core https://github.com/gradle/gradle/issues/12315
systemProp.org.gradle.dependency.duplicate.project.detection=false
\ No newline at end of file
diff --git a/gradlew b/gradlew
index f72592d..c82f27b 100755
--- a/gradlew
+++ b/gradlew
@@ -218,9 +218,6 @@
if [ -n "$DIST_DIR" ]; then
cp -r "$GRADLE_USER_HOME/daemon" "$DIST_DIR/gradle-daemon"
cp ./hs_err* $DIST_DIR/ 2>/dev/null || true
- # TODO (146217083): consider removing these after the Gradle daemons stop occasionally dying
- dmesg | tail -n 40 || true
- echo "Current java processes: '$(ps -eF | grep java)'"
fi
fi
}
diff --git a/leanback/leanback/src/main/java/androidx/leanback/widget/GridLayoutManager.java b/leanback/leanback/src/main/java/androidx/leanback/widget/GridLayoutManager.java
index 9ecb90d..4e4fcdd 100644
--- a/leanback/leanback/src/main/java/androidx/leanback/widget/GridLayoutManager.java
+++ b/leanback/leanback/src/main/java/androidx/leanback/widget/GridLayoutManager.java
@@ -2078,8 +2078,8 @@
@Override
public void onLayoutCompleted(State state) {
if (mOnLayoutCompletedListeners != null) {
- for (BaseGridView.OnLayoutCompletedListener listener : mOnLayoutCompletedListeners) {
- listener.onLayoutCompleted(state);
+ for (int i = mOnLayoutCompletedListeners.size() - 1; i >= 0; i--) {
+ mOnLayoutCompletedListeners.get(i).onLayoutCompleted(state);
}
}
}
diff --git a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/Lifecycle.java b/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/Lifecycle.java
index 6fd66bd8..78e9f92 100644
--- a/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/Lifecycle.java
+++ b/lifecycle/lifecycle-common/src/main/java/androidx/lifecycle/Lifecycle.java
@@ -39,8 +39,8 @@
* This gives you certain guarantees on which state the owner is in.
* <p>
* If you use <b>Java 8 Language</b>, then observe events with {@link DefaultLifecycleObserver}.
- * To include it you should add {@code "androidx.lifecycle:common-java8:<version>"} to your
- * build.gradle file.
+ * To include it you should add {@code "androidx.lifecycle:lifecycle-common-java8:<version>"} to
+ * your build.gradle file.
* <pre>
* class TestObserver implements DefaultLifecycleObserver {
* {@literal @}Override
diff --git a/lifecycle/lifecycle-extensions/api/2.3.0-alpha01.txt b/lifecycle/lifecycle-extensions/api/2.2.0.txt
similarity index 100%
rename from lifecycle/lifecycle-extensions/api/2.3.0-alpha01.txt
rename to lifecycle/lifecycle-extensions/api/2.2.0.txt
diff --git a/lifecycle/lifecycle-extensions/api/2.3.0-alpha01.txt b/lifecycle/lifecycle-extensions/api/public_plus_experimental_2.2.0.txt
similarity index 100%
copy from lifecycle/lifecycle-extensions/api/2.3.0-alpha01.txt
copy to lifecycle/lifecycle-extensions/api/public_plus_experimental_2.2.0.txt
diff --git a/lifecycle/lifecycle-extensions/api/public_plus_experimental_2.3.0-alpha01.txt b/lifecycle/lifecycle-extensions/api/public_plus_experimental_2.3.0-alpha01.txt
deleted file mode 100644
index 273ffbf..0000000
--- a/lifecycle/lifecycle-extensions/api/public_plus_experimental_2.3.0-alpha01.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-// Signature format: 3.0
-package androidx.lifecycle {
-
- @Deprecated public class ViewModelProviders {
- ctor @Deprecated public ViewModelProviders();
- method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.Fragment);
- method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.FragmentActivity);
- method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.Fragment, androidx.lifecycle.ViewModelProvider.Factory?);
- method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.FragmentActivity, androidx.lifecycle.ViewModelProvider.Factory?);
- }
-
- @Deprecated public static class ViewModelProviders.DefaultFactory extends androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory {
- ctor @Deprecated public ViewModelProviders.DefaultFactory(android.app.Application);
- }
-
- @Deprecated public class ViewModelStores {
- method @Deprecated @MainThread public static androidx.lifecycle.ViewModelStore of(androidx.fragment.app.FragmentActivity);
- method @Deprecated @MainThread public static androidx.lifecycle.ViewModelStore of(androidx.fragment.app.Fragment);
- }
-
-}
-
diff --git a/lifecycle/lifecycle-extensions/api/res-2.3.0-alpha01.txt b/lifecycle/lifecycle-extensions/api/res-2.2.0.txt
similarity index 100%
rename from lifecycle/lifecycle-extensions/api/res-2.3.0-alpha01.txt
rename to lifecycle/lifecycle-extensions/api/res-2.2.0.txt
diff --git a/lifecycle/lifecycle-extensions/api/2.3.0-alpha01.txt b/lifecycle/lifecycle-extensions/api/restricted_2.2.0.txt
similarity index 100%
copy from lifecycle/lifecycle-extensions/api/2.3.0-alpha01.txt
copy to lifecycle/lifecycle-extensions/api/restricted_2.2.0.txt
diff --git a/lifecycle/lifecycle-extensions/api/restricted_2.3.0-alpha01.txt b/lifecycle/lifecycle-extensions/api/restricted_2.3.0-alpha01.txt
deleted file mode 100644
index 273ffbf..0000000
--- a/lifecycle/lifecycle-extensions/api/restricted_2.3.0-alpha01.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-// Signature format: 3.0
-package androidx.lifecycle {
-
- @Deprecated public class ViewModelProviders {
- ctor @Deprecated public ViewModelProviders();
- method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.Fragment);
- method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.FragmentActivity);
- method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.Fragment, androidx.lifecycle.ViewModelProvider.Factory?);
- method @Deprecated @MainThread public static androidx.lifecycle.ViewModelProvider of(androidx.fragment.app.FragmentActivity, androidx.lifecycle.ViewModelProvider.Factory?);
- }
-
- @Deprecated public static class ViewModelProviders.DefaultFactory extends androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory {
- ctor @Deprecated public ViewModelProviders.DefaultFactory(android.app.Application);
- }
-
- @Deprecated public class ViewModelStores {
- method @Deprecated @MainThread public static androidx.lifecycle.ViewModelStore of(androidx.fragment.app.FragmentActivity);
- method @Deprecated @MainThread public static androidx.lifecycle.ViewModelStore of(androidx.fragment.app.Fragment);
- }
-
-}
-
diff --git a/lifecycle/lifecycle-extensions/build.gradle b/lifecycle/lifecycle-extensions/build.gradle
index fcd605f..705d120 100644
--- a/lifecycle/lifecycle-extensions/build.gradle
+++ b/lifecycle/lifecycle-extensions/build.gradle
@@ -27,15 +27,15 @@
}
dependencies {
- api(project(":lifecycle:lifecycle-runtime"))
+ api("androidx.lifecycle:lifecycle-runtime:2.2.0")
api("androidx.arch.core:core-common:2.1.0")
api("androidx.arch.core:core-runtime:2.1.0")
- api(project(":fragment:fragment"))
- api(project(":lifecycle:lifecycle-common"))
- api(project(":lifecycle:lifecycle-livedata"))
- api(project(":lifecycle:lifecycle-process"))
- api(project(":lifecycle:lifecycle-service"))
- api(project(":lifecycle:lifecycle-viewmodel"))
+ api("androidx.fragment:fragment:1.2.0")
+ api("androidx.lifecycle:lifecycle-common:2.2.0")
+ api("androidx.lifecycle:lifecycle-livedata:2.2.0")
+ api("androidx.lifecycle:lifecycle-process:2.2.0")
+ api("androidx.lifecycle:lifecycle-service:2.2.0")
+ api("androidx.lifecycle:lifecycle-viewmodel:2.2.0")
testImplementation("androidx.arch.core:core-testing:2.1.0")
testImplementation(JUNIT)
diff --git a/lifecycle/lifecycle-livedata-ktx/api/2.3.0-alpha02.txt b/lifecycle/lifecycle-livedata-ktx/api/2.3.0-alpha02.txt
new file mode 100644
index 0000000..b5a6b57
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/api/2.3.0-alpha02.txt
@@ -0,0 +1,31 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+ public final class CoroutineLiveDataKt {
+ method public static <T> androidx.lifecycle.LiveData<T> liveData(kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> liveData(kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, java.time.Duration timeout, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+ }
+
+ public final class FlowLiveDataConversions {
+ method public static <T> kotlinx.coroutines.flow.Flow<T> asFlow(androidx.lifecycle.LiveData<T>);
+ method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L);
+ method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext);
+ method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, java.time.Duration timeout);
+ }
+
+ public interface LiveDataScope<T> {
+ method public suspend Object! emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+ method public suspend Object emitSource(androidx.lifecycle.LiveData<T> source, kotlin.coroutines.Continuation<? super kotlinx.coroutines.DisposableHandle> p);
+ method public T? getLatestValue();
+ property public abstract T? latestValue;
+ }
+
+ public final class TransformationsKt {
+ method public static inline <X> androidx.lifecycle.LiveData<X> distinctUntilChanged(androidx.lifecycle.LiveData<X>);
+ method public static inline <X, Y> androidx.lifecycle.LiveData<Y> map(androidx.lifecycle.LiveData<X>, kotlin.jvm.functions.Function1<? super X,? extends Y> transform);
+ method public static inline <X, Y> androidx.lifecycle.LiveData<Y> switchMap(androidx.lifecycle.LiveData<X>, kotlin.jvm.functions.Function1<? super X,? extends androidx.lifecycle.LiveData<Y>> transform);
+ }
+
+}
+
diff --git a/lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_2.3.0-alpha02.txt b/lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_2.3.0-alpha02.txt
new file mode 100644
index 0000000..b5a6b57
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/api/public_plus_experimental_2.3.0-alpha02.txt
@@ -0,0 +1,31 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+ public final class CoroutineLiveDataKt {
+ method public static <T> androidx.lifecycle.LiveData<T> liveData(kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> liveData(kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, java.time.Duration timeout, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+ }
+
+ public final class FlowLiveDataConversions {
+ method public static <T> kotlinx.coroutines.flow.Flow<T> asFlow(androidx.lifecycle.LiveData<T>);
+ method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L);
+ method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext);
+ method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, java.time.Duration timeout);
+ }
+
+ public interface LiveDataScope<T> {
+ method public suspend Object! emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+ method public suspend Object emitSource(androidx.lifecycle.LiveData<T> source, kotlin.coroutines.Continuation<? super kotlinx.coroutines.DisposableHandle> p);
+ method public T? getLatestValue();
+ property public abstract T? latestValue;
+ }
+
+ public final class TransformationsKt {
+ method public static inline <X> androidx.lifecycle.LiveData<X> distinctUntilChanged(androidx.lifecycle.LiveData<X>);
+ method public static inline <X, Y> androidx.lifecycle.LiveData<Y> map(androidx.lifecycle.LiveData<X>, kotlin.jvm.functions.Function1<? super X,? extends Y> transform);
+ method public static inline <X, Y> androidx.lifecycle.LiveData<Y> switchMap(androidx.lifecycle.LiveData<X>, kotlin.jvm.functions.Function1<? super X,? extends androidx.lifecycle.LiveData<Y>> transform);
+ }
+
+}
+
diff --git a/lifecycle/lifecycle-livedata-ktx/api/restricted_2.3.0-alpha02.txt b/lifecycle/lifecycle-livedata-ktx/api/restricted_2.3.0-alpha02.txt
new file mode 100644
index 0000000..b5a6b57
--- /dev/null
+++ b/lifecycle/lifecycle-livedata-ktx/api/restricted_2.3.0-alpha02.txt
@@ -0,0 +1,31 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+ public final class CoroutineLiveDataKt {
+ method public static <T> androidx.lifecycle.LiveData<T> liveData(kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> liveData(kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, java.time.Duration timeout, kotlin.jvm.functions.Function2<? super androidx.lifecycle.LiveDataScope<T>,? super kotlin.coroutines.Continuation<? super kotlin.Unit>,?> block);
+ }
+
+ public final class FlowLiveDataConversions {
+ method public static <T> kotlinx.coroutines.flow.Flow<T> asFlow(androidx.lifecycle.LiveData<T>);
+ method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, long timeoutInMs = 5000L);
+ method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext);
+ method public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>);
+ method @RequiresApi(android.os.Build.VERSION_CODES.O) public static <T> androidx.lifecycle.LiveData<T> asLiveData(kotlinx.coroutines.flow.Flow<? extends T>, kotlin.coroutines.CoroutineContext context = EmptyCoroutineContext, java.time.Duration timeout);
+ }
+
+ public interface LiveDataScope<T> {
+ method public suspend Object! emit(T? value, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+ method public suspend Object emitSource(androidx.lifecycle.LiveData<T> source, kotlin.coroutines.Continuation<? super kotlinx.coroutines.DisposableHandle> p);
+ method public T? getLatestValue();
+ property public abstract T? latestValue;
+ }
+
+ public final class TransformationsKt {
+ method public static inline <X> androidx.lifecycle.LiveData<X> distinctUntilChanged(androidx.lifecycle.LiveData<X>);
+ method public static inline <X, Y> androidx.lifecycle.LiveData<Y> map(androidx.lifecycle.LiveData<X>, kotlin.jvm.functions.Function1<? super X,? extends Y> transform);
+ method public static inline <X, Y> androidx.lifecycle.LiveData<Y> switchMap(androidx.lifecycle.LiveData<X>, kotlin.jvm.functions.Function1<? super X,? extends androidx.lifecycle.LiveData<Y>> transform);
+ }
+
+}
+
diff --git a/lifecycle/lifecycle-reactivestreams-ktx/api/2.3.0-alpha02.txt b/lifecycle/lifecycle-reactivestreams-ktx/api/2.3.0-alpha02.txt
new file mode 100644
index 0000000..0f61097
--- /dev/null
+++ b/lifecycle/lifecycle-reactivestreams-ktx/api/2.3.0-alpha02.txt
@@ -0,0 +1,10 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+ public final class LiveDataReactiveSteamsKt {
+ method public static inline <T> androidx.lifecycle.LiveData<T> toLiveData(org.reactivestreams.Publisher<T>);
+ method public static inline <T> org.reactivestreams.Publisher<T> toPublisher(androidx.lifecycle.LiveData<T>, androidx.lifecycle.LifecycleOwner lifecycle);
+ }
+
+}
+
diff --git a/lifecycle/lifecycle-reactivestreams-ktx/api/public_plus_experimental_2.3.0-alpha02.txt b/lifecycle/lifecycle-reactivestreams-ktx/api/public_plus_experimental_2.3.0-alpha02.txt
new file mode 100644
index 0000000..0f61097
--- /dev/null
+++ b/lifecycle/lifecycle-reactivestreams-ktx/api/public_plus_experimental_2.3.0-alpha02.txt
@@ -0,0 +1,10 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+ public final class LiveDataReactiveSteamsKt {
+ method public static inline <T> androidx.lifecycle.LiveData<T> toLiveData(org.reactivestreams.Publisher<T>);
+ method public static inline <T> org.reactivestreams.Publisher<T> toPublisher(androidx.lifecycle.LiveData<T>, androidx.lifecycle.LifecycleOwner lifecycle);
+ }
+
+}
+
diff --git a/lifecycle/lifecycle-reactivestreams-ktx/api/restricted_2.3.0-alpha02.txt b/lifecycle/lifecycle-reactivestreams-ktx/api/restricted_2.3.0-alpha02.txt
new file mode 100644
index 0000000..0f61097
--- /dev/null
+++ b/lifecycle/lifecycle-reactivestreams-ktx/api/restricted_2.3.0-alpha02.txt
@@ -0,0 +1,10 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+ public final class LiveDataReactiveSteamsKt {
+ method public static inline <T> androidx.lifecycle.LiveData<T> toLiveData(org.reactivestreams.Publisher<T>);
+ method public static inline <T> org.reactivestreams.Publisher<T> toPublisher(androidx.lifecycle.LiveData<T>, androidx.lifecycle.LifecycleOwner lifecycle);
+ }
+
+}
+
diff --git a/lifecycle/lifecycle-reactivestreams/api/2.3.0-alpha02.txt b/lifecycle/lifecycle-reactivestreams/api/2.3.0-alpha02.txt
new file mode 100644
index 0000000..518fc95
--- /dev/null
+++ b/lifecycle/lifecycle-reactivestreams/api/2.3.0-alpha02.txt
@@ -0,0 +1,10 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+ public final class LiveDataReactiveStreams {
+ method public static <T> androidx.lifecycle.LiveData<T!> fromPublisher(org.reactivestreams.Publisher<T!>);
+ method public static <T> org.reactivestreams.Publisher<T!> toPublisher(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.LiveData<T!>);
+ }
+
+}
+
diff --git a/lifecycle/lifecycle-reactivestreams/api/public_plus_experimental_2.3.0-alpha02.txt b/lifecycle/lifecycle-reactivestreams/api/public_plus_experimental_2.3.0-alpha02.txt
new file mode 100644
index 0000000..518fc95
--- /dev/null
+++ b/lifecycle/lifecycle-reactivestreams/api/public_plus_experimental_2.3.0-alpha02.txt
@@ -0,0 +1,10 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+ public final class LiveDataReactiveStreams {
+ method public static <T> androidx.lifecycle.LiveData<T!> fromPublisher(org.reactivestreams.Publisher<T!>);
+ method public static <T> org.reactivestreams.Publisher<T!> toPublisher(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.LiveData<T!>);
+ }
+
+}
+
diff --git a/lifecycle/lifecycle-reactivestreams/api/restricted_2.3.0-alpha02.txt b/lifecycle/lifecycle-reactivestreams/api/restricted_2.3.0-alpha02.txt
new file mode 100644
index 0000000..518fc95
--- /dev/null
+++ b/lifecycle/lifecycle-reactivestreams/api/restricted_2.3.0-alpha02.txt
@@ -0,0 +1,10 @@
+// Signature format: 3.0
+package androidx.lifecycle {
+
+ public final class LiveDataReactiveStreams {
+ method public static <T> androidx.lifecycle.LiveData<T!> fromPublisher(org.reactivestreams.Publisher<T!>);
+ method public static <T> org.reactivestreams.Publisher<T!> toPublisher(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.LiveData<T!>);
+ }
+
+}
+
diff --git a/lint-checks/src/main/java/androidx/build/lint/SampledAnnotationEnforcer.kt b/lint-checks/src/main/java/androidx/build/lint/SampledAnnotationEnforcer.kt
index f56e12d..2d528aa 100644
--- a/lint-checks/src/main/java/androidx/build/lint/SampledAnnotationEnforcer.kt
+++ b/lint-checks/src/main/java/androidx/build/lint/SampledAnnotationEnforcer.kt
@@ -380,35 +380,39 @@
private fun buildSampleLinkCache(context: JavaContext): List<String> {
val currentProjectPath = context.project.dir.absolutePath
- // The paths of every module the current module depends on
- val dependenciesPathList = context.project.directLibraries.map {
+ // The paths of every (including transitive) module the current module depends on
+ val dependenciesPathList = context.project.allLibraries.map {
it.dir.absolutePath
}
// Try and find a common path, i.e if we are in a/b/foo/integration-tests/sample, we
- // will match a/b/foo for the parent
- var parentProjectPath = dependenciesPathList.find {
- currentProjectPath.startsWith(it)
- }
+ // will match a/b/foo for the parent. Find all such matching paths in case there are
+ // multiple modules sampling this one module.
+ var parentProjectPaths = dependenciesPathList
+ .filter {
+ currentProjectPath.startsWith(it)
+ }
+ .ifEmpty { null }
// If we haven't found a path, it might be that we are on the same top level, i.e
// we are in a/b/foo/integration-tests/sample, and the module is in a/b/foo/foo-xyz
// Try matching with the parent directory of each module.
- parentProjectPath = parentProjectPath ?: dependenciesPathList.find {
- currentProjectPath.startsWith(File(it).parent)
- }
+ parentProjectPaths = parentProjectPaths ?: dependenciesPathList
+ .filter {
+ currentProjectPath.startsWith(File(it).parent)
+ }
+ .ifEmpty { null }
// There is no dependent module that exists above us, or alongside us, so throw
- if (parentProjectPath == null) {
- throw IllegalStateException("Couldn't find a parent project for " +
- currentProjectPath
- )
+ checkNotNull(parentProjectPaths) {
+ "Couldn't find a parent project for $currentProjectPath"
}
- val parentProjectDirectory = navigateToDirectory(context, parentProjectPath)
-
- return parentProjectDirectory.getAllKtFiles().flatMap { file ->
- file.findAllSampleLinks()
+ return parentProjectPaths.flatMap { path ->
+ val parentProjectDirectory = navigateToDirectory(context, path)
+ parentProjectDirectory.getAllKtFiles().flatMap { file ->
+ file.findAllSampleLinks()
+ }
}
}
}
diff --git a/navigation/navigation-common-ktx/api/2.3.0-alpha04.txt b/navigation/navigation-common-ktx/api/2.3.0-alpha04.txt
new file mode 100644
index 0000000..14135e0
--- /dev/null
+++ b/navigation/navigation-common-ktx/api/2.3.0-alpha04.txt
@@ -0,0 +1,124 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+ @androidx.navigation.NavOptionsDsl public final class AnimBuilder {
+ ctor public AnimBuilder();
+ method public int getEnter();
+ method public int getExit();
+ method public int getPopEnter();
+ method public int getPopExit();
+ method public void setEnter(int p);
+ method public void setExit(int p);
+ method public void setPopEnter(int p);
+ method public void setPopExit(int p);
+ property public final int enter;
+ property public final int exit;
+ property public final int popEnter;
+ property public final int popExit;
+ }
+
+ @androidx.navigation.NavDestinationDsl public final class NavActionBuilder {
+ ctor public NavActionBuilder();
+ method public int getDestinationId();
+ method public void navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
+ method public void setDestinationId(int p);
+ property public final int destinationId;
+ }
+
+ public final class NavArgsLazy<Args extends androidx.navigation.NavArgs> implements kotlin.Lazy<Args> {
+ ctor public NavArgsLazy(kotlin.reflect.KClass<Args> navArgsClass, kotlin.jvm.functions.Function0<android.os.Bundle> argumentProducer);
+ method public Args getValue();
+ method public boolean isInitialized();
+ property public Args value;
+ }
+
+ public final class NavArgsLazyKt {
+ }
+
+ @androidx.navigation.NavDestinationDsl public final class NavArgumentBuilder {
+ ctor public NavArgumentBuilder();
+ method public androidx.navigation.NavArgument build();
+ method public Object? getDefaultValue();
+ method public boolean getNullable();
+ method public androidx.navigation.NavType<?> getType();
+ method public void setDefaultValue(Object? value);
+ method public void setNullable(boolean value);
+ method public void setType(androidx.navigation.NavType<?> value);
+ property public final Object? defaultValue;
+ property public final boolean nullable;
+ property public final androidx.navigation.NavType<?> type;
+ }
+
+ @androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
+ ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
+ method public final void action(int actionId, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit> actionBuilder);
+ method public final void argument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> argumentBuilder);
+ method public D build();
+ method public final void deepLink(String uriPattern);
+ method public final int getId();
+ method public final CharSequence? getLabel();
+ method protected final androidx.navigation.Navigator<? extends D> getNavigator();
+ method public final void setLabel(CharSequence? p);
+ property public final CharSequence? label;
+ }
+
+ @kotlin.DslMarker public @interface NavDestinationDsl {
+ }
+
+ @androidx.navigation.NavDestinationDsl public final class NavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.NavGraph> {
+ ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
+ method public void addDestination(androidx.navigation.NavDestination destination);
+ method public androidx.navigation.NavGraph build();
+ method public <D extends androidx.navigation.NavDestination> void destination(androidx.navigation.NavDestinationBuilder<? extends D> navDestination);
+ method public androidx.navigation.NavigatorProvider getProvider();
+ method public operator void unaryPlus(androidx.navigation.NavDestination);
+ }
+
+ public final class NavGraphBuilderKt {
+ method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, @IdRes int id = 0, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+ method public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+ }
+
+ public final class NavGraphKt {
+ method public static operator boolean contains(androidx.navigation.NavGraph, @IdRes int id);
+ method public static inline operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, @IdRes int id);
+ method public static inline operator void minusAssign(androidx.navigation.NavGraph, androidx.navigation.NavDestination node);
+ method public static inline operator void plusAssign(androidx.navigation.NavGraph, androidx.navigation.NavDestination node);
+ method public static inline operator void plusAssign(androidx.navigation.NavGraph, androidx.navigation.NavGraph other);
+ }
+
+ @androidx.navigation.NavOptionsDsl public final class NavOptionsBuilder {
+ ctor public NavOptionsBuilder();
+ method public void anim(kotlin.jvm.functions.Function1<? super androidx.navigation.AnimBuilder,kotlin.Unit> animBuilder);
+ method public boolean getLaunchSingleTop();
+ method public int getPopUpTo();
+ method public void popUpTo(@IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
+ method public void setLaunchSingleTop(boolean p);
+ method public void setPopUpTo(int value);
+ property public final boolean launchSingleTop;
+ property public final int popUpTo;
+ }
+
+ public final class NavOptionsBuilderKt {
+ method public static androidx.navigation.NavOptions navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
+ }
+
+ @kotlin.DslMarker public @interface NavOptionsDsl {
+ }
+
+ public final class NavigatorProviderKt {
+ method public static inline operator <T extends androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>> T get(androidx.navigation.NavigatorProvider, String name);
+ method public static inline operator <T extends androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>> T get(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<T> clazz);
+ method public static inline operator void plusAssign(androidx.navigation.NavigatorProvider, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
+ method public static inline operator androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? set(androidx.navigation.NavigatorProvider, String name, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
+ }
+
+ @androidx.navigation.NavOptionsDsl public final class PopUpToBuilder {
+ ctor public PopUpToBuilder();
+ method public boolean getInclusive();
+ method public void setInclusive(boolean p);
+ property public final boolean inclusive;
+ }
+
+}
+
diff --git a/navigation/navigation-common-ktx/api/public_plus_experimental_2.3.0-alpha04.txt b/navigation/navigation-common-ktx/api/public_plus_experimental_2.3.0-alpha04.txt
new file mode 100644
index 0000000..14135e0
--- /dev/null
+++ b/navigation/navigation-common-ktx/api/public_plus_experimental_2.3.0-alpha04.txt
@@ -0,0 +1,124 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+ @androidx.navigation.NavOptionsDsl public final class AnimBuilder {
+ ctor public AnimBuilder();
+ method public int getEnter();
+ method public int getExit();
+ method public int getPopEnter();
+ method public int getPopExit();
+ method public void setEnter(int p);
+ method public void setExit(int p);
+ method public void setPopEnter(int p);
+ method public void setPopExit(int p);
+ property public final int enter;
+ property public final int exit;
+ property public final int popEnter;
+ property public final int popExit;
+ }
+
+ @androidx.navigation.NavDestinationDsl public final class NavActionBuilder {
+ ctor public NavActionBuilder();
+ method public int getDestinationId();
+ method public void navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
+ method public void setDestinationId(int p);
+ property public final int destinationId;
+ }
+
+ public final class NavArgsLazy<Args extends androidx.navigation.NavArgs> implements kotlin.Lazy<Args> {
+ ctor public NavArgsLazy(kotlin.reflect.KClass<Args> navArgsClass, kotlin.jvm.functions.Function0<android.os.Bundle> argumentProducer);
+ method public Args getValue();
+ method public boolean isInitialized();
+ property public Args value;
+ }
+
+ public final class NavArgsLazyKt {
+ }
+
+ @androidx.navigation.NavDestinationDsl public final class NavArgumentBuilder {
+ ctor public NavArgumentBuilder();
+ method public androidx.navigation.NavArgument build();
+ method public Object? getDefaultValue();
+ method public boolean getNullable();
+ method public androidx.navigation.NavType<?> getType();
+ method public void setDefaultValue(Object? value);
+ method public void setNullable(boolean value);
+ method public void setType(androidx.navigation.NavType<?> value);
+ property public final Object? defaultValue;
+ property public final boolean nullable;
+ property public final androidx.navigation.NavType<?> type;
+ }
+
+ @androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
+ ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
+ method public final void action(int actionId, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit> actionBuilder);
+ method public final void argument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> argumentBuilder);
+ method public D build();
+ method public final void deepLink(String uriPattern);
+ method public final int getId();
+ method public final CharSequence? getLabel();
+ method protected final androidx.navigation.Navigator<? extends D> getNavigator();
+ method public final void setLabel(CharSequence? p);
+ property public final CharSequence? label;
+ }
+
+ @kotlin.DslMarker public @interface NavDestinationDsl {
+ }
+
+ @androidx.navigation.NavDestinationDsl public final class NavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.NavGraph> {
+ ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
+ method public void addDestination(androidx.navigation.NavDestination destination);
+ method public androidx.navigation.NavGraph build();
+ method public <D extends androidx.navigation.NavDestination> void destination(androidx.navigation.NavDestinationBuilder<? extends D> navDestination);
+ method public androidx.navigation.NavigatorProvider getProvider();
+ method public operator void unaryPlus(androidx.navigation.NavDestination);
+ }
+
+ public final class NavGraphBuilderKt {
+ method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, @IdRes int id = 0, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+ method public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+ }
+
+ public final class NavGraphKt {
+ method public static operator boolean contains(androidx.navigation.NavGraph, @IdRes int id);
+ method public static inline operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, @IdRes int id);
+ method public static inline operator void minusAssign(androidx.navigation.NavGraph, androidx.navigation.NavDestination node);
+ method public static inline operator void plusAssign(androidx.navigation.NavGraph, androidx.navigation.NavDestination node);
+ method public static inline operator void plusAssign(androidx.navigation.NavGraph, androidx.navigation.NavGraph other);
+ }
+
+ @androidx.navigation.NavOptionsDsl public final class NavOptionsBuilder {
+ ctor public NavOptionsBuilder();
+ method public void anim(kotlin.jvm.functions.Function1<? super androidx.navigation.AnimBuilder,kotlin.Unit> animBuilder);
+ method public boolean getLaunchSingleTop();
+ method public int getPopUpTo();
+ method public void popUpTo(@IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
+ method public void setLaunchSingleTop(boolean p);
+ method public void setPopUpTo(int value);
+ property public final boolean launchSingleTop;
+ property public final int popUpTo;
+ }
+
+ public final class NavOptionsBuilderKt {
+ method public static androidx.navigation.NavOptions navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
+ }
+
+ @kotlin.DslMarker public @interface NavOptionsDsl {
+ }
+
+ public final class NavigatorProviderKt {
+ method public static inline operator <T extends androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>> T get(androidx.navigation.NavigatorProvider, String name);
+ method public static inline operator <T extends androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>> T get(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<T> clazz);
+ method public static inline operator void plusAssign(androidx.navigation.NavigatorProvider, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
+ method public static inline operator androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? set(androidx.navigation.NavigatorProvider, String name, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
+ }
+
+ @androidx.navigation.NavOptionsDsl public final class PopUpToBuilder {
+ ctor public PopUpToBuilder();
+ method public boolean getInclusive();
+ method public void setInclusive(boolean p);
+ property public final boolean inclusive;
+ }
+
+}
+
diff --git a/navigation/navigation-common-ktx/api/restricted_2.3.0-alpha04.txt b/navigation/navigation-common-ktx/api/restricted_2.3.0-alpha04.txt
new file mode 100644
index 0000000..14135e0
--- /dev/null
+++ b/navigation/navigation-common-ktx/api/restricted_2.3.0-alpha04.txt
@@ -0,0 +1,124 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+ @androidx.navigation.NavOptionsDsl public final class AnimBuilder {
+ ctor public AnimBuilder();
+ method public int getEnter();
+ method public int getExit();
+ method public int getPopEnter();
+ method public int getPopExit();
+ method public void setEnter(int p);
+ method public void setExit(int p);
+ method public void setPopEnter(int p);
+ method public void setPopExit(int p);
+ property public final int enter;
+ property public final int exit;
+ property public final int popEnter;
+ property public final int popExit;
+ }
+
+ @androidx.navigation.NavDestinationDsl public final class NavActionBuilder {
+ ctor public NavActionBuilder();
+ method public int getDestinationId();
+ method public void navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
+ method public void setDestinationId(int p);
+ property public final int destinationId;
+ }
+
+ public final class NavArgsLazy<Args extends androidx.navigation.NavArgs> implements kotlin.Lazy<Args> {
+ ctor public NavArgsLazy(kotlin.reflect.KClass<Args> navArgsClass, kotlin.jvm.functions.Function0<android.os.Bundle> argumentProducer);
+ method public Args getValue();
+ method public boolean isInitialized();
+ property public Args value;
+ }
+
+ public final class NavArgsLazyKt {
+ }
+
+ @androidx.navigation.NavDestinationDsl public final class NavArgumentBuilder {
+ ctor public NavArgumentBuilder();
+ method public androidx.navigation.NavArgument build();
+ method public Object? getDefaultValue();
+ method public boolean getNullable();
+ method public androidx.navigation.NavType<?> getType();
+ method public void setDefaultValue(Object? value);
+ method public void setNullable(boolean value);
+ method public void setType(androidx.navigation.NavType<?> value);
+ property public final Object? defaultValue;
+ property public final boolean nullable;
+ property public final androidx.navigation.NavType<?> type;
+ }
+
+ @androidx.navigation.NavDestinationDsl public class NavDestinationBuilder<D extends androidx.navigation.NavDestination> {
+ ctor public NavDestinationBuilder(androidx.navigation.Navigator<? extends D> navigator, @IdRes int id);
+ method public final void action(int actionId, kotlin.jvm.functions.Function1<? super androidx.navigation.NavActionBuilder,kotlin.Unit> actionBuilder);
+ method public final void argument(String name, kotlin.jvm.functions.Function1<? super androidx.navigation.NavArgumentBuilder,kotlin.Unit> argumentBuilder);
+ method public D build();
+ method public final void deepLink(String uriPattern);
+ method public final int getId();
+ method public final CharSequence? getLabel();
+ method protected final androidx.navigation.Navigator<? extends D> getNavigator();
+ method public final void setLabel(CharSequence? p);
+ property public final CharSequence? label;
+ }
+
+ @kotlin.DslMarker public @interface NavDestinationDsl {
+ }
+
+ @androidx.navigation.NavDestinationDsl public final class NavGraphBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.NavGraph> {
+ ctor public NavGraphBuilder(androidx.navigation.NavigatorProvider provider, @IdRes int id, @IdRes int startDestination);
+ method public void addDestination(androidx.navigation.NavDestination destination);
+ method public androidx.navigation.NavGraph build();
+ method public <D extends androidx.navigation.NavDestination> void destination(androidx.navigation.NavDestinationBuilder<? extends D> navDestination);
+ method public androidx.navigation.NavigatorProvider getProvider();
+ method public operator void unaryPlus(androidx.navigation.NavDestination);
+ }
+
+ public final class NavGraphBuilderKt {
+ method public static inline androidx.navigation.NavGraph navigation(androidx.navigation.NavigatorProvider, @IdRes int id = 0, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+ method public static inline void navigation(androidx.navigation.NavGraphBuilder, @IdRes int id, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+ }
+
+ public final class NavGraphKt {
+ method public static operator boolean contains(androidx.navigation.NavGraph, @IdRes int id);
+ method public static inline operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, @IdRes int id);
+ method public static inline operator void minusAssign(androidx.navigation.NavGraph, androidx.navigation.NavDestination node);
+ method public static inline operator void plusAssign(androidx.navigation.NavGraph, androidx.navigation.NavDestination node);
+ method public static inline operator void plusAssign(androidx.navigation.NavGraph, androidx.navigation.NavGraph other);
+ }
+
+ @androidx.navigation.NavOptionsDsl public final class NavOptionsBuilder {
+ ctor public NavOptionsBuilder();
+ method public void anim(kotlin.jvm.functions.Function1<? super androidx.navigation.AnimBuilder,kotlin.Unit> animBuilder);
+ method public boolean getLaunchSingleTop();
+ method public int getPopUpTo();
+ method public void popUpTo(@IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.PopUpToBuilder,kotlin.Unit> popUpToBuilder);
+ method public void setLaunchSingleTop(boolean p);
+ method public void setPopUpTo(int value);
+ property public final boolean launchSingleTop;
+ property public final int popUpTo;
+ }
+
+ public final class NavOptionsBuilderKt {
+ method public static androidx.navigation.NavOptions navOptions(kotlin.jvm.functions.Function1<? super androidx.navigation.NavOptionsBuilder,kotlin.Unit> optionsBuilder);
+ }
+
+ @kotlin.DslMarker public @interface NavOptionsDsl {
+ }
+
+ public final class NavigatorProviderKt {
+ method public static inline operator <T extends androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>> T get(androidx.navigation.NavigatorProvider, String name);
+ method public static inline operator <T extends androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>> T get(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<T> clazz);
+ method public static inline operator void plusAssign(androidx.navigation.NavigatorProvider, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
+ method public static inline operator androidx.navigation.Navigator<? extends androidx.navigation.NavDestination>? set(androidx.navigation.NavigatorProvider, String name, androidx.navigation.Navigator<? extends androidx.navigation.NavDestination> navigator);
+ }
+
+ @androidx.navigation.NavOptionsDsl public final class PopUpToBuilder {
+ ctor public PopUpToBuilder();
+ method public boolean getInclusive();
+ method public void setInclusive(boolean p);
+ property public final boolean inclusive;
+ }
+
+}
+
diff --git a/navigation/navigation-dynamic-features-fragment/api/2.3.0-alpha04.txt b/navigation/navigation-dynamic-features-fragment/api/2.3.0-alpha04.txt
new file mode 100644
index 0000000..abff53c
--- /dev/null
+++ b/navigation/navigation-dynamic-features-fragment/api/2.3.0-alpha04.txt
@@ -0,0 +1,43 @@
+// Signature format: 3.0
+package androidx.navigation.dynamicfeatures.fragment {
+
+ @androidx.navigation.Navigator.Name("fragment") public final class DynamicFragmentNavigator extends androidx.navigation.fragment.FragmentNavigator {
+ ctor public DynamicFragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager manager, int containerId, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination createDestination();
+ }
+
+ public static final class DynamicFragmentNavigator.Destination extends androidx.navigation.fragment.FragmentNavigator.Destination {
+ ctor public DynamicFragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
+ ctor public DynamicFragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> fragmentNavigator);
+ method public String? getModuleName();
+ method public void setModuleName(String? p);
+ property public final String? moduleName;
+ }
+
+ public class DynamicNavHostFragment extends androidx.navigation.fragment.NavHostFragment {
+ ctor public DynamicNavHostFragment();
+ method protected com.google.android.play.core.splitinstall.SplitInstallManager createSplitInstallManager();
+ }
+
+}
+
+package androidx.navigation.dynamicfeatures.fragment.ui {
+
+ public abstract class AbstractProgressFragment extends androidx.fragment.app.Fragment {
+ ctor public AbstractProgressFragment();
+ ctor public AbstractProgressFragment(int contentLayoutId);
+ method protected abstract void onCancelled();
+ method protected abstract void onFailed(int errorCode);
+ method protected void onInstalled();
+ method protected abstract void onProgress(int status, long bytesDownloaded, long bytesTotal);
+ }
+
+ public final class DefaultProgressFragment extends androidx.navigation.dynamicfeatures.fragment.ui.AbstractProgressFragment {
+ ctor public DefaultProgressFragment();
+ method protected void onCancelled();
+ method protected void onFailed(int errorCode);
+ method protected void onProgress(int status, long bytesDownloaded, long bytesTotal);
+ }
+
+}
+
diff --git a/navigation/navigation-dynamic-features-fragment/api/public_plus_experimental_2.3.0-alpha04.txt b/navigation/navigation-dynamic-features-fragment/api/public_plus_experimental_2.3.0-alpha04.txt
new file mode 100644
index 0000000..abff53c
--- /dev/null
+++ b/navigation/navigation-dynamic-features-fragment/api/public_plus_experimental_2.3.0-alpha04.txt
@@ -0,0 +1,43 @@
+// Signature format: 3.0
+package androidx.navigation.dynamicfeatures.fragment {
+
+ @androidx.navigation.Navigator.Name("fragment") public final class DynamicFragmentNavigator extends androidx.navigation.fragment.FragmentNavigator {
+ ctor public DynamicFragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager manager, int containerId, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination createDestination();
+ }
+
+ public static final class DynamicFragmentNavigator.Destination extends androidx.navigation.fragment.FragmentNavigator.Destination {
+ ctor public DynamicFragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
+ ctor public DynamicFragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> fragmentNavigator);
+ method public String? getModuleName();
+ method public void setModuleName(String? p);
+ property public final String? moduleName;
+ }
+
+ public class DynamicNavHostFragment extends androidx.navigation.fragment.NavHostFragment {
+ ctor public DynamicNavHostFragment();
+ method protected com.google.android.play.core.splitinstall.SplitInstallManager createSplitInstallManager();
+ }
+
+}
+
+package androidx.navigation.dynamicfeatures.fragment.ui {
+
+ public abstract class AbstractProgressFragment extends androidx.fragment.app.Fragment {
+ ctor public AbstractProgressFragment();
+ ctor public AbstractProgressFragment(int contentLayoutId);
+ method protected abstract void onCancelled();
+ method protected abstract void onFailed(int errorCode);
+ method protected void onInstalled();
+ method protected abstract void onProgress(int status, long bytesDownloaded, long bytesTotal);
+ }
+
+ public final class DefaultProgressFragment extends androidx.navigation.dynamicfeatures.fragment.ui.AbstractProgressFragment {
+ ctor public DefaultProgressFragment();
+ method protected void onCancelled();
+ method protected void onFailed(int errorCode);
+ method protected void onProgress(int status, long bytesDownloaded, long bytesTotal);
+ }
+
+}
+
diff --git a/navigation/navigation-dynamic-features-fragment/api/restricted_2.3.0-alpha04.txt b/navigation/navigation-dynamic-features-fragment/api/restricted_2.3.0-alpha04.txt
new file mode 100644
index 0000000..abff53c
--- /dev/null
+++ b/navigation/navigation-dynamic-features-fragment/api/restricted_2.3.0-alpha04.txt
@@ -0,0 +1,43 @@
+// Signature format: 3.0
+package androidx.navigation.dynamicfeatures.fragment {
+
+ @androidx.navigation.Navigator.Name("fragment") public final class DynamicFragmentNavigator extends androidx.navigation.fragment.FragmentNavigator {
+ ctor public DynamicFragmentNavigator(android.content.Context context, androidx.fragment.app.FragmentManager manager, int containerId, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ method public androidx.navigation.dynamicfeatures.fragment.DynamicFragmentNavigator.Destination createDestination();
+ }
+
+ public static final class DynamicFragmentNavigator.Destination extends androidx.navigation.fragment.FragmentNavigator.Destination {
+ ctor public DynamicFragmentNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
+ ctor public DynamicFragmentNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.fragment.FragmentNavigator.Destination> fragmentNavigator);
+ method public String? getModuleName();
+ method public void setModuleName(String? p);
+ property public final String? moduleName;
+ }
+
+ public class DynamicNavHostFragment extends androidx.navigation.fragment.NavHostFragment {
+ ctor public DynamicNavHostFragment();
+ method protected com.google.android.play.core.splitinstall.SplitInstallManager createSplitInstallManager();
+ }
+
+}
+
+package androidx.navigation.dynamicfeatures.fragment.ui {
+
+ public abstract class AbstractProgressFragment extends androidx.fragment.app.Fragment {
+ ctor public AbstractProgressFragment();
+ ctor public AbstractProgressFragment(int contentLayoutId);
+ method protected abstract void onCancelled();
+ method protected abstract void onFailed(int errorCode);
+ method protected void onInstalled();
+ method protected abstract void onProgress(int status, long bytesDownloaded, long bytesTotal);
+ }
+
+ public final class DefaultProgressFragment extends androidx.navigation.dynamicfeatures.fragment.ui.AbstractProgressFragment {
+ ctor public DefaultProgressFragment();
+ method protected void onCancelled();
+ method protected void onFailed(int errorCode);
+ method protected void onProgress(int status, long bytesDownloaded, long bytesTotal);
+ }
+
+}
+
diff --git a/navigation/navigation-dynamic-features-runtime/api/2.3.0-alpha03.txt b/navigation/navigation-dynamic-features-runtime/api/2.3.0-alpha03.txt
index ea7cb29..0513b0ba 100644
--- a/navigation/navigation-dynamic-features-runtime/api/2.3.0-alpha03.txt
+++ b/navigation/navigation-dynamic-features-runtime/api/2.3.0-alpha03.txt
@@ -2,7 +2,7 @@
package androidx.navigation.dynamicfeatures {
@androidx.navigation.Navigator.Name("activity") public final class DynamicActivityNavigator extends androidx.navigation.ActivityNavigator {
- ctor public DynamicActivityNavigator(android.app.Activity activity, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ ctor public DynamicActivityNavigator(android.content.Context context, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination createDestination();
}
diff --git a/navigation/navigation-dynamic-features-runtime/api/2.3.0-alpha04.txt b/navigation/navigation-dynamic-features-runtime/api/2.3.0-alpha04.txt
new file mode 100644
index 0000000..0513b0ba
--- /dev/null
+++ b/navigation/navigation-dynamic-features-runtime/api/2.3.0-alpha04.txt
@@ -0,0 +1,82 @@
+// Signature format: 3.0
+package androidx.navigation.dynamicfeatures {
+
+ @androidx.navigation.Navigator.Name("activity") public final class DynamicActivityNavigator extends androidx.navigation.ActivityNavigator {
+ ctor public DynamicActivityNavigator(android.content.Context context, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination createDestination();
+ }
+
+ public static final class DynamicActivityNavigator.Destination extends androidx.navigation.ActivityNavigator.Destination {
+ ctor public DynamicActivityNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
+ ctor public DynamicActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination> activityNavigator);
+ method public String? getModuleName();
+ method public void setModuleName(String? p);
+ property public final String? moduleName;
+ }
+
+ public final class DynamicExtras implements androidx.navigation.Navigator.Extras {
+ method public androidx.navigation.Navigator.Extras? getDestinationExtras();
+ method public androidx.navigation.dynamicfeatures.DynamicInstallMonitor? getInstallMonitor();
+ }
+
+ public static final class DynamicExtras.Builder {
+ ctor public DynamicExtras.Builder();
+ method public androidx.navigation.dynamicfeatures.DynamicExtras build();
+ method public androidx.navigation.dynamicfeatures.DynamicExtras.Builder setDestinationExtras(androidx.navigation.Navigator.Extras destinationExtras);
+ method public androidx.navigation.dynamicfeatures.DynamicExtras.Builder setInstallMonitor(androidx.navigation.dynamicfeatures.DynamicInstallMonitor monitor);
+ }
+
+ @androidx.navigation.Navigator.Name("navigation") public final class DynamicGraphNavigator extends androidx.navigation.NavGraphNavigator {
+ ctor public DynamicGraphNavigator(androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ method public androidx.navigation.dynamicfeatures.DynamicGraphNavigator.DynamicNavGraph createDestination();
+ method public void installDefaultProgressDestination(kotlin.jvm.functions.Function0<? extends androidx.navigation.NavDestination> progressDestinationSupplier);
+ }
+
+ public static final class DynamicGraphNavigator.DynamicNavGraph extends androidx.navigation.NavGraph {
+ ctor public DynamicGraphNavigator.DynamicNavGraph(internal androidx.navigation.dynamicfeatures.DynamicGraphNavigator navGraphNavigator, internal androidx.navigation.NavigatorProvider navigatorProvider);
+ method public String? getModuleName();
+ method public int getProgressDestination();
+ method public void setModuleName(String? p);
+ method public void setProgressDestination(int p);
+ property public final String? moduleName;
+ property public final int progressDestination;
+ }
+
+ @androidx.navigation.Navigator.Name("include-dynamic") public final class DynamicIncludeGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
+ ctor public DynamicIncludeGraphNavigator(android.content.Context context, androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.NavInflater navInflater, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph createDestination();
+ method public androidx.navigation.NavDestination? navigate(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
+ method public boolean popBackStack();
+ }
+
+ public static final class DynamicIncludeGraphNavigator.DynamicIncludeNavGraph extends androidx.navigation.NavDestination {
+ method public String? getGraphPackage();
+ method public String? getGraphResourceName();
+ method public String? getModuleName();
+ method public void setGraphPackage(String? p);
+ method public void setGraphResourceName(String? p);
+ method public void setModuleName(String? p);
+ property public final String? graphPackage;
+ property public final String? graphResourceName;
+ property public final String? moduleName;
+ }
+
+ public class DynamicInstallManager {
+ ctor public DynamicInstallManager(android.content.Context context, com.google.android.play.core.splitinstall.SplitInstallManager splitInstallManager);
+ }
+
+ public final class DynamicInstallMonitor {
+ ctor public DynamicInstallMonitor();
+ method public void cancelInstall();
+ method public Exception? getException();
+ method public int getSessionId();
+ method public androidx.lifecycle.LiveData<com.google.android.play.core.splitinstall.SplitInstallSessionState> getStatus();
+ method public boolean isInstallRequired();
+ property public final Exception? exception;
+ property public final boolean isInstallRequired;
+ property public final int sessionId;
+ property public final androidx.lifecycle.LiveData<com.google.android.play.core.splitinstall.SplitInstallSessionState> status;
+ }
+
+}
+
diff --git a/navigation/navigation-dynamic-features-runtime/api/current.txt b/navigation/navigation-dynamic-features-runtime/api/current.txt
index ea7cb29..0513b0ba 100644
--- a/navigation/navigation-dynamic-features-runtime/api/current.txt
+++ b/navigation/navigation-dynamic-features-runtime/api/current.txt
@@ -2,7 +2,7 @@
package androidx.navigation.dynamicfeatures {
@androidx.navigation.Navigator.Name("activity") public final class DynamicActivityNavigator extends androidx.navigation.ActivityNavigator {
- ctor public DynamicActivityNavigator(android.app.Activity activity, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ ctor public DynamicActivityNavigator(android.content.Context context, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination createDestination();
}
diff --git a/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_2.3.0-alpha03.txt b/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_2.3.0-alpha03.txt
index ea7cb29..0513b0ba 100644
--- a/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_2.3.0-alpha03.txt
+++ b/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_2.3.0-alpha03.txt
@@ -2,7 +2,7 @@
package androidx.navigation.dynamicfeatures {
@androidx.navigation.Navigator.Name("activity") public final class DynamicActivityNavigator extends androidx.navigation.ActivityNavigator {
- ctor public DynamicActivityNavigator(android.app.Activity activity, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ ctor public DynamicActivityNavigator(android.content.Context context, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination createDestination();
}
diff --git a/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_2.3.0-alpha04.txt b/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_2.3.0-alpha04.txt
new file mode 100644
index 0000000..0513b0ba
--- /dev/null
+++ b/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_2.3.0-alpha04.txt
@@ -0,0 +1,82 @@
+// Signature format: 3.0
+package androidx.navigation.dynamicfeatures {
+
+ @androidx.navigation.Navigator.Name("activity") public final class DynamicActivityNavigator extends androidx.navigation.ActivityNavigator {
+ ctor public DynamicActivityNavigator(android.content.Context context, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination createDestination();
+ }
+
+ public static final class DynamicActivityNavigator.Destination extends androidx.navigation.ActivityNavigator.Destination {
+ ctor public DynamicActivityNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
+ ctor public DynamicActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination> activityNavigator);
+ method public String? getModuleName();
+ method public void setModuleName(String? p);
+ property public final String? moduleName;
+ }
+
+ public final class DynamicExtras implements androidx.navigation.Navigator.Extras {
+ method public androidx.navigation.Navigator.Extras? getDestinationExtras();
+ method public androidx.navigation.dynamicfeatures.DynamicInstallMonitor? getInstallMonitor();
+ }
+
+ public static final class DynamicExtras.Builder {
+ ctor public DynamicExtras.Builder();
+ method public androidx.navigation.dynamicfeatures.DynamicExtras build();
+ method public androidx.navigation.dynamicfeatures.DynamicExtras.Builder setDestinationExtras(androidx.navigation.Navigator.Extras destinationExtras);
+ method public androidx.navigation.dynamicfeatures.DynamicExtras.Builder setInstallMonitor(androidx.navigation.dynamicfeatures.DynamicInstallMonitor monitor);
+ }
+
+ @androidx.navigation.Navigator.Name("navigation") public final class DynamicGraphNavigator extends androidx.navigation.NavGraphNavigator {
+ ctor public DynamicGraphNavigator(androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ method public androidx.navigation.dynamicfeatures.DynamicGraphNavigator.DynamicNavGraph createDestination();
+ method public void installDefaultProgressDestination(kotlin.jvm.functions.Function0<? extends androidx.navigation.NavDestination> progressDestinationSupplier);
+ }
+
+ public static final class DynamicGraphNavigator.DynamicNavGraph extends androidx.navigation.NavGraph {
+ ctor public DynamicGraphNavigator.DynamicNavGraph(internal androidx.navigation.dynamicfeatures.DynamicGraphNavigator navGraphNavigator, internal androidx.navigation.NavigatorProvider navigatorProvider);
+ method public String? getModuleName();
+ method public int getProgressDestination();
+ method public void setModuleName(String? p);
+ method public void setProgressDestination(int p);
+ property public final String? moduleName;
+ property public final int progressDestination;
+ }
+
+ @androidx.navigation.Navigator.Name("include-dynamic") public final class DynamicIncludeGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
+ ctor public DynamicIncludeGraphNavigator(android.content.Context context, androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.NavInflater navInflater, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph createDestination();
+ method public androidx.navigation.NavDestination? navigate(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
+ method public boolean popBackStack();
+ }
+
+ public static final class DynamicIncludeGraphNavigator.DynamicIncludeNavGraph extends androidx.navigation.NavDestination {
+ method public String? getGraphPackage();
+ method public String? getGraphResourceName();
+ method public String? getModuleName();
+ method public void setGraphPackage(String? p);
+ method public void setGraphResourceName(String? p);
+ method public void setModuleName(String? p);
+ property public final String? graphPackage;
+ property public final String? graphResourceName;
+ property public final String? moduleName;
+ }
+
+ public class DynamicInstallManager {
+ ctor public DynamicInstallManager(android.content.Context context, com.google.android.play.core.splitinstall.SplitInstallManager splitInstallManager);
+ }
+
+ public final class DynamicInstallMonitor {
+ ctor public DynamicInstallMonitor();
+ method public void cancelInstall();
+ method public Exception? getException();
+ method public int getSessionId();
+ method public androidx.lifecycle.LiveData<com.google.android.play.core.splitinstall.SplitInstallSessionState> getStatus();
+ method public boolean isInstallRequired();
+ property public final Exception? exception;
+ property public final boolean isInstallRequired;
+ property public final int sessionId;
+ property public final androidx.lifecycle.LiveData<com.google.android.play.core.splitinstall.SplitInstallSessionState> status;
+ }
+
+}
+
diff --git a/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_current.txt b/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_current.txt
index ea7cb29..0513b0ba 100644
--- a/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_current.txt
+++ b/navigation/navigation-dynamic-features-runtime/api/public_plus_experimental_current.txt
@@ -2,7 +2,7 @@
package androidx.navigation.dynamicfeatures {
@androidx.navigation.Navigator.Name("activity") public final class DynamicActivityNavigator extends androidx.navigation.ActivityNavigator {
- ctor public DynamicActivityNavigator(android.app.Activity activity, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ ctor public DynamicActivityNavigator(android.content.Context context, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination createDestination();
}
diff --git a/navigation/navigation-dynamic-features-runtime/api/restricted_2.3.0-alpha03.txt b/navigation/navigation-dynamic-features-runtime/api/restricted_2.3.0-alpha03.txt
index ea7cb29..0513b0ba 100644
--- a/navigation/navigation-dynamic-features-runtime/api/restricted_2.3.0-alpha03.txt
+++ b/navigation/navigation-dynamic-features-runtime/api/restricted_2.3.0-alpha03.txt
@@ -2,7 +2,7 @@
package androidx.navigation.dynamicfeatures {
@androidx.navigation.Navigator.Name("activity") public final class DynamicActivityNavigator extends androidx.navigation.ActivityNavigator {
- ctor public DynamicActivityNavigator(android.app.Activity activity, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ ctor public DynamicActivityNavigator(android.content.Context context, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination createDestination();
}
diff --git a/navigation/navigation-dynamic-features-runtime/api/restricted_2.3.0-alpha04.txt b/navigation/navigation-dynamic-features-runtime/api/restricted_2.3.0-alpha04.txt
new file mode 100644
index 0000000..0513b0ba
--- /dev/null
+++ b/navigation/navigation-dynamic-features-runtime/api/restricted_2.3.0-alpha04.txt
@@ -0,0 +1,82 @@
+// Signature format: 3.0
+package androidx.navigation.dynamicfeatures {
+
+ @androidx.navigation.Navigator.Name("activity") public final class DynamicActivityNavigator extends androidx.navigation.ActivityNavigator {
+ ctor public DynamicActivityNavigator(android.content.Context context, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination createDestination();
+ }
+
+ public static final class DynamicActivityNavigator.Destination extends androidx.navigation.ActivityNavigator.Destination {
+ ctor public DynamicActivityNavigator.Destination(androidx.navigation.NavigatorProvider navigatorProvider);
+ ctor public DynamicActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination> activityNavigator);
+ method public String? getModuleName();
+ method public void setModuleName(String? p);
+ property public final String? moduleName;
+ }
+
+ public final class DynamicExtras implements androidx.navigation.Navigator.Extras {
+ method public androidx.navigation.Navigator.Extras? getDestinationExtras();
+ method public androidx.navigation.dynamicfeatures.DynamicInstallMonitor? getInstallMonitor();
+ }
+
+ public static final class DynamicExtras.Builder {
+ ctor public DynamicExtras.Builder();
+ method public androidx.navigation.dynamicfeatures.DynamicExtras build();
+ method public androidx.navigation.dynamicfeatures.DynamicExtras.Builder setDestinationExtras(androidx.navigation.Navigator.Extras destinationExtras);
+ method public androidx.navigation.dynamicfeatures.DynamicExtras.Builder setInstallMonitor(androidx.navigation.dynamicfeatures.DynamicInstallMonitor monitor);
+ }
+
+ @androidx.navigation.Navigator.Name("navigation") public final class DynamicGraphNavigator extends androidx.navigation.NavGraphNavigator {
+ ctor public DynamicGraphNavigator(androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ method public androidx.navigation.dynamicfeatures.DynamicGraphNavigator.DynamicNavGraph createDestination();
+ method public void installDefaultProgressDestination(kotlin.jvm.functions.Function0<? extends androidx.navigation.NavDestination> progressDestinationSupplier);
+ }
+
+ public static final class DynamicGraphNavigator.DynamicNavGraph extends androidx.navigation.NavGraph {
+ ctor public DynamicGraphNavigator.DynamicNavGraph(internal androidx.navigation.dynamicfeatures.DynamicGraphNavigator navGraphNavigator, internal androidx.navigation.NavigatorProvider navigatorProvider);
+ method public String? getModuleName();
+ method public int getProgressDestination();
+ method public void setModuleName(String? p);
+ method public void setProgressDestination(int p);
+ property public final String? moduleName;
+ property public final int progressDestination;
+ }
+
+ @androidx.navigation.Navigator.Name("include-dynamic") public final class DynamicIncludeGraphNavigator extends androidx.navigation.Navigator<androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph> {
+ ctor public DynamicIncludeGraphNavigator(android.content.Context context, androidx.navigation.NavigatorProvider navigatorProvider, androidx.navigation.NavInflater navInflater, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ method public androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph createDestination();
+ method public androidx.navigation.NavDestination? navigate(androidx.navigation.dynamicfeatures.DynamicIncludeGraphNavigator.DynamicIncludeNavGraph destination, android.os.Bundle? args, androidx.navigation.NavOptions? navOptions, androidx.navigation.Navigator.Extras? navigatorExtras);
+ method public boolean popBackStack();
+ }
+
+ public static final class DynamicIncludeGraphNavigator.DynamicIncludeNavGraph extends androidx.navigation.NavDestination {
+ method public String? getGraphPackage();
+ method public String? getGraphResourceName();
+ method public String? getModuleName();
+ method public void setGraphPackage(String? p);
+ method public void setGraphResourceName(String? p);
+ method public void setModuleName(String? p);
+ property public final String? graphPackage;
+ property public final String? graphResourceName;
+ property public final String? moduleName;
+ }
+
+ public class DynamicInstallManager {
+ ctor public DynamicInstallManager(android.content.Context context, com.google.android.play.core.splitinstall.SplitInstallManager splitInstallManager);
+ }
+
+ public final class DynamicInstallMonitor {
+ ctor public DynamicInstallMonitor();
+ method public void cancelInstall();
+ method public Exception? getException();
+ method public int getSessionId();
+ method public androidx.lifecycle.LiveData<com.google.android.play.core.splitinstall.SplitInstallSessionState> getStatus();
+ method public boolean isInstallRequired();
+ property public final Exception? exception;
+ property public final boolean isInstallRequired;
+ property public final int sessionId;
+ property public final androidx.lifecycle.LiveData<com.google.android.play.core.splitinstall.SplitInstallSessionState> status;
+ }
+
+}
+
diff --git a/navigation/navigation-dynamic-features-runtime/api/restricted_current.txt b/navigation/navigation-dynamic-features-runtime/api/restricted_current.txt
index ea7cb29..0513b0ba 100644
--- a/navigation/navigation-dynamic-features-runtime/api/restricted_current.txt
+++ b/navigation/navigation-dynamic-features-runtime/api/restricted_current.txt
@@ -2,7 +2,7 @@
package androidx.navigation.dynamicfeatures {
@androidx.navigation.Navigator.Name("activity") public final class DynamicActivityNavigator extends androidx.navigation.ActivityNavigator {
- ctor public DynamicActivityNavigator(android.app.Activity activity, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
+ ctor public DynamicActivityNavigator(android.content.Context context, androidx.navigation.dynamicfeatures.DynamicInstallManager installManager);
method public androidx.navigation.dynamicfeatures.DynamicActivityNavigator.Destination createDestination();
}
diff --git a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicActivityNavigator.kt b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicActivityNavigator.kt
index d6b28fb..898ee9e 100644
--- a/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicActivityNavigator.kt
+++ b/navigation/navigation-dynamic-features-runtime/src/main/java/androidx/navigation/dynamicfeatures/DynamicActivityNavigator.kt
@@ -16,7 +16,6 @@
package androidx.navigation.dynamicfeatures
-import android.app.Activity
import android.content.Context
import android.os.Bundle
import android.util.AttributeSet
@@ -32,9 +31,9 @@
*/
@Navigator.Name("activity")
class DynamicActivityNavigator(
- activity: Activity,
+ context: Context,
private val installManager: DynamicInstallManager
-) : ActivityNavigator(activity) {
+) : ActivityNavigator(context) {
override fun navigate(
destination: ActivityNavigator.Destination,
diff --git a/navigation/navigation-fragment-ktx/api/2.3.0-alpha04.txt b/navigation/navigation-fragment-ktx/api/2.3.0-alpha04.txt
new file mode 100644
index 0000000..a09cb97
--- /dev/null
+++ b/navigation/navigation-fragment-ktx/api/2.3.0-alpha04.txt
@@ -0,0 +1,45 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+ public final class NavGraphViewModelLazyKt {
+ method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+ }
+
+}
+
+package androidx.navigation.fragment {
+
+ public final class DialogFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
+ ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+ method public androidx.navigation.fragment.DialogFragmentNavigator.Destination build();
+ }
+
+ public final class DialogFragmentNavigatorDestinationBuilderKt {
+ method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id);
+ method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+ }
+
+ public final class FragmentKt {
+ method public static androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment);
+ }
+
+ public final class FragmentNavArgsLazyKt {
+ method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args> navArgs(androidx.fragment.app.Fragment);
+ }
+
+ public final class FragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
+ ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
+ method public androidx.navigation.fragment.FragmentNavigator.Destination build();
+ }
+
+ public final class FragmentNavigatorDestinationBuilderKt {
+ method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+ }
+
+ public final class FragmentNavigatorExtrasKt {
+ method public static androidx.navigation.fragment.FragmentNavigator.Extras FragmentNavigatorExtras(kotlin.Pair<? extends android.view.View,java.lang.String>... sharedElements);
+ }
+
+}
+
diff --git a/navigation/navigation-fragment-ktx/api/public_plus_experimental_2.3.0-alpha04.txt b/navigation/navigation-fragment-ktx/api/public_plus_experimental_2.3.0-alpha04.txt
new file mode 100644
index 0000000..a09cb97
--- /dev/null
+++ b/navigation/navigation-fragment-ktx/api/public_plus_experimental_2.3.0-alpha04.txt
@@ -0,0 +1,45 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+ public final class NavGraphViewModelLazyKt {
+ method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+ }
+
+}
+
+package androidx.navigation.fragment {
+
+ public final class DialogFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
+ ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+ method public androidx.navigation.fragment.DialogFragmentNavigator.Destination build();
+ }
+
+ public final class DialogFragmentNavigatorDestinationBuilderKt {
+ method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id);
+ method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+ }
+
+ public final class FragmentKt {
+ method public static androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment);
+ }
+
+ public final class FragmentNavArgsLazyKt {
+ method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args> navArgs(androidx.fragment.app.Fragment);
+ }
+
+ public final class FragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
+ ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
+ method public androidx.navigation.fragment.FragmentNavigator.Destination build();
+ }
+
+ public final class FragmentNavigatorDestinationBuilderKt {
+ method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+ }
+
+ public final class FragmentNavigatorExtrasKt {
+ method public static androidx.navigation.fragment.FragmentNavigator.Extras FragmentNavigatorExtras(kotlin.Pair<? extends android.view.View,java.lang.String>... sharedElements);
+ }
+
+}
+
diff --git a/navigation/navigation-fragment-ktx/api/restricted_2.3.0-alpha04.txt b/navigation/navigation-fragment-ktx/api/restricted_2.3.0-alpha04.txt
new file mode 100644
index 0000000..a09cb97
--- /dev/null
+++ b/navigation/navigation-fragment-ktx/api/restricted_2.3.0-alpha04.txt
@@ -0,0 +1,45 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+ public final class NavGraphViewModelLazyKt {
+ method @MainThread public static inline <reified VM extends androidx.lifecycle.ViewModel> kotlin.Lazy<VM> navGraphViewModels(androidx.fragment.app.Fragment, @IdRes int navGraphId, kotlin.jvm.functions.Function0<? extends androidx.lifecycle.ViewModelProvider.Factory>? factoryProducer = null);
+ }
+
+}
+
+package androidx.navigation.fragment {
+
+ public final class DialogFragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.DialogFragmentNavigator.Destination> {
+ ctor public DialogFragmentNavigatorDestinationBuilder(androidx.navigation.fragment.DialogFragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.DialogFragment> fragmentClass);
+ method public androidx.navigation.fragment.DialogFragmentNavigator.Destination build();
+ }
+
+ public final class DialogFragmentNavigatorDestinationBuilderKt {
+ method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id);
+ method public static inline <reified F extends androidx.fragment.app.DialogFragment> void dialog(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.DialogFragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+ }
+
+ public final class FragmentKt {
+ method public static androidx.navigation.NavController findNavController(androidx.fragment.app.Fragment);
+ }
+
+ public final class FragmentNavArgsLazyKt {
+ method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args> navArgs(androidx.fragment.app.Fragment);
+ }
+
+ public final class FragmentNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.fragment.FragmentNavigator.Destination> {
+ ctor public FragmentNavigatorDestinationBuilder(androidx.navigation.fragment.FragmentNavigator navigator, @IdRes int id, kotlin.reflect.KClass<? extends androidx.fragment.app.Fragment> fragmentClass);
+ method public androidx.navigation.fragment.FragmentNavigator.Destination build();
+ }
+
+ public final class FragmentNavigatorDestinationBuilderKt {
+ method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id);
+ method public static inline <reified F extends androidx.fragment.app.Fragment> void fragment(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.fragment.FragmentNavigatorDestinationBuilder,kotlin.Unit> builder);
+ }
+
+ public final class FragmentNavigatorExtrasKt {
+ method public static androidx.navigation.fragment.FragmentNavigator.Extras FragmentNavigatorExtras(kotlin.Pair<? extends android.view.View,java.lang.String>... sharedElements);
+ }
+
+}
+
diff --git a/navigation/navigation-runtime-ktx/api/2.3.0-alpha04.txt b/navigation/navigation-runtime-ktx/api/2.3.0-alpha04.txt
new file mode 100644
index 0000000..09505f5
--- /dev/null
+++ b/navigation/navigation-runtime-ktx/api/2.3.0-alpha04.txt
@@ -0,0 +1,53 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+ public final class ActivityKt {
+ method public static androidx.navigation.NavController findNavController(android.app.Activity, @IdRes int viewId);
+ }
+
+ public final class ActivityNavArgsLazyKt {
+ method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args> navArgs(android.app.Activity);
+ }
+
+ public final class ActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
+ ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
+ method public androidx.navigation.ActivityNavigator.Destination build();
+ method public String? getAction();
+ method public kotlin.reflect.KClass<? extends android.app.Activity>? getActivityClass();
+ method public android.net.Uri? getData();
+ method public String? getDataPattern();
+ method public String? getTargetPackage();
+ method public void setAction(String? p);
+ method public void setActivityClass(kotlin.reflect.KClass<? extends android.app.Activity>? p);
+ method public void setData(android.net.Uri? p);
+ method public void setDataPattern(String? p);
+ method public void setTargetPackage(String? p);
+ property public final String? action;
+ property public final kotlin.reflect.KClass<? extends android.app.Activity>? activityClass;
+ property public final android.net.Uri? data;
+ property public final String? dataPattern;
+ property public final String? targetPackage;
+ }
+
+ public final class ActivityNavigatorDestinationBuilderKt {
+ method public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+ }
+
+ public final class ActivityNavigatorExtrasKt {
+ method public static androidx.navigation.ActivityNavigator.Extras ActivityNavigatorExtras(androidx.core.app.ActivityOptionsCompat? activityOptions = null, int flags = 0);
+ }
+
+ public final class NavControllerKt {
+ method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, @IdRes int id = 0, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+ }
+
+ public final class NavHostKt {
+ method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, @IdRes int id = 0, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+ }
+
+ public final class ViewKt {
+ method public static androidx.navigation.NavController findNavController(android.view.View);
+ }
+
+}
+
diff --git a/navigation/navigation-runtime-ktx/api/public_plus_experimental_2.3.0-alpha04.txt b/navigation/navigation-runtime-ktx/api/public_plus_experimental_2.3.0-alpha04.txt
new file mode 100644
index 0000000..09505f5
--- /dev/null
+++ b/navigation/navigation-runtime-ktx/api/public_plus_experimental_2.3.0-alpha04.txt
@@ -0,0 +1,53 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+ public final class ActivityKt {
+ method public static androidx.navigation.NavController findNavController(android.app.Activity, @IdRes int viewId);
+ }
+
+ public final class ActivityNavArgsLazyKt {
+ method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args> navArgs(android.app.Activity);
+ }
+
+ public final class ActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
+ ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
+ method public androidx.navigation.ActivityNavigator.Destination build();
+ method public String? getAction();
+ method public kotlin.reflect.KClass<? extends android.app.Activity>? getActivityClass();
+ method public android.net.Uri? getData();
+ method public String? getDataPattern();
+ method public String? getTargetPackage();
+ method public void setAction(String? p);
+ method public void setActivityClass(kotlin.reflect.KClass<? extends android.app.Activity>? p);
+ method public void setData(android.net.Uri? p);
+ method public void setDataPattern(String? p);
+ method public void setTargetPackage(String? p);
+ property public final String? action;
+ property public final kotlin.reflect.KClass<? extends android.app.Activity>? activityClass;
+ property public final android.net.Uri? data;
+ property public final String? dataPattern;
+ property public final String? targetPackage;
+ }
+
+ public final class ActivityNavigatorDestinationBuilderKt {
+ method public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+ }
+
+ public final class ActivityNavigatorExtrasKt {
+ method public static androidx.navigation.ActivityNavigator.Extras ActivityNavigatorExtras(androidx.core.app.ActivityOptionsCompat? activityOptions = null, int flags = 0);
+ }
+
+ public final class NavControllerKt {
+ method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, @IdRes int id = 0, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+ }
+
+ public final class NavHostKt {
+ method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, @IdRes int id = 0, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+ }
+
+ public final class ViewKt {
+ method public static androidx.navigation.NavController findNavController(android.view.View);
+ }
+
+}
+
diff --git a/navigation/navigation-runtime-ktx/api/restricted_2.3.0-alpha04.txt b/navigation/navigation-runtime-ktx/api/restricted_2.3.0-alpha04.txt
new file mode 100644
index 0000000..09505f5
--- /dev/null
+++ b/navigation/navigation-runtime-ktx/api/restricted_2.3.0-alpha04.txt
@@ -0,0 +1,53 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+ public final class ActivityKt {
+ method public static androidx.navigation.NavController findNavController(android.app.Activity, @IdRes int viewId);
+ }
+
+ public final class ActivityNavArgsLazyKt {
+ method @MainThread public static inline <reified Args extends androidx.navigation.NavArgs> androidx.navigation.NavArgsLazy<Args> navArgs(android.app.Activity);
+ }
+
+ public final class ActivityNavigatorDestinationBuilder extends androidx.navigation.NavDestinationBuilder<androidx.navigation.ActivityNavigator.Destination> {
+ ctor public ActivityNavigatorDestinationBuilder(androidx.navigation.ActivityNavigator navigator, @IdRes int id);
+ method public androidx.navigation.ActivityNavigator.Destination build();
+ method public String? getAction();
+ method public kotlin.reflect.KClass<? extends android.app.Activity>? getActivityClass();
+ method public android.net.Uri? getData();
+ method public String? getDataPattern();
+ method public String? getTargetPackage();
+ method public void setAction(String? p);
+ method public void setActivityClass(kotlin.reflect.KClass<? extends android.app.Activity>? p);
+ method public void setData(android.net.Uri? p);
+ method public void setDataPattern(String? p);
+ method public void setTargetPackage(String? p);
+ property public final String? action;
+ property public final kotlin.reflect.KClass<? extends android.app.Activity>? activityClass;
+ property public final android.net.Uri? data;
+ property public final String? dataPattern;
+ property public final String? targetPackage;
+ }
+
+ public final class ActivityNavigatorDestinationBuilderKt {
+ method public static inline void activity(androidx.navigation.NavGraphBuilder, @IdRes int id, kotlin.jvm.functions.Function1<? super androidx.navigation.ActivityNavigatorDestinationBuilder,kotlin.Unit> builder);
+ }
+
+ public final class ActivityNavigatorExtrasKt {
+ method public static androidx.navigation.ActivityNavigator.Extras ActivityNavigatorExtras(androidx.core.app.ActivityOptionsCompat? activityOptions = null, int flags = 0);
+ }
+
+ public final class NavControllerKt {
+ method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavController, @IdRes int id = 0, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+ }
+
+ public final class NavHostKt {
+ method public static inline androidx.navigation.NavGraph createGraph(androidx.navigation.NavHost, @IdRes int id = 0, @IdRes int startDestination, kotlin.jvm.functions.Function1<? super androidx.navigation.NavGraphBuilder,kotlin.Unit> builder);
+ }
+
+ public final class ViewKt {
+ method public static androidx.navigation.NavController findNavController(android.view.View);
+ }
+
+}
+
diff --git a/navigation/navigation-runtime/api/2.3.0-alpha04.txt b/navigation/navigation-runtime/api/2.3.0-alpha04.txt
new file mode 100644
index 0000000..d0669a8
--- /dev/null
+++ b/navigation/navigation-runtime/api/2.3.0-alpha04.txt
@@ -0,0 +1,130 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+ @androidx.navigation.Navigator.Name("activity") public class ActivityNavigator extends androidx.navigation.Navigator<androidx.navigation.ActivityNavigator.Destination> {
+ ctor public ActivityNavigator(android.content.Context);
+ method public static void applyPopAnimationsToPendingTransition(android.app.Activity);
+ method public androidx.navigation.ActivityNavigator.Destination createDestination();
+ method public androidx.navigation.NavDestination? navigate(androidx.navigation.ActivityNavigator.Destination, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+ method public boolean popBackStack();
+ }
+
+ @androidx.navigation.NavDestination.ClassType(Activity.class) public static class ActivityNavigator.Destination extends androidx.navigation.NavDestination {
+ ctor public ActivityNavigator.Destination(androidx.navigation.NavigatorProvider);
+ ctor public ActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination>);
+ method public final String? getAction();
+ method public final android.content.ComponentName? getComponent();
+ method public final android.net.Uri? getData();
+ method public final String? getDataPattern();
+ method public final android.content.Intent? getIntent();
+ method public final String? getTargetPackage();
+ method public final androidx.navigation.ActivityNavigator.Destination setAction(String?);
+ method public final androidx.navigation.ActivityNavigator.Destination setComponentName(android.content.ComponentName?);
+ method public final androidx.navigation.ActivityNavigator.Destination setData(android.net.Uri?);
+ method public final androidx.navigation.ActivityNavigator.Destination setDataPattern(String?);
+ method public final androidx.navigation.ActivityNavigator.Destination setIntent(android.content.Intent?);
+ method public final androidx.navigation.ActivityNavigator.Destination setTargetPackage(String?);
+ }
+
+ public static final class ActivityNavigator.Extras implements androidx.navigation.Navigator.Extras {
+ method public androidx.core.app.ActivityOptionsCompat? getActivityOptions();
+ method public int getFlags();
+ }
+
+ public static final class ActivityNavigator.Extras.Builder {
+ ctor public ActivityNavigator.Extras.Builder();
+ method public androidx.navigation.ActivityNavigator.Extras.Builder addFlags(int);
+ method public androidx.navigation.ActivityNavigator.Extras build();
+ method public androidx.navigation.ActivityNavigator.Extras.Builder setActivityOptions(androidx.core.app.ActivityOptionsCompat);
+ }
+
+ public final class NavBackStackEntry implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+ method public android.os.Bundle? getArguments();
+ method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
+ method public androidx.navigation.NavDestination getDestination();
+ method public androidx.lifecycle.Lifecycle getLifecycle();
+ method public androidx.lifecycle.SavedStateHandle getSavedStateHandle();
+ method public androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
+ method public androidx.lifecycle.ViewModelStore getViewModelStore();
+ }
+
+ public class NavController {
+ ctor public NavController(android.content.Context);
+ method public void addOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener);
+ method public androidx.navigation.NavDeepLinkBuilder createDeepLink();
+ method public androidx.navigation.NavBackStackEntry getBackStackEntry(@IdRes int);
+ method public androidx.navigation.NavBackStackEntry? getCurrentBackStackEntry();
+ method public androidx.navigation.NavDestination? getCurrentDestination();
+ method public androidx.navigation.NavGraph getGraph();
+ method public androidx.navigation.NavInflater getNavInflater();
+ method public androidx.navigation.NavigatorProvider getNavigatorProvider();
+ method public androidx.navigation.NavBackStackEntry? getPreviousBackStackEntry();
+ method public androidx.lifecycle.ViewModelStoreOwner getViewModelStoreOwner(@IdRes int);
+ method public boolean handleDeepLink(android.content.Intent?);
+ method public void navigate(@IdRes int);
+ method public void navigate(@IdRes int, android.os.Bundle?);
+ method public void navigate(@IdRes int, android.os.Bundle?, androidx.navigation.NavOptions?);
+ method public void navigate(@IdRes int, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+ method public void navigate(android.net.Uri);
+ method public void navigate(android.net.Uri, androidx.navigation.NavOptions?);
+ method public void navigate(android.net.Uri, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+ method public void navigate(androidx.navigation.NavDirections);
+ method public void navigate(androidx.navigation.NavDirections, androidx.navigation.NavOptions?);
+ method public void navigate(androidx.navigation.NavDirections, androidx.navigation.Navigator.Extras);
+ method public boolean navigateUp();
+ method public boolean popBackStack();
+ method public boolean popBackStack(@IdRes int, boolean);
+ method public void removeOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener);
+ method @CallSuper public void restoreState(android.os.Bundle?);
+ method @CallSuper public android.os.Bundle? saveState();
+ method @CallSuper public void setGraph(@NavigationRes int);
+ method @CallSuper public void setGraph(@NavigationRes int, android.os.Bundle?);
+ method @CallSuper public void setGraph(androidx.navigation.NavGraph);
+ method @CallSuper public void setGraph(androidx.navigation.NavGraph, android.os.Bundle?);
+ field public static final String KEY_DEEP_LINK_INTENT = "android-support-nav:controller:deepLinkIntent";
+ }
+
+ public static interface NavController.OnDestinationChangedListener {
+ method public void onDestinationChanged(androidx.navigation.NavController, androidx.navigation.NavDestination, android.os.Bundle?);
+ }
+
+ public final class NavDeepLinkBuilder {
+ ctor public NavDeepLinkBuilder(android.content.Context);
+ method public android.app.PendingIntent createPendingIntent();
+ method public androidx.core.app.TaskStackBuilder createTaskStackBuilder();
+ method public androidx.navigation.NavDeepLinkBuilder setArguments(android.os.Bundle?);
+ method public androidx.navigation.NavDeepLinkBuilder setComponentName(Class<? extends android.app.Activity>);
+ method public androidx.navigation.NavDeepLinkBuilder setComponentName(android.content.ComponentName);
+ method public androidx.navigation.NavDeepLinkBuilder setDestination(@IdRes int);
+ method public androidx.navigation.NavDeepLinkBuilder setGraph(@NavigationRes int);
+ method public androidx.navigation.NavDeepLinkBuilder setGraph(androidx.navigation.NavGraph);
+ }
+
+ public interface NavHost {
+ method public androidx.navigation.NavController getNavController();
+ }
+
+ public class NavHostController extends androidx.navigation.NavController {
+ ctor public NavHostController(android.content.Context);
+ method public final void enableOnBackPressed(boolean);
+ method public final void setLifecycleOwner(androidx.lifecycle.LifecycleOwner);
+ method public final void setOnBackPressedDispatcher(androidx.activity.OnBackPressedDispatcher);
+ method public final void setViewModelStore(androidx.lifecycle.ViewModelStore);
+ }
+
+ public final class NavInflater {
+ ctor public NavInflater(android.content.Context, androidx.navigation.NavigatorProvider);
+ method public androidx.navigation.NavGraph inflate(@NavigationRes int);
+ }
+
+ public final class Navigation {
+ method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int);
+ method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int, android.os.Bundle?);
+ method public static android.view.View.OnClickListener createNavigateOnClickListener(androidx.navigation.NavDirections);
+ method public static androidx.navigation.NavController findNavController(android.app.Activity, @IdRes int);
+ method public static androidx.navigation.NavController findNavController(android.view.View);
+ method public static void setViewNavController(android.view.View, androidx.navigation.NavController?);
+ }
+
+}
+
diff --git a/navigation/navigation-runtime/api/public_plus_experimental_2.3.0-alpha04.txt b/navigation/navigation-runtime/api/public_plus_experimental_2.3.0-alpha04.txt
new file mode 100644
index 0000000..d0669a8
--- /dev/null
+++ b/navigation/navigation-runtime/api/public_plus_experimental_2.3.0-alpha04.txt
@@ -0,0 +1,130 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+ @androidx.navigation.Navigator.Name("activity") public class ActivityNavigator extends androidx.navigation.Navigator<androidx.navigation.ActivityNavigator.Destination> {
+ ctor public ActivityNavigator(android.content.Context);
+ method public static void applyPopAnimationsToPendingTransition(android.app.Activity);
+ method public androidx.navigation.ActivityNavigator.Destination createDestination();
+ method public androidx.navigation.NavDestination? navigate(androidx.navigation.ActivityNavigator.Destination, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+ method public boolean popBackStack();
+ }
+
+ @androidx.navigation.NavDestination.ClassType(Activity.class) public static class ActivityNavigator.Destination extends androidx.navigation.NavDestination {
+ ctor public ActivityNavigator.Destination(androidx.navigation.NavigatorProvider);
+ ctor public ActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination>);
+ method public final String? getAction();
+ method public final android.content.ComponentName? getComponent();
+ method public final android.net.Uri? getData();
+ method public final String? getDataPattern();
+ method public final android.content.Intent? getIntent();
+ method public final String? getTargetPackage();
+ method public final androidx.navigation.ActivityNavigator.Destination setAction(String?);
+ method public final androidx.navigation.ActivityNavigator.Destination setComponentName(android.content.ComponentName?);
+ method public final androidx.navigation.ActivityNavigator.Destination setData(android.net.Uri?);
+ method public final androidx.navigation.ActivityNavigator.Destination setDataPattern(String?);
+ method public final androidx.navigation.ActivityNavigator.Destination setIntent(android.content.Intent?);
+ method public final androidx.navigation.ActivityNavigator.Destination setTargetPackage(String?);
+ }
+
+ public static final class ActivityNavigator.Extras implements androidx.navigation.Navigator.Extras {
+ method public androidx.core.app.ActivityOptionsCompat? getActivityOptions();
+ method public int getFlags();
+ }
+
+ public static final class ActivityNavigator.Extras.Builder {
+ ctor public ActivityNavigator.Extras.Builder();
+ method public androidx.navigation.ActivityNavigator.Extras.Builder addFlags(int);
+ method public androidx.navigation.ActivityNavigator.Extras build();
+ method public androidx.navigation.ActivityNavigator.Extras.Builder setActivityOptions(androidx.core.app.ActivityOptionsCompat);
+ }
+
+ public final class NavBackStackEntry implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+ method public android.os.Bundle? getArguments();
+ method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
+ method public androidx.navigation.NavDestination getDestination();
+ method public androidx.lifecycle.Lifecycle getLifecycle();
+ method public androidx.lifecycle.SavedStateHandle getSavedStateHandle();
+ method public androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
+ method public androidx.lifecycle.ViewModelStore getViewModelStore();
+ }
+
+ public class NavController {
+ ctor public NavController(android.content.Context);
+ method public void addOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener);
+ method public androidx.navigation.NavDeepLinkBuilder createDeepLink();
+ method public androidx.navigation.NavBackStackEntry getBackStackEntry(@IdRes int);
+ method public androidx.navigation.NavBackStackEntry? getCurrentBackStackEntry();
+ method public androidx.navigation.NavDestination? getCurrentDestination();
+ method public androidx.navigation.NavGraph getGraph();
+ method public androidx.navigation.NavInflater getNavInflater();
+ method public androidx.navigation.NavigatorProvider getNavigatorProvider();
+ method public androidx.navigation.NavBackStackEntry? getPreviousBackStackEntry();
+ method public androidx.lifecycle.ViewModelStoreOwner getViewModelStoreOwner(@IdRes int);
+ method public boolean handleDeepLink(android.content.Intent?);
+ method public void navigate(@IdRes int);
+ method public void navigate(@IdRes int, android.os.Bundle?);
+ method public void navigate(@IdRes int, android.os.Bundle?, androidx.navigation.NavOptions?);
+ method public void navigate(@IdRes int, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+ method public void navigate(android.net.Uri);
+ method public void navigate(android.net.Uri, androidx.navigation.NavOptions?);
+ method public void navigate(android.net.Uri, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+ method public void navigate(androidx.navigation.NavDirections);
+ method public void navigate(androidx.navigation.NavDirections, androidx.navigation.NavOptions?);
+ method public void navigate(androidx.navigation.NavDirections, androidx.navigation.Navigator.Extras);
+ method public boolean navigateUp();
+ method public boolean popBackStack();
+ method public boolean popBackStack(@IdRes int, boolean);
+ method public void removeOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener);
+ method @CallSuper public void restoreState(android.os.Bundle?);
+ method @CallSuper public android.os.Bundle? saveState();
+ method @CallSuper public void setGraph(@NavigationRes int);
+ method @CallSuper public void setGraph(@NavigationRes int, android.os.Bundle?);
+ method @CallSuper public void setGraph(androidx.navigation.NavGraph);
+ method @CallSuper public void setGraph(androidx.navigation.NavGraph, android.os.Bundle?);
+ field public static final String KEY_DEEP_LINK_INTENT = "android-support-nav:controller:deepLinkIntent";
+ }
+
+ public static interface NavController.OnDestinationChangedListener {
+ method public void onDestinationChanged(androidx.navigation.NavController, androidx.navigation.NavDestination, android.os.Bundle?);
+ }
+
+ public final class NavDeepLinkBuilder {
+ ctor public NavDeepLinkBuilder(android.content.Context);
+ method public android.app.PendingIntent createPendingIntent();
+ method public androidx.core.app.TaskStackBuilder createTaskStackBuilder();
+ method public androidx.navigation.NavDeepLinkBuilder setArguments(android.os.Bundle?);
+ method public androidx.navigation.NavDeepLinkBuilder setComponentName(Class<? extends android.app.Activity>);
+ method public androidx.navigation.NavDeepLinkBuilder setComponentName(android.content.ComponentName);
+ method public androidx.navigation.NavDeepLinkBuilder setDestination(@IdRes int);
+ method public androidx.navigation.NavDeepLinkBuilder setGraph(@NavigationRes int);
+ method public androidx.navigation.NavDeepLinkBuilder setGraph(androidx.navigation.NavGraph);
+ }
+
+ public interface NavHost {
+ method public androidx.navigation.NavController getNavController();
+ }
+
+ public class NavHostController extends androidx.navigation.NavController {
+ ctor public NavHostController(android.content.Context);
+ method public final void enableOnBackPressed(boolean);
+ method public final void setLifecycleOwner(androidx.lifecycle.LifecycleOwner);
+ method public final void setOnBackPressedDispatcher(androidx.activity.OnBackPressedDispatcher);
+ method public final void setViewModelStore(androidx.lifecycle.ViewModelStore);
+ }
+
+ public final class NavInflater {
+ ctor public NavInflater(android.content.Context, androidx.navigation.NavigatorProvider);
+ method public androidx.navigation.NavGraph inflate(@NavigationRes int);
+ }
+
+ public final class Navigation {
+ method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int);
+ method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int, android.os.Bundle?);
+ method public static android.view.View.OnClickListener createNavigateOnClickListener(androidx.navigation.NavDirections);
+ method public static androidx.navigation.NavController findNavController(android.app.Activity, @IdRes int);
+ method public static androidx.navigation.NavController findNavController(android.view.View);
+ method public static void setViewNavController(android.view.View, androidx.navigation.NavController?);
+ }
+
+}
+
diff --git a/navigation/navigation-runtime/api/restricted_2.3.0-alpha04.txt b/navigation/navigation-runtime/api/restricted_2.3.0-alpha04.txt
new file mode 100644
index 0000000..d0669a8
--- /dev/null
+++ b/navigation/navigation-runtime/api/restricted_2.3.0-alpha04.txt
@@ -0,0 +1,130 @@
+// Signature format: 3.0
+package androidx.navigation {
+
+ @androidx.navigation.Navigator.Name("activity") public class ActivityNavigator extends androidx.navigation.Navigator<androidx.navigation.ActivityNavigator.Destination> {
+ ctor public ActivityNavigator(android.content.Context);
+ method public static void applyPopAnimationsToPendingTransition(android.app.Activity);
+ method public androidx.navigation.ActivityNavigator.Destination createDestination();
+ method public androidx.navigation.NavDestination? navigate(androidx.navigation.ActivityNavigator.Destination, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+ method public boolean popBackStack();
+ }
+
+ @androidx.navigation.NavDestination.ClassType(Activity.class) public static class ActivityNavigator.Destination extends androidx.navigation.NavDestination {
+ ctor public ActivityNavigator.Destination(androidx.navigation.NavigatorProvider);
+ ctor public ActivityNavigator.Destination(androidx.navigation.Navigator<? extends androidx.navigation.ActivityNavigator.Destination>);
+ method public final String? getAction();
+ method public final android.content.ComponentName? getComponent();
+ method public final android.net.Uri? getData();
+ method public final String? getDataPattern();
+ method public final android.content.Intent? getIntent();
+ method public final String? getTargetPackage();
+ method public final androidx.navigation.ActivityNavigator.Destination setAction(String?);
+ method public final androidx.navigation.ActivityNavigator.Destination setComponentName(android.content.ComponentName?);
+ method public final androidx.navigation.ActivityNavigator.Destination setData(android.net.Uri?);
+ method public final androidx.navigation.ActivityNavigator.Destination setDataPattern(String?);
+ method public final androidx.navigation.ActivityNavigator.Destination setIntent(android.content.Intent?);
+ method public final androidx.navigation.ActivityNavigator.Destination setTargetPackage(String?);
+ }
+
+ public static final class ActivityNavigator.Extras implements androidx.navigation.Navigator.Extras {
+ method public androidx.core.app.ActivityOptionsCompat? getActivityOptions();
+ method public int getFlags();
+ }
+
+ public static final class ActivityNavigator.Extras.Builder {
+ ctor public ActivityNavigator.Extras.Builder();
+ method public androidx.navigation.ActivityNavigator.Extras.Builder addFlags(int);
+ method public androidx.navigation.ActivityNavigator.Extras build();
+ method public androidx.navigation.ActivityNavigator.Extras.Builder setActivityOptions(androidx.core.app.ActivityOptionsCompat);
+ }
+
+ public final class NavBackStackEntry implements androidx.lifecycle.HasDefaultViewModelProviderFactory androidx.lifecycle.LifecycleOwner androidx.savedstate.SavedStateRegistryOwner androidx.lifecycle.ViewModelStoreOwner {
+ method public android.os.Bundle? getArguments();
+ method public androidx.lifecycle.ViewModelProvider.Factory getDefaultViewModelProviderFactory();
+ method public androidx.navigation.NavDestination getDestination();
+ method public androidx.lifecycle.Lifecycle getLifecycle();
+ method public androidx.lifecycle.SavedStateHandle getSavedStateHandle();
+ method public androidx.savedstate.SavedStateRegistry getSavedStateRegistry();
+ method public androidx.lifecycle.ViewModelStore getViewModelStore();
+ }
+
+ public class NavController {
+ ctor public NavController(android.content.Context);
+ method public void addOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener);
+ method public androidx.navigation.NavDeepLinkBuilder createDeepLink();
+ method public androidx.navigation.NavBackStackEntry getBackStackEntry(@IdRes int);
+ method public androidx.navigation.NavBackStackEntry? getCurrentBackStackEntry();
+ method public androidx.navigation.NavDestination? getCurrentDestination();
+ method public androidx.navigation.NavGraph getGraph();
+ method public androidx.navigation.NavInflater getNavInflater();
+ method public androidx.navigation.NavigatorProvider getNavigatorProvider();
+ method public androidx.navigation.NavBackStackEntry? getPreviousBackStackEntry();
+ method public androidx.lifecycle.ViewModelStoreOwner getViewModelStoreOwner(@IdRes int);
+ method public boolean handleDeepLink(android.content.Intent?);
+ method public void navigate(@IdRes int);
+ method public void navigate(@IdRes int, android.os.Bundle?);
+ method public void navigate(@IdRes int, android.os.Bundle?, androidx.navigation.NavOptions?);
+ method public void navigate(@IdRes int, android.os.Bundle?, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+ method public void navigate(android.net.Uri);
+ method public void navigate(android.net.Uri, androidx.navigation.NavOptions?);
+ method public void navigate(android.net.Uri, androidx.navigation.NavOptions?, androidx.navigation.Navigator.Extras?);
+ method public void navigate(androidx.navigation.NavDirections);
+ method public void navigate(androidx.navigation.NavDirections, androidx.navigation.NavOptions?);
+ method public void navigate(androidx.navigation.NavDirections, androidx.navigation.Navigator.Extras);
+ method public boolean navigateUp();
+ method public boolean popBackStack();
+ method public boolean popBackStack(@IdRes int, boolean);
+ method public void removeOnDestinationChangedListener(androidx.navigation.NavController.OnDestinationChangedListener);
+ method @CallSuper public void restoreState(android.os.Bundle?);
+ method @CallSuper public android.os.Bundle? saveState();
+ method @CallSuper public void setGraph(@NavigationRes int);
+ method @CallSuper public void setGraph(@NavigationRes int, android.os.Bundle?);
+ method @CallSuper public void setGraph(androidx.navigation.NavGraph);
+ method @CallSuper public void setGraph(androidx.navigation.NavGraph, android.os.Bundle?);
+ field public static final String KEY_DEEP_LINK_INTENT = "android-support-nav:controller:deepLinkIntent";
+ }
+
+ public static interface NavController.OnDestinationChangedListener {
+ method public void onDestinationChanged(androidx.navigation.NavController, androidx.navigation.NavDestination, android.os.Bundle?);
+ }
+
+ public final class NavDeepLinkBuilder {
+ ctor public NavDeepLinkBuilder(android.content.Context);
+ method public android.app.PendingIntent createPendingIntent();
+ method public androidx.core.app.TaskStackBuilder createTaskStackBuilder();
+ method public androidx.navigation.NavDeepLinkBuilder setArguments(android.os.Bundle?);
+ method public androidx.navigation.NavDeepLinkBuilder setComponentName(Class<? extends android.app.Activity>);
+ method public androidx.navigation.NavDeepLinkBuilder setComponentName(android.content.ComponentName);
+ method public androidx.navigation.NavDeepLinkBuilder setDestination(@IdRes int);
+ method public androidx.navigation.NavDeepLinkBuilder setGraph(@NavigationRes int);
+ method public androidx.navigation.NavDeepLinkBuilder setGraph(androidx.navigation.NavGraph);
+ }
+
+ public interface NavHost {
+ method public androidx.navigation.NavController getNavController();
+ }
+
+ public class NavHostController extends androidx.navigation.NavController {
+ ctor public NavHostController(android.content.Context);
+ method public final void enableOnBackPressed(boolean);
+ method public final void setLifecycleOwner(androidx.lifecycle.LifecycleOwner);
+ method public final void setOnBackPressedDispatcher(androidx.activity.OnBackPressedDispatcher);
+ method public final void setViewModelStore(androidx.lifecycle.ViewModelStore);
+ }
+
+ public final class NavInflater {
+ ctor public NavInflater(android.content.Context, androidx.navigation.NavigatorProvider);
+ method public androidx.navigation.NavGraph inflate(@NavigationRes int);
+ }
+
+ public final class Navigation {
+ method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int);
+ method public static android.view.View.OnClickListener createNavigateOnClickListener(@IdRes int, android.os.Bundle?);
+ method public static android.view.View.OnClickListener createNavigateOnClickListener(androidx.navigation.NavDirections);
+ method public static androidx.navigation.NavController findNavController(android.app.Activity, @IdRes int);
+ method public static androidx.navigation.NavController findNavController(android.view.View);
+ method public static void setViewNavController(android.view.View, androidx.navigation.NavController?);
+ }
+
+}
+
diff --git a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavInflaterTest.kt b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavInflaterTest.kt
index e295fe70..4eebd52 100644
--- a/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavInflaterTest.kt
+++ b/navigation/navigation-runtime/src/androidTest/java/androidx/navigation/NavInflaterTest.kt
@@ -52,6 +52,17 @@
.isEqualTo(R.id.start_test)
}
+ @Test
+ fun testEmptyLabel() {
+ val context = ApplicationProvider.getApplicationContext() as Context
+ val navInflater = NavInflater(context, TestNavigatorProvider())
+ val graph = navInflater.inflate(R.navigation.nav_simple)
+
+ assertThat(graph).isNotNull()
+ assertThat(graph.label)
+ .isEqualTo("")
+ }
+
@Test(expected = RuntimeException::class)
fun testInflateInvalidArgumentArgType() {
val context = ApplicationProvider.getApplicationContext() as Context
diff --git a/navigation/navigation-runtime/src/androidTest/res/navigation/nav_simple.xml b/navigation/navigation-runtime/src/androidTest/res/navigation/nav_simple.xml
index 6063a71..98fec31 100644
--- a/navigation/navigation-runtime/src/androidTest/res/navigation/nav_simple.xml
+++ b/navigation/navigation-runtime/src/androidTest/res/navigation/nav_simple.xml
@@ -17,6 +17,7 @@
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/nav_root"
+ android:label=""
app:startDestination="@+id/start_test">
<test android:id="@+id/start_test">
diff --git a/navigation/navigation-safe-args-gradle-plugin/src/main/kotlin/androidx/navigation/safeargs/gradle/ArgumentsGenerationTask.kt b/navigation/navigation-safe-args-gradle-plugin/src/main/kotlin/androidx/navigation/safeargs/gradle/ArgumentsGenerationTask.kt
index 04e24e3..2eb4685 100644
--- a/navigation/navigation-safe-args-gradle-plugin/src/main/kotlin/androidx/navigation/safeargs/gradle/ArgumentsGenerationTask.kt
+++ b/navigation/navigation-safe-args-gradle-plugin/src/main/kotlin/androidx/navigation/safeargs/gradle/ArgumentsGenerationTask.kt
@@ -27,6 +27,7 @@
import org.gradle.api.resources.TextResource
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
+import org.gradle.api.tasks.Internal
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.work.ChangeType
@@ -40,8 +41,10 @@
@get:Input
lateinit var rFilePackage: Provider<String>
+ @get:Internal
var applicationIdResource: TextResource? = null // null on AGP 3.2.1 and below
+ @get:Internal
var applicationId: String? = null // null on AGP 3.3.0 and above
@get:Input
diff --git a/navigation/navigation-testing/api/2.3.0-alpha04.txt b/navigation/navigation-testing/api/2.3.0-alpha04.txt
new file mode 100644
index 0000000..be673f0
--- /dev/null
+++ b/navigation/navigation-testing/api/2.3.0-alpha04.txt
@@ -0,0 +1,13 @@
+// Signature format: 3.0
+package androidx.navigation.testing {
+
+ public final class TestNavHostController extends androidx.navigation.NavHostController {
+ ctor public TestNavHostController(android.content.Context context);
+ method public java.util.List<androidx.navigation.NavBackStackEntry> getBackStack();
+ method public void setCurrentDestination(@IdRes int destId, android.os.Bundle args = android.os.Bundle());
+ method public void setCurrentDestination(@IdRes int destId);
+ property public final java.util.List<androidx.navigation.NavBackStackEntry> backStack;
+ }
+
+}
+
diff --git a/navigation/navigation-testing/api/public_plus_experimental_2.3.0-alpha04.txt b/navigation/navigation-testing/api/public_plus_experimental_2.3.0-alpha04.txt
new file mode 100644
index 0000000..be673f0
--- /dev/null
+++ b/navigation/navigation-testing/api/public_plus_experimental_2.3.0-alpha04.txt
@@ -0,0 +1,13 @@
+// Signature format: 3.0
+package androidx.navigation.testing {
+
+ public final class TestNavHostController extends androidx.navigation.NavHostController {
+ ctor public TestNavHostController(android.content.Context context);
+ method public java.util.List<androidx.navigation.NavBackStackEntry> getBackStack();
+ method public void setCurrentDestination(@IdRes int destId, android.os.Bundle args = android.os.Bundle());
+ method public void setCurrentDestination(@IdRes int destId);
+ property public final java.util.List<androidx.navigation.NavBackStackEntry> backStack;
+ }
+
+}
+
diff --git a/navigation/navigation-testing/api/restricted_2.3.0-alpha04.txt b/navigation/navigation-testing/api/restricted_2.3.0-alpha04.txt
new file mode 100644
index 0000000..be673f0
--- /dev/null
+++ b/navigation/navigation-testing/api/restricted_2.3.0-alpha04.txt
@@ -0,0 +1,13 @@
+// Signature format: 3.0
+package androidx.navigation.testing {
+
+ public final class TestNavHostController extends androidx.navigation.NavHostController {
+ ctor public TestNavHostController(android.content.Context context);
+ method public java.util.List<androidx.navigation.NavBackStackEntry> getBackStack();
+ method public void setCurrentDestination(@IdRes int destId, android.os.Bundle args = android.os.Bundle());
+ method public void setCurrentDestination(@IdRes int destId);
+ property public final java.util.List<androidx.navigation.NavBackStackEntry> backStack;
+ }
+
+}
+
diff --git a/navigation/navigation-ui-ktx/api/2.3.0-alpha04.ignore b/navigation/navigation-ui-ktx/api/2.3.0-alpha04.ignore
new file mode 100644
index 0000000..657afee
--- /dev/null
+++ b/navigation/navigation-ui-ktx/api/2.3.0-alpha04.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+RemovedMethod: androidx.navigation.ui.AppBarConfigurationKt#AppBarConfiguration(android.view.Menu, androidx.drawerlayout.widget.DrawerLayout, kotlin.jvm.functions.Function0<java.lang.Boolean>):
+ Removed method androidx.navigation.ui.AppBarConfigurationKt.AppBarConfiguration(android.view.Menu,androidx.drawerlayout.widget.DrawerLayout,kotlin.jvm.functions.Function0<java.lang.Boolean>)
+RemovedMethod: androidx.navigation.ui.AppBarConfigurationKt#AppBarConfiguration(androidx.navigation.NavGraph, androidx.drawerlayout.widget.DrawerLayout, kotlin.jvm.functions.Function0<java.lang.Boolean>):
+ Removed method androidx.navigation.ui.AppBarConfigurationKt.AppBarConfiguration(androidx.navigation.NavGraph,androidx.drawerlayout.widget.DrawerLayout,kotlin.jvm.functions.Function0<java.lang.Boolean>)
+RemovedMethod: androidx.navigation.ui.AppBarConfigurationKt#AppBarConfiguration(java.util.Set<java.lang.Integer>, androidx.drawerlayout.widget.DrawerLayout, kotlin.jvm.functions.Function0<java.lang.Boolean>):
+ Removed method androidx.navigation.ui.AppBarConfigurationKt.AppBarConfiguration(java.util.Set<java.lang.Integer>,androidx.drawerlayout.widget.DrawerLayout,kotlin.jvm.functions.Function0<java.lang.Boolean>)
+RemovedMethod: androidx.navigation.ui.NavControllerKt#navigateUp(androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout):
+ Removed method androidx.navigation.ui.NavControllerKt.navigateUp(androidx.navigation.NavController,androidx.drawerlayout.widget.DrawerLayout)
diff --git a/navigation/navigation-ui-ktx/api/2.3.0-alpha04.txt b/navigation/navigation-ui-ktx/api/2.3.0-alpha04.txt
new file mode 100644
index 0000000..168f63e
--- /dev/null
+++ b/navigation/navigation-ui-ktx/api/2.3.0-alpha04.txt
@@ -0,0 +1,43 @@
+// Signature format: 3.0
+package androidx.navigation.ui {
+
+ public final class ActivityKt {
+ method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+ method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController navController, androidx.navigation.ui.AppBarConfiguration configuration = AppBarConfiguration(navController.graph));
+ }
+
+ public final class AppBarConfigurationKt {
+ method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(androidx.navigation.NavGraph navGraph, androidx.customview.widget.Openable? drawerLayout = null, kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener = { false });
+ method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(android.view.Menu topLevelMenu, androidx.customview.widget.Openable? drawerLayout = null, kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener = { false });
+ method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(java.util.Set<java.lang.Integer> topLevelDestinationIds, androidx.customview.widget.Openable? drawerLayout = null, kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener = { false });
+ }
+
+ public final class BottomNavigationViewKt {
+ method public static void setupWithNavController(com.google.android.material.bottomnavigation.BottomNavigationView, androidx.navigation.NavController navController);
+ }
+
+ public final class CollapsingToolbarLayoutKt {
+ method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+ method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.navigation.ui.AppBarConfiguration configuration = AppBarConfiguration(navController.graph));
+ }
+
+ public final class MenuItemKt {
+ method public static boolean onNavDestinationSelected(android.view.MenuItem, androidx.navigation.NavController navController);
+ }
+
+ public final class NavControllerKt {
+ method public static boolean navigateUp(androidx.navigation.NavController, androidx.customview.widget.Openable? drawerLayout);
+ method public static boolean navigateUp(androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration appBarConfiguration);
+ }
+
+ public final class NavigationViewKt {
+ method public static void setupWithNavController(com.google.android.material.navigation.NavigationView, androidx.navigation.NavController navController);
+ }
+
+ public final class ToolbarKt {
+ method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+ method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController navController, androidx.navigation.ui.AppBarConfiguration configuration = AppBarConfiguration(navController.graph));
+ }
+
+}
+
diff --git a/navigation/navigation-ui-ktx/api/public_plus_experimental_2.3.0-alpha04.txt b/navigation/navigation-ui-ktx/api/public_plus_experimental_2.3.0-alpha04.txt
new file mode 100644
index 0000000..168f63e
--- /dev/null
+++ b/navigation/navigation-ui-ktx/api/public_plus_experimental_2.3.0-alpha04.txt
@@ -0,0 +1,43 @@
+// Signature format: 3.0
+package androidx.navigation.ui {
+
+ public final class ActivityKt {
+ method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+ method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController navController, androidx.navigation.ui.AppBarConfiguration configuration = AppBarConfiguration(navController.graph));
+ }
+
+ public final class AppBarConfigurationKt {
+ method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(androidx.navigation.NavGraph navGraph, androidx.customview.widget.Openable? drawerLayout = null, kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener = { false });
+ method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(android.view.Menu topLevelMenu, androidx.customview.widget.Openable? drawerLayout = null, kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener = { false });
+ method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(java.util.Set<java.lang.Integer> topLevelDestinationIds, androidx.customview.widget.Openable? drawerLayout = null, kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener = { false });
+ }
+
+ public final class BottomNavigationViewKt {
+ method public static void setupWithNavController(com.google.android.material.bottomnavigation.BottomNavigationView, androidx.navigation.NavController navController);
+ }
+
+ public final class CollapsingToolbarLayoutKt {
+ method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+ method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.navigation.ui.AppBarConfiguration configuration = AppBarConfiguration(navController.graph));
+ }
+
+ public final class MenuItemKt {
+ method public static boolean onNavDestinationSelected(android.view.MenuItem, androidx.navigation.NavController navController);
+ }
+
+ public final class NavControllerKt {
+ method public static boolean navigateUp(androidx.navigation.NavController, androidx.customview.widget.Openable? drawerLayout);
+ method public static boolean navigateUp(androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration appBarConfiguration);
+ }
+
+ public final class NavigationViewKt {
+ method public static void setupWithNavController(com.google.android.material.navigation.NavigationView, androidx.navigation.NavController navController);
+ }
+
+ public final class ToolbarKt {
+ method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+ method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController navController, androidx.navigation.ui.AppBarConfiguration configuration = AppBarConfiguration(navController.graph));
+ }
+
+}
+
diff --git a/navigation/navigation-ui-ktx/api/restricted_2.3.0-alpha04.ignore b/navigation/navigation-ui-ktx/api/restricted_2.3.0-alpha04.ignore
new file mode 100644
index 0000000..657afee
--- /dev/null
+++ b/navigation/navigation-ui-ktx/api/restricted_2.3.0-alpha04.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+RemovedMethod: androidx.navigation.ui.AppBarConfigurationKt#AppBarConfiguration(android.view.Menu, androidx.drawerlayout.widget.DrawerLayout, kotlin.jvm.functions.Function0<java.lang.Boolean>):
+ Removed method androidx.navigation.ui.AppBarConfigurationKt.AppBarConfiguration(android.view.Menu,androidx.drawerlayout.widget.DrawerLayout,kotlin.jvm.functions.Function0<java.lang.Boolean>)
+RemovedMethod: androidx.navigation.ui.AppBarConfigurationKt#AppBarConfiguration(androidx.navigation.NavGraph, androidx.drawerlayout.widget.DrawerLayout, kotlin.jvm.functions.Function0<java.lang.Boolean>):
+ Removed method androidx.navigation.ui.AppBarConfigurationKt.AppBarConfiguration(androidx.navigation.NavGraph,androidx.drawerlayout.widget.DrawerLayout,kotlin.jvm.functions.Function0<java.lang.Boolean>)
+RemovedMethod: androidx.navigation.ui.AppBarConfigurationKt#AppBarConfiguration(java.util.Set<java.lang.Integer>, androidx.drawerlayout.widget.DrawerLayout, kotlin.jvm.functions.Function0<java.lang.Boolean>):
+ Removed method androidx.navigation.ui.AppBarConfigurationKt.AppBarConfiguration(java.util.Set<java.lang.Integer>,androidx.drawerlayout.widget.DrawerLayout,kotlin.jvm.functions.Function0<java.lang.Boolean>)
+RemovedMethod: androidx.navigation.ui.NavControllerKt#navigateUp(androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout):
+ Removed method androidx.navigation.ui.NavControllerKt.navigateUp(androidx.navigation.NavController,androidx.drawerlayout.widget.DrawerLayout)
diff --git a/navigation/navigation-ui-ktx/api/restricted_2.3.0-alpha04.txt b/navigation/navigation-ui-ktx/api/restricted_2.3.0-alpha04.txt
new file mode 100644
index 0000000..168f63e
--- /dev/null
+++ b/navigation/navigation-ui-ktx/api/restricted_2.3.0-alpha04.txt
@@ -0,0 +1,43 @@
+// Signature format: 3.0
+package androidx.navigation.ui {
+
+ public final class ActivityKt {
+ method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+ method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController navController, androidx.navigation.ui.AppBarConfiguration configuration = AppBarConfiguration(navController.graph));
+ }
+
+ public final class AppBarConfigurationKt {
+ method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(androidx.navigation.NavGraph navGraph, androidx.customview.widget.Openable? drawerLayout = null, kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener = { false });
+ method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(android.view.Menu topLevelMenu, androidx.customview.widget.Openable? drawerLayout = null, kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener = { false });
+ method public static inline androidx.navigation.ui.AppBarConfiguration AppBarConfiguration(java.util.Set<java.lang.Integer> topLevelDestinationIds, androidx.customview.widget.Openable? drawerLayout = null, kotlin.jvm.functions.Function0<java.lang.Boolean> fallbackOnNavigateUpListener = { false });
+ }
+
+ public final class BottomNavigationViewKt {
+ method public static void setupWithNavController(com.google.android.material.bottomnavigation.BottomNavigationView, androidx.navigation.NavController navController);
+ }
+
+ public final class CollapsingToolbarLayoutKt {
+ method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+ method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar toolbar, androidx.navigation.NavController navController, androidx.navigation.ui.AppBarConfiguration configuration = AppBarConfiguration(navController.graph));
+ }
+
+ public final class MenuItemKt {
+ method public static boolean onNavDestinationSelected(android.view.MenuItem, androidx.navigation.NavController navController);
+ }
+
+ public final class NavControllerKt {
+ method public static boolean navigateUp(androidx.navigation.NavController, androidx.customview.widget.Openable? drawerLayout);
+ method public static boolean navigateUp(androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration appBarConfiguration);
+ }
+
+ public final class NavigationViewKt {
+ method public static void setupWithNavController(com.google.android.material.navigation.NavigationView, androidx.navigation.NavController navController);
+ }
+
+ public final class ToolbarKt {
+ method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController navController, androidx.drawerlayout.widget.DrawerLayout? drawerLayout);
+ method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController navController, androidx.navigation.ui.AppBarConfiguration configuration = AppBarConfiguration(navController.graph));
+ }
+
+}
+
diff --git a/navigation/navigation-ui/api/2.3.0-alpha04.ignore b/navigation/navigation-ui/api/2.3.0-alpha04.ignore
new file mode 100644
index 0000000..9e9e553
--- /dev/null
+++ b/navigation/navigation-ui/api/2.3.0-alpha04.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+RemovedMethod: androidx.navigation.ui.NavigationUI#navigateUp(androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout):
+ Removed method androidx.navigation.ui.NavigationUI.navigateUp(androidx.navigation.NavController,androidx.drawerlayout.widget.DrawerLayout)
+RemovedMethod: androidx.navigation.ui.NavigationUI#setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout):
+ Removed method androidx.navigation.ui.NavigationUI.setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity,androidx.navigation.NavController,androidx.drawerlayout.widget.DrawerLayout)
+RemovedMethod: androidx.navigation.ui.NavigationUI#setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout):
+ Removed method androidx.navigation.ui.NavigationUI.setupWithNavController(androidx.appcompat.widget.Toolbar,androidx.navigation.NavController,androidx.drawerlayout.widget.DrawerLayout)
+RemovedMethod: androidx.navigation.ui.NavigationUI#setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout):
+ Removed method androidx.navigation.ui.NavigationUI.setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout,androidx.appcompat.widget.Toolbar,androidx.navigation.NavController,androidx.drawerlayout.widget.DrawerLayout)
diff --git a/navigation/navigation-ui/api/2.3.0-alpha04.txt b/navigation/navigation-ui/api/2.3.0-alpha04.txt
new file mode 100644
index 0000000..694afbd
--- /dev/null
+++ b/navigation/navigation-ui/api/2.3.0-alpha04.txt
@@ -0,0 +1,44 @@
+// Signature format: 3.0
+package androidx.navigation.ui {
+
+ public final class AppBarConfiguration {
+ method @Deprecated public androidx.drawerlayout.widget.DrawerLayout? getDrawerLayout();
+ method public androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? getFallbackOnNavigateUpListener();
+ method public androidx.customview.widget.Openable? getOpenableLayout();
+ method public java.util.Set<java.lang.Integer!> getTopLevelDestinations();
+ }
+
+ public static final class AppBarConfiguration.Builder {
+ ctor public AppBarConfiguration.Builder(androidx.navigation.NavGraph);
+ ctor public AppBarConfiguration.Builder(android.view.Menu);
+ ctor public AppBarConfiguration.Builder(int...);
+ ctor public AppBarConfiguration.Builder(java.util.Set<java.lang.Integer!>);
+ method public androidx.navigation.ui.AppBarConfiguration build();
+ method @Deprecated public androidx.navigation.ui.AppBarConfiguration.Builder setDrawerLayout(androidx.drawerlayout.widget.DrawerLayout?);
+ method public androidx.navigation.ui.AppBarConfiguration.Builder setFallbackOnNavigateUpListener(androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener?);
+ method public androidx.navigation.ui.AppBarConfiguration.Builder setOpenableLayout(androidx.customview.widget.Openable?);
+ }
+
+ public static interface AppBarConfiguration.OnNavigateUpListener {
+ method public boolean onNavigateUp();
+ }
+
+ public final class NavigationUI {
+ method public static boolean navigateUp(androidx.navigation.NavController, androidx.customview.widget.Openable?);
+ method public static boolean navigateUp(androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+ method public static boolean onNavDestinationSelected(android.view.MenuItem, androidx.navigation.NavController);
+ method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController);
+ method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController, androidx.customview.widget.Openable?);
+ method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+ method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController);
+ method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.customview.widget.Openable?);
+ method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+ method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar, androidx.navigation.NavController);
+ method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.customview.widget.Openable?);
+ method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+ method public static void setupWithNavController(com.google.android.material.navigation.NavigationView, androidx.navigation.NavController);
+ method public static void setupWithNavController(com.google.android.material.bottomnavigation.BottomNavigationView, androidx.navigation.NavController);
+ }
+
+}
+
diff --git a/navigation/navigation-ui/api/public_plus_experimental_2.3.0-alpha04.txt b/navigation/navigation-ui/api/public_plus_experimental_2.3.0-alpha04.txt
new file mode 100644
index 0000000..694afbd
--- /dev/null
+++ b/navigation/navigation-ui/api/public_plus_experimental_2.3.0-alpha04.txt
@@ -0,0 +1,44 @@
+// Signature format: 3.0
+package androidx.navigation.ui {
+
+ public final class AppBarConfiguration {
+ method @Deprecated public androidx.drawerlayout.widget.DrawerLayout? getDrawerLayout();
+ method public androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? getFallbackOnNavigateUpListener();
+ method public androidx.customview.widget.Openable? getOpenableLayout();
+ method public java.util.Set<java.lang.Integer!> getTopLevelDestinations();
+ }
+
+ public static final class AppBarConfiguration.Builder {
+ ctor public AppBarConfiguration.Builder(androidx.navigation.NavGraph);
+ ctor public AppBarConfiguration.Builder(android.view.Menu);
+ ctor public AppBarConfiguration.Builder(int...);
+ ctor public AppBarConfiguration.Builder(java.util.Set<java.lang.Integer!>);
+ method public androidx.navigation.ui.AppBarConfiguration build();
+ method @Deprecated public androidx.navigation.ui.AppBarConfiguration.Builder setDrawerLayout(androidx.drawerlayout.widget.DrawerLayout?);
+ method public androidx.navigation.ui.AppBarConfiguration.Builder setFallbackOnNavigateUpListener(androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener?);
+ method public androidx.navigation.ui.AppBarConfiguration.Builder setOpenableLayout(androidx.customview.widget.Openable?);
+ }
+
+ public static interface AppBarConfiguration.OnNavigateUpListener {
+ method public boolean onNavigateUp();
+ }
+
+ public final class NavigationUI {
+ method public static boolean navigateUp(androidx.navigation.NavController, androidx.customview.widget.Openable?);
+ method public static boolean navigateUp(androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+ method public static boolean onNavDestinationSelected(android.view.MenuItem, androidx.navigation.NavController);
+ method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController);
+ method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController, androidx.customview.widget.Openable?);
+ method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+ method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController);
+ method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.customview.widget.Openable?);
+ method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+ method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar, androidx.navigation.NavController);
+ method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.customview.widget.Openable?);
+ method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+ method public static void setupWithNavController(com.google.android.material.navigation.NavigationView, androidx.navigation.NavController);
+ method public static void setupWithNavController(com.google.android.material.bottomnavigation.BottomNavigationView, androidx.navigation.NavController);
+ }
+
+}
+
diff --git a/navigation/navigation-ui/api/restricted_2.3.0-alpha04.ignore b/navigation/navigation-ui/api/restricted_2.3.0-alpha04.ignore
new file mode 100644
index 0000000..9e9e553
--- /dev/null
+++ b/navigation/navigation-ui/api/restricted_2.3.0-alpha04.ignore
@@ -0,0 +1,9 @@
+// Baseline format: 1.0
+RemovedMethod: androidx.navigation.ui.NavigationUI#navigateUp(androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout):
+ Removed method androidx.navigation.ui.NavigationUI.navigateUp(androidx.navigation.NavController,androidx.drawerlayout.widget.DrawerLayout)
+RemovedMethod: androidx.navigation.ui.NavigationUI#setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout):
+ Removed method androidx.navigation.ui.NavigationUI.setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity,androidx.navigation.NavController,androidx.drawerlayout.widget.DrawerLayout)
+RemovedMethod: androidx.navigation.ui.NavigationUI#setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout):
+ Removed method androidx.navigation.ui.NavigationUI.setupWithNavController(androidx.appcompat.widget.Toolbar,androidx.navigation.NavController,androidx.drawerlayout.widget.DrawerLayout)
+RemovedMethod: androidx.navigation.ui.NavigationUI#setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.drawerlayout.widget.DrawerLayout):
+ Removed method androidx.navigation.ui.NavigationUI.setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout,androidx.appcompat.widget.Toolbar,androidx.navigation.NavController,androidx.drawerlayout.widget.DrawerLayout)
diff --git a/navigation/navigation-ui/api/restricted_2.3.0-alpha04.txt b/navigation/navigation-ui/api/restricted_2.3.0-alpha04.txt
new file mode 100644
index 0000000..694afbd
--- /dev/null
+++ b/navigation/navigation-ui/api/restricted_2.3.0-alpha04.txt
@@ -0,0 +1,44 @@
+// Signature format: 3.0
+package androidx.navigation.ui {
+
+ public final class AppBarConfiguration {
+ method @Deprecated public androidx.drawerlayout.widget.DrawerLayout? getDrawerLayout();
+ method public androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener? getFallbackOnNavigateUpListener();
+ method public androidx.customview.widget.Openable? getOpenableLayout();
+ method public java.util.Set<java.lang.Integer!> getTopLevelDestinations();
+ }
+
+ public static final class AppBarConfiguration.Builder {
+ ctor public AppBarConfiguration.Builder(androidx.navigation.NavGraph);
+ ctor public AppBarConfiguration.Builder(android.view.Menu);
+ ctor public AppBarConfiguration.Builder(int...);
+ ctor public AppBarConfiguration.Builder(java.util.Set<java.lang.Integer!>);
+ method public androidx.navigation.ui.AppBarConfiguration build();
+ method @Deprecated public androidx.navigation.ui.AppBarConfiguration.Builder setDrawerLayout(androidx.drawerlayout.widget.DrawerLayout?);
+ method public androidx.navigation.ui.AppBarConfiguration.Builder setFallbackOnNavigateUpListener(androidx.navigation.ui.AppBarConfiguration.OnNavigateUpListener?);
+ method public androidx.navigation.ui.AppBarConfiguration.Builder setOpenableLayout(androidx.customview.widget.Openable?);
+ }
+
+ public static interface AppBarConfiguration.OnNavigateUpListener {
+ method public boolean onNavigateUp();
+ }
+
+ public final class NavigationUI {
+ method public static boolean navigateUp(androidx.navigation.NavController, androidx.customview.widget.Openable?);
+ method public static boolean navigateUp(androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+ method public static boolean onNavDestinationSelected(android.view.MenuItem, androidx.navigation.NavController);
+ method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController);
+ method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController, androidx.customview.widget.Openable?);
+ method public static void setupActionBarWithNavController(androidx.appcompat.app.AppCompatActivity, androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+ method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController);
+ method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.customview.widget.Openable?);
+ method public static void setupWithNavController(androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+ method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar, androidx.navigation.NavController);
+ method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.customview.widget.Openable?);
+ method public static void setupWithNavController(com.google.android.material.appbar.CollapsingToolbarLayout, androidx.appcompat.widget.Toolbar, androidx.navigation.NavController, androidx.navigation.ui.AppBarConfiguration);
+ method public static void setupWithNavController(com.google.android.material.navigation.NavigationView, androidx.navigation.NavController);
+ method public static void setupWithNavController(com.google.android.material.bottomnavigation.BottomNavigationView, androidx.navigation.NavController);
+ }
+
+}
+
diff --git a/navigation/navigation-ui/build.gradle b/navigation/navigation-ui/build.gradle
index eb5a57c..67463c9 100644
--- a/navigation/navigation-ui/build.gradle
+++ b/navigation/navigation-ui/build.gradle
@@ -34,8 +34,8 @@
dependencies {
api(project(":navigation:navigation-runtime"))
- api(project(":customview:customview"))
- api(project(":drawerlayout:drawerlayout"))
+ api("androidx.customview:customview:1.1.0-alpha02")
+ api("androidx.drawerlayout:drawerlayout:1.1.0-alpha04")
api(MATERIAL)
implementation('androidx.transition:transition:1.3.0')
diff --git a/navigation/navigation-ui/src/main/java/androidx/navigation/ui/AbstractAppBarOnDestinationChangedListener.java b/navigation/navigation-ui/src/main/java/androidx/navigation/ui/AbstractAppBarOnDestinationChangedListener.java
index 98fa4c7..59518aa 100644
--- a/navigation/navigation-ui/src/main/java/androidx/navigation/ui/AbstractAppBarOnDestinationChangedListener.java
+++ b/navigation/navigation-ui/src/main/java/androidx/navigation/ui/AbstractAppBarOnDestinationChangedListener.java
@@ -21,7 +21,6 @@
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
-import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -84,7 +83,7 @@
return;
}
CharSequence label = destination.getLabel();
- if (!TextUtils.isEmpty(label)) {
+ if (label != null) {
// Fill in the data pattern with the args to build a valid URI
StringBuffer title = new StringBuffer();
Pattern fillInPattern = Pattern.compile("\\{(.+?)\\}");
diff --git a/paging/common/api/3.0.0-alpha01.txt b/paging/common/api/3.0.0-alpha01.txt
index 7014741..2ab42bfb 100644
--- a/paging/common/api/3.0.0-alpha01.txt
+++ b/paging/common/api/3.0.0-alpha01.txt
@@ -140,25 +140,25 @@
field @Deprecated public final int requestedLoadSize;
}
- public abstract class PagedList<T> extends java.util.AbstractList<T> {
+ @Deprecated public abstract class PagedList<T> extends java.util.AbstractList<T> {
method @Deprecated public final void addWeakCallback(java.util.List<? extends T>? previousSnapshot, androidx.paging.PagedList.Callback callback);
- method public final void addWeakCallback(androidx.paging.PagedList.Callback callback);
- method public final void addWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
- method public abstract void detach();
- method public T? get(int index);
- method public final androidx.paging.PagedList.Config getConfig();
+ method @Deprecated public final void addWeakCallback(androidx.paging.PagedList.Callback callback);
+ method @Deprecated public final void addWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
+ method @Deprecated public abstract void detach();
+ method @Deprecated public T? get(int index);
+ method @Deprecated public final androidx.paging.PagedList.Config getConfig();
method @Deprecated public final androidx.paging.DataSource<?,T> getDataSource();
- method public abstract Object? getLastKey();
- method public final int getLoadedCount();
- method public final int getPositionOffset();
- method public int getSize();
- method public abstract boolean isDetached();
- method public boolean isImmutable();
- method public final void loadAround(int index);
- method public final void removeWeakCallback(androidx.paging.PagedList.Callback callback);
- method public final void removeWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
- method public void retry();
- method public final java.util.List<T> snapshot();
+ method @Deprecated public abstract Object? getLastKey();
+ method @Deprecated public final int getLoadedCount();
+ method @Deprecated public final int getPositionOffset();
+ method @Deprecated public int getSize();
+ method @Deprecated public abstract boolean isDetached();
+ method @Deprecated public boolean isImmutable();
+ method @Deprecated public final void loadAround(int index);
+ method @Deprecated public final void removeWeakCallback(androidx.paging.PagedList.Callback callback);
+ method @Deprecated public final void removeWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
+ method @Deprecated public void retry();
+ method @Deprecated public final java.util.List<T> snapshot();
property @Deprecated public final androidx.paging.DataSource<?,T> dataSource;
property public abstract boolean isDetached;
property public boolean isImmutable;
@@ -168,52 +168,52 @@
property public int size;
}
- @MainThread public abstract static class PagedList.BoundaryCallback<T> {
- ctor public PagedList.BoundaryCallback();
- method public void onItemAtEndLoaded(T itemAtEnd);
- method public void onItemAtFrontLoaded(T itemAtFront);
- method public void onZeroItemsLoaded();
+ @Deprecated @MainThread public abstract static class PagedList.BoundaryCallback<T> {
+ ctor @Deprecated public PagedList.BoundaryCallback();
+ method @Deprecated public void onItemAtEndLoaded(T itemAtEnd);
+ method @Deprecated public void onItemAtFrontLoaded(T itemAtFront);
+ method @Deprecated public void onZeroItemsLoaded();
}
- public static final class PagedList.Builder<Key, Value> {
+ @Deprecated public static final class PagedList.Builder<Key, Value> {
ctor @Deprecated public PagedList.Builder(androidx.paging.DataSource<Key,Value> dataSource, androidx.paging.PagedList.Config config);
ctor @Deprecated public PagedList.Builder(androidx.paging.DataSource<Key,Value> dataSource, int pageSize);
- ctor public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, androidx.paging.PagedList.Config config);
- ctor public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, int pageSize);
- method public androidx.paging.PagedList<Value> build();
- method public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback);
- method public androidx.paging.PagedList.Builder<Key,Value> setCoroutineScope(kotlinx.coroutines.CoroutineScope coroutineScope);
- method public androidx.paging.PagedList.Builder<Key,Value> setFetchDispatcher(kotlinx.coroutines.CoroutineDispatcher fetchDispatcher);
+ ctor @Deprecated public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, androidx.paging.PagedList.Config config);
+ ctor @Deprecated public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, int pageSize);
+ method @Deprecated public androidx.paging.PagedList<Value> build();
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setCoroutineScope(kotlinx.coroutines.CoroutineScope coroutineScope);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setFetchDispatcher(kotlinx.coroutines.CoroutineDispatcher fetchDispatcher);
method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setFetchExecutor(java.util.concurrent.Executor fetchExecutor);
- method public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key? initialKey);
- method public androidx.paging.PagedList.Builder<Key,Value> setNotifyDispatcher(kotlinx.coroutines.CoroutineDispatcher notifyDispatcher);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key? initialKey);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setNotifyDispatcher(kotlinx.coroutines.CoroutineDispatcher notifyDispatcher);
method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setNotifyExecutor(java.util.concurrent.Executor notifyExecutor);
}
- public abstract static class PagedList.Callback {
- ctor public PagedList.Callback();
- method public abstract void onChanged(int position, int count);
- method public abstract void onInserted(int position, int count);
- method public abstract void onRemoved(int position, int count);
+ @Deprecated public abstract static class PagedList.Callback {
+ ctor @Deprecated public PagedList.Callback();
+ method @Deprecated public abstract void onChanged(int position, int count);
+ method @Deprecated public abstract void onInserted(int position, int count);
+ method @Deprecated public abstract void onRemoved(int position, int count);
}
- public static final class PagedList.Config {
- field public static final int MAX_SIZE_UNBOUNDED = 2147483647; // 0x7fffffff
- field public final boolean enablePlaceholders;
- field public final int initialLoadSizeHint;
- field public final int maxSize;
- field public final int pageSize;
- field public final int prefetchDistance;
+ @Deprecated public static final class PagedList.Config {
+ field @Deprecated public static final int MAX_SIZE_UNBOUNDED = 2147483647; // 0x7fffffff
+ field @Deprecated public final boolean enablePlaceholders;
+ field @Deprecated public final int initialLoadSizeHint;
+ field @Deprecated public final int maxSize;
+ field @Deprecated public final int pageSize;
+ field @Deprecated public final int prefetchDistance;
}
- public static final class PagedList.Config.Builder {
- ctor public PagedList.Config.Builder();
- method public androidx.paging.PagedList.Config build();
- method public androidx.paging.PagedList.Config.Builder setEnablePlaceholders(boolean enablePlaceholders);
- method public androidx.paging.PagedList.Config.Builder setInitialLoadSizeHint(@IntRange(from=1) int initialLoadSizeHint);
- method public androidx.paging.PagedList.Config.Builder setMaxSize(@IntRange(from=2) int maxSize);
- method public androidx.paging.PagedList.Config.Builder setPageSize(@IntRange(from=1) int pageSize);
- method public androidx.paging.PagedList.Config.Builder setPrefetchDistance(@IntRange(from=0) int prefetchDistance);
+ @Deprecated public static final class PagedList.Config.Builder {
+ ctor @Deprecated public PagedList.Config.Builder();
+ method @Deprecated public androidx.paging.PagedList.Config build();
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setEnablePlaceholders(boolean enablePlaceholders);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setInitialLoadSizeHint(@IntRange(from=1) int initialLoadSizeHint);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setMaxSize(@IntRange(from=2) int maxSize);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setPageSize(@IntRange(from=1) int pageSize);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setPrefetchDistance(@IntRange(from=0) int prefetchDistance);
}
public final class PagedListConfigKt {
diff --git a/paging/common/api/current.txt b/paging/common/api/current.txt
index 7014741..2ab42bfb 100644
--- a/paging/common/api/current.txt
+++ b/paging/common/api/current.txt
@@ -140,25 +140,25 @@
field @Deprecated public final int requestedLoadSize;
}
- public abstract class PagedList<T> extends java.util.AbstractList<T> {
+ @Deprecated public abstract class PagedList<T> extends java.util.AbstractList<T> {
method @Deprecated public final void addWeakCallback(java.util.List<? extends T>? previousSnapshot, androidx.paging.PagedList.Callback callback);
- method public final void addWeakCallback(androidx.paging.PagedList.Callback callback);
- method public final void addWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
- method public abstract void detach();
- method public T? get(int index);
- method public final androidx.paging.PagedList.Config getConfig();
+ method @Deprecated public final void addWeakCallback(androidx.paging.PagedList.Callback callback);
+ method @Deprecated public final void addWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
+ method @Deprecated public abstract void detach();
+ method @Deprecated public T? get(int index);
+ method @Deprecated public final androidx.paging.PagedList.Config getConfig();
method @Deprecated public final androidx.paging.DataSource<?,T> getDataSource();
- method public abstract Object? getLastKey();
- method public final int getLoadedCount();
- method public final int getPositionOffset();
- method public int getSize();
- method public abstract boolean isDetached();
- method public boolean isImmutable();
- method public final void loadAround(int index);
- method public final void removeWeakCallback(androidx.paging.PagedList.Callback callback);
- method public final void removeWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
- method public void retry();
- method public final java.util.List<T> snapshot();
+ method @Deprecated public abstract Object? getLastKey();
+ method @Deprecated public final int getLoadedCount();
+ method @Deprecated public final int getPositionOffset();
+ method @Deprecated public int getSize();
+ method @Deprecated public abstract boolean isDetached();
+ method @Deprecated public boolean isImmutable();
+ method @Deprecated public final void loadAround(int index);
+ method @Deprecated public final void removeWeakCallback(androidx.paging.PagedList.Callback callback);
+ method @Deprecated public final void removeWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
+ method @Deprecated public void retry();
+ method @Deprecated public final java.util.List<T> snapshot();
property @Deprecated public final androidx.paging.DataSource<?,T> dataSource;
property public abstract boolean isDetached;
property public boolean isImmutable;
@@ -168,52 +168,52 @@
property public int size;
}
- @MainThread public abstract static class PagedList.BoundaryCallback<T> {
- ctor public PagedList.BoundaryCallback();
- method public void onItemAtEndLoaded(T itemAtEnd);
- method public void onItemAtFrontLoaded(T itemAtFront);
- method public void onZeroItemsLoaded();
+ @Deprecated @MainThread public abstract static class PagedList.BoundaryCallback<T> {
+ ctor @Deprecated public PagedList.BoundaryCallback();
+ method @Deprecated public void onItemAtEndLoaded(T itemAtEnd);
+ method @Deprecated public void onItemAtFrontLoaded(T itemAtFront);
+ method @Deprecated public void onZeroItemsLoaded();
}
- public static final class PagedList.Builder<Key, Value> {
+ @Deprecated public static final class PagedList.Builder<Key, Value> {
ctor @Deprecated public PagedList.Builder(androidx.paging.DataSource<Key,Value> dataSource, androidx.paging.PagedList.Config config);
ctor @Deprecated public PagedList.Builder(androidx.paging.DataSource<Key,Value> dataSource, int pageSize);
- ctor public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, androidx.paging.PagedList.Config config);
- ctor public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, int pageSize);
- method public androidx.paging.PagedList<Value> build();
- method public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback);
- method public androidx.paging.PagedList.Builder<Key,Value> setCoroutineScope(kotlinx.coroutines.CoroutineScope coroutineScope);
- method public androidx.paging.PagedList.Builder<Key,Value> setFetchDispatcher(kotlinx.coroutines.CoroutineDispatcher fetchDispatcher);
+ ctor @Deprecated public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, androidx.paging.PagedList.Config config);
+ ctor @Deprecated public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, int pageSize);
+ method @Deprecated public androidx.paging.PagedList<Value> build();
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setCoroutineScope(kotlinx.coroutines.CoroutineScope coroutineScope);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setFetchDispatcher(kotlinx.coroutines.CoroutineDispatcher fetchDispatcher);
method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setFetchExecutor(java.util.concurrent.Executor fetchExecutor);
- method public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key? initialKey);
- method public androidx.paging.PagedList.Builder<Key,Value> setNotifyDispatcher(kotlinx.coroutines.CoroutineDispatcher notifyDispatcher);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key? initialKey);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setNotifyDispatcher(kotlinx.coroutines.CoroutineDispatcher notifyDispatcher);
method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setNotifyExecutor(java.util.concurrent.Executor notifyExecutor);
}
- public abstract static class PagedList.Callback {
- ctor public PagedList.Callback();
- method public abstract void onChanged(int position, int count);
- method public abstract void onInserted(int position, int count);
- method public abstract void onRemoved(int position, int count);
+ @Deprecated public abstract static class PagedList.Callback {
+ ctor @Deprecated public PagedList.Callback();
+ method @Deprecated public abstract void onChanged(int position, int count);
+ method @Deprecated public abstract void onInserted(int position, int count);
+ method @Deprecated public abstract void onRemoved(int position, int count);
}
- public static final class PagedList.Config {
- field public static final int MAX_SIZE_UNBOUNDED = 2147483647; // 0x7fffffff
- field public final boolean enablePlaceholders;
- field public final int initialLoadSizeHint;
- field public final int maxSize;
- field public final int pageSize;
- field public final int prefetchDistance;
+ @Deprecated public static final class PagedList.Config {
+ field @Deprecated public static final int MAX_SIZE_UNBOUNDED = 2147483647; // 0x7fffffff
+ field @Deprecated public final boolean enablePlaceholders;
+ field @Deprecated public final int initialLoadSizeHint;
+ field @Deprecated public final int maxSize;
+ field @Deprecated public final int pageSize;
+ field @Deprecated public final int prefetchDistance;
}
- public static final class PagedList.Config.Builder {
- ctor public PagedList.Config.Builder();
- method public androidx.paging.PagedList.Config build();
- method public androidx.paging.PagedList.Config.Builder setEnablePlaceholders(boolean enablePlaceholders);
- method public androidx.paging.PagedList.Config.Builder setInitialLoadSizeHint(@IntRange(from=1) int initialLoadSizeHint);
- method public androidx.paging.PagedList.Config.Builder setMaxSize(@IntRange(from=2) int maxSize);
- method public androidx.paging.PagedList.Config.Builder setPageSize(@IntRange(from=1) int pageSize);
- method public androidx.paging.PagedList.Config.Builder setPrefetchDistance(@IntRange(from=0) int prefetchDistance);
+ @Deprecated public static final class PagedList.Config.Builder {
+ ctor @Deprecated public PagedList.Config.Builder();
+ method @Deprecated public androidx.paging.PagedList.Config build();
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setEnablePlaceholders(boolean enablePlaceholders);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setInitialLoadSizeHint(@IntRange(from=1) int initialLoadSizeHint);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setMaxSize(@IntRange(from=2) int maxSize);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setPageSize(@IntRange(from=1) int pageSize);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setPrefetchDistance(@IntRange(from=0) int prefetchDistance);
}
public final class PagedListConfigKt {
diff --git a/paging/common/api/public_plus_experimental_3.0.0-alpha01.txt b/paging/common/api/public_plus_experimental_3.0.0-alpha01.txt
index 7014741..2ab42bfb 100644
--- a/paging/common/api/public_plus_experimental_3.0.0-alpha01.txt
+++ b/paging/common/api/public_plus_experimental_3.0.0-alpha01.txt
@@ -140,25 +140,25 @@
field @Deprecated public final int requestedLoadSize;
}
- public abstract class PagedList<T> extends java.util.AbstractList<T> {
+ @Deprecated public abstract class PagedList<T> extends java.util.AbstractList<T> {
method @Deprecated public final void addWeakCallback(java.util.List<? extends T>? previousSnapshot, androidx.paging.PagedList.Callback callback);
- method public final void addWeakCallback(androidx.paging.PagedList.Callback callback);
- method public final void addWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
- method public abstract void detach();
- method public T? get(int index);
- method public final androidx.paging.PagedList.Config getConfig();
+ method @Deprecated public final void addWeakCallback(androidx.paging.PagedList.Callback callback);
+ method @Deprecated public final void addWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
+ method @Deprecated public abstract void detach();
+ method @Deprecated public T? get(int index);
+ method @Deprecated public final androidx.paging.PagedList.Config getConfig();
method @Deprecated public final androidx.paging.DataSource<?,T> getDataSource();
- method public abstract Object? getLastKey();
- method public final int getLoadedCount();
- method public final int getPositionOffset();
- method public int getSize();
- method public abstract boolean isDetached();
- method public boolean isImmutable();
- method public final void loadAround(int index);
- method public final void removeWeakCallback(androidx.paging.PagedList.Callback callback);
- method public final void removeWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
- method public void retry();
- method public final java.util.List<T> snapshot();
+ method @Deprecated public abstract Object? getLastKey();
+ method @Deprecated public final int getLoadedCount();
+ method @Deprecated public final int getPositionOffset();
+ method @Deprecated public int getSize();
+ method @Deprecated public abstract boolean isDetached();
+ method @Deprecated public boolean isImmutable();
+ method @Deprecated public final void loadAround(int index);
+ method @Deprecated public final void removeWeakCallback(androidx.paging.PagedList.Callback callback);
+ method @Deprecated public final void removeWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
+ method @Deprecated public void retry();
+ method @Deprecated public final java.util.List<T> snapshot();
property @Deprecated public final androidx.paging.DataSource<?,T> dataSource;
property public abstract boolean isDetached;
property public boolean isImmutable;
@@ -168,52 +168,52 @@
property public int size;
}
- @MainThread public abstract static class PagedList.BoundaryCallback<T> {
- ctor public PagedList.BoundaryCallback();
- method public void onItemAtEndLoaded(T itemAtEnd);
- method public void onItemAtFrontLoaded(T itemAtFront);
- method public void onZeroItemsLoaded();
+ @Deprecated @MainThread public abstract static class PagedList.BoundaryCallback<T> {
+ ctor @Deprecated public PagedList.BoundaryCallback();
+ method @Deprecated public void onItemAtEndLoaded(T itemAtEnd);
+ method @Deprecated public void onItemAtFrontLoaded(T itemAtFront);
+ method @Deprecated public void onZeroItemsLoaded();
}
- public static final class PagedList.Builder<Key, Value> {
+ @Deprecated public static final class PagedList.Builder<Key, Value> {
ctor @Deprecated public PagedList.Builder(androidx.paging.DataSource<Key,Value> dataSource, androidx.paging.PagedList.Config config);
ctor @Deprecated public PagedList.Builder(androidx.paging.DataSource<Key,Value> dataSource, int pageSize);
- ctor public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, androidx.paging.PagedList.Config config);
- ctor public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, int pageSize);
- method public androidx.paging.PagedList<Value> build();
- method public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback);
- method public androidx.paging.PagedList.Builder<Key,Value> setCoroutineScope(kotlinx.coroutines.CoroutineScope coroutineScope);
- method public androidx.paging.PagedList.Builder<Key,Value> setFetchDispatcher(kotlinx.coroutines.CoroutineDispatcher fetchDispatcher);
+ ctor @Deprecated public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, androidx.paging.PagedList.Config config);
+ ctor @Deprecated public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, int pageSize);
+ method @Deprecated public androidx.paging.PagedList<Value> build();
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setCoroutineScope(kotlinx.coroutines.CoroutineScope coroutineScope);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setFetchDispatcher(kotlinx.coroutines.CoroutineDispatcher fetchDispatcher);
method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setFetchExecutor(java.util.concurrent.Executor fetchExecutor);
- method public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key? initialKey);
- method public androidx.paging.PagedList.Builder<Key,Value> setNotifyDispatcher(kotlinx.coroutines.CoroutineDispatcher notifyDispatcher);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key? initialKey);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setNotifyDispatcher(kotlinx.coroutines.CoroutineDispatcher notifyDispatcher);
method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setNotifyExecutor(java.util.concurrent.Executor notifyExecutor);
}
- public abstract static class PagedList.Callback {
- ctor public PagedList.Callback();
- method public abstract void onChanged(int position, int count);
- method public abstract void onInserted(int position, int count);
- method public abstract void onRemoved(int position, int count);
+ @Deprecated public abstract static class PagedList.Callback {
+ ctor @Deprecated public PagedList.Callback();
+ method @Deprecated public abstract void onChanged(int position, int count);
+ method @Deprecated public abstract void onInserted(int position, int count);
+ method @Deprecated public abstract void onRemoved(int position, int count);
}
- public static final class PagedList.Config {
- field public static final int MAX_SIZE_UNBOUNDED = 2147483647; // 0x7fffffff
- field public final boolean enablePlaceholders;
- field public final int initialLoadSizeHint;
- field public final int maxSize;
- field public final int pageSize;
- field public final int prefetchDistance;
+ @Deprecated public static final class PagedList.Config {
+ field @Deprecated public static final int MAX_SIZE_UNBOUNDED = 2147483647; // 0x7fffffff
+ field @Deprecated public final boolean enablePlaceholders;
+ field @Deprecated public final int initialLoadSizeHint;
+ field @Deprecated public final int maxSize;
+ field @Deprecated public final int pageSize;
+ field @Deprecated public final int prefetchDistance;
}
- public static final class PagedList.Config.Builder {
- ctor public PagedList.Config.Builder();
- method public androidx.paging.PagedList.Config build();
- method public androidx.paging.PagedList.Config.Builder setEnablePlaceholders(boolean enablePlaceholders);
- method public androidx.paging.PagedList.Config.Builder setInitialLoadSizeHint(@IntRange(from=1) int initialLoadSizeHint);
- method public androidx.paging.PagedList.Config.Builder setMaxSize(@IntRange(from=2) int maxSize);
- method public androidx.paging.PagedList.Config.Builder setPageSize(@IntRange(from=1) int pageSize);
- method public androidx.paging.PagedList.Config.Builder setPrefetchDistance(@IntRange(from=0) int prefetchDistance);
+ @Deprecated public static final class PagedList.Config.Builder {
+ ctor @Deprecated public PagedList.Config.Builder();
+ method @Deprecated public androidx.paging.PagedList.Config build();
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setEnablePlaceholders(boolean enablePlaceholders);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setInitialLoadSizeHint(@IntRange(from=1) int initialLoadSizeHint);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setMaxSize(@IntRange(from=2) int maxSize);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setPageSize(@IntRange(from=1) int pageSize);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setPrefetchDistance(@IntRange(from=0) int prefetchDistance);
}
public final class PagedListConfigKt {
diff --git a/paging/common/api/public_plus_experimental_current.txt b/paging/common/api/public_plus_experimental_current.txt
index 7014741..2ab42bfb 100644
--- a/paging/common/api/public_plus_experimental_current.txt
+++ b/paging/common/api/public_plus_experimental_current.txt
@@ -140,25 +140,25 @@
field @Deprecated public final int requestedLoadSize;
}
- public abstract class PagedList<T> extends java.util.AbstractList<T> {
+ @Deprecated public abstract class PagedList<T> extends java.util.AbstractList<T> {
method @Deprecated public final void addWeakCallback(java.util.List<? extends T>? previousSnapshot, androidx.paging.PagedList.Callback callback);
- method public final void addWeakCallback(androidx.paging.PagedList.Callback callback);
- method public final void addWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
- method public abstract void detach();
- method public T? get(int index);
- method public final androidx.paging.PagedList.Config getConfig();
+ method @Deprecated public final void addWeakCallback(androidx.paging.PagedList.Callback callback);
+ method @Deprecated public final void addWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
+ method @Deprecated public abstract void detach();
+ method @Deprecated public T? get(int index);
+ method @Deprecated public final androidx.paging.PagedList.Config getConfig();
method @Deprecated public final androidx.paging.DataSource<?,T> getDataSource();
- method public abstract Object? getLastKey();
- method public final int getLoadedCount();
- method public final int getPositionOffset();
- method public int getSize();
- method public abstract boolean isDetached();
- method public boolean isImmutable();
- method public final void loadAround(int index);
- method public final void removeWeakCallback(androidx.paging.PagedList.Callback callback);
- method public final void removeWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
- method public void retry();
- method public final java.util.List<T> snapshot();
+ method @Deprecated public abstract Object? getLastKey();
+ method @Deprecated public final int getLoadedCount();
+ method @Deprecated public final int getPositionOffset();
+ method @Deprecated public int getSize();
+ method @Deprecated public abstract boolean isDetached();
+ method @Deprecated public boolean isImmutable();
+ method @Deprecated public final void loadAround(int index);
+ method @Deprecated public final void removeWeakCallback(androidx.paging.PagedList.Callback callback);
+ method @Deprecated public final void removeWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
+ method @Deprecated public void retry();
+ method @Deprecated public final java.util.List<T> snapshot();
property @Deprecated public final androidx.paging.DataSource<?,T> dataSource;
property public abstract boolean isDetached;
property public boolean isImmutable;
@@ -168,52 +168,52 @@
property public int size;
}
- @MainThread public abstract static class PagedList.BoundaryCallback<T> {
- ctor public PagedList.BoundaryCallback();
- method public void onItemAtEndLoaded(T itemAtEnd);
- method public void onItemAtFrontLoaded(T itemAtFront);
- method public void onZeroItemsLoaded();
+ @Deprecated @MainThread public abstract static class PagedList.BoundaryCallback<T> {
+ ctor @Deprecated public PagedList.BoundaryCallback();
+ method @Deprecated public void onItemAtEndLoaded(T itemAtEnd);
+ method @Deprecated public void onItemAtFrontLoaded(T itemAtFront);
+ method @Deprecated public void onZeroItemsLoaded();
}
- public static final class PagedList.Builder<Key, Value> {
+ @Deprecated public static final class PagedList.Builder<Key, Value> {
ctor @Deprecated public PagedList.Builder(androidx.paging.DataSource<Key,Value> dataSource, androidx.paging.PagedList.Config config);
ctor @Deprecated public PagedList.Builder(androidx.paging.DataSource<Key,Value> dataSource, int pageSize);
- ctor public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, androidx.paging.PagedList.Config config);
- ctor public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, int pageSize);
- method public androidx.paging.PagedList<Value> build();
- method public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback);
- method public androidx.paging.PagedList.Builder<Key,Value> setCoroutineScope(kotlinx.coroutines.CoroutineScope coroutineScope);
- method public androidx.paging.PagedList.Builder<Key,Value> setFetchDispatcher(kotlinx.coroutines.CoroutineDispatcher fetchDispatcher);
+ ctor @Deprecated public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, androidx.paging.PagedList.Config config);
+ ctor @Deprecated public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, int pageSize);
+ method @Deprecated public androidx.paging.PagedList<Value> build();
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setCoroutineScope(kotlinx.coroutines.CoroutineScope coroutineScope);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setFetchDispatcher(kotlinx.coroutines.CoroutineDispatcher fetchDispatcher);
method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setFetchExecutor(java.util.concurrent.Executor fetchExecutor);
- method public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key? initialKey);
- method public androidx.paging.PagedList.Builder<Key,Value> setNotifyDispatcher(kotlinx.coroutines.CoroutineDispatcher notifyDispatcher);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key? initialKey);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setNotifyDispatcher(kotlinx.coroutines.CoroutineDispatcher notifyDispatcher);
method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setNotifyExecutor(java.util.concurrent.Executor notifyExecutor);
}
- public abstract static class PagedList.Callback {
- ctor public PagedList.Callback();
- method public abstract void onChanged(int position, int count);
- method public abstract void onInserted(int position, int count);
- method public abstract void onRemoved(int position, int count);
+ @Deprecated public abstract static class PagedList.Callback {
+ ctor @Deprecated public PagedList.Callback();
+ method @Deprecated public abstract void onChanged(int position, int count);
+ method @Deprecated public abstract void onInserted(int position, int count);
+ method @Deprecated public abstract void onRemoved(int position, int count);
}
- public static final class PagedList.Config {
- field public static final int MAX_SIZE_UNBOUNDED = 2147483647; // 0x7fffffff
- field public final boolean enablePlaceholders;
- field public final int initialLoadSizeHint;
- field public final int maxSize;
- field public final int pageSize;
- field public final int prefetchDistance;
+ @Deprecated public static final class PagedList.Config {
+ field @Deprecated public static final int MAX_SIZE_UNBOUNDED = 2147483647; // 0x7fffffff
+ field @Deprecated public final boolean enablePlaceholders;
+ field @Deprecated public final int initialLoadSizeHint;
+ field @Deprecated public final int maxSize;
+ field @Deprecated public final int pageSize;
+ field @Deprecated public final int prefetchDistance;
}
- public static final class PagedList.Config.Builder {
- ctor public PagedList.Config.Builder();
- method public androidx.paging.PagedList.Config build();
- method public androidx.paging.PagedList.Config.Builder setEnablePlaceholders(boolean enablePlaceholders);
- method public androidx.paging.PagedList.Config.Builder setInitialLoadSizeHint(@IntRange(from=1) int initialLoadSizeHint);
- method public androidx.paging.PagedList.Config.Builder setMaxSize(@IntRange(from=2) int maxSize);
- method public androidx.paging.PagedList.Config.Builder setPageSize(@IntRange(from=1) int pageSize);
- method public androidx.paging.PagedList.Config.Builder setPrefetchDistance(@IntRange(from=0) int prefetchDistance);
+ @Deprecated public static final class PagedList.Config.Builder {
+ ctor @Deprecated public PagedList.Config.Builder();
+ method @Deprecated public androidx.paging.PagedList.Config build();
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setEnablePlaceholders(boolean enablePlaceholders);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setInitialLoadSizeHint(@IntRange(from=1) int initialLoadSizeHint);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setMaxSize(@IntRange(from=2) int maxSize);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setPageSize(@IntRange(from=1) int pageSize);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setPrefetchDistance(@IntRange(from=0) int prefetchDistance);
}
public final class PagedListConfigKt {
diff --git a/paging/common/api/restricted_3.0.0-alpha01.txt b/paging/common/api/restricted_3.0.0-alpha01.txt
index 7014741..2ab42bfb 100644
--- a/paging/common/api/restricted_3.0.0-alpha01.txt
+++ b/paging/common/api/restricted_3.0.0-alpha01.txt
@@ -140,25 +140,25 @@
field @Deprecated public final int requestedLoadSize;
}
- public abstract class PagedList<T> extends java.util.AbstractList<T> {
+ @Deprecated public abstract class PagedList<T> extends java.util.AbstractList<T> {
method @Deprecated public final void addWeakCallback(java.util.List<? extends T>? previousSnapshot, androidx.paging.PagedList.Callback callback);
- method public final void addWeakCallback(androidx.paging.PagedList.Callback callback);
- method public final void addWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
- method public abstract void detach();
- method public T? get(int index);
- method public final androidx.paging.PagedList.Config getConfig();
+ method @Deprecated public final void addWeakCallback(androidx.paging.PagedList.Callback callback);
+ method @Deprecated public final void addWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
+ method @Deprecated public abstract void detach();
+ method @Deprecated public T? get(int index);
+ method @Deprecated public final androidx.paging.PagedList.Config getConfig();
method @Deprecated public final androidx.paging.DataSource<?,T> getDataSource();
- method public abstract Object? getLastKey();
- method public final int getLoadedCount();
- method public final int getPositionOffset();
- method public int getSize();
- method public abstract boolean isDetached();
- method public boolean isImmutable();
- method public final void loadAround(int index);
- method public final void removeWeakCallback(androidx.paging.PagedList.Callback callback);
- method public final void removeWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
- method public void retry();
- method public final java.util.List<T> snapshot();
+ method @Deprecated public abstract Object? getLastKey();
+ method @Deprecated public final int getLoadedCount();
+ method @Deprecated public final int getPositionOffset();
+ method @Deprecated public int getSize();
+ method @Deprecated public abstract boolean isDetached();
+ method @Deprecated public boolean isImmutable();
+ method @Deprecated public final void loadAround(int index);
+ method @Deprecated public final void removeWeakCallback(androidx.paging.PagedList.Callback callback);
+ method @Deprecated public final void removeWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
+ method @Deprecated public void retry();
+ method @Deprecated public final java.util.List<T> snapshot();
property @Deprecated public final androidx.paging.DataSource<?,T> dataSource;
property public abstract boolean isDetached;
property public boolean isImmutable;
@@ -168,52 +168,52 @@
property public int size;
}
- @MainThread public abstract static class PagedList.BoundaryCallback<T> {
- ctor public PagedList.BoundaryCallback();
- method public void onItemAtEndLoaded(T itemAtEnd);
- method public void onItemAtFrontLoaded(T itemAtFront);
- method public void onZeroItemsLoaded();
+ @Deprecated @MainThread public abstract static class PagedList.BoundaryCallback<T> {
+ ctor @Deprecated public PagedList.BoundaryCallback();
+ method @Deprecated public void onItemAtEndLoaded(T itemAtEnd);
+ method @Deprecated public void onItemAtFrontLoaded(T itemAtFront);
+ method @Deprecated public void onZeroItemsLoaded();
}
- public static final class PagedList.Builder<Key, Value> {
+ @Deprecated public static final class PagedList.Builder<Key, Value> {
ctor @Deprecated public PagedList.Builder(androidx.paging.DataSource<Key,Value> dataSource, androidx.paging.PagedList.Config config);
ctor @Deprecated public PagedList.Builder(androidx.paging.DataSource<Key,Value> dataSource, int pageSize);
- ctor public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, androidx.paging.PagedList.Config config);
- ctor public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, int pageSize);
- method public androidx.paging.PagedList<Value> build();
- method public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback);
- method public androidx.paging.PagedList.Builder<Key,Value> setCoroutineScope(kotlinx.coroutines.CoroutineScope coroutineScope);
- method public androidx.paging.PagedList.Builder<Key,Value> setFetchDispatcher(kotlinx.coroutines.CoroutineDispatcher fetchDispatcher);
+ ctor @Deprecated public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, androidx.paging.PagedList.Config config);
+ ctor @Deprecated public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, int pageSize);
+ method @Deprecated public androidx.paging.PagedList<Value> build();
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setCoroutineScope(kotlinx.coroutines.CoroutineScope coroutineScope);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setFetchDispatcher(kotlinx.coroutines.CoroutineDispatcher fetchDispatcher);
method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setFetchExecutor(java.util.concurrent.Executor fetchExecutor);
- method public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key? initialKey);
- method public androidx.paging.PagedList.Builder<Key,Value> setNotifyDispatcher(kotlinx.coroutines.CoroutineDispatcher notifyDispatcher);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key? initialKey);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setNotifyDispatcher(kotlinx.coroutines.CoroutineDispatcher notifyDispatcher);
method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setNotifyExecutor(java.util.concurrent.Executor notifyExecutor);
}
- public abstract static class PagedList.Callback {
- ctor public PagedList.Callback();
- method public abstract void onChanged(int position, int count);
- method public abstract void onInserted(int position, int count);
- method public abstract void onRemoved(int position, int count);
+ @Deprecated public abstract static class PagedList.Callback {
+ ctor @Deprecated public PagedList.Callback();
+ method @Deprecated public abstract void onChanged(int position, int count);
+ method @Deprecated public abstract void onInserted(int position, int count);
+ method @Deprecated public abstract void onRemoved(int position, int count);
}
- public static final class PagedList.Config {
- field public static final int MAX_SIZE_UNBOUNDED = 2147483647; // 0x7fffffff
- field public final boolean enablePlaceholders;
- field public final int initialLoadSizeHint;
- field public final int maxSize;
- field public final int pageSize;
- field public final int prefetchDistance;
+ @Deprecated public static final class PagedList.Config {
+ field @Deprecated public static final int MAX_SIZE_UNBOUNDED = 2147483647; // 0x7fffffff
+ field @Deprecated public final boolean enablePlaceholders;
+ field @Deprecated public final int initialLoadSizeHint;
+ field @Deprecated public final int maxSize;
+ field @Deprecated public final int pageSize;
+ field @Deprecated public final int prefetchDistance;
}
- public static final class PagedList.Config.Builder {
- ctor public PagedList.Config.Builder();
- method public androidx.paging.PagedList.Config build();
- method public androidx.paging.PagedList.Config.Builder setEnablePlaceholders(boolean enablePlaceholders);
- method public androidx.paging.PagedList.Config.Builder setInitialLoadSizeHint(@IntRange(from=1) int initialLoadSizeHint);
- method public androidx.paging.PagedList.Config.Builder setMaxSize(@IntRange(from=2) int maxSize);
- method public androidx.paging.PagedList.Config.Builder setPageSize(@IntRange(from=1) int pageSize);
- method public androidx.paging.PagedList.Config.Builder setPrefetchDistance(@IntRange(from=0) int prefetchDistance);
+ @Deprecated public static final class PagedList.Config.Builder {
+ ctor @Deprecated public PagedList.Config.Builder();
+ method @Deprecated public androidx.paging.PagedList.Config build();
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setEnablePlaceholders(boolean enablePlaceholders);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setInitialLoadSizeHint(@IntRange(from=1) int initialLoadSizeHint);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setMaxSize(@IntRange(from=2) int maxSize);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setPageSize(@IntRange(from=1) int pageSize);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setPrefetchDistance(@IntRange(from=0) int prefetchDistance);
}
public final class PagedListConfigKt {
diff --git a/paging/common/api/restricted_current.txt b/paging/common/api/restricted_current.txt
index 7014741..2ab42bfb 100644
--- a/paging/common/api/restricted_current.txt
+++ b/paging/common/api/restricted_current.txt
@@ -140,25 +140,25 @@
field @Deprecated public final int requestedLoadSize;
}
- public abstract class PagedList<T> extends java.util.AbstractList<T> {
+ @Deprecated public abstract class PagedList<T> extends java.util.AbstractList<T> {
method @Deprecated public final void addWeakCallback(java.util.List<? extends T>? previousSnapshot, androidx.paging.PagedList.Callback callback);
- method public final void addWeakCallback(androidx.paging.PagedList.Callback callback);
- method public final void addWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
- method public abstract void detach();
- method public T? get(int index);
- method public final androidx.paging.PagedList.Config getConfig();
+ method @Deprecated public final void addWeakCallback(androidx.paging.PagedList.Callback callback);
+ method @Deprecated public final void addWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
+ method @Deprecated public abstract void detach();
+ method @Deprecated public T? get(int index);
+ method @Deprecated public final androidx.paging.PagedList.Config getConfig();
method @Deprecated public final androidx.paging.DataSource<?,T> getDataSource();
- method public abstract Object? getLastKey();
- method public final int getLoadedCount();
- method public final int getPositionOffset();
- method public int getSize();
- method public abstract boolean isDetached();
- method public boolean isImmutable();
- method public final void loadAround(int index);
- method public final void removeWeakCallback(androidx.paging.PagedList.Callback callback);
- method public final void removeWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
- method public void retry();
- method public final java.util.List<T> snapshot();
+ method @Deprecated public abstract Object? getLastKey();
+ method @Deprecated public final int getLoadedCount();
+ method @Deprecated public final int getPositionOffset();
+ method @Deprecated public int getSize();
+ method @Deprecated public abstract boolean isDetached();
+ method @Deprecated public boolean isImmutable();
+ method @Deprecated public final void loadAround(int index);
+ method @Deprecated public final void removeWeakCallback(androidx.paging.PagedList.Callback callback);
+ method @Deprecated public final void removeWeakLoadStateListener(kotlin.jvm.functions.Function2<? super androidx.paging.LoadType,? super androidx.paging.LoadState,kotlin.Unit> listener);
+ method @Deprecated public void retry();
+ method @Deprecated public final java.util.List<T> snapshot();
property @Deprecated public final androidx.paging.DataSource<?,T> dataSource;
property public abstract boolean isDetached;
property public boolean isImmutable;
@@ -168,52 +168,52 @@
property public int size;
}
- @MainThread public abstract static class PagedList.BoundaryCallback<T> {
- ctor public PagedList.BoundaryCallback();
- method public void onItemAtEndLoaded(T itemAtEnd);
- method public void onItemAtFrontLoaded(T itemAtFront);
- method public void onZeroItemsLoaded();
+ @Deprecated @MainThread public abstract static class PagedList.BoundaryCallback<T> {
+ ctor @Deprecated public PagedList.BoundaryCallback();
+ method @Deprecated public void onItemAtEndLoaded(T itemAtEnd);
+ method @Deprecated public void onItemAtFrontLoaded(T itemAtFront);
+ method @Deprecated public void onZeroItemsLoaded();
}
- public static final class PagedList.Builder<Key, Value> {
+ @Deprecated public static final class PagedList.Builder<Key, Value> {
ctor @Deprecated public PagedList.Builder(androidx.paging.DataSource<Key,Value> dataSource, androidx.paging.PagedList.Config config);
ctor @Deprecated public PagedList.Builder(androidx.paging.DataSource<Key,Value> dataSource, int pageSize);
- ctor public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, androidx.paging.PagedList.Config config);
- ctor public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, int pageSize);
- method public androidx.paging.PagedList<Value> build();
- method public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback);
- method public androidx.paging.PagedList.Builder<Key,Value> setCoroutineScope(kotlinx.coroutines.CoroutineScope coroutineScope);
- method public androidx.paging.PagedList.Builder<Key,Value> setFetchDispatcher(kotlinx.coroutines.CoroutineDispatcher fetchDispatcher);
+ ctor @Deprecated public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, androidx.paging.PagedList.Config config);
+ ctor @Deprecated public PagedList.Builder(androidx.paging.PagingSource<Key,Value> pagingSource, androidx.paging.PagingSource.LoadResult.Page<Key,Value> initialPage, int pageSize);
+ method @Deprecated public androidx.paging.PagedList<Value> build();
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setBoundaryCallback(androidx.paging.PagedList.BoundaryCallback<Value>? boundaryCallback);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setCoroutineScope(kotlinx.coroutines.CoroutineScope coroutineScope);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setFetchDispatcher(kotlinx.coroutines.CoroutineDispatcher fetchDispatcher);
method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setFetchExecutor(java.util.concurrent.Executor fetchExecutor);
- method public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key? initialKey);
- method public androidx.paging.PagedList.Builder<Key,Value> setNotifyDispatcher(kotlinx.coroutines.CoroutineDispatcher notifyDispatcher);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setInitialKey(Key? initialKey);
+ method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setNotifyDispatcher(kotlinx.coroutines.CoroutineDispatcher notifyDispatcher);
method @Deprecated public androidx.paging.PagedList.Builder<Key,Value> setNotifyExecutor(java.util.concurrent.Executor notifyExecutor);
}
- public abstract static class PagedList.Callback {
- ctor public PagedList.Callback();
- method public abstract void onChanged(int position, int count);
- method public abstract void onInserted(int position, int count);
- method public abstract void onRemoved(int position, int count);
+ @Deprecated public abstract static class PagedList.Callback {
+ ctor @Deprecated public PagedList.Callback();
+ method @Deprecated public abstract void onChanged(int position, int count);
+ method @Deprecated public abstract void onInserted(int position, int count);
+ method @Deprecated public abstract void onRemoved(int position, int count);
}
- public static final class PagedList.Config {
- field public static final int MAX_SIZE_UNBOUNDED = 2147483647; // 0x7fffffff
- field public final boolean enablePlaceholders;
- field public final int initialLoadSizeHint;
- field public final int maxSize;
- field public final int pageSize;
- field public final int prefetchDistance;
+ @Deprecated public static final class PagedList.Config {
+ field @Deprecated public static final int MAX_SIZE_UNBOUNDED = 2147483647; // 0x7fffffff
+ field @Deprecated public final boolean enablePlaceholders;
+ field @Deprecated public final int initialLoadSizeHint;
+ field @Deprecated public final int maxSize;
+ field @Deprecated public final int pageSize;
+ field @Deprecated public final int prefetchDistance;
}
- public static final class PagedList.Config.Builder {
- ctor public PagedList.Config.Builder();
- method public androidx.paging.PagedList.Config build();
- method public androidx.paging.PagedList.Config.Builder setEnablePlaceholders(boolean enablePlaceholders);
- method public androidx.paging.PagedList.Config.Builder setInitialLoadSizeHint(@IntRange(from=1) int initialLoadSizeHint);
- method public androidx.paging.PagedList.Config.Builder setMaxSize(@IntRange(from=2) int maxSize);
- method public androidx.paging.PagedList.Config.Builder setPageSize(@IntRange(from=1) int pageSize);
- method public androidx.paging.PagedList.Config.Builder setPrefetchDistance(@IntRange(from=0) int prefetchDistance);
+ @Deprecated public static final class PagedList.Config.Builder {
+ ctor @Deprecated public PagedList.Config.Builder();
+ method @Deprecated public androidx.paging.PagedList.Config build();
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setEnablePlaceholders(boolean enablePlaceholders);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setInitialLoadSizeHint(@IntRange(from=1) int initialLoadSizeHint);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setMaxSize(@IntRange(from=2) int maxSize);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setPageSize(@IntRange(from=1) int pageSize);
+ method @Deprecated public androidx.paging.PagedList.Config.Builder setPrefetchDistance(@IntRange(from=0) int prefetchDistance);
}
public final class PagedListConfigKt {
diff --git a/paging/common/src/main/kotlin/androidx/paging/CachedPagingData.kt b/paging/common/src/main/kotlin/androidx/paging/CachedPagingData.kt
index 4cd9476..812be18 100644
--- a/paging/common/src/main/kotlin/androidx/paging/CachedPagingData.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/CachedPagingData.kt
@@ -30,14 +30,13 @@
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.scan
-@UseExperimental(ExperimentalCoroutinesApi::class)
+@UseExperimental(ExperimentalCoroutinesApi::class, FlowPreview::class)
private class MulticastedPagingData<T : Any>(
val scope: CoroutineScope,
val parent: PagingData<T>,
// used in tests
val tracker: ActiveFlowTracker? = null
) {
- @FlowPreview
private val accumulated = CachedPageEventFlow(
src = parent.flow.onStart {
tracker?.onStart(PAGE_EVENT_FLOW)
@@ -47,15 +46,12 @@
scope = scope
)
- @FlowPreview
- @ExperimentalCoroutinesApi
fun asPagingData() = PagingData(
flow = accumulated.downstreamFlow,
receiver = parent.receiver
)
@FlowPreview
- @ExperimentalCoroutinesApi
suspend fun close() = accumulated.close()
}
@@ -74,32 +70,15 @@
* Note that this does not turn the `Flow<PagingData>` into a hot stream. It won't execute any
* unnecessary code unless it is being collected.
*
- * ```
- * class MyViewModel : ViewModel() {
- * val pagingData : Flow<PagingData<Item>> = PagingDataFlowBuilder(
- * pagingSourceFactory = <factory>,
- * config = <config>)
- * ).build()
- * .cached(viewModelScope)
- * }
- *
- * class MyActivity : Activity() {
- * override fun onCreate() {
- * val pages = myViewModel.pagingData
- * }
- * }
- * ```
+ * @sample androidx.paging.samples.cachedInSample
*
* @param scope The coroutine scope where this page cache will be kept alive.
*/
-@ExperimentalCoroutinesApi
-@FlowPreview
fun <T : Any> Flow<PagingData<T>>.cachedIn(
scope: CoroutineScope
) = cachedIn(scope, null)
-@FlowPreview
-@ExperimentalCoroutinesApi
+@UseExperimental(ExperimentalCoroutinesApi::class, FlowPreview::class)
internal fun <T : Any> Flow<PagingData<T>>.cachedIn(
scope: CoroutineScope,
// used in tests
diff --git a/paging/common/src/main/kotlin/androidx/paging/ContiguousPagedList.kt b/paging/common/src/main/kotlin/androidx/paging/ContiguousPagedList.kt
index ebd597d..5481a4b 100644
--- a/paging/common/src/main/kotlin/androidx/paging/ContiguousPagedList.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/ContiguousPagedList.kt
@@ -32,6 +32,7 @@
/**
* @suppress
*/
+@Suppress("DEPRECATION")
@RestrictTo(RestrictTo.Scope.LIBRARY)
open class ContiguousPagedList<K : Any, V : Any>(
final override val pagingSource: PagingSource<K, V>,
diff --git a/paging/common/src/main/kotlin/androidx/paging/LegacyPager.kt b/paging/common/src/main/kotlin/androidx/paging/LegacyPager.kt
index a167d70..7882738 100644
--- a/paging/common/src/main/kotlin/androidx/paging/LegacyPager.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/LegacyPager.kt
@@ -24,6 +24,7 @@
internal class LegacyPager<K : Any, V : Any>(
private val pagedListScope: CoroutineScope,
+ @Suppress("DEPRECATION")
val config: PagedList.Config,
val source: PagingSource<K, V>,
private val notifyDispatcher: CoroutineDispatcher,
@@ -33,6 +34,7 @@
) {
private val detached = AtomicBoolean(false)
+ @Suppress("DEPRECATION")
var loadStateManager = object : PagedList.LoadStateManager() {
override fun onStateChanged(type: LoadType, state: LoadState) {
pageConsumer.onStateChanged(type, state)
@@ -105,7 +107,7 @@
loadStateManager.setState(LoadType.START, LoadState.Loading)
- val loadParams = LoadParams<K>(
+ val loadParams = LoadParams(
LoadType.START,
key,
config.pageSize,
diff --git a/paging/common/src/main/kotlin/androidx/paging/PagedList.kt b/paging/common/src/main/kotlin/androidx/paging/PagedList.kt
index 5a82670..b01c0ab 100644
--- a/paging/common/src/main/kotlin/androidx/paging/PagedList.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/PagedList.kt
@@ -21,10 +21,6 @@
import androidx.annotation.IntRange
import androidx.annotation.MainThread
import androidx.annotation.RestrictTo
-import androidx.paging.PagedList.Callback
-import androidx.paging.PagedList.Config
-import androidx.paging.PagedList.Config.Builder
-import androidx.paging.PagedList.Config.Companion.MAX_SIZE_UNBOUNDED
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
@@ -118,6 +114,7 @@
*
* @param T The type of the entries in the list.
*/
+@Deprecated("PagedList is deprecated and has been replaced by PagingData")
abstract class PagedList<T : Any> internal constructor(
/**
* The [PagingSource] that provides data to this [PagedList].
@@ -160,6 +157,7 @@
*
* @suppress
*/
+ @Suppress("DEPRECATION")
@JvmStatic
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
fun <K : Any, T : Any> create(
@@ -255,6 +253,11 @@
* @param Key Type of key used to load data from the [PagingSource].
* @param Value Type of items held and loaded by the [PagedList].
*/
+ @Deprecated(
+ message = "PagedList is deprecated and has been replaced by PagingData, which no " +
+ "longer supports constructing snapshots of loaded data manually.",
+ replaceWith = ReplaceWith("PagingDataFlow", "androidx.paging.PagingDataFlow")
+ )
class Builder<Key : Any, Value : Any> {
private val pagingSource: PagingSource<Key, Value>?
private var dataSource: DataSource<Key, Value>?
@@ -272,7 +275,6 @@
* @param dataSource [DataSource] the [PagedList] will load from.
* @param config [Config] that defines how the [PagedList] loads data from its [DataSource].
*/
- @Deprecated("DataSource is deprecated and has been replaced by PagingSource")
constructor(dataSource: DataSource<Key, Value>, config: Config) {
this.pagingSource = null
this.dataSource = dataSource
@@ -293,8 +295,6 @@
* @param pageSize [Config] that defines how the [PagedList] loads data from its
* [DataSource].
*/
- @Suppress("DEPRECATION")
- @Deprecated("DataSource is deprecated and has been replaced by PagingSource")
constructor(dataSource: DataSource<Key, Value>, pageSize: Int) : this(
dataSource = dataSource,
config = Config(pageSize)
@@ -476,6 +476,7 @@
*
* @return The newly constructed [PagedList]
*/
+ @Suppress("DEPRECATION")
fun build(): PagedList<Value> {
val fetchDispatcher = fetchDispatcher ?: Dispatchers.IO
val pagingSource = pagingSource
@@ -1234,11 +1235,11 @@
* @param boundaryCallback [PagedList.BoundaryCallback] for listening to out-of-data events.
* @param initialKey [Key] the [DataSource] should load around as part of initialization.
*/
-@Suppress("FunctionName", "DeprecatedCallableAddReplaceWith")
+@Suppress("FunctionName", "DEPRECATION")
@Deprecated("DataSource is deprecated and has been replaced by PagingSource")
fun <Key : Any, Value : Any> PagedList(
dataSource: DataSource<Key, Value>,
- config: Config,
+ config: PagedList.Config,
notifyExecutor: Executor,
fetchExecutor: Executor,
boundaryCallback: PagedList.BoundaryCallback<Value>? = null,
diff --git a/paging/common/src/main/kotlin/androidx/paging/PagedListConfig.kt b/paging/common/src/main/kotlin/androidx/paging/PagedListConfig.kt
index 06a2157..c58704b 100644
--- a/paging/common/src/main/kotlin/androidx/paging/PagedListConfig.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/PagedListConfig.kt
@@ -16,9 +16,6 @@
package androidx.paging
-import androidx.paging.PagedList.Config.Builder.Companion.DEFAULT_INITIAL_PAGE_MULTIPLIER
-import androidx.paging.PagedList.Config.Companion.MAX_SIZE_UNBOUNDED
-
/**
* Constructs a [PagedList.Config], convenience for [PagedList.Config.Builder].
*
@@ -29,13 +26,13 @@
* @param maxSize Maximum number of items to keep in memory, or
* [PagedList.Config.MAX_SIZE_UNBOUNDED] to disable page dropping.
*/
-@Suppress("FunctionName")
+@Suppress("FunctionName", "DEPRECATION")
fun Config(
pageSize: Int,
prefetchDistance: Int = pageSize,
enablePlaceholders: Boolean = true,
- initialLoadSizeHint: Int = pageSize * DEFAULT_INITIAL_PAGE_MULTIPLIER,
- maxSize: Int = MAX_SIZE_UNBOUNDED
+ initialLoadSizeHint: Int = pageSize * PagedList.Config.Builder.DEFAULT_INITIAL_PAGE_MULTIPLIER,
+ maxSize: Int = PagedList.Config.MAX_SIZE_UNBOUNDED
): PagedList.Config {
return PagedList.Config.Builder()
.setPageSize(pageSize)
diff --git a/paging/common/src/main/kotlin/androidx/paging/PagerState.kt b/paging/common/src/main/kotlin/androidx/paging/PagerState.kt
index ba5b10e..510bbaa 100644
--- a/paging/common/src/main/kotlin/androidx/paging/PagerState.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/PagerState.kt
@@ -23,7 +23,6 @@
import androidx.paging.PageEvent.Insert.Companion.End
import androidx.paging.PageEvent.Insert.Companion.Refresh
import androidx.paging.PageEvent.Insert.Companion.Start
-import androidx.paging.PagedList.Config.Companion.MAX_SIZE_UNBOUNDED
import androidx.paging.PagingSource.LoadResult.Page
import androidx.paging.PagingSource.LoadResult.Page.Companion.COUNT_UNDEFINED
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -202,7 +201,8 @@
START -> {
// TODO: Incrementally compute this.
val currentSize = pages.sumBy { it.data.size }
- if (maxSize != MAX_SIZE_UNBOUNDED && currentSize > maxSize) {
+ @Suppress("DEPRECATION")
+ if (maxSize != PagedList.Config.MAX_SIZE_UNBOUNDED && currentSize > maxSize) {
var pageCount = 0
var itemCount = 0
pages.takeWhile {
@@ -217,7 +217,8 @@
END -> {
// TODO: Incrementally compute this.
val currentSize = pages.sumBy { it.data.size }
- if (maxSize != MAX_SIZE_UNBOUNDED && currentSize > maxSize) {
+ @Suppress("DEPRECATION")
+ if (maxSize != PagedList.Config.MAX_SIZE_UNBOUNDED && currentSize > maxSize) {
var pageCount = 0
var itemCount = 0
pages.takeLastWhile {
diff --git a/paging/common/src/main/kotlin/androidx/paging/PagingData.kt b/paging/common/src/main/kotlin/androidx/paging/PagingData.kt
index 1879158..50024228 100644
--- a/paging/common/src/main/kotlin/androidx/paging/PagingData.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/PagingData.kt
@@ -64,30 +64,10 @@
* Returns a [PagingData] containing each original element, with an optional separator generated
* by [generator], given the elements before and after (or null, in boundary conditions).
*
- * For example, to create letter separators in an alphabetically sorted list:
- *
- * ```
- * flow.insertSeparators { before: String?, after: String? ->
- * if (before == null || before.get(0) != after?.get(0) ?: null) {
- * // separator - after is first item with its first letter
- * after.get(0).toUpperCase().toString()
- * } else {
- * // no separator - first letters of before/after are the same
- * null
- * }
- * }
- * ```
- *
- * This transformation would make the example data set:
- *
- * "apple", "apricot", "banana", "carrot"
- *
- * Become:
- *
- * "A", "apple", "apricot", "B", "banana", "C", "carrot"
- *
* Note that this transform is applied asynchronously, as pages are loaded. Potential
* separators between pages are only computed once both pages are loaded.
+ *
+ * @sample androidx.paging.samples.insertSeparatorsSample
*/
fun <R : T> insertSeparators(
generator: (T?, T?) -> R?
diff --git a/paging/common/src/main/kotlin/androidx/paging/PagingSource.kt b/paging/common/src/main/kotlin/androidx/paging/PagingSource.kt
index 0c78f1b..1d5c59a 100644
--- a/paging/common/src/main/kotlin/androidx/paging/PagingSource.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/PagingSource.kt
@@ -24,6 +24,7 @@
/**
* @suppress
*/
+@Suppress("DEPRECATION")
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
fun <Key : Any> PagedList.Config.toRefreshLoadParams(key: Key?): PagingSource.LoadParams<Key> =
PagingSource.LoadParams(
diff --git a/paging/common/src/main/kotlin/androidx/paging/SnapshotPagedList.kt b/paging/common/src/main/kotlin/androidx/paging/SnapshotPagedList.kt
index a560bfc..bd7c42f 100644
--- a/paging/common/src/main/kotlin/androidx/paging/SnapshotPagedList.kt
+++ b/paging/common/src/main/kotlin/androidx/paging/SnapshotPagedList.kt
@@ -16,6 +16,7 @@
package androidx.paging
+@Suppress("DEPRECATION")
internal class SnapshotPagedList<T : Any>(private val pagedList: PagedList<T>) : PagedList<T>(
pagedList.pagingSource,
pagedList.storage.snapshot(),
diff --git a/paging/common/src/test/kotlin/androidx/paging/PagedListConfigBuilderTest.kt b/paging/common/src/test/kotlin/androidx/paging/PagedListConfigBuilderTest.kt
index 05faea4..ad107b9 100644
--- a/paging/common/src/test/kotlin/androidx/paging/PagedListConfigBuilderTest.kt
+++ b/paging/common/src/test/kotlin/androidx/paging/PagedListConfigBuilderTest.kt
@@ -25,6 +25,7 @@
class PagedListConfigBuilderTest {
@Test
fun defaults() {
+ @Suppress("DEPRECATION")
val config = PagedList.Config.Builder()
.setPageSize(10)
.build()
@@ -32,11 +33,13 @@
Assert.assertEquals(30, config.initialLoadSizeHint)
Assert.assertEquals(true, config.enablePlaceholders)
Assert.assertEquals(10, config.prefetchDistance)
+ @Suppress("DEPRECATION")
Assert.assertEquals(PagedList.Config.MAX_SIZE_UNBOUNDED, config.maxSize)
}
@Test(expected = IllegalArgumentException::class)
fun maxSizeTooSmall() {
+ @Suppress("DEPRECATION")
PagedList.Config.Builder()
.setPageSize(20)
.setPrefetchDistance(15)
@@ -46,6 +49,7 @@
@Test
fun maxSizeAccepted() {
+ @Suppress("DEPRECATION")
PagedList.Config.Builder()
.setPageSize(20)
.setPrefetchDistance(15)
diff --git a/paging/integration-tests/samples/build.gradle b/paging/integration-tests/samples/build.gradle
new file mode 100644
index 0000000..99c723e
--- /dev/null
+++ b/paging/integration-tests/samples/build.gradle
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 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.
+ */
+
+plugins {
+ id("AndroidXPlugin")
+ id("com.android.library")
+ id("kotlin-android")
+}
+
+dependencies {
+ implementation("androidx.appcompat:appcompat:1.1.0")
+
+ implementation(project(":annotation:annotation-sampled"))
+ implementation(project(":lifecycle:lifecycle-viewmodel-ktx"))
+ implementation(project(":fragment:fragment-ktx"))
+ implementation(project(":paging:paging-runtime"))
+ implementation(project(":recyclerview:recyclerview"))
+}
diff --git a/paging/integration-tests/samples/src/main/AndroidManifest.xml b/paging/integration-tests/samples/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..344848e
--- /dev/null
+++ b/paging/integration-tests/samples/src/main/AndroidManifest.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+ ~ Copyright (C) 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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="androidx.paging.samples"/>
diff --git a/paging/integration-tests/samples/src/main/java/androidx/paging/samples/BasePagingAdapter.kt b/paging/integration-tests/samples/src/main/java/androidx/paging/samples/BasePagingAdapter.kt
new file mode 100644
index 0000000..f762d5b
--- /dev/null
+++ b/paging/integration-tests/samples/src/main/java/androidx/paging/samples/BasePagingAdapter.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.paging.samples
+
+import android.view.ViewGroup
+import androidx.paging.PagingDataAdapter
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.RecyclerView
+
+/**
+ * No-op PagingAdapter interface impl to be used by sample code that doesn't show adapter impl
+ */
+internal open class BasePagingAdapter<T : Any> : PagingDataAdapter<T, RecyclerView.ViewHolder>(
+ object : DiffUtil.ItemCallback<T>() {
+ override fun areItemsTheSame(oldItem: T, newItem: T): Boolean {
+ return true
+ }
+
+ override fun areContentsTheSame(oldItem: T, newItem: T): Boolean {
+ return true
+ }
+ }
+) {
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
+ throw NotImplementedError()
+ }
+
+ override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
+ throw NotImplementedError()
+ }
+}
diff --git a/paging/integration-tests/samples/src/main/java/androidx/paging/samples/BaseViewModel.kt b/paging/integration-tests/samples/src/main/java/androidx/paging/samples/BaseViewModel.kt
new file mode 100644
index 0000000..63a56b2
--- /dev/null
+++ b/paging/integration-tests/samples/src/main/java/androidx/paging/samples/BaseViewModel.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.paging.samples
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.viewModelScope
+import androidx.paging.PagingConfig
+import androidx.paging.PagingDataFlow
+import androidx.paging.PagingSource
+import androidx.paging.cachedIn
+
+/**
+ * No-op ViewModel base class to be used by sample code that doesn't show ViewModel impl
+ */
+open class BaseViewModel<T : Any> : ViewModel() {
+ private lateinit var pagingSourceFactory: () -> PagingSource<String, T>
+
+ val pagingFlow = PagingDataFlow(PagingConfig(pageSize = 40), pagingSourceFactory)
+ .cachedIn(viewModelScope)
+}
\ No newline at end of file
diff --git a/paging/integration-tests/samples/src/main/java/androidx/paging/samples/CachedInSample.kt b/paging/integration-tests/samples/src/main/java/androidx/paging/samples/CachedInSample.kt
new file mode 100644
index 0000000..27fdbf6
--- /dev/null
+++ b/paging/integration-tests/samples/src/main/java/androidx/paging/samples/CachedInSample.kt
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+@file:Suppress("unused")
+
+package androidx.paging.samples
+
+import android.os.Bundle
+import androidx.activity.viewModels
+import androidx.annotation.Sampled
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.viewModelScope
+import androidx.paging.PagingConfig
+import androidx.paging.PagingDataFlow
+import androidx.paging.PagingSource
+import androidx.paging.cachedIn
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+
+internal class UiModel(@Suppress("UNUSED_PARAMETER") string: String)
+internal class MyPagingAdapter : BasePagingAdapter<UiModel>()
+internal class MyViewModel : BaseViewModel<UiModel>()
+lateinit var pagingSourceFactory: () -> PagingSource<String, String>
+
+@ExperimentalCoroutinesApi
+@Sampled
+fun cachedInSample() {
+ class MyViewModel : ViewModel() {
+ val flow = PagingDataFlow(PagingConfig(pageSize = 40), pagingSourceFactory)
+ // Loads and transformations before the cachedIn operation will be cached, so that
+ // multiple observers get the same data. This is true either for simultaneous
+ // observers, or e.g. an Activity re-subscribing after being recreated
+ .cachedIn(viewModelScope)
+ }
+
+ class MyActivity : AppCompatActivity() {
+ val pagingAdapter = MyPagingAdapter()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val viewModel by viewModels<MyViewModel>()
+
+ lifecycleScope.launch {
+ viewModel.flow
+ // Any transformations after the ViewModel's cachedIn step will not be cached,
+ // and will instead by re-run immediately on Activity re-creation.
+ .map { pagingData ->
+ // example un-cached transformation
+ pagingData.map { UiModel(it) }
+ }
+ .collectLatest {
+ pagingAdapter.presentData(it)
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/paging/integration-tests/samples/src/main/java/androidx/paging/samples/PagingDataAdapterSample.kt b/paging/integration-tests/samples/src/main/java/androidx/paging/samples/PagingDataAdapterSample.kt
new file mode 100644
index 0000000..a62edce
--- /dev/null
+++ b/paging/integration-tests/samples/src/main/java/androidx/paging/samples/PagingDataAdapterSample.kt
@@ -0,0 +1,122 @@
+/*
+ * 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.
+ */
+
+@file:Suppress("unused")
+
+package androidx.paging.samples
+
+import android.os.Bundle
+import android.view.View
+import android.view.ViewGroup
+import androidx.activity.viewModels
+import androidx.annotation.Sampled
+import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.lifecycleScope
+import androidx.paging.PagingDataAdapter
+import androidx.recyclerview.widget.DiffUtil
+import androidx.recyclerview.widget.RecyclerView
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.launch
+
+data class User(
+ val userId: String,
+ val favoriteFood: String,
+ val isFavorite: Boolean
+)
+
+// TODO: consider adding a fleshed out ViewHolder as part of the sample
+@Suppress("UNUSED_PARAMETER")
+class UserViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+ fun bind(user: User?) {}
+
+ companion object {
+ fun create(parent: ViewGroup): UserViewHolder {
+ throw NotImplementedError()
+ }
+ }
+}
+
+@Suppress("LocalVariableName") // We're pretending local val is global
+@Sampled
+fun pagingDataAdapterSample() {
+ val USER_COMPARATOR = object : DiffUtil.ItemCallback<User>() {
+ override fun areItemsTheSame(oldItem: User, newItem: User): Boolean =
+ // User ID serves as unique ID
+ oldItem.userId == newItem.userId
+
+ override fun areContentsTheSame(oldItem: User, newItem: User): Boolean =
+ // Compare full contents (note: Java users should call .equals())
+ oldItem == newItem
+ }
+
+ class UserAdapter : PagingDataAdapter<User, UserViewHolder>(USER_COMPARATOR) {
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
+ return UserViewHolder.create(parent)
+ }
+
+ override fun onBindViewHolder(holder: UserViewHolder, position: Int) {
+ val repoItem = getItem(position)
+ // Note that item may be null, ViewHolder must support binding null item as placeholder
+ holder.bind(repoItem)
+ }
+ }
+}
+
+internal class UserPagingAdapter : BasePagingAdapter<User>()
+internal class UserListViewModel : BaseViewModel<User>()
+
+@ExperimentalCoroutinesApi
+@Sampled
+fun presentDataSample() {
+ class MyActivity : AppCompatActivity() {
+ val pagingAdapter = UserPagingAdapter()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val viewModel by viewModels<UserListViewModel>()
+
+ lifecycleScope.launch {
+ viewModel.pagingFlow
+ .collectLatest {
+ // present data suspends, so you typically want collectLatest {}
+ // when using it to present data
+ pagingAdapter.presentData(it)
+ }
+ }
+ }
+ }
+}
+
+@ExperimentalCoroutinesApi
+@Sampled
+fun submitDataSample() {
+ class MyActivity : AppCompatActivity() {
+ val pagingAdapter = UserPagingAdapter()
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ val viewModel by viewModels<UserListViewModel>()
+
+ lifecycleScope.launch {
+ viewModel.pagingFlow
+ .collectLatest {
+ pagingAdapter.submitData(lifecycle, it)
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/paging/integration-tests/samples/src/main/java/androidx/paging/samples/PagingDataSample.kt b/paging/integration-tests/samples/src/main/java/androidx/paging/samples/PagingDataSample.kt
new file mode 100644
index 0000000..061284d
--- /dev/null
+++ b/paging/integration-tests/samples/src/main/java/androidx/paging/samples/PagingDataSample.kt
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+@file:Suppress("unused") // Currently, all samples incorrectly labeled as unused.
+
+package androidx.paging.samples
+
+import androidx.annotation.Sampled
+import androidx.paging.PagingData
+
+lateinit var pagingData: PagingData<String>
+
+@Sampled
+fun insertSeparatorsSample() {
+ /*
+ * Create letter separators in an alphabetically sorted list.
+ *
+ * For example, if the input is:
+ * "apple", "apricot", "banana", "carrot"
+ *
+ * The operator would output:
+ * "A", "apple", "apricot", "B", "banana", "C", "carrot"
+ */
+ pagingData.insertSeparators { before: String?, after: String? ->
+ if (after != null && before?.first() != after.first()) {
+ // separator - after is first item that starts with its first letter
+ after.first().toUpperCase().toString()
+ } else {
+ // no separator - either end of list, or first letters of before/after are the same
+ null
+ }
+ }
+}
diff --git a/paging/integration-tests/testapp/build.gradle b/paging/integration-tests/testapp/build.gradle
index 6d3dd8f..93073da 100644
--- a/paging/integration-tests/testapp/build.gradle
+++ b/paging/integration-tests/testapp/build.gradle
@@ -26,14 +26,14 @@
dependencies {
implementation("androidx.arch.core:core-runtime:2.1.0")
- implementation("androidx.room:room-runtime:2.2.3")
- implementation("androidx.room:room-rxjava2:2.2.3")
+ implementation("androidx.room:room-runtime:2.2.5")
+ implementation("androidx.room:room-rxjava2:2.2.5")
implementation(project(":paging:paging-common-ktx"))
implementation(project(":paging:paging-runtime"))
implementation(project(":paging:paging-rxjava2"))
- kapt("androidx.room:room-compiler:2.2.3")
+ kapt("androidx.room:room-compiler:2.2.5")
implementation(MULTIDEX)
implementation(project(":recyclerview:recyclerview"))
diff --git a/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/custom/PagedListSampleActivity.kt b/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/custom/PagedListSampleActivity.kt
index f98408f..978d355 100644
--- a/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/custom/PagedListSampleActivity.kt
+++ b/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/custom/PagedListSampleActivity.kt
@@ -47,6 +47,7 @@
footer = StateItemAdapter { pagingAdapter.currentList?.retry() }
)
+ @Suppress("DEPRECATION")
viewModel.livePagedList.observe(this,
Observer<PagedList<Item>> { pagingAdapter.submitList(it) })
diff --git a/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3/V3Activity.kt b/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3/V3Activity.kt
index 7607187..a81c33e 100644
--- a/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3/V3Activity.kt
+++ b/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3/V3Activity.kt
@@ -29,14 +29,10 @@
import androidx.paging.PagingDataAdapter
import androidx.paging.integration.testapp.R
import androidx.recyclerview.widget.RecyclerView
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
-@ExperimentalCoroutinesApi
-@FlowPreview
class V3Activity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
diff --git a/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3/V3ViewModel.kt b/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3/V3ViewModel.kt
index 3bfe61d..dd1cffb 100644
--- a/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3/V3ViewModel.kt
+++ b/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3/V3ViewModel.kt
@@ -22,13 +22,9 @@
import androidx.paging.PagingConfig
import androidx.paging.PagingDataFlow
import androidx.paging.cachedIn
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.map
-@ExperimentalCoroutinesApi
class V3ViewModel : ViewModel() {
- @FlowPreview
val flow = PagingDataFlow(PagingConfig(10), ItemPagingSource.Factory)
.map { pagingData ->
pagingData
diff --git a/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3room/V3RoomActivity.kt b/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3room/V3RoomActivity.kt
index 06ed030..e36cd36 100644
--- a/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3room/V3RoomActivity.kt
+++ b/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3room/V3RoomActivity.kt
@@ -28,8 +28,6 @@
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
-@ExperimentalCoroutinesApi
-@FlowPreview
class V3RoomActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
diff --git a/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3room/V3RoomViewModel.kt b/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3room/V3RoomViewModel.kt
index 54a2c9b..c6ba658 100644
--- a/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3room/V3RoomViewModel.kt
+++ b/paging/integration-tests/testapp/src/main/java/androidx/paging/integration/testapp/v3room/V3RoomViewModel.kt
@@ -32,7 +32,6 @@
import kotlinx.coroutines.flow.map
import java.util.UUID
-@ExperimentalCoroutinesApi
class V3RoomViewModel(application: Application) : AndroidViewModel(application) {
val database = Room.databaseBuilder(
getApplication(),
@@ -62,7 +61,6 @@
private val pagingSourceFactory = database.customerDao.loadPagedAgeOrder()
.asPagingSourceFactory()
- @FlowPreview
val flow = PagingDataFlow(PagingConfig(10), pagingSourceFactory)
.map { pagingData ->
pagingData
diff --git a/paging/runtime/src/androidTest/java/androidx/paging/AsyncPagedListDifferTest.kt b/paging/runtime/src/androidTest/java/androidx/paging/AsyncPagedListDifferTest.kt
index 8136a07..01a27f2 100644
--- a/paging/runtime/src/androidTest/java/androidx/paging/AsyncPagedListDifferTest.kt
+++ b/paging/runtime/src/androidTest/java/androidx/paging/AsyncPagedListDifferTest.kt
@@ -60,12 +60,12 @@
return differ
}
+ @Suppress("DEPRECATION")
private fun <V : Any> createPagedListFromListAndPos(
config: PagedList.Config,
data: List<V>,
initialKey: Int
): PagedList<V> {
- @Suppress("DEPRECATION")
return PagedList.Builder(ListDataSource(data), config)
.setInitialKey(initialKey)
.setNotifyExecutor(mainThread)
@@ -165,6 +165,7 @@
@Test
fun pagingInContent() {
+ @Suppress("DEPRECATION")
val config = PagedList.Config.Builder()
.setInitialLoadSizeHint(4)
.setPageSize(2)
@@ -214,6 +215,7 @@
@Test
fun simpleSwap() {
// Page size large enough to load
+ @Suppress("DEPRECATION")
val config = PagedList.Config.Builder()
.setPageSize(50)
.build()
@@ -247,6 +249,7 @@
@Test
fun oldListUpdateIgnoredWhileDiffing() {
+ @Suppress("DEPRECATION")
val config = PagedList.Config.Builder()
.setInitialLoadSizeHint(4)
.setPageSize(2)
@@ -358,6 +361,7 @@
val differ = createDiffer(callback)
differAccessor[0] = differ
+ @Suppress("DEPRECATION")
val config = PagedList.Config.Builder()
.setPageSize(20)
.build()
@@ -386,6 +390,7 @@
fun loadAroundHandlePrepend() {
val differ = createDiffer()
+ @Suppress("DEPRECATION")
val config = PagedList.Config.Builder()
.setPageSize(5)
.setEnablePlaceholders(false)
@@ -406,6 +411,7 @@
@Test
fun submitSubset() {
// Page size large enough to load
+ @Suppress("DEPRECATION")
val config = PagedList.Config.Builder()
.setInitialLoadSizeHint(4)
.setPageSize(2)
@@ -522,9 +528,11 @@
@Test
fun addRemovePagedListCallback() {
val differ = createDiffer()
+ @Suppress("DEPRECATION")
val noopCallback = { _: PagedList<String>?, _: PagedList<String>? -> }
differ.addPagedListListener(noopCallback)
assert(differ.listeners.size == 1)
+ @Suppress("DEPRECATION")
differ.removePagedListListener { _: PagedList<String>?, _: PagedList<String>? -> }
assert(differ.listeners.size == 1)
differ.removePagedListListener(noopCallback)
diff --git a/paging/runtime/src/androidTest/java/androidx/paging/LivePagedListBuilderTest.kt b/paging/runtime/src/androidTest/java/androidx/paging/LivePagedListBuilderTest.kt
index f61b6e3..13b0d53 100644
--- a/paging/runtime/src/androidTest/java/androidx/paging/LivePagedListBuilderTest.kt
+++ b/paging/runtime/src/androidTest/java/androidx/paging/LivePagedListBuilderTest.kt
@@ -140,8 +140,10 @@
.setFetchExecutor(backgroundExecutor)
.build()
+ @Suppress("DEPRECATION")
val pagedListHolder: Array<PagedList<String>?> = arrayOfNulls(1)
+ @Suppress("DEPRECATION")
livePagedList.observe(lifecycleOwner, Observer<PagedList<String>> { newList ->
pagedListHolder[0] = newList
})
@@ -174,8 +176,10 @@
.setFetchExecutor(backgroundExecutor)
.build()
+ @Suppress("DEPRECATION")
val pagedListHolder: Array<PagedList<String>?> = arrayOfNulls(1)
+ @Suppress("DEPRECATION")
livePagedList.observe(lifecycleOwner, Observer<PagedList<String>> { newList ->
pagedListHolder[0] = newList
})
diff --git a/paging/runtime/src/androidTest/java/androidx/paging/PagedListAdapterTest.kt b/paging/runtime/src/androidTest/java/androidx/paging/PagedListAdapterTest.kt
index f90857d..2480c96 100644
--- a/paging/runtime/src/androidTest/java/androidx/paging/PagedListAdapterTest.kt
+++ b/paging/runtime/src/androidTest/java/androidx/paging/PagedListAdapterTest.kt
@@ -58,6 +58,7 @@
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) =
throw IllegalStateException("not supported")
+ @Suppress("OverridingDeprecatedMember")
override fun onCurrentListChanged(currentList: PagedList<String>?) {
onChangedLegacy?.onCurrentListChanged(null, currentList)
}
@@ -137,12 +138,10 @@
}
private fun verifyOnCurrentListChanged(
- @Suppress("DEPRECATION")
- legacyListener: AsyncPagedListDiffer.PagedListListener<String>,
- @Suppress("DEPRECATION")
- listener: AsyncPagedListDiffer.PagedListListener<String>,
- previousList: PagedList<String>?,
- currentList: PagedList<String>?
+ @Suppress("DEPRECATION") legacyListener: AsyncPagedListDiffer.PagedListListener<String>,
+ @Suppress("DEPRECATION") listener: AsyncPagedListDiffer.PagedListListener<String>,
+ @Suppress("DEPRECATION") previousList: PagedList<String>?,
+ @Suppress("DEPRECATION") currentList: PagedList<String>?
) {
verify(legacyListener).onCurrentListChanged(null, currentList)
verify(listener).onCurrentListChanged(previousList, currentList)
diff --git a/paging/runtime/src/androidTest/java/androidx/paging/RecordingCallbackTest.kt b/paging/runtime/src/androidTest/java/androidx/paging/RecordingCallbackTest.kt
index b2189fe..7171b32 100644
--- a/paging/runtime/src/androidTest/java/androidx/paging/RecordingCallbackTest.kt
+++ b/paging/runtime/src/androidTest/java/androidx/paging/RecordingCallbackTest.kt
@@ -30,6 +30,7 @@
fun recordReplay() {
val recordingCallback = RecordingCallback()
+ @Suppress("DEPRECATION")
val failCallback = object : PagedList.Callback() {
override fun onChanged(position: Int, count: Int) = fail("not expected")
override fun onInserted(position: Int, count: Int) = fail("not expected")
@@ -44,6 +45,7 @@
recordingCallback.onRemoved(5, 6)
var inc = 0
+ @Suppress("DEPRECATION")
val verifyCallback = object : PagedList.Callback() {
override fun onChanged(position: Int, count: Int) {
assertEquals(inc, 0)
@@ -51,12 +53,14 @@
assertEquals(count, 2)
inc += 1
}
+
override fun onInserted(position: Int, count: Int) {
assertEquals(inc, 1)
assertEquals(position, 3)
assertEquals(count, 4)
inc += 1
}
+
override fun onRemoved(position: Int, count: Int) {
assertEquals(inc, 2)
assertEquals(position, 5)
diff --git a/paging/runtime/src/androidTest/java/androidx/paging/StringPagedList.kt b/paging/runtime/src/androidTest/java/androidx/paging/StringPagedList.kt
index 7208cd3..6c99a64 100644
--- a/paging/runtime/src/androidTest/java/androidx/paging/StringPagedList.kt
+++ b/paging/runtime/src/androidTest/java/androidx/paging/StringPagedList.kt
@@ -44,7 +44,7 @@
}
}
-@Suppress("TestFunctionName")
+@Suppress("TestFunctionName", "DEPRECATION")
fun StringPagedList(
leadingNulls: Int,
trailingNulls: Int,
diff --git a/paging/runtime/src/main/java/androidx/paging/AsyncPagedListDiffer.kt b/paging/runtime/src/main/java/androidx/paging/AsyncPagedListDiffer.kt
index e2bd838..fae0b93 100644
--- a/paging/runtime/src/main/java/androidx/paging/AsyncPagedListDiffer.kt
+++ b/paging/runtime/src/main/java/androidx/paging/AsyncPagedListDiffer.kt
@@ -19,7 +19,6 @@
import androidx.annotation.VisibleForTesting
import androidx.arch.core.executor.ArchTaskExecutor
import androidx.lifecycle.LiveData
-import androidx.paging.PagedList.LoadStateManager
import androidx.recyclerview.widget.AdapterListUpdateCallback
import androidx.recyclerview.widget.AsyncDifferConfig
import androidx.recyclerview.widget.DiffUtil
@@ -131,9 +130,12 @@
internal var mainThreadExecutor = ArchTaskExecutor.getMainThreadExecutor()
+ @Suppress("DEPRECATION")
@VisibleForTesting
internal val listeners = CopyOnWriteArrayList<PagedListListener<T>>()
+ @Suppress("DEPRECATION")
private var pagedList: PagedList<T>? = null
+ @Suppress("DEPRECATION")
private var snapshot: PagedList<T>? = null
/**
@@ -142,7 +144,8 @@
@Suppress("MemberVisibilityCanBePrivate") // synthetic access
internal var maxScheduledGeneration: Int = 0
- private val loadStateManager: LoadStateManager = object : LoadStateManager() {
+ @Suppress("DEPRECATION")
+ private val loadStateManager = object : PagedList.LoadStateManager() {
override fun onStateChanged(type: LoadType, state: LoadState) {
// Don't need to post - PagedList will already have done that
loadStateListeners.forEach { it(type, state) }
@@ -154,6 +157,7 @@
internal val loadStateListeners: MutableList<(LoadType, LoadState) -> Unit> =
CopyOnWriteArrayList()
+ @Suppress("DEPRECATION")
private val pagedListCallback = object : PagedList.Callback() {
override fun onInserted(position: Int, count: Int) =
updateCallback.onInserted(position, count)
@@ -185,6 +189,7 @@
*
* @return The list currently being displayed, may be `null`.
*/
+ @Suppress("DEPRECATION")
open val currentList: PagedList<T>?
get() = snapshot ?: pagedList
@@ -193,6 +198,7 @@
*
* @param T Type of items in [PagedList]
*/
+ @Deprecated("PagedList is deprecated and has been replaced by PagingData")
interface PagedListListener<T : Any> {
/**
* Called after the current PagedList has been updated.
@@ -200,7 +206,10 @@
* @param previousList The previous list, may be null.
* @param currentList The new current list, may be null.
*/
- fun onCurrentListChanged(previousList: PagedList<T>?, currentList: PagedList<T>?)
+ fun onCurrentListChanged(
+ @Suppress("DEPRECATION") previousList: PagedList<T>?,
+ @Suppress("DEPRECATION") currentList: PagedList<T>?
+ )
}
/**
@@ -208,6 +217,7 @@
*
* @param T Type of items in [PagedList]
*/
+ @Suppress("DEPRECATION")
private class OnCurrentListChangedWrapper<T : Any>(
val callback: (PagedList<T>?, PagedList<T>?) -> Unit
) : PagedListListener<T> {
@@ -296,7 +306,8 @@
*
* @param pagedList The new PagedList.
*/
- open fun submitList(pagedList: PagedList<T>?) = submitList(pagedList, null)
+ open fun submitList(@Suppress("DEPRECATION") pagedList: PagedList<T>?) =
+ submitList(pagedList, null)
/**
* Pass a new PagedList to the differ.
@@ -314,7 +325,10 @@
* @param commitCallback Optional runnable that is executed when the PagedList is committed, if
* it is committed.
*/
- open fun submitList(pagedList: PagedList<T>?, commitCallback: Runnable?) {
+ open fun submitList(
+ @Suppress("DEPRECATION") pagedList: PagedList<T>?,
+ commitCallback: Runnable?
+ ) {
// incrementing generation means any currently-running diffs are discarded when they finish
val runGeneration = ++maxScheduledGeneration
@@ -361,6 +375,7 @@
it.removeWeakCallback(pagedListCallback)
it.removeWeakLoadStateListener(loadStateListener)
+ @Suppress("DEPRECATION")
snapshot = it.snapshot() as PagedList<T>
this.pagedList = null
}
@@ -370,6 +385,7 @@
throw IllegalStateException("must be in snapshot state to diff")
}
+ @Suppress("DEPRECATION")
val newSnapshot = pagedList.snapshot() as PagedList<T>
val recordingCallback = RecordingCallback()
pagedList.addWeakCallback(recordingCallback)
@@ -396,8 +412,8 @@
@Suppress("MemberVisibilityCanBePrivate") // synthetic access
internal fun latchPagedList(
- newList: PagedList<T>,
- diffSnapshot: PagedList<T>,
+ @Suppress("DEPRECATION") newList: PagedList<T>,
+ @Suppress("DEPRECATION") diffSnapshot: PagedList<T>,
diffResult: DiffUtil.DiffResult,
recordingCallback: RecordingCallback,
lastAccessIndex: Int,
@@ -450,8 +466,8 @@
}
private fun onCurrentListChanged(
- previousList: PagedList<T>?,
- currentList: PagedList<T>?,
+ @Suppress("DEPRECATION") previousList: PagedList<T>?,
+ @Suppress("DEPRECATION") currentList: PagedList<T>?,
commitCallback: Runnable?
) {
listeners.forEach { it.onCurrentListChanged(previousList, currentList) }
@@ -466,7 +482,7 @@
* @see currentList
* @see removePagedListListener
*/
- open fun addPagedListListener(listener: PagedListListener<T>) {
+ open fun addPagedListListener(@Suppress("DEPRECATION") listener: PagedListListener<T>) {
listeners.add(listener)
}
@@ -478,7 +494,9 @@
* @see currentList
* @see removePagedListListener
*/
- fun addPagedListListener(callback: (PagedList<T>?, PagedList<T>?) -> Unit) {
+ fun addPagedListListener(
+ @Suppress("DEPRECATION") callback: (PagedList<T>?, PagedList<T>?) -> Unit
+ ) {
listeners.add(OnCurrentListChangedWrapper(callback))
}
@@ -490,7 +508,7 @@
* @see currentList
* @see addPagedListListener
*/
- open fun removePagedListListener(listener: PagedListListener<T>) {
+ open fun removePagedListListener(@Suppress("DEPRECATION") listener: PagedListListener<T>) {
listeners.remove(listener)
}
@@ -502,7 +520,9 @@
* @see currentList
* @see addPagedListListener
*/
- fun removePagedListListener(callback: (PagedList<T>?, PagedList<T>?) -> Unit) {
+ fun removePagedListListener(
+ @Suppress("DEPRECATION") callback: (PagedList<T>?, PagedList<T>?) -> Unit
+ ) {
listeners.removeAll { it is OnCurrentListChangedWrapper<T> && it.callback === callback }
}
diff --git a/paging/runtime/src/main/java/androidx/paging/LivePagedList.kt b/paging/runtime/src/main/java/androidx/paging/LivePagedList.kt
index faea28c..9205c17 100644
--- a/paging/runtime/src/main/java/androidx/paging/LivePagedList.kt
+++ b/paging/runtime/src/main/java/androidx/paging/LivePagedList.kt
@@ -30,6 +30,7 @@
import kotlinx.coroutines.withContext
import java.util.concurrent.Executor
+@Suppress("DEPRECATION")
internal class LivePagedList<Key : Any, Value : Any>(
private val coroutineScope: CoroutineScope,
initialKey: Key?,
@@ -122,6 +123,7 @@
*
* @see LivePagedListBuilder
*/
+@Suppress("DEPRECATION")
@Deprecated(
message = "PagedList is deprecated and has been replaced by PagingData",
replaceWith = ReplaceWith(
@@ -147,7 +149,6 @@
boundaryCallback: PagedList.BoundaryCallback<Value>? = null,
fetchExecutor: Executor = ArchTaskExecutor.getIOThreadExecutor()
): LiveData<PagedList<Value>> {
- @Suppress("DEPRECATION")
return LivePagedListBuilder(this, config)
.setInitialLoadKey(initialLoadKey)
.setBoundaryCallback(boundaryCallback)
@@ -169,6 +170,7 @@
*
* @see LivePagedListBuilder
*/
+@Suppress("DEPRECATION")
@Deprecated(
message = "PagedList is deprecated and has been replaced by PagingData",
replaceWith = ReplaceWith(
@@ -188,7 +190,6 @@
boundaryCallback: PagedList.BoundaryCallback<Value>? = null,
fetchExecutor: Executor = ArchTaskExecutor.getIOThreadExecutor()
): LiveData<PagedList<Value>> {
- @Suppress("DEPRECATION")
return LivePagedListBuilder(this, Config(pageSize))
.setInitialLoadKey(initialLoadKey)
.setBoundaryCallback(boundaryCallback)
@@ -215,6 +216,7 @@
*
* @see LivePagedListBuilder
*/
+@Suppress("DEPRECATION")
@Deprecated(
message = "PagedList is deprecated and has been replaced by PagingData",
replaceWith = ReplaceWith(
@@ -270,6 +272,7 @@
*
* @see LivePagedListBuilder
*/
+@Suppress("DEPRECATION")
@Deprecated(
message = "PagedList is deprecated and has been replaced by PagingData",
replaceWith = ReplaceWith(
diff --git a/paging/runtime/src/main/java/androidx/paging/LivePagedListBuilder.kt b/paging/runtime/src/main/java/androidx/paging/LivePagedListBuilder.kt
index 55bd769..edd9bd5 100644
--- a/paging/runtime/src/main/java/androidx/paging/LivePagedListBuilder.kt
+++ b/paging/runtime/src/main/java/androidx/paging/LivePagedListBuilder.kt
@@ -39,9 +39,11 @@
class LivePagedListBuilder<Key : Any, Value : Any> {
private val pagingSourceFactory: (() -> PagingSource<Key, Value>)?
private val dataSourceFactory: DataSource.Factory<Key, Value>?
+ @Suppress("DEPRECATION")
private val config: PagedList.Config
private var coroutineScope: CoroutineScope = GlobalScope
private var initialLoadKey: Key? = null
+ @Suppress("DEPRECATION")
private var boundaryCallback: PagedList.BoundaryCallback<Value>? = null
private var fetchDispatcher = Dispatchers.IO
@@ -70,7 +72,11 @@
"kotlinx.coroutines.Dispatchers"
)
)
- constructor(dataSourceFactory: DataSource.Factory<Key, Value>, config: PagedList.Config) {
+ constructor(
+ dataSourceFactory: DataSource.Factory<Key, Value>,
+ @Suppress("DEPRECATION")
+ config: PagedList.Config
+ ) {
this.pagingSourceFactory = null
this.dataSourceFactory = dataSourceFactory
this.config = config
@@ -139,7 +145,11 @@
"androidx.paging.PagingConfig"
)
)
- constructor(pagingSourceFactory: () -> PagingSource<Key, Value>, config: PagedList.Config) {
+ constructor(
+ pagingSourceFactory: () -> PagingSource<Key, Value>,
+ @Suppress("DEPRECATION")
+ config: PagedList.Config
+ ) {
this.pagingSourceFactory = pagingSourceFactory
this.dataSourceFactory = null
this.config = config
@@ -231,7 +241,10 @@
* @param boundaryCallback The boundary callback for listening to PagedList load state.
* @return this
*/
- fun setBoundaryCallback(boundaryCallback: PagedList.BoundaryCallback<Value>?) = this.apply {
+ fun setBoundaryCallback(
+ @Suppress("DEPRECATION")
+ boundaryCallback: PagedList.BoundaryCallback<Value>?
+ ) = this.apply {
this.boundaryCallback = boundaryCallback
}
@@ -257,6 +270,7 @@
*
* @return The [LiveData] of [PagedList]s
*/
+ @Suppress("DEPRECATION")
fun build(): LiveData<PagedList<Value>> {
val pagingSourceFactory = pagingSourceFactory
?: dataSourceFactory?.asPagingSourceFactory(fetchDispatcher)
diff --git a/paging/runtime/src/main/java/androidx/paging/PagedListAdapter.kt b/paging/runtime/src/main/java/androidx/paging/PagedListAdapter.kt
index 5c71b8c..96863e9 100644
--- a/paging/runtime/src/main/java/androidx/paging/PagedListAdapter.kt
+++ b/paging/runtime/src/main/java/androidx/paging/PagedListAdapter.kt
@@ -41,7 +41,7 @@
* A complete usage pattern with Room would look like this:
* ```
* @Dao
- * interface UserDao {
+ * interface UserDao {
* @Query("SELECT * FROM user ORDER BY lastName ASC")
* public abstract DataSource.Factory<Integer, User> usersByLastName();
* }
@@ -115,8 +115,8 @@
abstract class PagedListAdapter<T : Any, VH : RecyclerView.ViewHolder> : RecyclerView.Adapter<VH> {
@Suppress("DEPRECATION")
internal val differ: AsyncPagedListDiffer<T>
+ @Suppress("DEPRECATION")
private val listener = { previousList: PagedList<T>?, currentList: PagedList<T>? ->
- @Suppress("DEPRECATION")
[email protected](currentList)
[email protected](previousList, currentList)
}
@@ -132,6 +132,7 @@
*
* @see onCurrentListChanged
*/
+ @Suppress("DEPRECATION")
open val currentList: PagedList<T>?
get() = differ.currentList
@@ -164,7 +165,8 @@
*
* @param pagedList The new list to be displayed.
*/
- open fun submitList(pagedList: PagedList<T>?) = differ.submitList(pagedList)
+ open fun submitList(@Suppress("DEPRECATION") pagedList: PagedList<T>?) =
+ differ.submitList(pagedList)
/**
* Set the new list to be displayed.
@@ -180,8 +182,10 @@
* @param commitCallback Optional runnable that is executed when the PagedList is committed, if
* it is committed.
*/
- open fun submitList(pagedList: PagedList<T>?, commitCallback: Runnable?) =
- differ.submitList(pagedList, commitCallback)
+ open fun submitList(
+ @Suppress("DEPRECATION") pagedList: PagedList<T>?,
+ commitCallback: Runnable?
+ ) = differ.submitList(pagedList, commitCallback)
protected open fun getItem(position: Int) = differ.getItem(position)
@@ -207,7 +211,7 @@
"Use the two argument variant instead.",
ReplaceWith("onCurrentListChanged(previousList, currentList)")
)
- open fun onCurrentListChanged(currentList: PagedList<T>?) {
+ open fun onCurrentListChanged(@Suppress("DEPRECATION") currentList: PagedList<T>?) {
}
/**
@@ -227,7 +231,10 @@
*
* @see currentList
*/
- open fun onCurrentListChanged(previousList: PagedList<T>?, currentList: PagedList<T>?) {
+ open fun onCurrentListChanged(
+ @Suppress("DEPRECATION") previousList: PagedList<T>?,
+ @Suppress("DEPRECATION") currentList: PagedList<T>?
+ ) {
}
/**
diff --git a/paging/runtime/src/main/java/androidx/paging/PagingDataAdapter.kt b/paging/runtime/src/main/java/androidx/paging/PagingDataAdapter.kt
index 0dfa288c0..48c83bc 100644
--- a/paging/runtime/src/main/java/androidx/paging/PagingDataAdapter.kt
+++ b/paging/runtime/src/main/java/androidx/paging/PagingDataAdapter.kt
@@ -23,7 +23,29 @@
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.Flow
+/**
+ * [RecyclerView.Adapter] base class for presenting paged data from [PagingData]s in
+ * a [RecyclerView].
+ *
+ * This class is a convenience wrapper around [AsyncPagingDataDiffer] that implements common default
+ * behavior for item counting, and listening to update events.
+ *
+ * To present a [Flow]<[PagingData]>, you would connect generally use
+ * [collectLatest][kotlinx.coroutines.flow.collectLatest], and
+ * call [presentData] on the latest generation of [PagingData].
+ *
+ * If you are using RxJava or LiveData as your reactive stream API, you would typically connect
+ * those to [submitData].
+ *
+ * PagingDataAdapter listens to internal PagingData loading events as
+ * [pages][PagingSource.LoadResult.Page] are loaded, and uses [DiffUtil] on a background thread to
+ * compute fine grained updates as updated content in the form of new PagingData objects are
+ * received.
+ *
+ * @sample androidx.paging.samples.pagingDataAdapterSample
+ */
abstract class PagingDataAdapter<T : Any, VH : RecyclerView.ViewHolder>(
diffCallback: DiffUtil.ItemCallback<T>,
mainDispatcher: CoroutineDispatcher = Dispatchers.Main,
@@ -36,10 +58,31 @@
updateCallback = AdapterListUpdateCallback(this)
)
+ /**
+ * Present the new [PagingData], and suspend as long as it is not invalidated.
+ *
+ * This method should be called on the same [CoroutineDispatcher] where updates will be
+ * dispatched to UI, typically [Dispatchers.Main].
+ *
+ * This method is typically used when observing a [Flow]. For a RxJava or LiveData stream,
+ * see [submitData]
+ *
+ * @sample androidx.paging.samples.presentDataSample
+ * @see [submitData]
+ */
suspend fun presentData(pagingData: PagingData<T>) {
differ.presentData(pagingData)
}
+ /**
+ * Present the new PagingData until the next call to submitData.
+ *
+ * This method is typically used when observing a RxJava or LiveData stream. For [Flow], see
+ * [presentData]
+ *
+ * @sample androidx.paging.samples.submitDataSample
+ * @see [presentData]
+ */
fun submitData(lifecycle: Lifecycle, pagingData: PagingData<T>) {
differ.submitData(lifecycle, pagingData)
}
diff --git a/paging/runtime/src/main/java/androidx/paging/RecordingCallback.kt b/paging/runtime/src/main/java/androidx/paging/RecordingCallback.kt
index b4371af..c559a72 100644
--- a/paging/runtime/src/main/java/androidx/paging/RecordingCallback.kt
+++ b/paging/runtime/src/main/java/androidx/paging/RecordingCallback.kt
@@ -16,6 +16,7 @@
package androidx.paging
+@Suppress("DEPRECATION")
internal class RecordingCallback : PagedList.Callback() {
private val list = mutableListOf<Int>()
override fun onChanged(position: Int, count: Int) {
diff --git a/paging/rxjava2/src/main/java/androidx/paging/RxPagedList.kt b/paging/rxjava2/src/main/java/androidx/paging/RxPagedList.kt
index 8d38dd8..8e5d64d 100644
--- a/paging/rxjava2/src/main/java/androidx/paging/RxPagedList.kt
+++ b/paging/rxjava2/src/main/java/androidx/paging/RxPagedList.kt
@@ -23,9 +23,9 @@
private fun <Key : Any, Value : Any> createRxPagedListBuilder(
dataSourceFactory: DataSource.Factory<Key, Value>,
- config: PagedList.Config,
+ @Suppress("DEPRECATION") config: PagedList.Config,
initialLoadKey: Key?,
- boundaryCallback: PagedList.BoundaryCallback<Value>?,
+ @Suppress("DEPRECATION") boundaryCallback: PagedList.BoundaryCallback<Value>?,
fetchScheduler: Scheduler?,
notifyScheduler: Scheduler?
): RxPagedListBuilder<Key, Value> {
@@ -40,9 +40,9 @@
private fun <Key : Any, Value : Any> createRxPagedListBuilder(
pagingSourceFactory: () -> PagingSource<Key, Value>,
- config: PagedList.Config,
+ @Suppress("DEPRECATION") config: PagedList.Config,
initialLoadKey: Key?,
- boundaryCallback: PagedList.BoundaryCallback<Value>?,
+ @Suppress("DEPRECATION") boundaryCallback: PagedList.BoundaryCallback<Value>?,
fetchScheduler: Scheduler?,
notifyScheduler: Scheduler?
): RxPagedListBuilder<Key, Value> {
@@ -74,6 +74,7 @@
* @see RxPagedListBuilder
* @see toFlowable
*/
+@Suppress("DEPRECATION")
@Deprecated(
message = "PagedList is deprecated and has been replaced by PagingData",
replaceWith = ReplaceWith(
@@ -130,6 +131,7 @@
* @see RxPagedListBuilder
* @see toFlowable
*/
+@Suppress("DEPRECATION")
@Deprecated(
message = "PagedList is deprecated and has been replaced by PagingData",
replaceWith = ReplaceWith(
@@ -181,6 +183,7 @@
* @see RxPagedListBuilder
* @see toObservable
*/
+@Suppress("DEPRECATION")
@Deprecated(
message = "PagedList is deprecated and has been replaced by PagingData",
replaceWith = ReplaceWith(
@@ -239,6 +242,7 @@
* @see RxPagedListBuilder
* @see toObservable
*/
+@Suppress("DEPRECATION")
@Deprecated(
message = "PagedList is deprecated and has been replaced by PagingData",
replaceWith = ReplaceWith(
@@ -290,6 +294,7 @@
* @see RxPagedListBuilder
* @see toFlowable
*/
+@Suppress("DEPRECATION")
@Deprecated(
message = "PagedList is deprecated and has been replaced by PagingData",
replaceWith = ReplaceWith(
@@ -346,6 +351,7 @@
* @see RxPagedListBuilder
* @see toFlowable
*/
+@Suppress("DEPRECATION")
@Deprecated(
message = "PagedList is deprecated and has been replaced by PagingData",
replaceWith = ReplaceWith(
@@ -395,6 +401,7 @@
* @see RxPagedListBuilder
* @see toObservable
*/
+@Suppress("DEPRECATION")
@Deprecated(
message = "PagedList is deprecated and has been replaced by PagingData",
replaceWith = ReplaceWith(
@@ -451,6 +458,7 @@
* @see RxPagedListBuilder
* @see toObservable
*/
+@Suppress("DEPRECATION")
@Deprecated(
message = "PagedList is deprecated and has been replaced by PagingData",
replaceWith = ReplaceWith(
diff --git a/paging/rxjava2/src/main/java/androidx/paging/RxPagedListBuilder.kt b/paging/rxjava2/src/main/java/androidx/paging/RxPagedListBuilder.kt
index 76814ef..cedf80a 100644
--- a/paging/rxjava2/src/main/java/androidx/paging/RxPagedListBuilder.kt
+++ b/paging/rxjava2/src/main/java/androidx/paging/RxPagedListBuilder.kt
@@ -52,9 +52,11 @@
class RxPagedListBuilder<Key : Any, Value : Any> {
private val pagingSourceFactory: (() -> PagingSource<Key, Value>)?
private val dataSourceFactory: DataSource.Factory<Key, Value>?
+ @Suppress("DEPRECATION")
private val config: PagedList.Config
private var initialLoadKey: Key? = null
+ @Suppress("DEPRECATION")
private var boundaryCallback: PagedList.BoundaryCallback<Value>? = null
private var notifyDispatcher: SchedulerCoroutineDispatcher? = null
private var notifyScheduler: Scheduler? = null
@@ -89,7 +91,7 @@
)
constructor(
pagingSourceFactory: () -> PagingSource<Key, Value>,
- config: PagedList.Config
+ @Suppress("DEPRECATION") config: PagedList.Config
) {
this.pagingSourceFactory = pagingSourceFactory
this.dataSourceFactory = null
@@ -159,7 +161,7 @@
)
constructor(
dataSourceFactory: DataSource.Factory<Key, Value>,
- config: PagedList.Config
+ @Suppress("DEPRECATION") config: PagedList.Config
) {
this.pagingSourceFactory = null
this.dataSourceFactory = dataSourceFactory
@@ -237,9 +239,9 @@
* @param boundaryCallback The boundary callback for listening to PagedList load state.
* @return this
*/
- fun setBoundaryCallback(boundaryCallback: PagedList.BoundaryCallback<Value>?) = apply {
- this.boundaryCallback = boundaryCallback
- }
+ fun setBoundaryCallback(
+ @Suppress("DEPRECATION") boundaryCallback: PagedList.BoundaryCallback<Value>?
+ ) = apply { this.boundaryCallback = boundaryCallback }
/**
* Sets scheduler which will be used for observing new PagedLists, as well as loading updates
@@ -284,6 +286,7 @@
*
* @return The [Observable] of PagedLists
*/
+ @Suppress("DEPRECATION")
fun buildObservable(): Observable<PagedList<Value>> {
@SuppressLint("RestrictedApi")
val notifyScheduler = notifyScheduler
@@ -326,10 +329,12 @@
* @param backpressureStrategy BackpressureStrategy for the [Flowable] to use.
* @return The [Flowable] of PagedLists
*/
+ @Suppress("DEPRECATION")
fun buildFlowable(backpressureStrategy: BackpressureStrategy): Flowable<PagedList<Value>> {
return buildObservable().toFlowable(backpressureStrategy)
}
+ @Suppress("DEPRECATION")
internal class PagingObservableOnSubscribe<Key : Any, Value : Any>(
initialLoadKey: Key?,
private val config: PagedList.Config,
diff --git a/preference/preference/src/main/java/androidx/preference/PreferenceViewHolder.java b/preference/preference/src/main/java/androidx/preference/PreferenceViewHolder.java
index 3ff36b5..e465513 100644
--- a/preference/preference/src/main/java/androidx/preference/PreferenceViewHolder.java
+++ b/preference/preference/src/main/java/androidx/preference/PreferenceViewHolder.java
@@ -144,7 +144,7 @@
}
final TextView titleView = (TextView) findViewById(android.R.id.title);
- if (titleView != null) {
+ if (titleView != null && mTitleTextColors != null) {
if (!titleView.getTextColors().equals(mTitleTextColors)) {
titleView.setTextColor(mTitleTextColors);
}
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/MergeAdapterTest.kt b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/MergeAdapterTest.kt
index 94fc581..1bd0888 100644
--- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/MergeAdapterTest.kt
+++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/MergeAdapterTest.kt
@@ -164,6 +164,7 @@
@UiThreadTest
@Test
+ @SdkSuppress(minSdkVersion = 16)
fun failedToRecycleTest() {
val adapter1 = NestedTestAdapter(10)
val adapter2 = NestedTestAdapter(5)
diff --git a/settings.gradle b/settings.gradle
index 2855201..8214feb 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -200,6 +200,7 @@
includeProject(":navigation:navigation-integration-tests:testapp", "navigation/integration-tests/testapp")
includeProject(":navigation:navigation-safe-args-generator", "navigation/navigation-safe-args-generator")
includeProject(":navigation:navigation-safe-args-gradle-plugin", "navigation/navigation-safe-args-gradle-plugin")
+includeProject(":paging:integration-tests:samples", "paging/integration-tests/samples")
includeProject(":paging:integration-tests:testapp", "paging/integration-tests/testapp")
includeProject(":paging:paging-common", "paging/common")
includeProject(":paging:paging-common-ktx", "paging/common/ktx")
diff --git a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/BasicTest.kt b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/BasicTest.kt
index a95b53f..778bfa8 100644
--- a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/BasicTest.kt
+++ b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/BasicTest.kt
@@ -21,6 +21,7 @@
import androidx.test.filters.MediumTest
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.runBlocking
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -48,4 +49,14 @@
// no crash means the inspector was successfully injected
testEnvironment.assertNoQueuedEvents()
}
+
+ @Test
+ fun test_unset_command() = runBlocking {
+ testEnvironment.sendCommand(SqliteInspectorProtocol.Command.getDefaultInstance())
+ .let { response ->
+ assertThat(response.hasErrorOccurred()).isEqualTo(true)
+ assertThat(response.errorOccurred.content.message)
+ .contains("Unrecognised command type: ONEOF_NOT_SET")
+ }
+ }
}
diff --git a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/GetSchemaTest.kt b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/GetSchemaTest.kt
index 1c201da1..96af14a 100644
--- a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/GetSchemaTest.kt
+++ b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/GetSchemaTest.kt
@@ -127,6 +127,17 @@
)
}
+ @Test
+ fun test_get_schema_wrong_database_id() = runBlocking {
+ val databaseId = 123456789
+ testEnvironment.sendCommand(createGetSchemaCommand(databaseId)).let { response ->
+ assertThat(response.hasErrorOccurred()).isEqualTo(true)
+ val error = response.errorOccurred.content
+ assertThat(error.message).isEqualTo("No database with id=$databaseId")
+ assertThat(error.isRecoverable).isEqualTo(true)
+ }
+ }
+
private fun test_get_schema(
alreadyOpenDatabases: List<Database>,
onDatabaseCreated: (SQLiteDatabase) -> Unit = {}
diff --git a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/QueryTest.kt b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/QueryTest.kt
index 9755395..ea6b2d6 100644
--- a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/QueryTest.kt
+++ b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/QueryTest.kt
@@ -113,6 +113,59 @@
}
@Test
+ fun test_error_wrong_database_id() = runBlocking {
+ val databaseId = 123456789
+ val command = "select * from sqlite_master"
+ val queryParams = null
+ testEnvironment.sendCommand(createQueryCommand(databaseId, command, queryParams))
+ .let { response ->
+ assertThat(response.hasErrorOccurred()).isEqualTo(true)
+ val error = response.errorOccurred.content
+ assertThat(error.message).isEqualTo("No database with id=$databaseId")
+ assertThat(error.stackTrace).isEqualTo("")
+ assertThat(error.isRecoverable).isEqualTo(true)
+ }
+ }
+
+ @Test
+ fun test_error_invalid_query() = runBlocking {
+ val databaseId = inspectDatabase(Database("db", table2).createInstance(temporaryFolder))
+ val mistypedSelect = "selecttt"
+ val command = "$mistypedSelect * from sqlite_master"
+ val queryParams = null
+ val response =
+ testEnvironment.sendCommand(createQueryCommand(databaseId, command, queryParams))
+ assertThat(response.hasErrorOccurred()).isEqualTo(true)
+ val error = response.errorOccurred.content
+ assertThat(error.message).contains("syntax error")
+ assertThat(error.message).contains("near \"$mistypedSelect\"")
+ assertThat(error.message).contains("while compiling: $command")
+ assertThat(error.stackTrace).contains("SqliteInspector.onReceiveCommand")
+ assertThat(error.stackTrace).contains("SQLiteConnection.nativePrepareStatement")
+ assertThat(error.stackTrace).contains("SQLiteDatabase.rawQueryWithFactory")
+ assertThat(error.isRecoverable).isEqualTo(true)
+ }
+
+ @Test
+ fun test_error_wrong_param_count() = runBlocking {
+ val databaseId = inspectDatabase(Database("db", table2).createInstance(temporaryFolder))
+ val command = "select * from sqlite_master where name=?"
+ val queryParams = listOf("'a'", "'b'") // one too many param
+ val response =
+ testEnvironment.sendCommand(createQueryCommand(databaseId, command, queryParams))
+ assertThat(response.hasErrorOccurred()).isEqualTo(true)
+ val error = response.errorOccurred.content
+ assertThat(error.message).contains("Cannot bind argument")
+ assertThat(error.message).contains("index is out of range")
+ assertThat(error.message).contains("The statement has 1 parameters")
+ assertThat(error.stackTrace).contains("SqliteInspector.onReceiveCommand")
+ assertThat(error.stackTrace).contains("SQLiteDatabase.rawQueryWithFactory")
+ assertThat(error.stackTrace).contains("SQLiteDirectCursorDriver.query")
+ assertThat(error.stackTrace).contains("SQLiteProgram.bind")
+ assertThat(error.isRecoverable).isEqualTo(true)
+ }
+
+ @Test
fun test_valid_query_nested_query_with_a_comment() {
test_valid_query(
Database("db", table2),
diff --git a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/TrackDatabasesTest.kt b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/TrackDatabasesTest.kt
index 4b40068..b6a1d50 100644
--- a/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/TrackDatabasesTest.kt
+++ b/sqlite/sqlite-inspection/src/androidTest/java/androidx/sqlite/inspection/test/TrackDatabasesTest.kt
@@ -17,7 +17,7 @@
package androidx.sqlite.inspection.test
import android.database.sqlite.SQLiteDatabase
-import androidx.inspection.InspectorEnvironment
+import androidx.inspection.InspectorEnvironment.ExitHook
import androidx.sqlite.inspection.test.MessageFactory.createTrackDatabasesCommand
import androidx.sqlite.inspection.test.MessageFactory.createTrackDatabasesResponse
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -85,7 +85,7 @@
testEnvironment.assertNoQueuedEvents()
@Suppress("UNCHECKED_CAST")
val exitHook = (entry as Hook.ExitHook).exitHook as
- InspectorEnvironment.ExitHook<SQLiteDatabase>
+ ExitHook<SQLiteDatabase>
val database = Database("db3").createInstance(temporaryFolder)
assertThat(exitHook.onExit(database)).isSameInstanceAs(database)
testEnvironment.receiveEvent().let { event ->
@@ -95,4 +95,33 @@
assertThat(testEnvironment.consumeRegisteredHooks()).isEmpty()
}
+
+ @Test
+ fun test_track_databases_the_same_database_opened_twice() = runBlocking {
+ testEnvironment.sendCommand(createTrackDatabasesCommand())
+ val hooks = testEnvironment.consumeRegisteredHooks()
+ assertThat(hooks).hasSize(1)
+
+ val onOpenHook = hooks.first()
+ assertThat(onOpenHook.originMethod).isEqualTo(OPEN_DATABASE_COMMAND_SIGNATURE)
+ val database = Database("db").createInstance(temporaryFolder)
+ @Suppress("UNCHECKED_CAST")
+ val onExit = ((onOpenHook as Hook.ExitHook).exitHook as ExitHook<SQLiteDatabase>)::onExit
+
+ // open event on a database first time
+ onExit(database)
+ testEnvironment.receiveEvent()
+ .let { event -> assertThat(event.hasDatabaseOpened()).isEqualTo(true) }
+
+ // open event on the same database for the second time
+ // TODO: track close database events or handle the below gracefully
+ onExit(database)
+ testEnvironment.receiveEvent().let { event ->
+ assertThat(event.hasErrorOccurred()).isEqualTo(true)
+ val error = event.errorOccurred.content
+ assertThat(error.message).contains("Database is already tracked")
+ assertThat(error.message).contains(database.path)
+ assertThat(error.isRecoverable).isEqualTo(false)
+ }
+ }
}
diff --git a/sqlite/sqlite-inspection/src/main/java/androidx/sqlite/inspection/SqliteInspector.java b/sqlite/sqlite-inspection/src/main/java/androidx/sqlite/inspection/SqliteInspector.java
index 17f9f37..0e3351e 100644
--- a/sqlite/sqlite-inspection/src/main/java/androidx/sqlite/inspection/SqliteInspector.java
+++ b/sqlite/sqlite-inspection/src/main/java/androidx/sqlite/inspection/SqliteInspector.java
@@ -16,10 +16,12 @@
package androidx.sqlite.inspection;
+import android.annotation.SuppressLint;
import android.database.Cursor;
import android.database.sqlite.SQLiteCursor;
import android.database.sqlite.SQLiteCursorDriver;
import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteQuery;
import android.os.Build;
import android.os.CancellationSignal;
@@ -34,6 +36,7 @@
import androidx.sqlite.inspection.SqliteInspectorProtocol.Column;
import androidx.sqlite.inspection.SqliteInspectorProtocol.Command;
import androidx.sqlite.inspection.SqliteInspectorProtocol.DatabaseOpenedEvent;
+import androidx.sqlite.inspection.SqliteInspectorProtocol.ErrorContent;
import androidx.sqlite.inspection.SqliteInspectorProtocol.ErrorOccurredEvent;
import androidx.sqlite.inspection.SqliteInspectorProtocol.ErrorOccurredResponse;
import androidx.sqlite.inspection.SqliteInspectorProtocol.Event;
@@ -48,7 +51,6 @@
import androidx.sqlite.inspection.SqliteInspectorProtocol.TrackDatabasesResponse;
import com.google.protobuf.ByteString;
-import com.google.protobuf.InvalidProtocolBufferException;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -64,6 +66,7 @@
/**
* Inspector to work with SQLite databases
*/
+@SuppressWarnings({"TryFinallyCanBeTryWithResources", "SameParameterValue"})
final class SqliteInspector extends Inspector {
// TODO: identify all SQLiteDatabase openDatabase methods
private static final String sOpenDatabaseCommandSignature = "openDatabase"
@@ -75,6 +78,7 @@
// Note: this only works on API26+ because of pragma_* functions
// TODO: replace with a resource file
+ // language=SQLite
private static final String sQueryTableInfo = "select\n"
+ " m.type as type,\n"
+ " m.name as tableName,\n"
@@ -130,10 +134,22 @@
} else if (command.hasQuery()) {
handleQuery(command.getQuery(), callback);
} else {
- // TODO: handle unrecognised command
+ callback.reply(
+ createErrorOccurredResponse(
+ "Unrecognised command type: " + command.getOneOfCase().name(),
+ null,
+ true
+ ).toByteArray());
}
- } catch (InvalidProtocolBufferException exception) {
- // TODO: decide on error handling strategy
+ } catch (Exception exception) {
+ callback.reply(
+ createErrorOccurredResponse(
+ "Unhandled Exception while processing the command: "
+ + exception.getMessage(),
+ stackTraceFromException(exception),
+ false
+ ).toByteArray()
+ );
}
}
@@ -147,9 +163,19 @@
SQLiteDatabase.class,
sOpenDatabaseCommandSignature,
new InspectorEnvironment.ExitHook<SQLiteDatabase>() {
+ @SuppressLint("SyntheticAccessor")
@Override
public SQLiteDatabase onExit(SQLiteDatabase database) {
- onDatabaseAdded(database);
+ try {
+ onDatabaseAdded(database);
+ } catch (Exception exception) {
+ getConnection().sendEvent(createErrorOccurredEvent(
+ "Unhandled Exception while processing an onDatabaseAdded "
+ + "event: "
+ + exception.getMessage(),
+ stackTraceFromException(exception), false)
+ .toByteArray());
+ }
return database;
}
});
@@ -172,8 +198,9 @@
if (database == null) return;
String[] params = parseQueryParameterValues(command);
- Cursor cursor = rawQuery(database, command.getQuery(), params, null);
+ Cursor cursor = null;
try {
+ cursor = rawQuery(database, command.getQuery(), params, null);
List<String> columnNames = Arrays.asList(cursor.getColumnNames());
callback.reply(Response.newBuilder()
.setQuery(QueryResponse.newBuilder()
@@ -183,13 +210,18 @@
.build()
.toByteArray()
);
+ } catch (SQLiteException | IllegalArgumentException exception) {
+ callback.reply(createErrorOccurredResponse(exception, true).toByteArray());
} finally {
- cursor.close();
+ if (cursor != null) {
+ cursor.close();
+ }
}
}
- private Cursor rawQuery(SQLiteDatabase database, String queryText, final String[] params,
- CancellationSignal cancellationSignal) {
+ @SuppressLint("Recycle") // For: "The cursor should be freed up after use with #close"
+ private Cursor rawQuery(@NonNull SQLiteDatabase database, @NonNull String queryText,
+ @NonNull final String[] params, @Nullable CancellationSignal cancellationSignal) {
SQLiteDatabase.CursorFactory cursorFactory = new SQLiteDatabase.CursorFactory() {
@Override
public Cursor newCursor(SQLiteDatabase db, SQLiteCursorDriver driver,
@@ -289,12 +321,13 @@
private void replyNoDatabaseWithId(CommandCallback callback, int databaseId) {
callback.reply(createErrorOccurredResponse("No database with id=" + databaseId,
- null).toByteArray());
+ null, true).toByteArray());
}
private @NonNull Response querySchema(SQLiteDatabase database) {
- Cursor cursor = database.rawQuery(sQueryTableInfo, null);
+ Cursor cursor = null;
try {
+ cursor = rawQuery(database, sQueryTableInfo, new String[0], null);
GetSchemaResponse.Builder schemaBuilder = GetSchemaResponse.newBuilder();
int tableNameIx = cursor.getColumnIndex("tableName");
@@ -338,7 +371,9 @@
return Response.newBuilder().setGetSchema(schemaBuilder.build()).build();
} finally {
- cursor.close();
+ if (cursor != null) {
+ cursor.close();
+ }
}
}
@@ -351,7 +386,13 @@
String name = database.getPath();
response = createDatabaseOpenedEvent(id, name);
} catch (IllegalArgumentException exception) {
- response = createErrorOccurredEvent(exception);
+ String message = exception.getMessage();
+ // TODO: clean up, e.g. replace Exception message check with a custom Exception class
+ if (message != null && message.contains("Database is already tracked")) {
+ response = createErrorOccurredEvent(exception, false);
+ } else {
+ throw exception;
+ }
}
getConnection().sendEvent(response.toByteArray());
@@ -363,22 +404,49 @@
.build();
}
- private Event createErrorOccurredEvent(@NonNull Exception exception) {
+ private Event createErrorOccurredEvent(@Nullable String message, @Nullable String stackTrace,
+ boolean isRecoverable) {
return Event.newBuilder().setErrorOccurred(
ErrorOccurredEvent.newBuilder()
- .setMessage(exception.getMessage())
- .setStackTrace(stackTraceFromException(exception))
+ .setContent(
+ createErrorContentMessage(message,
+ stackTrace,
+ isRecoverable))
.build())
.build();
}
- private Response createErrorOccurredResponse(@NonNull String message,
- @SuppressWarnings("SameParameterValue") @Nullable String stackTrace) {
- return Response.newBuilder().setErrorOccurred(
- ErrorOccurredResponse.newBuilder()
- .setMessage(message)
- .setStackTrace(stackTrace)
- .build())
+ private Event createErrorOccurredEvent(@NonNull Exception exception, boolean isRecoverable) {
+ return createErrorOccurredEvent(exception.getMessage(), stackTraceFromException(exception),
+ isRecoverable);
+ }
+
+ private ErrorContent createErrorContentMessage(@Nullable String message,
+ @Nullable String stackTrace, boolean isRecoverable) {
+ ErrorContent.Builder builder = ErrorContent.newBuilder();
+ if (message != null) {
+ builder.setMessage(message);
+ }
+ if (stackTrace != null) {
+ builder.setStackTrace(stackTrace);
+ }
+ builder.setIsRecoverable(isRecoverable);
+ return builder.build();
+ }
+
+ private Response createErrorOccurredResponse(@NonNull Exception exception,
+ boolean isRecoverable) {
+ return createErrorOccurredResponse(exception.getMessage(),
+ stackTraceFromException(exception), isRecoverable);
+ }
+
+ private Response createErrorOccurredResponse(@Nullable String message,
+ @Nullable String stackTrace, boolean isRecoverable) {
+ return Response.newBuilder()
+ .setErrorOccurred(
+ ErrorOccurredResponse.newBuilder()
+ .setContent(createErrorContentMessage(message, stackTrace,
+ isRecoverable)))
.build();
}
@@ -414,7 +482,8 @@
// check if already tracked
for (Map.Entry<Integer, SQLiteDatabase> entry : mDatabases.entrySet()) {
if (entry.getValue() == database) {
- throw new IllegalArgumentException("Database is already tracked.");
+ throw new IllegalArgumentException(
+ "Database is already tracked: " + database.getPath());
}
}
diff --git a/sqlite/sqlite-inspection/src/main/proto/live_sql_protocol.proto b/sqlite/sqlite-inspection/src/main/proto/live_sql_protocol.proto
index 2c638bf..47b5d32 100644
--- a/sqlite/sqlite-inspection/src/main/proto/live_sql_protocol.proto
+++ b/sqlite/sqlite-inspection/src/main/proto/live_sql_protocol.proto
@@ -134,12 +134,17 @@
// General Error message.
// TODO: decide on a more fine-grained approach
-// TODO: decide if to unify ErrorOccurredResponse and ErrorOccurredEvent
message ErrorOccurredResponse {
+ ErrorContent content = 1;
+}
+
+message ErrorContent {
// Main error message.
string message = 1;
// Optional stack trace.
string stack_trace = 2;
+ // True for e.g. a query syntax error; False for e.g. corrupt internal inspector state.
+ bool is_recoverable = 3;
}
// --- Events ---
@@ -168,10 +173,6 @@
// General Error message.
// TODO: decide on a more fine-grained approach
-// TODO: decide if to unify ErrorOccurredResponse and ErrorOccurredEvent
message ErrorOccurredEvent {
- // Main error message.
- string message = 1;
- // Optional stack trace.
- string stack_trace = 2;
+ ErrorContent content = 1;
}
diff --git a/swiperefreshlayout/swiperefreshlayout/api/1.1.0-beta02.txt b/swiperefreshlayout/swiperefreshlayout/api/1.1.0-beta02.txt
new file mode 100644
index 0000000..40ac939
--- /dev/null
+++ b/swiperefreshlayout/swiperefreshlayout/api/1.1.0-beta02.txt
@@ -0,0 +1,92 @@
+// Signature format: 3.0
+package androidx.swiperefreshlayout.widget {
+
+ public class CircularProgressDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Animatable {
+ ctor public CircularProgressDrawable(android.content.Context);
+ method public void draw(android.graphics.Canvas!);
+ method public boolean getArrowEnabled();
+ method public float getArrowHeight();
+ method public float getArrowScale();
+ method public float getArrowWidth();
+ method public int getBackgroundColor();
+ method public float getCenterRadius();
+ method public int[] getColorSchemeColors();
+ method public float getEndTrim();
+ method public int getOpacity();
+ method public float getProgressRotation();
+ method public float getStartTrim();
+ method public android.graphics.Paint.Cap getStrokeCap();
+ method public float getStrokeWidth();
+ method public boolean isRunning();
+ method public void setAlpha(int);
+ method public void setArrowDimensions(float, float);
+ method public void setArrowEnabled(boolean);
+ method public void setArrowScale(float);
+ method public void setBackgroundColor(int);
+ method public void setCenterRadius(float);
+ method public void setColorFilter(android.graphics.ColorFilter!);
+ method public void setColorSchemeColors(int...);
+ method public void setProgressRotation(float);
+ method public void setStartEndTrim(float, float);
+ method public void setStrokeCap(android.graphics.Paint.Cap);
+ method public void setStrokeWidth(float);
+ method public void setStyle(int);
+ method public void start();
+ method public void stop();
+ field public static final int DEFAULT = 1; // 0x1
+ field public static final int LARGE = 0; // 0x0
+ }
+
+ public class SwipeRefreshLayout extends android.view.ViewGroup implements androidx.core.view.NestedScrollingChild androidx.core.view.NestedScrollingChild2 androidx.core.view.NestedScrollingChild3 androidx.core.view.NestedScrollingParent androidx.core.view.NestedScrollingParent2 androidx.core.view.NestedScrollingParent3 {
+ ctor public SwipeRefreshLayout(android.content.Context);
+ ctor public SwipeRefreshLayout(android.content.Context, android.util.AttributeSet?);
+ method public boolean canChildScrollUp();
+ method public boolean dispatchNestedPreScroll(int, int, int[]!, int[]!, int);
+ method public void dispatchNestedScroll(int, int, int, int, int[]?, int, int[]);
+ method public boolean dispatchNestedScroll(int, int, int, int, int[]!, int);
+ method public int getProgressCircleDiameter();
+ method public int getProgressViewEndOffset();
+ method public int getProgressViewStartOffset();
+ method public boolean hasNestedScrollingParent(int);
+ method public boolean isRefreshing();
+ method public void onMeasure(int, int);
+ method public void onNestedPreScroll(android.view.View!, int, int, int[]!, int);
+ method public void onNestedScroll(android.view.View, int, int, int, int, int, int[]);
+ method public void onNestedScroll(android.view.View!, int, int, int, int, int);
+ method public void onNestedScrollAccepted(android.view.View!, android.view.View!, int, int);
+ method public boolean onStartNestedScroll(android.view.View!, android.view.View!, int, int);
+ method public void onStopNestedScroll(android.view.View!, int);
+ method @Deprecated public void setColorScheme(@ColorRes int...);
+ method public void setColorSchemeColors(@ColorInt int...);
+ method public void setColorSchemeResources(@ColorRes int...);
+ method public void setDistanceToTriggerSync(int);
+ method @Deprecated public void setLegacyRequestDisallowInterceptTouchEventEnabled(boolean);
+ method public void setOnChildScrollUpCallback(androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnChildScrollUpCallback?);
+ method public void setOnRefreshListener(androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener?);
+ method @Deprecated public void setProgressBackgroundColor(int);
+ method public void setProgressBackgroundColorSchemeColor(@ColorInt int);
+ method public void setProgressBackgroundColorSchemeResource(@ColorRes int);
+ method public void setProgressViewEndTarget(boolean, int);
+ method public void setProgressViewOffset(boolean, int, int);
+ method public void setRefreshing(boolean);
+ method public void setSize(int);
+ method public void setSlingshotDistance(@Px int);
+ method public boolean startNestedScroll(int, int);
+ method public void stopNestedScroll(int);
+ field public static final int DEFAULT = 1; // 0x1
+ field public static final int DEFAULT_SLINGSHOT_DISTANCE = -1; // 0xffffffff
+ field public static final int LARGE = 0; // 0x0
+ field protected int mFrom;
+ field protected int mOriginalOffsetTop;
+ }
+
+ public static interface SwipeRefreshLayout.OnChildScrollUpCallback {
+ method public boolean canChildScrollUp(androidx.swiperefreshlayout.widget.SwipeRefreshLayout, android.view.View?);
+ }
+
+ public static interface SwipeRefreshLayout.OnRefreshListener {
+ method public void onRefresh();
+ }
+
+}
+
diff --git a/swiperefreshlayout/swiperefreshlayout/api/public_plus_experimental_1.1.0-beta02.txt b/swiperefreshlayout/swiperefreshlayout/api/public_plus_experimental_1.1.0-beta02.txt
new file mode 100644
index 0000000..40ac939
--- /dev/null
+++ b/swiperefreshlayout/swiperefreshlayout/api/public_plus_experimental_1.1.0-beta02.txt
@@ -0,0 +1,92 @@
+// Signature format: 3.0
+package androidx.swiperefreshlayout.widget {
+
+ public class CircularProgressDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Animatable {
+ ctor public CircularProgressDrawable(android.content.Context);
+ method public void draw(android.graphics.Canvas!);
+ method public boolean getArrowEnabled();
+ method public float getArrowHeight();
+ method public float getArrowScale();
+ method public float getArrowWidth();
+ method public int getBackgroundColor();
+ method public float getCenterRadius();
+ method public int[] getColorSchemeColors();
+ method public float getEndTrim();
+ method public int getOpacity();
+ method public float getProgressRotation();
+ method public float getStartTrim();
+ method public android.graphics.Paint.Cap getStrokeCap();
+ method public float getStrokeWidth();
+ method public boolean isRunning();
+ method public void setAlpha(int);
+ method public void setArrowDimensions(float, float);
+ method public void setArrowEnabled(boolean);
+ method public void setArrowScale(float);
+ method public void setBackgroundColor(int);
+ method public void setCenterRadius(float);
+ method public void setColorFilter(android.graphics.ColorFilter!);
+ method public void setColorSchemeColors(int...);
+ method public void setProgressRotation(float);
+ method public void setStartEndTrim(float, float);
+ method public void setStrokeCap(android.graphics.Paint.Cap);
+ method public void setStrokeWidth(float);
+ method public void setStyle(int);
+ method public void start();
+ method public void stop();
+ field public static final int DEFAULT = 1; // 0x1
+ field public static final int LARGE = 0; // 0x0
+ }
+
+ public class SwipeRefreshLayout extends android.view.ViewGroup implements androidx.core.view.NestedScrollingChild androidx.core.view.NestedScrollingChild2 androidx.core.view.NestedScrollingChild3 androidx.core.view.NestedScrollingParent androidx.core.view.NestedScrollingParent2 androidx.core.view.NestedScrollingParent3 {
+ ctor public SwipeRefreshLayout(android.content.Context);
+ ctor public SwipeRefreshLayout(android.content.Context, android.util.AttributeSet?);
+ method public boolean canChildScrollUp();
+ method public boolean dispatchNestedPreScroll(int, int, int[]!, int[]!, int);
+ method public void dispatchNestedScroll(int, int, int, int, int[]?, int, int[]);
+ method public boolean dispatchNestedScroll(int, int, int, int, int[]!, int);
+ method public int getProgressCircleDiameter();
+ method public int getProgressViewEndOffset();
+ method public int getProgressViewStartOffset();
+ method public boolean hasNestedScrollingParent(int);
+ method public boolean isRefreshing();
+ method public void onMeasure(int, int);
+ method public void onNestedPreScroll(android.view.View!, int, int, int[]!, int);
+ method public void onNestedScroll(android.view.View, int, int, int, int, int, int[]);
+ method public void onNestedScroll(android.view.View!, int, int, int, int, int);
+ method public void onNestedScrollAccepted(android.view.View!, android.view.View!, int, int);
+ method public boolean onStartNestedScroll(android.view.View!, android.view.View!, int, int);
+ method public void onStopNestedScroll(android.view.View!, int);
+ method @Deprecated public void setColorScheme(@ColorRes int...);
+ method public void setColorSchemeColors(@ColorInt int...);
+ method public void setColorSchemeResources(@ColorRes int...);
+ method public void setDistanceToTriggerSync(int);
+ method @Deprecated public void setLegacyRequestDisallowInterceptTouchEventEnabled(boolean);
+ method public void setOnChildScrollUpCallback(androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnChildScrollUpCallback?);
+ method public void setOnRefreshListener(androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener?);
+ method @Deprecated public void setProgressBackgroundColor(int);
+ method public void setProgressBackgroundColorSchemeColor(@ColorInt int);
+ method public void setProgressBackgroundColorSchemeResource(@ColorRes int);
+ method public void setProgressViewEndTarget(boolean, int);
+ method public void setProgressViewOffset(boolean, int, int);
+ method public void setRefreshing(boolean);
+ method public void setSize(int);
+ method public void setSlingshotDistance(@Px int);
+ method public boolean startNestedScroll(int, int);
+ method public void stopNestedScroll(int);
+ field public static final int DEFAULT = 1; // 0x1
+ field public static final int DEFAULT_SLINGSHOT_DISTANCE = -1; // 0xffffffff
+ field public static final int LARGE = 0; // 0x0
+ field protected int mFrom;
+ field protected int mOriginalOffsetTop;
+ }
+
+ public static interface SwipeRefreshLayout.OnChildScrollUpCallback {
+ method public boolean canChildScrollUp(androidx.swiperefreshlayout.widget.SwipeRefreshLayout, android.view.View?);
+ }
+
+ public static interface SwipeRefreshLayout.OnRefreshListener {
+ method public void onRefresh();
+ }
+
+}
+
diff --git a/swiperefreshlayout/swiperefreshlayout/api/restricted_1.1.0-beta02.txt b/swiperefreshlayout/swiperefreshlayout/api/restricted_1.1.0-beta02.txt
new file mode 100644
index 0000000..21e0e84
--- /dev/null
+++ b/swiperefreshlayout/swiperefreshlayout/api/restricted_1.1.0-beta02.txt
@@ -0,0 +1,95 @@
+// Signature format: 3.0
+package androidx.swiperefreshlayout.widget {
+
+ public class CircularProgressDrawable extends android.graphics.drawable.Drawable implements android.graphics.drawable.Animatable {
+ ctor public CircularProgressDrawable(android.content.Context);
+ method public void draw(android.graphics.Canvas!);
+ method public boolean getArrowEnabled();
+ method public float getArrowHeight();
+ method public float getArrowScale();
+ method public float getArrowWidth();
+ method public int getBackgroundColor();
+ method public float getCenterRadius();
+ method public int[] getColorSchemeColors();
+ method public float getEndTrim();
+ method public int getOpacity();
+ method public float getProgressRotation();
+ method public float getStartTrim();
+ method public android.graphics.Paint.Cap getStrokeCap();
+ method public float getStrokeWidth();
+ method public boolean isRunning();
+ method public void setAlpha(int);
+ method public void setArrowDimensions(float, float);
+ method public void setArrowEnabled(boolean);
+ method public void setArrowScale(float);
+ method public void setBackgroundColor(int);
+ method public void setCenterRadius(float);
+ method public void setColorFilter(android.graphics.ColorFilter!);
+ method public void setColorSchemeColors(int...);
+ method public void setProgressRotation(float);
+ method public void setStartEndTrim(float, float);
+ method public void setStrokeCap(android.graphics.Paint.Cap);
+ method public void setStrokeWidth(float);
+ method public void setStyle(@androidx.swiperefreshlayout.widget.CircularProgressDrawable.ProgressDrawableSize int);
+ method public void start();
+ method public void stop();
+ field public static final int DEFAULT = 1; // 0x1
+ field public static final int LARGE = 0; // 0x0
+ }
+
+ @IntDef({androidx.swiperefreshlayout.widget.CircularProgressDrawable.LARGE, androidx.swiperefreshlayout.widget.CircularProgressDrawable.DEFAULT}) @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface CircularProgressDrawable.ProgressDrawableSize {
+ }
+
+ public class SwipeRefreshLayout extends android.view.ViewGroup implements androidx.core.view.NestedScrollingChild androidx.core.view.NestedScrollingChild2 androidx.core.view.NestedScrollingChild3 androidx.core.view.NestedScrollingParent androidx.core.view.NestedScrollingParent2 androidx.core.view.NestedScrollingParent3 {
+ ctor public SwipeRefreshLayout(android.content.Context);
+ ctor public SwipeRefreshLayout(android.content.Context, android.util.AttributeSet?);
+ method public boolean canChildScrollUp();
+ method public boolean dispatchNestedPreScroll(int, int, int[]!, int[]!, int);
+ method public void dispatchNestedScroll(int, int, int, int, int[]?, int, int[]);
+ method public boolean dispatchNestedScroll(int, int, int, int, int[]!, int);
+ method public int getProgressCircleDiameter();
+ method public int getProgressViewEndOffset();
+ method public int getProgressViewStartOffset();
+ method public boolean hasNestedScrollingParent(int);
+ method public boolean isRefreshing();
+ method public void onMeasure(int, int);
+ method public void onNestedPreScroll(android.view.View!, int, int, int[]!, int);
+ method public void onNestedScroll(android.view.View, int, int, int, int, int, int[]);
+ method public void onNestedScroll(android.view.View!, int, int, int, int, int);
+ method public void onNestedScrollAccepted(android.view.View!, android.view.View!, int, int);
+ method public boolean onStartNestedScroll(android.view.View!, android.view.View!, int, int);
+ method public void onStopNestedScroll(android.view.View!, int);
+ method @Deprecated public void setColorScheme(@ColorRes int...);
+ method public void setColorSchemeColors(@ColorInt int...);
+ method public void setColorSchemeResources(@ColorRes int...);
+ method public void setDistanceToTriggerSync(int);
+ method @Deprecated public void setLegacyRequestDisallowInterceptTouchEventEnabled(boolean);
+ method public void setOnChildScrollUpCallback(androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnChildScrollUpCallback?);
+ method public void setOnRefreshListener(androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener?);
+ method @Deprecated public void setProgressBackgroundColor(int);
+ method public void setProgressBackgroundColorSchemeColor(@ColorInt int);
+ method public void setProgressBackgroundColorSchemeResource(@ColorRes int);
+ method public void setProgressViewEndTarget(boolean, int);
+ method public void setProgressViewOffset(boolean, int, int);
+ method public void setRefreshing(boolean);
+ method public void setSize(int);
+ method public void setSlingshotDistance(@Px int);
+ method public boolean startNestedScroll(int, int);
+ method public void stopNestedScroll(int);
+ field public static final int DEFAULT = 1; // 0x1
+ field public static final int DEFAULT_SLINGSHOT_DISTANCE = -1; // 0xffffffff
+ field public static final int LARGE = 0; // 0x0
+ field protected int mFrom;
+ field protected int mOriginalOffsetTop;
+ }
+
+ public static interface SwipeRefreshLayout.OnChildScrollUpCallback {
+ method public boolean canChildScrollUp(androidx.swiperefreshlayout.widget.SwipeRefreshLayout, android.view.View?);
+ }
+
+ public static interface SwipeRefreshLayout.OnRefreshListener {
+ method public void onRefresh();
+ }
+
+}
+
diff --git a/ui/gradle.properties b/ui/gradle.properties
index 332182b..0e62dbf 100644
--- a/ui/gradle.properties
+++ b/ui/gradle.properties
@@ -13,4 +13,3 @@
android.useNewJarCreator=false
# Workaround for b/141364941
android.forceJacocoOutOfProcess=true
-android.namespacedRClass=true
\ No newline at end of file
diff --git a/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/core/WithConstraintsBenchmark.kt b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/core/WithConstraintsBenchmark.kt
index 6aab3fd..1cfb79f 100644
--- a/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/core/WithConstraintsBenchmark.kt
+++ b/ui/integration-tests/benchmark/src/androidTest/java/androidx/ui/core/WithConstraintsBenchmark.kt
@@ -88,7 +88,7 @@
override fun emitContent() {
val size = state { 200.dp }
this.state = size
- WithConstraints {
+ WithConstraints { _, _ ->
Container(width = 300.dp, height = 300.dp) {
Spacer(LayoutSize(width = size.value, height = size.value))
}
@@ -109,7 +109,7 @@
val size = state { 100.ipx }
this.state = size
ChangingConstraintsLayout(state) {
- WithConstraints {
+ WithConstraints { _, _ ->
Container(expanded = true) {}
}
}
diff --git a/ui/integration-tests/test/src/androidTest/java/androidx/ui/integration/test/TableRecompositionTest.kt b/ui/integration-tests/test/src/androidTest/java/androidx/ui/integration/test/TableRecompositionTest.kt
index 69d4b04..2b18eae 100644
--- a/ui/integration-tests/test/src/androidTest/java/androidx/ui/integration/test/TableRecompositionTest.kt
+++ b/ui/integration-tests/test/src/androidTest/java/androidx/ui/integration/test/TableRecompositionTest.kt
@@ -23,7 +23,7 @@
import androidx.ui.layout.LayoutPadding
import androidx.ui.layout.Table
import androidx.ui.material.MaterialTheme
-import androidx.ui.material.surface.Surface
+import androidx.ui.material.Surface
import androidx.ui.test.createComposeRule
import androidx.ui.test.doFramesUntilNoChangesPending
import org.junit.Rule
diff --git a/ui/integration-tests/test/src/main/java/androidx/ui/integration/test/foundation/NestedScrollerTestCase.kt b/ui/integration-tests/test/src/main/java/androidx/ui/integration/test/foundation/NestedScrollerTestCase.kt
index 7a9f294c..a65c99c 100644
--- a/ui/integration-tests/test/src/main/java/androidx/ui/integration/test/foundation/NestedScrollerTestCase.kt
+++ b/ui/integration-tests/test/src/main/java/androidx/ui/integration/test/foundation/NestedScrollerTestCase.kt
@@ -32,7 +32,7 @@
import androidx.ui.layout.LayoutWidth
import androidx.ui.layout.Row
import androidx.ui.material.MaterialTheme
-import androidx.ui.material.surface.Surface
+import androidx.ui.material.Surface
import androidx.ui.test.ComposeTestCase
import androidx.ui.text.TextStyle
import androidx.ui.unit.px
diff --git a/ui/integration-tests/test/src/main/java/androidx/ui/integration/test/foundation/RectsInColumnTestCase.kt b/ui/integration-tests/test/src/main/java/androidx/ui/integration/test/foundation/RectsInColumnTestCase.kt
index 1fdf58d..0206adc 100644
--- a/ui/integration-tests/test/src/main/java/androidx/ui/integration/test/foundation/RectsInColumnTestCase.kt
+++ b/ui/integration-tests/test/src/main/java/androidx/ui/integration/test/foundation/RectsInColumnTestCase.kt
@@ -24,7 +24,7 @@
import androidx.ui.graphics.Color
import androidx.ui.layout.Column
import androidx.ui.material.MaterialTheme
-import androidx.ui.material.surface.Surface
+import androidx.ui.material.Surface
import androidx.ui.test.ComposeTestCase
import androidx.ui.integration.test.ToggleableTestCase
diff --git a/ui/integration-tests/test/src/main/java/androidx/ui/integration/test/material/CheckboxesInRowsTestCase.kt b/ui/integration-tests/test/src/main/java/androidx/ui/integration/test/material/CheckboxesInRowsTestCase.kt
index 8fd915a..1348662 100644
--- a/ui/integration-tests/test/src/main/java/androidx/ui/integration/test/material/CheckboxesInRowsTestCase.kt
+++ b/ui/integration-tests/test/src/main/java/androidx/ui/integration/test/material/CheckboxesInRowsTestCase.kt
@@ -26,7 +26,7 @@
import androidx.ui.layout.Row
import androidx.ui.material.Checkbox
import androidx.ui.material.MaterialTheme
-import androidx.ui.material.surface.Surface
+import androidx.ui.material.Surface
import androidx.ui.test.ComposeTestCase
import androidx.ui.integration.test.ToggleableTestCase
diff --git a/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/WebComponentActivity.kt b/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/WebComponentActivity.kt
index b7517de..154a280 100644
--- a/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/WebComponentActivity.kt
+++ b/ui/ui-android-view/integration-tests/android-view-demos/src/main/java/androidx/ui/androidview/demos/WebComponentActivity.kt
@@ -36,10 +36,10 @@
import androidx.ui.androidview.adapters.setOnTextChanged
import androidx.compose.Composable
import androidx.compose.Model
-import androidx.compose.setViewContent
import androidx.compose.state
import androidx.ui.androidview.WebComponent
import androidx.ui.androidview.WebContext
+import androidx.ui.core.setViewContent
@Model
class WebParams {
diff --git a/ui/ui-android-view/src/main/java/androidx/ui/androidview/adapters/ArrayAdapter.kt b/ui/ui-android-view/src/main/java/androidx/ui/androidview/adapters/ArrayAdapter.kt
index a9b5859..018d9f8 100644
--- a/ui/ui-android-view/src/main/java/androidx/ui/androidview/adapters/ArrayAdapter.kt
+++ b/ui/ui-android-view/src/main/java/androidx/ui/androidview/adapters/ArrayAdapter.kt
@@ -26,7 +26,7 @@
import android.widget.FrameLayout
import android.widget.TextView
import androidx.compose.Composable
-import androidx.compose.setViewContent
+import androidx.ui.core.setViewContent
// TODO(lmr): This should be moved to a separate module, but needs to be one that is not IR-compiled
class ArrayAdapter<T> : BaseAdapter(), Filterable {
diff --git a/ui/ui-android-view/src/main/java/androidx/ui/androidview/adapters/LayoutBuilder.kt b/ui/ui-android-view/src/main/java/androidx/ui/androidview/adapters/LayoutBuilder.kt
index 1f164f6..f04afef 100644
--- a/ui/ui-android-view/src/main/java/androidx/ui/androidview/adapters/LayoutBuilder.kt
+++ b/ui/ui-android-view/src/main/java/androidx/ui/androidview/adapters/LayoutBuilder.kt
@@ -18,8 +18,8 @@
import android.view.View
import android.view.ViewGroup
-import androidx.compose.adapters.ViewAdapter
-import androidx.compose.adapters.getOrAddAdapter
+import androidx.ui.node.ViewAdapter
+import androidx.ui.node.getOrAddAdapter
private val LayoutBuilderId = tagKey("LayoutBuilder")
private val intHandlers = HashMap<Int, ViewGroup.LayoutParams.(Int) -> Unit>()
diff --git a/ui/ui-animation-core/api/0.1.0-dev07.txt b/ui/ui-animation-core/api/0.1.0-dev07.txt
index 768cc00..3dd6437 100644
--- a/ui/ui-animation-core/api/0.1.0-dev07.txt
+++ b/ui/ui-animation-core/api/0.1.0-dev07.txt
@@ -36,6 +36,9 @@
field public static final int Infinite = 2147483647; // 0x7fffffff
}
+ public final class AnimationClockKt {
+ }
+
public interface AnimationClockObservable {
method public void subscribe(androidx.animation.AnimationClockObserver observer);
method public void unsubscribe(androidx.animation.AnimationClockObserver observer);
diff --git a/ui/ui-animation-core/api/api_lint.ignore b/ui/ui-animation-core/api/api_lint.ignore
index c717d5d..3ffc491 100644
--- a/ui/ui-animation-core/api/api_lint.ignore
+++ b/ui/ui-animation-core/api/api_lint.ignore
@@ -27,6 +27,8 @@
Method RepeatableBuilder.setIterations appears to be throwing java.lang.IllegalStateException; this should be listed in the documentation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
+HiddenTypeParameter: androidx.animation.BaseAnimationClock#Companion:
+ Field BaseAnimationClock.Companion references hidden type androidx.animation.BaseAnimationClock.Companion.
HiddenTypeParameter: androidx.animation.DurationBasedAnimationBuilder#build$lintWithKotlin(androidx.animation.TwoWayConverter<T,V>):
Method androidx.animation.DurationBasedAnimationBuilder.build$lintWithKotlin(androidx.animation.TwoWayConverter<T,V>) references hidden type androidx.animation.DurationBasedAnimation<V>.
HiddenTypeParameter: androidx.animation.KeyframesBuilder#build$lintWithKotlin(androidx.animation.TwoWayConverter<T,V>):
@@ -39,14 +41,6 @@
Method androidx.animation.SnapBuilder.build$lintWithKotlin(androidx.animation.TwoWayConverter<T,V>) references hidden type androidx.animation.Animation<V>.
HiddenTypeParameter: androidx.animation.TweenBuilder#build$lintWithKotlin(androidx.animation.TwoWayConverter<T,V>):
Method androidx.animation.TweenBuilder.build$lintWithKotlin(androidx.animation.TwoWayConverter<T,V>) references hidden type androidx.animation.DurationBasedAnimation<V>.
-HiddenTypeParameter: androidx.animation.TypeConverter1D#getArithmetic$lintWithKotlin():
- Method androidx.animation.TypeConverter1D.getArithmetic$lintWithKotlin() references hidden type androidx.animation.Arithmetic<androidx.animation.AnimationVector1D>.
-HiddenTypeParameter: androidx.animation.TypeConverter2D#getArithmetic$lintWithKotlin():
- Method androidx.animation.TypeConverter2D.getArithmetic$lintWithKotlin() references hidden type androidx.animation.Arithmetic<androidx.animation.AnimationVector2D>.
-HiddenTypeParameter: androidx.animation.TypeConverter3D#getArithmetic$lintWithKotlin():
- Method androidx.animation.TypeConverter3D.getArithmetic$lintWithKotlin() references hidden type androidx.animation.Arithmetic<androidx.animation.AnimationVector3D>.
-HiddenTypeParameter: androidx.animation.TypeConverter4D#getArithmetic$lintWithKotlin():
- Method androidx.animation.TypeConverter4D.getArithmetic$lintWithKotlin() references hidden type androidx.animation.Arithmetic<androidx.animation.AnimationVector4D>.
MissingBuildMethod: androidx.animation.AnimationBuilder:
diff --git a/ui/ui-animation-core/api/current.txt b/ui/ui-animation-core/api/current.txt
index 768cc00..3dd6437 100644
--- a/ui/ui-animation-core/api/current.txt
+++ b/ui/ui-animation-core/api/current.txt
@@ -36,6 +36,9 @@
field public static final int Infinite = 2147483647; // 0x7fffffff
}
+ public final class AnimationClockKt {
+ }
+
public interface AnimationClockObservable {
method public void subscribe(androidx.animation.AnimationClockObserver observer);
method public void unsubscribe(androidx.animation.AnimationClockObserver observer);
diff --git a/ui/ui-animation-core/api/public_plus_experimental_0.1.0-dev07.txt b/ui/ui-animation-core/api/public_plus_experimental_0.1.0-dev07.txt
index 768cc00..3dd6437 100644
--- a/ui/ui-animation-core/api/public_plus_experimental_0.1.0-dev07.txt
+++ b/ui/ui-animation-core/api/public_plus_experimental_0.1.0-dev07.txt
@@ -36,6 +36,9 @@
field public static final int Infinite = 2147483647; // 0x7fffffff
}
+ public final class AnimationClockKt {
+ }
+
public interface AnimationClockObservable {
method public void subscribe(androidx.animation.AnimationClockObserver observer);
method public void unsubscribe(androidx.animation.AnimationClockObserver observer);
diff --git a/ui/ui-animation-core/api/public_plus_experimental_current.txt b/ui/ui-animation-core/api/public_plus_experimental_current.txt
index 768cc00..3dd6437 100644
--- a/ui/ui-animation-core/api/public_plus_experimental_current.txt
+++ b/ui/ui-animation-core/api/public_plus_experimental_current.txt
@@ -36,6 +36,9 @@
field public static final int Infinite = 2147483647; // 0x7fffffff
}
+ public final class AnimationClockKt {
+ }
+
public interface AnimationClockObservable {
method public void subscribe(androidx.animation.AnimationClockObserver observer);
method public void unsubscribe(androidx.animation.AnimationClockObserver observer);
diff --git a/ui/ui-animation-core/api/restricted_0.1.0-dev07.txt b/ui/ui-animation-core/api/restricted_0.1.0-dev07.txt
index 768cc00..3dd6437 100644
--- a/ui/ui-animation-core/api/restricted_0.1.0-dev07.txt
+++ b/ui/ui-animation-core/api/restricted_0.1.0-dev07.txt
@@ -36,6 +36,9 @@
field public static final int Infinite = 2147483647; // 0x7fffffff
}
+ public final class AnimationClockKt {
+ }
+
public interface AnimationClockObservable {
method public void subscribe(androidx.animation.AnimationClockObserver observer);
method public void unsubscribe(androidx.animation.AnimationClockObserver observer);
diff --git a/ui/ui-animation-core/api/restricted_current.txt b/ui/ui-animation-core/api/restricted_current.txt
index 768cc00..3dd6437 100644
--- a/ui/ui-animation-core/api/restricted_current.txt
+++ b/ui/ui-animation-core/api/restricted_current.txt
@@ -36,6 +36,9 @@
field public static final int Infinite = 2147483647; // 0x7fffffff
}
+ public final class AnimationClockKt {
+ }
+
public interface AnimationClockObservable {
method public void subscribe(androidx.animation.AnimationClockObserver observer);
method public void unsubscribe(androidx.animation.AnimationClockObserver observer);
diff --git a/ui/ui-animation-core/src/main/java/androidx/animation/AnimationClock.kt b/ui/ui-animation-core/src/main/java/androidx/animation/AnimationClock.kt
index 98f3dd8..138bff84 100644
--- a/ui/ui-animation-core/src/main/java/androidx/animation/AnimationClock.kt
+++ b/ui/ui-animation-core/src/main/java/androidx/animation/AnimationClock.kt
@@ -20,11 +20,18 @@
import android.os.Looper
import android.view.Choreographer
import androidx.annotation.CallSuper
+import androidx.annotation.RestrictTo
import java.util.concurrent.CountDownLatch
+/** @hide */
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+var rootAnimationClockFactory: () -> AnimationClockObservable = { DefaultAnimationClock() }
+
/**
* Default Choreographer based clock that pushes a new frame to all subscribers on each
- * Choreographer tick, until all subscribers have unsubscribed.
+ * Choreographer tick, until all subscribers have unsubscribed. An instance of this clock will be
+ * provided through [AnimationClockAmbient][androidx.ui.core.AnimationClockAmbient] at the root
+ * of the composition tree.
*
* If initialized from any other thread but the main thread, part of the initialization is done
* synchronously on the main thread. If this poses a problem, consider initializing this clock on
diff --git a/ui/ui-animation/integration-tests/samples/src/main/java/androidx/ui/animation/samples/AnimatedValueSamples.kt b/ui/ui-animation/integration-tests/samples/src/main/java/androidx/ui/animation/samples/AnimatedValueSamples.kt
index a84ef44..a9f8484 100644
--- a/ui/ui-animation/integration-tests/samples/src/main/java/androidx/ui/animation/samples/AnimatedValueSamples.kt
+++ b/ui/ui-animation/integration-tests/samples/src/main/java/androidx/ui/animation/samples/AnimatedValueSamples.kt
@@ -22,9 +22,9 @@
import androidx.compose.Composable
import androidx.compose.remember
import androidx.ui.animation.animate
-import androidx.ui.core.Opacity
import androidx.ui.core.Text
import androidx.ui.core.currentTextStyle
+import androidx.ui.core.drawOpacity
import androidx.ui.foundation.ColoredRect
import androidx.ui.graphics.Color
import androidx.ui.layout.Container
@@ -41,9 +41,7 @@
fun VisibilityTransition(visibility: VisibilityState) {
Container(expanded = true) {
val opacity = animate(if (visibility == VisibilityState.Invisible) 0f else 1f)
- Opacity(opacity = opacity) {
- Text("Visibility Transition")
- }
+ Text("Visibility Transition", modifier = drawOpacity(opacity))
}
}
diff --git a/ui/ui-animation/src/main/java/androidx/ui/animation/Crossfade.kt b/ui/ui-animation/src/main/java/androidx/ui/animation/Crossfade.kt
index 76cbc48..e230be5 100644
--- a/ui/ui-animation/src/main/java/androidx/ui/animation/Crossfade.kt
+++ b/ui/ui-animation/src/main/java/androidx/ui/animation/Crossfade.kt
@@ -16,13 +16,14 @@
package androidx.ui.animation
+import androidx.animation.AnimatedFloat
import androidx.animation.AnimationEndReason
import androidx.animation.TweenBuilder
import androidx.compose.Composable
import androidx.compose.key
import androidx.compose.onCommit
import androidx.compose.remember
-import androidx.ui.core.Opacity
+import androidx.ui.core.drawOpacity
import androidx.ui.layout.Stack
/**
@@ -46,17 +47,17 @@
state.items.clear()
keys.forEach { key ->
state.items.add(key to @Composable() { children ->
- Opacity(
- opacity = animatedOpacity(
- visible = (key == current),
- onAnimationFinish = {
- if (key == state.current) {
- // leave only the current in the list
- state.items.removeAll { it.first != state.current }
- }
- }),
- children = children
- )
+ val opacity = animatedOpacity(
+ visible = (key == current),
+ onAnimationFinish = {
+ if (key == state.current) {
+ // leave only the current in the list
+ state.items.removeAll { it.first != state.current }
+ }
+ })
+ Stack(modifier = drawOpacity(opacity.value)) {
+ children()
+ }
})
}
}
@@ -80,7 +81,7 @@
private fun animatedOpacity(
visible: Boolean,
onAnimationFinish: () -> Unit = {}
-): Float {
+): AnimatedFloat {
val animatedFloat = animatedFloat(if (!visible) 1f else 0f)
onCommit(visible) {
animatedFloat.animateTo(
@@ -92,5 +93,5 @@
}
})
}
- return animatedFloat.value
+ return animatedFloat
}
diff --git a/ui/ui-animation/src/main/java/androidx/ui/animation/Transition.kt b/ui/ui-animation/src/main/java/androidx/ui/animation/Transition.kt
index 719026f..2bdce17 100644
--- a/ui/ui-animation/src/main/java/androidx/ui/animation/Transition.kt
+++ b/ui/ui-animation/src/main/java/androidx/ui/animation/Transition.kt
@@ -25,7 +25,7 @@
import androidx.animation.createAnimation
import androidx.compose.Composable
import androidx.compose.Model
-import androidx.compose.onCommit
+import androidx.compose.onPreCommit
import androidx.compose.remember
import androidx.ui.core.AnimationClockAmbient
@@ -81,7 +81,10 @@
}
model.anim.onStateChangeFinished = onStateChangeFinished
- onCommit(model, toState) {
+ // TODO(b/150674848): Should be onCommit, but that posts to the Choreographer. Until that
+ // callback is executed, nothing is aware that the animation is kicked off, so if
+ // Espresso checks for idleness between now and then, it will think all is idle.
+ onPreCommit(model, toState) {
model.anim.toState(toState)
}
children(model)
diff --git a/ui/ui-core/api/0.1.0-dev07.txt b/ui/ui-core/api/0.1.0-dev07.txt
index 61e2694..2df6bda 100644
--- a/ui/ui-core/api/0.1.0-dev07.txt
+++ b/ui/ui-core/api/0.1.0-dev07.txt
@@ -114,6 +114,39 @@
enum_constant public static final androidx.ui.core.Direction UP;
}
+ public interface DrawLayerModifier extends androidx.ui.core.Modifier.Element {
+ method public androidx.ui.core.DrawLayerProperties getProperties();
+ property public abstract androidx.ui.core.DrawLayerProperties properties;
+ }
+
+ public final class DrawLayerModifierKt {
+ method public static androidx.ui.core.Modifier drawLayer(androidx.ui.core.DrawLayerProperties drawLayerProperties);
+ method public static androidx.ui.core.Modifier drawLayer(float scaleX = 1f, float scaleY = 1f, float alpha = 1f, float elevation = 0f, float rotationX = 0f, float rotationY = 0f, float rotationZ = 0f, androidx.ui.graphics.Shape? outlineShape = null, boolean clipToBounds = true, boolean clipToOutline = true);
+ }
+
+ public interface DrawLayerProperties {
+ method @FloatRange(from=0.0, to=1.0) public default float getAlpha();
+ method public default boolean getClipToBounds();
+ method public default boolean getClipToOutline();
+ method @FloatRange(from=0.0) public default float getElevation();
+ method public default androidx.ui.graphics.Shape? getOutlineShape();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationX();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationY();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationZ();
+ method public default float getScaleX();
+ method public default float getScaleY();
+ property @FloatRange(from=0.0, to=1.0) public default float alpha;
+ property public default boolean clipToBounds;
+ property public default boolean clipToOutline;
+ property @FloatRange(from=0.0) public default float elevation;
+ property public default androidx.ui.graphics.Shape? outlineShape;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationX;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationY;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationZ;
+ property public default float scaleX;
+ property public default float scaleY;
+ }
+
public interface DrawModifier extends androidx.ui.core.Modifier.Element {
method public void draw(androidx.ui.unit.Density density, kotlin.jvm.functions.Function0<kotlin.Unit> drawContent, androidx.ui.graphics.Canvas canvas, androidx.ui.unit.PxSize size);
}
@@ -196,7 +229,7 @@
method public java.util.Map<androidx.ui.core.AlignmentLine,androidx.ui.unit.IntPx> getAlignmentLines();
method public androidx.ui.unit.IntPx getHeight();
method public androidx.ui.unit.IntPx getWidth();
- method public void placeChildren(androidx.ui.core.Placeable.PlacementScope placementScope);
+ method public void placeChildren(androidx.ui.core.LayoutDirection layoutDirection);
property public abstract java.util.Map<androidx.ui.core.AlignmentLine,androidx.ui.unit.IntPx> alignmentLines;
property public abstract androidx.ui.unit.IntPx height;
property public abstract androidx.ui.unit.IntPx width;
@@ -245,6 +278,10 @@
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.PxPosition position);
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.IntPx x, androidx.ui.unit.IntPx y);
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.Px x, androidx.ui.unit.Px y);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.IntPxPosition position);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.PxPosition position);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.IntPx x, androidx.ui.unit.IntPx y);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.Px x, androidx.ui.unit.Px y);
}
public enum PointerEventPass {
diff --git a/ui/ui-core/api/current.txt b/ui/ui-core/api/current.txt
index 61e2694..2df6bda 100644
--- a/ui/ui-core/api/current.txt
+++ b/ui/ui-core/api/current.txt
@@ -114,6 +114,39 @@
enum_constant public static final androidx.ui.core.Direction UP;
}
+ public interface DrawLayerModifier extends androidx.ui.core.Modifier.Element {
+ method public androidx.ui.core.DrawLayerProperties getProperties();
+ property public abstract androidx.ui.core.DrawLayerProperties properties;
+ }
+
+ public final class DrawLayerModifierKt {
+ method public static androidx.ui.core.Modifier drawLayer(androidx.ui.core.DrawLayerProperties drawLayerProperties);
+ method public static androidx.ui.core.Modifier drawLayer(float scaleX = 1f, float scaleY = 1f, float alpha = 1f, float elevation = 0f, float rotationX = 0f, float rotationY = 0f, float rotationZ = 0f, androidx.ui.graphics.Shape? outlineShape = null, boolean clipToBounds = true, boolean clipToOutline = true);
+ }
+
+ public interface DrawLayerProperties {
+ method @FloatRange(from=0.0, to=1.0) public default float getAlpha();
+ method public default boolean getClipToBounds();
+ method public default boolean getClipToOutline();
+ method @FloatRange(from=0.0) public default float getElevation();
+ method public default androidx.ui.graphics.Shape? getOutlineShape();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationX();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationY();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationZ();
+ method public default float getScaleX();
+ method public default float getScaleY();
+ property @FloatRange(from=0.0, to=1.0) public default float alpha;
+ property public default boolean clipToBounds;
+ property public default boolean clipToOutline;
+ property @FloatRange(from=0.0) public default float elevation;
+ property public default androidx.ui.graphics.Shape? outlineShape;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationX;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationY;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationZ;
+ property public default float scaleX;
+ property public default float scaleY;
+ }
+
public interface DrawModifier extends androidx.ui.core.Modifier.Element {
method public void draw(androidx.ui.unit.Density density, kotlin.jvm.functions.Function0<kotlin.Unit> drawContent, androidx.ui.graphics.Canvas canvas, androidx.ui.unit.PxSize size);
}
@@ -196,7 +229,7 @@
method public java.util.Map<androidx.ui.core.AlignmentLine,androidx.ui.unit.IntPx> getAlignmentLines();
method public androidx.ui.unit.IntPx getHeight();
method public androidx.ui.unit.IntPx getWidth();
- method public void placeChildren(androidx.ui.core.Placeable.PlacementScope placementScope);
+ method public void placeChildren(androidx.ui.core.LayoutDirection layoutDirection);
property public abstract java.util.Map<androidx.ui.core.AlignmentLine,androidx.ui.unit.IntPx> alignmentLines;
property public abstract androidx.ui.unit.IntPx height;
property public abstract androidx.ui.unit.IntPx width;
@@ -245,6 +278,10 @@
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.PxPosition position);
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.IntPx x, androidx.ui.unit.IntPx y);
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.Px x, androidx.ui.unit.Px y);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.IntPxPosition position);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.PxPosition position);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.IntPx x, androidx.ui.unit.IntPx y);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.Px x, androidx.ui.unit.Px y);
}
public enum PointerEventPass {
diff --git a/ui/ui-core/api/public_plus_experimental_0.1.0-dev07.txt b/ui/ui-core/api/public_plus_experimental_0.1.0-dev07.txt
index 61e2694..2df6bda 100644
--- a/ui/ui-core/api/public_plus_experimental_0.1.0-dev07.txt
+++ b/ui/ui-core/api/public_plus_experimental_0.1.0-dev07.txt
@@ -114,6 +114,39 @@
enum_constant public static final androidx.ui.core.Direction UP;
}
+ public interface DrawLayerModifier extends androidx.ui.core.Modifier.Element {
+ method public androidx.ui.core.DrawLayerProperties getProperties();
+ property public abstract androidx.ui.core.DrawLayerProperties properties;
+ }
+
+ public final class DrawLayerModifierKt {
+ method public static androidx.ui.core.Modifier drawLayer(androidx.ui.core.DrawLayerProperties drawLayerProperties);
+ method public static androidx.ui.core.Modifier drawLayer(float scaleX = 1f, float scaleY = 1f, float alpha = 1f, float elevation = 0f, float rotationX = 0f, float rotationY = 0f, float rotationZ = 0f, androidx.ui.graphics.Shape? outlineShape = null, boolean clipToBounds = true, boolean clipToOutline = true);
+ }
+
+ public interface DrawLayerProperties {
+ method @FloatRange(from=0.0, to=1.0) public default float getAlpha();
+ method public default boolean getClipToBounds();
+ method public default boolean getClipToOutline();
+ method @FloatRange(from=0.0) public default float getElevation();
+ method public default androidx.ui.graphics.Shape? getOutlineShape();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationX();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationY();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationZ();
+ method public default float getScaleX();
+ method public default float getScaleY();
+ property @FloatRange(from=0.0, to=1.0) public default float alpha;
+ property public default boolean clipToBounds;
+ property public default boolean clipToOutline;
+ property @FloatRange(from=0.0) public default float elevation;
+ property public default androidx.ui.graphics.Shape? outlineShape;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationX;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationY;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationZ;
+ property public default float scaleX;
+ property public default float scaleY;
+ }
+
public interface DrawModifier extends androidx.ui.core.Modifier.Element {
method public void draw(androidx.ui.unit.Density density, kotlin.jvm.functions.Function0<kotlin.Unit> drawContent, androidx.ui.graphics.Canvas canvas, androidx.ui.unit.PxSize size);
}
@@ -196,7 +229,7 @@
method public java.util.Map<androidx.ui.core.AlignmentLine,androidx.ui.unit.IntPx> getAlignmentLines();
method public androidx.ui.unit.IntPx getHeight();
method public androidx.ui.unit.IntPx getWidth();
- method public void placeChildren(androidx.ui.core.Placeable.PlacementScope placementScope);
+ method public void placeChildren(androidx.ui.core.LayoutDirection layoutDirection);
property public abstract java.util.Map<androidx.ui.core.AlignmentLine,androidx.ui.unit.IntPx> alignmentLines;
property public abstract androidx.ui.unit.IntPx height;
property public abstract androidx.ui.unit.IntPx width;
@@ -245,6 +278,10 @@
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.PxPosition position);
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.IntPx x, androidx.ui.unit.IntPx y);
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.Px x, androidx.ui.unit.Px y);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.IntPxPosition position);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.PxPosition position);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.IntPx x, androidx.ui.unit.IntPx y);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.Px x, androidx.ui.unit.Px y);
}
public enum PointerEventPass {
diff --git a/ui/ui-core/api/public_plus_experimental_current.txt b/ui/ui-core/api/public_plus_experimental_current.txt
index 61e2694..2df6bda 100644
--- a/ui/ui-core/api/public_plus_experimental_current.txt
+++ b/ui/ui-core/api/public_plus_experimental_current.txt
@@ -114,6 +114,39 @@
enum_constant public static final androidx.ui.core.Direction UP;
}
+ public interface DrawLayerModifier extends androidx.ui.core.Modifier.Element {
+ method public androidx.ui.core.DrawLayerProperties getProperties();
+ property public abstract androidx.ui.core.DrawLayerProperties properties;
+ }
+
+ public final class DrawLayerModifierKt {
+ method public static androidx.ui.core.Modifier drawLayer(androidx.ui.core.DrawLayerProperties drawLayerProperties);
+ method public static androidx.ui.core.Modifier drawLayer(float scaleX = 1f, float scaleY = 1f, float alpha = 1f, float elevation = 0f, float rotationX = 0f, float rotationY = 0f, float rotationZ = 0f, androidx.ui.graphics.Shape? outlineShape = null, boolean clipToBounds = true, boolean clipToOutline = true);
+ }
+
+ public interface DrawLayerProperties {
+ method @FloatRange(from=0.0, to=1.0) public default float getAlpha();
+ method public default boolean getClipToBounds();
+ method public default boolean getClipToOutline();
+ method @FloatRange(from=0.0) public default float getElevation();
+ method public default androidx.ui.graphics.Shape? getOutlineShape();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationX();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationY();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationZ();
+ method public default float getScaleX();
+ method public default float getScaleY();
+ property @FloatRange(from=0.0, to=1.0) public default float alpha;
+ property public default boolean clipToBounds;
+ property public default boolean clipToOutline;
+ property @FloatRange(from=0.0) public default float elevation;
+ property public default androidx.ui.graphics.Shape? outlineShape;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationX;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationY;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationZ;
+ property public default float scaleX;
+ property public default float scaleY;
+ }
+
public interface DrawModifier extends androidx.ui.core.Modifier.Element {
method public void draw(androidx.ui.unit.Density density, kotlin.jvm.functions.Function0<kotlin.Unit> drawContent, androidx.ui.graphics.Canvas canvas, androidx.ui.unit.PxSize size);
}
@@ -196,7 +229,7 @@
method public java.util.Map<androidx.ui.core.AlignmentLine,androidx.ui.unit.IntPx> getAlignmentLines();
method public androidx.ui.unit.IntPx getHeight();
method public androidx.ui.unit.IntPx getWidth();
- method public void placeChildren(androidx.ui.core.Placeable.PlacementScope placementScope);
+ method public void placeChildren(androidx.ui.core.LayoutDirection layoutDirection);
property public abstract java.util.Map<androidx.ui.core.AlignmentLine,androidx.ui.unit.IntPx> alignmentLines;
property public abstract androidx.ui.unit.IntPx height;
property public abstract androidx.ui.unit.IntPx width;
@@ -245,6 +278,10 @@
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.PxPosition position);
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.IntPx x, androidx.ui.unit.IntPx y);
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.Px x, androidx.ui.unit.Px y);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.IntPxPosition position);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.PxPosition position);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.IntPx x, androidx.ui.unit.IntPx y);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.Px x, androidx.ui.unit.Px y);
}
public enum PointerEventPass {
diff --git a/ui/ui-core/api/restricted_0.1.0-dev07.txt b/ui/ui-core/api/restricted_0.1.0-dev07.txt
index 61e2694..2df6bda 100644
--- a/ui/ui-core/api/restricted_0.1.0-dev07.txt
+++ b/ui/ui-core/api/restricted_0.1.0-dev07.txt
@@ -114,6 +114,39 @@
enum_constant public static final androidx.ui.core.Direction UP;
}
+ public interface DrawLayerModifier extends androidx.ui.core.Modifier.Element {
+ method public androidx.ui.core.DrawLayerProperties getProperties();
+ property public abstract androidx.ui.core.DrawLayerProperties properties;
+ }
+
+ public final class DrawLayerModifierKt {
+ method public static androidx.ui.core.Modifier drawLayer(androidx.ui.core.DrawLayerProperties drawLayerProperties);
+ method public static androidx.ui.core.Modifier drawLayer(float scaleX = 1f, float scaleY = 1f, float alpha = 1f, float elevation = 0f, float rotationX = 0f, float rotationY = 0f, float rotationZ = 0f, androidx.ui.graphics.Shape? outlineShape = null, boolean clipToBounds = true, boolean clipToOutline = true);
+ }
+
+ public interface DrawLayerProperties {
+ method @FloatRange(from=0.0, to=1.0) public default float getAlpha();
+ method public default boolean getClipToBounds();
+ method public default boolean getClipToOutline();
+ method @FloatRange(from=0.0) public default float getElevation();
+ method public default androidx.ui.graphics.Shape? getOutlineShape();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationX();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationY();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationZ();
+ method public default float getScaleX();
+ method public default float getScaleY();
+ property @FloatRange(from=0.0, to=1.0) public default float alpha;
+ property public default boolean clipToBounds;
+ property public default boolean clipToOutline;
+ property @FloatRange(from=0.0) public default float elevation;
+ property public default androidx.ui.graphics.Shape? outlineShape;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationX;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationY;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationZ;
+ property public default float scaleX;
+ property public default float scaleY;
+ }
+
public interface DrawModifier extends androidx.ui.core.Modifier.Element {
method public void draw(androidx.ui.unit.Density density, kotlin.jvm.functions.Function0<kotlin.Unit> drawContent, androidx.ui.graphics.Canvas canvas, androidx.ui.unit.PxSize size);
}
@@ -196,7 +229,7 @@
method public java.util.Map<androidx.ui.core.AlignmentLine,androidx.ui.unit.IntPx> getAlignmentLines();
method public androidx.ui.unit.IntPx getHeight();
method public androidx.ui.unit.IntPx getWidth();
- method public void placeChildren(androidx.ui.core.Placeable.PlacementScope placementScope);
+ method public void placeChildren(androidx.ui.core.LayoutDirection layoutDirection);
property public abstract java.util.Map<androidx.ui.core.AlignmentLine,androidx.ui.unit.IntPx> alignmentLines;
property public abstract androidx.ui.unit.IntPx height;
property public abstract androidx.ui.unit.IntPx width;
@@ -245,6 +278,10 @@
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.PxPosition position);
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.IntPx x, androidx.ui.unit.IntPx y);
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.Px x, androidx.ui.unit.Px y);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.IntPxPosition position);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.PxPosition position);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.IntPx x, androidx.ui.unit.IntPx y);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.Px x, androidx.ui.unit.Px y);
}
public enum PointerEventPass {
diff --git a/ui/ui-core/api/restricted_current.txt b/ui/ui-core/api/restricted_current.txt
index 61e2694..2df6bda 100644
--- a/ui/ui-core/api/restricted_current.txt
+++ b/ui/ui-core/api/restricted_current.txt
@@ -114,6 +114,39 @@
enum_constant public static final androidx.ui.core.Direction UP;
}
+ public interface DrawLayerModifier extends androidx.ui.core.Modifier.Element {
+ method public androidx.ui.core.DrawLayerProperties getProperties();
+ property public abstract androidx.ui.core.DrawLayerProperties properties;
+ }
+
+ public final class DrawLayerModifierKt {
+ method public static androidx.ui.core.Modifier drawLayer(androidx.ui.core.DrawLayerProperties drawLayerProperties);
+ method public static androidx.ui.core.Modifier drawLayer(float scaleX = 1f, float scaleY = 1f, float alpha = 1f, float elevation = 0f, float rotationX = 0f, float rotationY = 0f, float rotationZ = 0f, androidx.ui.graphics.Shape? outlineShape = null, boolean clipToBounds = true, boolean clipToOutline = true);
+ }
+
+ public interface DrawLayerProperties {
+ method @FloatRange(from=0.0, to=1.0) public default float getAlpha();
+ method public default boolean getClipToBounds();
+ method public default boolean getClipToOutline();
+ method @FloatRange(from=0.0) public default float getElevation();
+ method public default androidx.ui.graphics.Shape? getOutlineShape();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationX();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationY();
+ method @FloatRange(from=0.0, to=360.0) public default float getRotationZ();
+ method public default float getScaleX();
+ method public default float getScaleY();
+ property @FloatRange(from=0.0, to=1.0) public default float alpha;
+ property public default boolean clipToBounds;
+ property public default boolean clipToOutline;
+ property @FloatRange(from=0.0) public default float elevation;
+ property public default androidx.ui.graphics.Shape? outlineShape;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationX;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationY;
+ property @FloatRange(from=0.0, to=360.0) public default float rotationZ;
+ property public default float scaleX;
+ property public default float scaleY;
+ }
+
public interface DrawModifier extends androidx.ui.core.Modifier.Element {
method public void draw(androidx.ui.unit.Density density, kotlin.jvm.functions.Function0<kotlin.Unit> drawContent, androidx.ui.graphics.Canvas canvas, androidx.ui.unit.PxSize size);
}
@@ -196,7 +229,7 @@
method public java.util.Map<androidx.ui.core.AlignmentLine,androidx.ui.unit.IntPx> getAlignmentLines();
method public androidx.ui.unit.IntPx getHeight();
method public androidx.ui.unit.IntPx getWidth();
- method public void placeChildren(androidx.ui.core.Placeable.PlacementScope placementScope);
+ method public void placeChildren(androidx.ui.core.LayoutDirection layoutDirection);
property public abstract java.util.Map<androidx.ui.core.AlignmentLine,androidx.ui.unit.IntPx> alignmentLines;
property public abstract androidx.ui.unit.IntPx height;
property public abstract androidx.ui.unit.IntPx width;
@@ -245,6 +278,10 @@
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.PxPosition position);
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.IntPx x, androidx.ui.unit.IntPx y);
method public void place(androidx.ui.core.Placeable, androidx.ui.unit.Px x, androidx.ui.unit.Px y);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.IntPxPosition position);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.PxPosition position);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.IntPx x, androidx.ui.unit.IntPx y);
+ method public void placeAbsolute(androidx.ui.core.Placeable, androidx.ui.unit.Px x, androidx.ui.unit.Px y);
}
public enum PointerEventPass {
diff --git a/ui/ui-core/build.gradle b/ui/ui-core/build.gradle
index e12f7b3..107c590 100644
--- a/ui/ui-core/build.gradle
+++ b/ui/ui-core/build.gradle
@@ -29,6 +29,7 @@
}
dependencies {
+ kotlinPlugin project(path: ":compose:compose-compiler")
implementation(KOTLIN_STDLIB)
api "androidx.annotation:annotation:1.1.0"
diff --git a/ui/ui-core/integration-tests/samples/src/main/java/androidx/ui/core/samples/AlignmentLineSample.kt b/ui/ui-core/integration-tests/samples/src/main/java/androidx/ui/core/samples/AlignmentLineSample.kt
index 8a4a5ee..7de5bbb 100644
--- a/ui/ui-core/integration-tests/samples/src/main/java/androidx/ui/core/samples/AlignmentLineSample.kt
+++ b/ui/ui-core/integration-tests/samples/src/main/java/androidx/ui/core/samples/AlignmentLineSample.kt
@@ -51,8 +51,8 @@
// placeables[0][line] will be 5.ipx
// placeables[1][line] will be 10.ipx
layout(constraints.maxWidth, constraints.maxHeight) {
- placeables[0].place(0.ipx, 3.ipx)
- placeables[1].place(constraints.maxWidth / 2, 0.ipx)
+ placeables[0].placeAbsolute(0.ipx, 3.ipx)
+ placeables[1].placeAbsolute(constraints.maxWidth / 2, 0.ipx)
}
}
// Note that if the parent of this Layout (the parent of AlignmentLineSample) was able to
diff --git a/ui/ui-core/integration-tests/samples/src/main/java/androidx/ui/core/samples/LayerModifierSamples.kt b/ui/ui-core/integration-tests/samples/src/main/java/androidx/ui/core/samples/LayerModifierSamples.kt
new file mode 100644
index 0000000..948b2b7c
--- /dev/null
+++ b/ui/ui-core/integration-tests/samples/src/main/java/androidx/ui/core/samples/LayerModifierSamples.kt
@@ -0,0 +1,48 @@
+/*
+ * 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.ui.core.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.Composable
+import androidx.compose.onCommit
+import androidx.compose.remember
+import androidx.ui.animation.animatedFloat
+import androidx.ui.core.drawLayer
+import androidx.ui.core.DrawLayerProperties
+import androidx.ui.core.Text
+
+@Sampled
+@Composable
+fun ChangeOpacity() {
+ Text("Hello World", drawLayer(alpha = 0.5f))
+}
+
+@Sampled
+@Composable
+fun AnimateFadeIn() {
+ val alpha = animatedFloat(initVal = 0f)
+ val layerProperties = remember {
+ object : DrawLayerProperties {
+ override val alpha: Float get() = alpha.value
+ }
+ }
+ val layerModifier = drawLayer(layerProperties)
+ Text("Hello World", layerModifier)
+ onCommit {
+ alpha.animateTo(1f)
+ }
+}
\ No newline at end of file
diff --git a/ui/ui-core/integration-tests/samples/src/main/java/androidx/ui/core/samples/ModifierSamples.kt b/ui/ui-core/integration-tests/samples/src/main/java/androidx/ui/core/samples/ModifierSamples.kt
index bbf8440..655713c 100644
--- a/ui/ui-core/integration-tests/samples/src/main/java/androidx/ui/core/samples/ModifierSamples.kt
+++ b/ui/ui-core/integration-tests/samples/src/main/java/androidx/ui/core/samples/ModifierSamples.kt
@@ -50,10 +50,10 @@
buttonModifier: Modifier = Modifier.None
) {
Row(modifier) {
- Button(buttonModifier, onClick = onCancel) {
+ Button(onCancel, buttonModifier) {
Text("Cancel")
}
- Button(buttonModifier, onClick = onOk) {
+ Button(onOk, buttonModifier) {
Text("Ok")
}
}
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/DrawLayerModifier.kt b/ui/ui-core/src/main/java/androidx/ui/core/DrawLayerModifier.kt
new file mode 100644
index 0000000..2dc5a07
--- /dev/null
+++ b/ui/ui-core/src/main/java/androidx/ui/core/DrawLayerModifier.kt
@@ -0,0 +1,169 @@
+/*
+ * 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.ui.core
+
+import androidx.annotation.FloatRange
+import androidx.ui.graphics.Shape
+
+/**
+ * A set of properties that can be modified in a [DrawLayerModifier].
+ *
+ * @sample androidx.ui.core.samples.ChangeOpacity
+ */
+interface DrawLayerProperties {
+ /**
+ * The horizontal scale of the drawn area. This would typically default to `1`.
+ */
+ val scaleX: Float get() = 1f
+
+ /**
+ * The vertical scale of the drawn area. This would typically default to `1`.
+ */
+ val scaleY: Float get() = 1f
+
+ /**
+ * The alpha of the drawn area. Setting this to something other than `1`
+ * will cause the drawn contents to be translucent and setting it to `0` will
+ * cause it to be fully invisible.
+ */
+ @get:FloatRange(from = 0.0, to = 1.0)
+ val alpha: Float get() = 1f
+
+ /**
+ * Sets the Z coordinate of the layer in pixels. With [outlineShape] set, this will cause
+ * a shadow. Varying the [elevation] can also change the order in which layers are drawn.
+ */
+ @get:FloatRange(from = 0.0)
+ val elevation: Float get() = 0f
+
+ /**
+ * The rotation of the contents around the horizontal axis in degrees.
+ */
+ @get:FloatRange(from = 0.0, to = 360.0)
+ val rotationX: Float get() = 0f
+
+ /**
+ * The rotation of the contents around the vertical axis in degrees.
+ */
+ @get:FloatRange(from = 0.0, to = 360.0)
+ val rotationY: Float get() = 0f
+
+ /**
+ * The rotation of the contents around the Z axis in degrees.
+ */
+ @get:FloatRange(from = 0.0, to = 360.0)
+ val rotationZ: Float get() = 0f
+
+ /**
+ * The [Shape] of the layer. When [elevation] is non-zero and [outlineShape] is non-null,
+ * a shadow is produced. When [clipToOutline] is `true` and [outlineShape] is non-null, the
+ * contents will be clipped to the outline.
+ */
+ val outlineShape: Shape? get() = null
+
+ /**
+ * Set to `true` to clip the content to the size of the layer or `false` to allow
+ * drawing outside of the layer's bounds. This a convenient way to clip to the bounding
+ * rectangle. When [clipToOutline] is `true` the contents are clipped by both the
+ * bounding rectangle and the [outlineShape].
+ *
+ * @see clipToOutline
+ */
+ val clipToBounds: Boolean get() = true
+
+ /**
+ * Clips the content to the [outlineShape]. If [outlineShape] is null, no clipping will occur.
+ * When both [clipToBounds] and [clipToOutline] are `true`, the content will be clipped by
+ * both the bounding rectangle and the [outlineShape].
+ */
+ val clipToOutline: Boolean get() = true
+}
+
+/**
+ * A [Modifier.Element] that makes content draw into a layer, allowing easily changing
+ * [DrawLayerProperties] for the drawn contents.
+ *
+ * @sample androidx.ui.core.samples.AnimateFadeIn
+ */
+interface DrawLayerModifier : Modifier.Element {
+ val properties: DrawLayerProperties
+}
+
+private class SimpleDrawLayerModifier(
+ override val properties: DrawLayerProperties
+) : DrawLayerModifier
+
+/**
+ * Create a [DrawLayerModifier] with a given [DrawLayerProperties].
+ */
+fun drawLayer(drawLayerProperties: DrawLayerProperties): Modifier =
+ SimpleDrawLayerModifier(drawLayerProperties)
+
+/**
+ * Create a [DrawLayerModifier] with fixed properties.
+ *
+ * @sample androidx.ui.core.samples.ChangeOpacity
+ *
+ * @param scaleX [DrawLayerProperties.scaleX]
+ * @param scaleY [DrawLayerProperties.scaleY]
+ * @param alpha [DrawLayerProperties.alpha]
+ * @param elevation [DrawLayerProperties.elevation]
+ * @param rotationX [DrawLayerProperties.rotationX]
+ * @param rotationY [DrawLayerProperties.rotationY]
+ * @param rotationZ [DrawLayerProperties.rotationZ]
+ * @param outlineShape [DrawLayerProperties.outlineShape]
+ * @param clipToBounds [DrawLayerProperties.clipToBounds]
+ * @param clipToOutline [DrawLayerProperties.clipToOutline]
+ */
+fun drawLayer(
+ scaleX: Float = 1f,
+ scaleY: Float = 1f,
+ alpha: Float = 1f,
+ elevation: Float = 0f,
+ rotationX: Float = 0f,
+ rotationY: Float = 0f,
+ rotationZ: Float = 0f,
+ outlineShape: Shape? = null,
+ clipToBounds: Boolean = true,
+ clipToOutline: Boolean = true
+): Modifier = SimpleDrawLayerModifier(
+ SimpleDrawLayerProperties(
+ scaleX,
+ scaleY,
+ alpha,
+ elevation,
+ rotationX,
+ rotationY,
+ rotationZ,
+ outlineShape,
+ clipToBounds,
+ clipToOutline
+ )
+)
+
+private data class SimpleDrawLayerProperties(
+ override val scaleX: Float,
+ override val scaleY: Float,
+ override val alpha: Float,
+ override val elevation: Float,
+ override val rotationX: Float,
+ override val rotationY: Float,
+ override val rotationZ: Float,
+ override val outlineShape: Shape?,
+ override val clipToBounds: Boolean,
+ override val clipToOutline: Boolean
+) : DrawLayerProperties
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/MeasureScope.kt b/ui/ui-core/src/main/java/androidx/ui/core/MeasureScope.kt
index 058711c..ec72a4d 100644
--- a/ui/ui-core/src/main/java/androidx/ui/core/MeasureScope.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/MeasureScope.kt
@@ -37,7 +37,7 @@
val width: IntPx
val height: IntPx
val alignmentLines: Map<AlignmentLine, IntPx>
- fun placeChildren(placementScope: Placeable.PlacementScope)
+ fun placeChildren(layoutDirection: LayoutDirection)
}
/**
@@ -64,8 +64,15 @@
override val width = width
override val height = height
override val alignmentLines = alignmentLines
- override fun placeChildren(placementScope: Placeable.PlacementScope) =
- placementScope.placementBlock()
+ override fun placeChildren(layoutDirection: LayoutDirection) {
+ with(Placeable.PlacementScope) {
+ this.parentLayoutDirection = layoutDirection
+ val previousParentWidth = parentWidth
+ parentWidth = width
+ placementBlock()
+ parentWidth = previousParentWidth
+ }
+ }
}
}
diff --git a/ui/ui-core/src/main/java/androidx/ui/core/Placeable.kt b/ui/ui-core/src/main/java/androidx/ui/core/Placeable.kt
index 37c8c2b7..c9618f63 100644
--- a/ui/ui-core/src/main/java/androidx/ui/core/Placeable.kt
+++ b/ui/ui-core/src/main/java/androidx/ui/core/Placeable.kt
@@ -66,30 +66,110 @@
* This permits Compose UI to perform additional layout optimizations allowing repositioning
* a [Placeable] without remeasuring its original [Measurable] if factors contributing to its
* potential measurement have not changed.
+ * The scope also allows automatic mirroring of children positions in RTL layout direction
+ * contexts using the [place] methods available in the scope. If the automatic mirroring is not
+ * desired, [placeAbsolute] should be used instead.
*/
+ // TODO(b/150276678): this API is incomplete and should accept the parent width in constructor
+ // to be used correctly outside the MeasureScope.layout() call.
companion object PlacementScope {
/**
+ * Keeps the parent layout node's width to make the automatic mirroring of the position
+ * in RTL environment. If the value is zero, than the [Placeable] will be be placed to
+ * the original position (position will not be mirrored).
+ */
+ internal var parentWidth = IntPx.Zero
+
+ /**
+ * Keeps the layout direction of the parent of the placeable that is being places using
+ * current [PlacementScope]. Used to support automatic position mirroring for convenient
+ * RTL support in custom layouts.
+ */
+ internal var parentLayoutDirection = LayoutDirection.Ltr
+
+ /**
* Place a [Placeable] at [position] in its parent's coordinate system.
+ * If the layout direction is right-to-left, the given [position] will be horizontally
+ * mirrored so that the position of the [Placeable] implicitly reacts to RTL layout
+ * direction contexts.
+ * If this method is used outside the [MeasureScope.layout] positioning block, the
+ * automatic position mirroring will not happen and the [Placeable] will be placed at the
+ * given [position], similar to the [placeAbsolute] method.
*/
fun Placeable.place(position: IntPxPosition) {
- performPlace(position)
+ if (parentLayoutDirection == LayoutDirection.Ltr || parentWidth == IntPx.Zero) {
+ performPlace(position)
+ } else {
+ performPlace(IntPxPosition(parentWidth - width - position.x, position.y))
+ }
}
/**
* Place a [Placeable] at [position] in its parent's coordinate system.
+ * If the layout direction is right-to-left, the given [position] will be horizontally
+ * mirrored so that the position of the [Placeable] implicitly reacts to RTL layout
+ * direction contexts.
+ * If this method is used outside the [MeasureScope.layout] positioning block, the
+ * automatic position mirroring will not happen and the [Placeable] will be placed at the
+ * given [position], similar to the [placeAbsolute] method.
*/
fun Placeable.place(position: PxPosition) {
- performPlace(position.round())
+ place(position.round())
}
/**
* Place a [Placeable] at [x], [y] in its parent's coordinate system.
+ * If the layout direction is right-to-left, the given [position] will be horizontally
+ * mirrored so that the position of the [Placeable] implicitly reacts to RTL layout
+ * direction contexts.
+ * If this method is used outside the [MeasureScope.layout] positioning block, the
+ * automatic position mirroring will not happen and the [Placeable] will be placed at the
+ * given [position], similar to the [placeAbsolute] method.
*/
fun Placeable.place(x: IntPx, y: IntPx) = place(IntPxPosition(x, y))
/**
* Place a [Placeable] at [x], [y] in its parent's coordinate system.
+ * If the layout direction is right-to-left, the given [position] will be horizontally
+ * mirrored so that the position of the [Placeable] implicitly reacts to RTL layout
+ * direction contexts.
+ * If this method is used outside the [MeasureScope.layout] positioning block, the
+ * automatic position mirroring will not happen and the [Placeable] will be placed at the
+ * given [position], similar to the [placeAbsolute] method.
*/
fun Placeable.place(x: Px, y: Px) = place(IntPxPosition(x.round(), y.round()))
+
+ /**
+ * Place a [Placeable] at [position] in its parent's coordinate system.
+ * Unlike [place], the given [position] will not implicitly react in RTL layout direction
+ * contexts.
+ */
+ fun Placeable.placeAbsolute(position: IntPxPosition) {
+ performPlace(position)
+ }
+
+ /**
+ * Place a [Placeable] at [position] in its parent's coordinate system.
+ * Unlike [place], the given [position] will not implicitly react in RTL layout direction
+ * contexts.
+ */
+ fun Placeable.placeAbsolute(position: PxPosition) {
+ placeAbsolute(position.round())
+ }
+
+ /**
+ * Place a [Placeable] at [x], [y] in its parent's coordinate system.
+ * Unlike [place], the given [position] will not implicitly react in RTL layout direction
+ * contexts.
+ */
+ fun Placeable.placeAbsolute(x: IntPx, y: IntPx) = placeAbsolute(IntPxPosition(x, y))
+
+ /**
+ * Place a [Placeable] at [x], [y] in its parent's coordinate system.
+ * Unlike [place], the given [position] will not implicitly react in RTL layout direction
+ * contexts.
+ */
+ fun Placeable.placeAbsolute(x: Px, y: Px) =
+ placeAbsolute(IntPxPosition(x.round(), y.round()))
}
}
\ No newline at end of file
diff --git a/ui/ui-foundation/api/0.1.0-dev07.txt b/ui/ui-foundation/api/0.1.0-dev07.txt
index 8d501c9..9e2dce0 100644
--- a/ui/ui-foundation/api/0.1.0-dev07.txt
+++ b/ui/ui-foundation/api/0.1.0-dev07.txt
@@ -20,9 +20,9 @@
public final class BoxKt {
method public static void Box(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp padding = elvis {
- @null var var4119045e: androidx.ui.unit.Dp = border?.size
- if (var4119045e != null) var4119045e else 0.dp
-}, androidx.ui.unit.Dp paddingLeft = Dp.Unspecified, androidx.ui.unit.Dp paddingTop = Dp.Unspecified, androidx.ui.unit.Dp paddingRight = Dp.Unspecified, androidx.ui.unit.Dp paddingBottom = Dp.Unspecified, androidx.ui.core.Alignment gravity = ContentGravity.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children = emptyContent());
+ @null var var411905cf: androidx.ui.unit.Dp = border?.size
+ if (var411905cf != null) var411905cf else 0.dp
+}, androidx.ui.unit.Dp paddingStart = Dp.Unspecified, androidx.ui.unit.Dp paddingTop = Dp.Unspecified, androidx.ui.unit.Dp paddingEnd = Dp.Unspecified, androidx.ui.unit.Dp paddingBottom = Dp.Unspecified, androidx.ui.core.Alignment gravity = ContentGravity.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children = emptyContent());
}
public final class CanvasKt {
@@ -35,7 +35,7 @@
}
public final class ClickableKt {
- method public static void Clickable(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, String? onClickLabel = null, boolean consumeDownOnStart = false, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void Clickable(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, boolean enabled = true, String? onClickLabel = null, boolean consumeDownOnStart = false, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class ColoredRectKt {
@@ -99,7 +99,9 @@
}
public final class ImageKt {
- method public static void SimpleImage(androidx.ui.graphics.ImageAsset image, androidx.ui.graphics.Color? tint = null);
+ method public static void Image(androidx.ui.graphics.ImageAsset image, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.graphics.ScaleFit scaleFit = ScaleFit.Fit, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.core.LayoutDirection layoutDirection = LayoutDirectionAmbient.current);
+ method public static void Image(androidx.ui.graphics.painter.Painter painter, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.unit.Dp minWidth = Dp.Unspecified, androidx.ui.unit.Dp minHeight = Dp.Unspecified, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.graphics.ScaleFit scaleFit = ScaleFit.Fit, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.core.LayoutDirection layoutDirection = LayoutDirectionAmbient.current);
+ method @Deprecated public static void SimpleImage(androidx.ui.graphics.ImageAsset image, androidx.ui.graphics.Color? tint = null);
}
public final class ScrollerKt {
diff --git a/ui/ui-foundation/api/api_lint.ignore b/ui/ui-foundation/api/api_lint.ignore
deleted file mode 100644
index a3e5eb1..0000000
--- a/ui/ui-foundation/api/api_lint.ignore
+++ /dev/null
@@ -1,7 +0,0 @@
-// Baseline format: 1.0
-AutoBoxing: androidx.ui.foundation.animation.AnimatedValueHolder#getValue():
- Must avoid boxed primitives (`java.lang.Float`)
-
-
-MissingNullability: androidx.ui.foundation.animation.AnimatedValueHolder#getValue():
- Missing nullability on method `getValue` return
diff --git a/ui/ui-foundation/api/current.txt b/ui/ui-foundation/api/current.txt
index 8d501c9..9e2dce0 100644
--- a/ui/ui-foundation/api/current.txt
+++ b/ui/ui-foundation/api/current.txt
@@ -20,9 +20,9 @@
public final class BoxKt {
method public static void Box(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp padding = elvis {
- @null var var4119045e: androidx.ui.unit.Dp = border?.size
- if (var4119045e != null) var4119045e else 0.dp
-}, androidx.ui.unit.Dp paddingLeft = Dp.Unspecified, androidx.ui.unit.Dp paddingTop = Dp.Unspecified, androidx.ui.unit.Dp paddingRight = Dp.Unspecified, androidx.ui.unit.Dp paddingBottom = Dp.Unspecified, androidx.ui.core.Alignment gravity = ContentGravity.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children = emptyContent());
+ @null var var411905cf: androidx.ui.unit.Dp = border?.size
+ if (var411905cf != null) var411905cf else 0.dp
+}, androidx.ui.unit.Dp paddingStart = Dp.Unspecified, androidx.ui.unit.Dp paddingTop = Dp.Unspecified, androidx.ui.unit.Dp paddingEnd = Dp.Unspecified, androidx.ui.unit.Dp paddingBottom = Dp.Unspecified, androidx.ui.core.Alignment gravity = ContentGravity.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children = emptyContent());
}
public final class CanvasKt {
@@ -35,7 +35,7 @@
}
public final class ClickableKt {
- method public static void Clickable(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, String? onClickLabel = null, boolean consumeDownOnStart = false, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void Clickable(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, boolean enabled = true, String? onClickLabel = null, boolean consumeDownOnStart = false, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class ColoredRectKt {
@@ -99,7 +99,9 @@
}
public final class ImageKt {
- method public static void SimpleImage(androidx.ui.graphics.ImageAsset image, androidx.ui.graphics.Color? tint = null);
+ method public static void Image(androidx.ui.graphics.ImageAsset image, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.graphics.ScaleFit scaleFit = ScaleFit.Fit, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.core.LayoutDirection layoutDirection = LayoutDirectionAmbient.current);
+ method public static void Image(androidx.ui.graphics.painter.Painter painter, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.unit.Dp minWidth = Dp.Unspecified, androidx.ui.unit.Dp minHeight = Dp.Unspecified, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.graphics.ScaleFit scaleFit = ScaleFit.Fit, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.core.LayoutDirection layoutDirection = LayoutDirectionAmbient.current);
+ method @Deprecated public static void SimpleImage(androidx.ui.graphics.ImageAsset image, androidx.ui.graphics.Color? tint = null);
}
public final class ScrollerKt {
diff --git a/ui/ui-foundation/api/public_plus_experimental_0.1.0-dev07.txt b/ui/ui-foundation/api/public_plus_experimental_0.1.0-dev07.txt
index 8d501c9..9e2dce0 100644
--- a/ui/ui-foundation/api/public_plus_experimental_0.1.0-dev07.txt
+++ b/ui/ui-foundation/api/public_plus_experimental_0.1.0-dev07.txt
@@ -20,9 +20,9 @@
public final class BoxKt {
method public static void Box(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp padding = elvis {
- @null var var4119045e: androidx.ui.unit.Dp = border?.size
- if (var4119045e != null) var4119045e else 0.dp
-}, androidx.ui.unit.Dp paddingLeft = Dp.Unspecified, androidx.ui.unit.Dp paddingTop = Dp.Unspecified, androidx.ui.unit.Dp paddingRight = Dp.Unspecified, androidx.ui.unit.Dp paddingBottom = Dp.Unspecified, androidx.ui.core.Alignment gravity = ContentGravity.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children = emptyContent());
+ @null var var411905cf: androidx.ui.unit.Dp = border?.size
+ if (var411905cf != null) var411905cf else 0.dp
+}, androidx.ui.unit.Dp paddingStart = Dp.Unspecified, androidx.ui.unit.Dp paddingTop = Dp.Unspecified, androidx.ui.unit.Dp paddingEnd = Dp.Unspecified, androidx.ui.unit.Dp paddingBottom = Dp.Unspecified, androidx.ui.core.Alignment gravity = ContentGravity.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children = emptyContent());
}
public final class CanvasKt {
@@ -35,7 +35,7 @@
}
public final class ClickableKt {
- method public static void Clickable(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, String? onClickLabel = null, boolean consumeDownOnStart = false, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void Clickable(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, boolean enabled = true, String? onClickLabel = null, boolean consumeDownOnStart = false, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class ColoredRectKt {
@@ -99,7 +99,9 @@
}
public final class ImageKt {
- method public static void SimpleImage(androidx.ui.graphics.ImageAsset image, androidx.ui.graphics.Color? tint = null);
+ method public static void Image(androidx.ui.graphics.ImageAsset image, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.graphics.ScaleFit scaleFit = ScaleFit.Fit, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.core.LayoutDirection layoutDirection = LayoutDirectionAmbient.current);
+ method public static void Image(androidx.ui.graphics.painter.Painter painter, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.unit.Dp minWidth = Dp.Unspecified, androidx.ui.unit.Dp minHeight = Dp.Unspecified, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.graphics.ScaleFit scaleFit = ScaleFit.Fit, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.core.LayoutDirection layoutDirection = LayoutDirectionAmbient.current);
+ method @Deprecated public static void SimpleImage(androidx.ui.graphics.ImageAsset image, androidx.ui.graphics.Color? tint = null);
}
public final class ScrollerKt {
diff --git a/ui/ui-foundation/api/public_plus_experimental_current.txt b/ui/ui-foundation/api/public_plus_experimental_current.txt
index 8d501c9..9e2dce0 100644
--- a/ui/ui-foundation/api/public_plus_experimental_current.txt
+++ b/ui/ui-foundation/api/public_plus_experimental_current.txt
@@ -20,9 +20,9 @@
public final class BoxKt {
method public static void Box(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp padding = elvis {
- @null var var4119045e: androidx.ui.unit.Dp = border?.size
- if (var4119045e != null) var4119045e else 0.dp
-}, androidx.ui.unit.Dp paddingLeft = Dp.Unspecified, androidx.ui.unit.Dp paddingTop = Dp.Unspecified, androidx.ui.unit.Dp paddingRight = Dp.Unspecified, androidx.ui.unit.Dp paddingBottom = Dp.Unspecified, androidx.ui.core.Alignment gravity = ContentGravity.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children = emptyContent());
+ @null var var411905cf: androidx.ui.unit.Dp = border?.size
+ if (var411905cf != null) var411905cf else 0.dp
+}, androidx.ui.unit.Dp paddingStart = Dp.Unspecified, androidx.ui.unit.Dp paddingTop = Dp.Unspecified, androidx.ui.unit.Dp paddingEnd = Dp.Unspecified, androidx.ui.unit.Dp paddingBottom = Dp.Unspecified, androidx.ui.core.Alignment gravity = ContentGravity.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children = emptyContent());
}
public final class CanvasKt {
@@ -35,7 +35,7 @@
}
public final class ClickableKt {
- method public static void Clickable(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, String? onClickLabel = null, boolean consumeDownOnStart = false, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void Clickable(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, boolean enabled = true, String? onClickLabel = null, boolean consumeDownOnStart = false, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class ColoredRectKt {
@@ -99,7 +99,9 @@
}
public final class ImageKt {
- method public static void SimpleImage(androidx.ui.graphics.ImageAsset image, androidx.ui.graphics.Color? tint = null);
+ method public static void Image(androidx.ui.graphics.ImageAsset image, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.graphics.ScaleFit scaleFit = ScaleFit.Fit, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.core.LayoutDirection layoutDirection = LayoutDirectionAmbient.current);
+ method public static void Image(androidx.ui.graphics.painter.Painter painter, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.unit.Dp minWidth = Dp.Unspecified, androidx.ui.unit.Dp minHeight = Dp.Unspecified, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.graphics.ScaleFit scaleFit = ScaleFit.Fit, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.core.LayoutDirection layoutDirection = LayoutDirectionAmbient.current);
+ method @Deprecated public static void SimpleImage(androidx.ui.graphics.ImageAsset image, androidx.ui.graphics.Color? tint = null);
}
public final class ScrollerKt {
diff --git a/ui/ui-foundation/api/restricted_0.1.0-dev07.txt b/ui/ui-foundation/api/restricted_0.1.0-dev07.txt
index 8d501c9..9e2dce0 100644
--- a/ui/ui-foundation/api/restricted_0.1.0-dev07.txt
+++ b/ui/ui-foundation/api/restricted_0.1.0-dev07.txt
@@ -20,9 +20,9 @@
public final class BoxKt {
method public static void Box(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp padding = elvis {
- @null var var4119045e: androidx.ui.unit.Dp = border?.size
- if (var4119045e != null) var4119045e else 0.dp
-}, androidx.ui.unit.Dp paddingLeft = Dp.Unspecified, androidx.ui.unit.Dp paddingTop = Dp.Unspecified, androidx.ui.unit.Dp paddingRight = Dp.Unspecified, androidx.ui.unit.Dp paddingBottom = Dp.Unspecified, androidx.ui.core.Alignment gravity = ContentGravity.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children = emptyContent());
+ @null var var411905cf: androidx.ui.unit.Dp = border?.size
+ if (var411905cf != null) var411905cf else 0.dp
+}, androidx.ui.unit.Dp paddingStart = Dp.Unspecified, androidx.ui.unit.Dp paddingTop = Dp.Unspecified, androidx.ui.unit.Dp paddingEnd = Dp.Unspecified, androidx.ui.unit.Dp paddingBottom = Dp.Unspecified, androidx.ui.core.Alignment gravity = ContentGravity.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children = emptyContent());
}
public final class CanvasKt {
@@ -35,7 +35,7 @@
}
public final class ClickableKt {
- method public static void Clickable(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, String? onClickLabel = null, boolean consumeDownOnStart = false, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void Clickable(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, boolean enabled = true, String? onClickLabel = null, boolean consumeDownOnStart = false, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class ColoredRectKt {
@@ -99,7 +99,9 @@
}
public final class ImageKt {
- method public static void SimpleImage(androidx.ui.graphics.ImageAsset image, androidx.ui.graphics.Color? tint = null);
+ method public static void Image(androidx.ui.graphics.ImageAsset image, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.graphics.ScaleFit scaleFit = ScaleFit.Fit, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.core.LayoutDirection layoutDirection = LayoutDirectionAmbient.current);
+ method public static void Image(androidx.ui.graphics.painter.Painter painter, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.unit.Dp minWidth = Dp.Unspecified, androidx.ui.unit.Dp minHeight = Dp.Unspecified, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.graphics.ScaleFit scaleFit = ScaleFit.Fit, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.core.LayoutDirection layoutDirection = LayoutDirectionAmbient.current);
+ method @Deprecated public static void SimpleImage(androidx.ui.graphics.ImageAsset image, androidx.ui.graphics.Color? tint = null);
}
public final class ScrollerKt {
diff --git a/ui/ui-foundation/api/restricted_current.txt b/ui/ui-foundation/api/restricted_current.txt
index 8d501c9..9e2dce0 100644
--- a/ui/ui-foundation/api/restricted_current.txt
+++ b/ui/ui-foundation/api/restricted_current.txt
@@ -20,9 +20,9 @@
public final class BoxKt {
method public static void Box(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp padding = elvis {
- @null var var4119045e: androidx.ui.unit.Dp = border?.size
- if (var4119045e != null) var4119045e else 0.dp
-}, androidx.ui.unit.Dp paddingLeft = Dp.Unspecified, androidx.ui.unit.Dp paddingTop = Dp.Unspecified, androidx.ui.unit.Dp paddingRight = Dp.Unspecified, androidx.ui.unit.Dp paddingBottom = Dp.Unspecified, androidx.ui.core.Alignment gravity = ContentGravity.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children = emptyContent());
+ @null var var411905cf: androidx.ui.unit.Dp = border?.size
+ if (var411905cf != null) var411905cf else 0.dp
+}, androidx.ui.unit.Dp paddingStart = Dp.Unspecified, androidx.ui.unit.Dp paddingTop = Dp.Unspecified, androidx.ui.unit.Dp paddingEnd = Dp.Unspecified, androidx.ui.unit.Dp paddingBottom = Dp.Unspecified, androidx.ui.core.Alignment gravity = ContentGravity.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children = emptyContent());
}
public final class CanvasKt {
@@ -35,7 +35,7 @@
}
public final class ClickableKt {
- method public static void Clickable(kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, String? onClickLabel = null, boolean consumeDownOnStart = false, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void Clickable(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, boolean enabled = true, String? onClickLabel = null, boolean consumeDownOnStart = false, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class ColoredRectKt {
@@ -99,7 +99,9 @@
}
public final class ImageKt {
- method public static void SimpleImage(androidx.ui.graphics.ImageAsset image, androidx.ui.graphics.Color? tint = null);
+ method public static void Image(androidx.ui.graphics.ImageAsset image, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.graphics.ScaleFit scaleFit = ScaleFit.Fit, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.core.LayoutDirection layoutDirection = LayoutDirectionAmbient.current);
+ method public static void Image(androidx.ui.graphics.painter.Painter painter, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.unit.Dp minWidth = Dp.Unspecified, androidx.ui.unit.Dp minHeight = Dp.Unspecified, androidx.ui.core.Alignment alignment = Alignment.Center, androidx.ui.graphics.ScaleFit scaleFit = ScaleFit.Fit, float alpha = 1.0f, androidx.ui.graphics.ColorFilter? colorFilter = null, androidx.ui.core.LayoutDirection layoutDirection = LayoutDirectionAmbient.current);
+ method @Deprecated public static void SimpleImage(androidx.ui.graphics.ImageAsset image, androidx.ui.graphics.Color? tint = null);
}
public final class ScrollerKt {
diff --git a/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/BoxActivity.kt b/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/BoxActivity.kt
index d70a7d4..cc9da15 100644
--- a/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/BoxActivity.kt
+++ b/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/BoxActivity.kt
@@ -46,7 +46,7 @@
modifier = LayoutSize(200.dp, 100.dp),
shape = RoundedCornerShape(10.dp),
border = Border(5.dp, Color.Gray),
- paddingLeft = 20.dp,
+ paddingStart = 20.dp,
backgroundColor = Color.White
) {
Box(
diff --git a/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/HighLevelGesturesActivity.kt b/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/HighLevelGesturesActivity.kt
index d309fa0..c762786 100644
--- a/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/HighLevelGesturesActivity.kt
+++ b/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/HighLevelGesturesActivity.kt
@@ -25,7 +25,6 @@
import androidx.ui.layout.Column
import androidx.ui.layout.LayoutHeight
import androidx.ui.layout.Spacer
-import androidx.ui.layout.Wrap
import androidx.ui.unit.dp
class HighLevelGesturesActivity : Activity() {
@@ -33,14 +32,12 @@
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
- Wrap {
- Column {
- DraggableSample()
- Spacer(LayoutHeight(100.dp))
- AnchoredDraggableSample()
- Spacer(LayoutHeight(100.dp))
- ScrollableSample()
- }
+ Column {
+ DraggableSample()
+ Spacer(LayoutHeight(100.dp))
+ AnchoredDraggableSample()
+ Spacer(LayoutHeight(100.dp))
+ ScrollableSample()
}
}
}
diff --git a/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/HorizontalScrollerActivity.kt b/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/HorizontalScrollerActivity.kt
index e3708dd..5164fe3 100644
--- a/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/HorizontalScrollerActivity.kt
+++ b/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/HorizontalScrollerActivity.kt
@@ -20,16 +20,13 @@
import android.os.Bundle
import androidx.ui.core.setContent
import androidx.ui.foundation.samples.ControlledHorizontalScrollerSample
-import androidx.ui.layout.Wrap
class HorizontalScrollerActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
- Wrap {
- ControlledHorizontalScrollerSample()
- }
+ ControlledHorizontalScrollerSample()
}
}
}
\ No newline at end of file
diff --git a/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/VerticalScrollerActivity.kt b/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/VerticalScrollerActivity.kt
index bf48cd3..fdaaa49 100644
--- a/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/VerticalScrollerActivity.kt
+++ b/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/ui/foundation/demos/VerticalScrollerActivity.kt
@@ -20,16 +20,13 @@
import android.os.Bundle
import androidx.ui.core.setContent
import androidx.ui.foundation.samples.VerticalScrollerSample
-import androidx.ui.layout.Wrap
class VerticalScrollerActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
- Wrap {
- VerticalScrollerSample()
- }
+ VerticalScrollerSample()
}
}
}
\ No newline at end of file
diff --git a/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/DarkThemeSample.kt b/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/DarkThemeSample.kt
index c454259..e195dcc 100644
--- a/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/DarkThemeSample.kt
+++ b/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/DarkThemeSample.kt
@@ -21,7 +21,7 @@
import androidx.ui.foundation.ColoredRect
import androidx.ui.foundation.isSystemInDarkTheme
import androidx.ui.graphics.Color
-import androidx.ui.layout.Wrap
+import androidx.ui.layout.Stack
import androidx.ui.unit.dp
@Sampled
@@ -29,7 +29,7 @@
fun DarkThemeSample() {
val dark = isSystemInDarkTheme()
val color = if (dark) Color.White else Color.Black
- Wrap {
+ Stack {
ColoredRect(color = color, width = 50.dp, height = 50.dp)
}
}
diff --git a/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/ImageSamples.kt b/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/ImageSamples.kt
new file mode 100644
index 0000000..d8373e3
--- /dev/null
+++ b/ui/ui-foundation/integration-tests/samples/src/main/java/androidx/ui/foundation/samples/ImageSamples.kt
@@ -0,0 +1,59 @@
+/*
+ * 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.ui.foundation.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.Composable
+import androidx.ui.foundation.Image
+import androidx.ui.geometry.Offset
+import androidx.ui.graphics.Canvas
+import androidx.ui.graphics.Color
+import androidx.ui.graphics.ImageAsset
+import androidx.ui.graphics.Paint
+import androidx.ui.graphics.painter.ColorPainter
+import androidx.ui.unit.dp
+
+@Sampled
+@Composable
+fun ImageSample() {
+ val imageAsset = createTestImage()
+ // Lays out and draws an image sized to the dimensions of the ImageAsset
+ Image(image = imageAsset)
+}
+
+@Sampled
+@Composable
+fun ImageSamplePainterMinSize() {
+ // Lays out 20 dp x 20 dp composable and draws the area with the given color
+ Image(
+ painter = ColorPainter(Color.Red),
+ minWidth = 20.dp,
+ minHeight = 20.dp
+ )
+}
+
+/**
+ * Helper method to create an ImageAsset with some content in it
+ */
+private fun createTestImage(): ImageAsset {
+ val imageAsset = ImageAsset(100, 100)
+ Canvas(imageAsset).drawCircle(
+ Offset(50.0f, 50.0f), 50.0f,
+ Paint().apply { this.color = Color.Cyan }
+ )
+ return imageAsset
+}
\ No newline at end of file
diff --git a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/BoxTest.kt b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/BoxTest.kt
index 35fffe1..3a2f4da 100644
--- a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/BoxTest.kt
+++ b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/BoxTest.kt
@@ -27,6 +27,7 @@
import androidx.ui.foundation.shape.corner.CircleShape
import androidx.ui.graphics.Color
import androidx.ui.layout.LayoutAlign
+import androidx.ui.layout.LayoutDirectionModifier
import androidx.ui.layout.LayoutSize
import androidx.ui.layout.Stack
import androidx.ui.semantics.Semantics
@@ -36,6 +37,7 @@
import androidx.ui.test.findByTag
import androidx.ui.unit.Density
import androidx.ui.unit.IntPxSize
+import androidx.ui.unit.PxPosition
import androidx.ui.unit.dp
import androidx.ui.unit.px
import com.google.common.truth.Truth
@@ -78,21 +80,25 @@
@Test
fun box_testPadding_separate() {
var childSize: IntPxSize? = null
+ var childPosition: PxPosition? = null
val size = 100.dp
- val left = 17.dp
+ val start = 17.dp
val top = 2.dp
- val right = 5.dp
+ val end = 5.dp
val bottom = 8.dp
composeTestRule.setContent {
SemanticsParent {
Box(
LayoutSize(size),
- paddingLeft = left,
- paddingRight = right,
+ paddingStart = start,
+ paddingEnd = end,
paddingTop = top,
paddingBottom = bottom
) {
- OnChildPositioned({ childSize = it.size }) {
+ OnChildPositioned({
+ childSize = it.size
+ childPosition = it.localToGlobal(PxPosition.Origin)
+ }) {
Box(LayoutSize.Fill)
}
}
@@ -100,10 +106,50 @@
}
with(composeTestRule.density) {
Truth.assertThat(childSize!!.width).isEqualTo(
- size.toIntPx() - left.toIntPx() - right.toIntPx()
+ size.toIntPx() - start.toIntPx() - end.toIntPx()
)
Truth.assertThat(childSize!!.height)
.isEqualTo(size.toIntPx() - top.toIntPx() - bottom.toIntPx())
+ Truth.assertThat(childPosition!!)
+ .isEqualTo(PxPosition(start.toIntPx(), top.toIntPx()))
+ }
+ }
+
+ @Test
+ fun box_testPadding_rtl() {
+ var childSize: IntPxSize? = null
+ var childPosition: PxPosition? = null
+ val size = 100.dp
+ val start = 17.dp
+ val top = 2.dp
+ val end = 5.dp
+ val bottom = 8.dp
+ composeTestRule.setContent {
+ SemanticsParent {
+ Box(
+ LayoutSize(size) + LayoutDirectionModifier.Rtl,
+ paddingStart = start,
+ paddingEnd = end,
+ paddingTop = top,
+ paddingBottom = bottom
+ ) {
+ OnChildPositioned({
+ childSize = it.size
+ childPosition = it.localToGlobal(PxPosition.Origin)
+ }) {
+ Box(LayoutSize.Fill)
+ }
+ }
+ }
+ }
+ with(composeTestRule.density) {
+ Truth.assertThat(childSize!!.width).isEqualTo(
+ size.toIntPx() - start.toIntPx() - end.toIntPx()
+ )
+ Truth.assertThat(childSize!!.height)
+ .isEqualTo(size.toIntPx() - top.toIntPx() - bottom.toIntPx())
+ Truth.assertThat(childPosition!!)
+ .isEqualTo(PxPosition(end.toIntPx(), top.toIntPx()))
}
}
@@ -120,7 +166,7 @@
Box(
LayoutSize(size),
padding = padding,
- paddingLeft = left,
+ paddingStart = left,
paddingTop = top,
paddingBottom = bottom
) {
diff --git a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/ClickableTest.kt b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/ClickableTest.kt
index bbb4b25..6006132 100644
--- a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/ClickableTest.kt
+++ b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/ClickableTest.kt
@@ -66,7 +66,7 @@
composeTestRule.setContent {
Center {
TestTag(tag = "myClickable") {
- Clickable {
+ Clickable(onClick = {}, enabled = false) {
Text("ClickableText")
}
}
diff --git a/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/ImageTest.kt b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/ImageTest.kt
new file mode 100644
index 0000000..c85a3b9
--- /dev/null
+++ b/ui/ui-foundation/src/androidTest/java/androidx/ui/foundation/ImageTest.kt
@@ -0,0 +1,234 @@
+/*
+ * 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.ui.foundation
+
+import android.os.Build
+import androidx.test.filters.SdkSuppress
+import androidx.test.filters.MediumTest
+import androidx.ui.core.Alignment
+import androidx.ui.core.DensityAmbient
+import androidx.ui.core.TestTag
+import androidx.ui.test.createComposeRule
+import androidx.ui.geometry.Rect
+import androidx.ui.graphics.Canvas
+import androidx.ui.graphics.Color
+import androidx.ui.graphics.ImageAsset
+import androidx.ui.graphics.Paint
+import androidx.ui.graphics.Path
+import androidx.ui.graphics.ScaleFit
+import androidx.ui.graphics.painter.ColorPainter
+import androidx.ui.graphics.toArgb
+import androidx.ui.layout.LayoutAlign
+import androidx.ui.layout.LayoutSize
+import androidx.ui.test.captureToBitmap
+import androidx.ui.test.findByTag
+import androidx.ui.unit.dp
+import org.junit.Assert
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@MediumTest
+@SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+@RunWith(JUnit4::class)
+class ImageTest {
+
+ val contentTag = "ImageTest"
+
+ val imageWidth = 100
+ val imageHeight = 100
+ val containerSize = imageWidth
+
+ val bgColor = Color.Blue
+ val pathColor = Color.Red
+
+ @get:Rule
+ val rule = createComposeRule()
+
+ private fun createImageAsset(): ImageAsset {
+ val image = ImageAsset(imageWidth, imageHeight)
+ val path = Path().apply {
+ lineTo(imageWidth.toFloat(), imageHeight.toFloat())
+ lineTo(0.0f, imageHeight.toFloat())
+ close()
+ }
+ val paint = Paint()
+ Canvas(image).apply {
+ paint.color = bgColor
+ drawRect(
+ Rect.fromLTWH(
+ 0.0f,
+ 0.0f,
+ imageWidth.toFloat(),
+ imageHeight.toFloat()
+ ),
+ paint
+ )
+
+ paint.color = pathColor
+ drawPath(path, paint)
+ }
+ return image
+ }
+
+ @Test
+ fun testImage() {
+ rule.setContent {
+ val size = (containerSize / DensityAmbient.current.density).dp
+ Box(modifier = LayoutSize(size) + DrawBackground(Color.White) + LayoutAlign.Center) {
+ TestTag(contentTag) {
+ Image(image = createImageAsset())
+ }
+ }
+ }
+
+ val bgColorArgb = bgColor.toArgb()
+ val pathArgb = pathColor.toArgb()
+
+ findByTag(contentTag).captureToBitmap().apply {
+ val imageStartX = width / 2 - imageWidth / 2
+ val imageStartY = height / 2 - imageHeight / 2
+ Assert.assertEquals(bgColorArgb, getPixel(imageStartX + 2, imageStartY))
+ Assert.assertEquals(pathArgb, getPixel(imageStartX, imageStartY + 1))
+ Assert.assertEquals(pathArgb, getPixel(imageStartX + (imageWidth / 2) - 1,
+ imageStartY + (imageHeight / 2) + 1))
+ Assert.assertEquals(bgColorArgb, getPixel(imageStartX + (imageWidth / 2) - 2,
+ imageStartY + (imageHeight / 2) - 5))
+ Assert.assertEquals(pathArgb, getPixel(imageStartX, imageStartY + imageHeight - 1))
+ }
+ }
+
+ @Test
+ fun testImageFixedSizeIsStretched() {
+ val imageComposableWidth = imageWidth * 2
+ val imageComposableHeight = imageHeight * 2
+ rule.setContent {
+ val density = DensityAmbient.current.density
+ val size = (containerSize * 2 / density).dp
+ Box(modifier = LayoutSize(size) + DrawBackground(Color.White) + LayoutAlign.Center) {
+ TestTag(contentTag) {
+ // The resultant Image composable should be twice the size of the underlying
+ // ImageAsset that is to be drawn and will stretch the content to fit
+ // the bounds
+ Image(image = createImageAsset(),
+ modifier = LayoutSize(
+ (imageComposableWidth / density).dp,
+ (imageComposableHeight / density).dp
+ ),
+ scaleFit = ScaleFit.FillMinDimension
+ )
+ }
+ }
+ }
+
+ val bgColorArgb = bgColor.toArgb()
+ val pathArgb = pathColor.toArgb()
+ findByTag(contentTag).captureToBitmap().apply {
+ val imageStartX = width / 2 - imageComposableWidth / 2
+ val imageStartY = height / 2 - imageComposableHeight / 2
+ Assert.assertEquals(bgColorArgb, getPixel(imageStartX + 5, imageStartY))
+ Assert.assertEquals(pathArgb, getPixel(imageStartX, imageStartY + 5))
+ Assert.assertEquals(pathArgb, getPixel(imageStartX + (imageComposableWidth / 2) - 5,
+ imageStartY + (imageComposableHeight / 2) + 5))
+ Assert.assertEquals(bgColorArgb, getPixel(imageStartX + (imageComposableWidth / 2),
+ imageStartY + (imageComposableHeight / 2) - 10))
+ Assert.assertEquals(pathArgb, getPixel(imageStartX, imageStartY +
+ imageComposableHeight - 1))
+ }
+ }
+
+ @Test
+ fun testImageFixedSizeAlignedBottomEnd() {
+ val imageComposableWidth = imageWidth * 2
+ val imageComposableHeight = imageHeight * 2
+ rule.setContent {
+ val density = DensityAmbient.current.density
+ val size = (containerSize * 2 / density).dp
+ Box(modifier = LayoutSize(size) + DrawBackground(Color.White) + LayoutAlign.Center) {
+ TestTag(contentTag) {
+ // The resultant Image composable should be twice the size of the underlying
+ // ImageAsset that is to be drawn in the bottom end section of the composable
+ Image(image = createImageAsset(),
+ modifier = LayoutSize(
+ (imageComposableWidth / density).dp,
+ (imageComposableHeight / density).dp
+ ),
+ alignment = Alignment.BottomEnd
+ )
+ }
+ }
+ }
+
+ val bgColorArgb = bgColor.toArgb()
+ val pathArgb = pathColor.toArgb()
+ findByTag(contentTag).captureToBitmap().apply {
+ val composableEndX = width / 2 + imageComposableWidth / 2
+ val composableEndY = height / 2 + imageComposableHeight / 2
+ val imageStartX = composableEndX - imageWidth
+ val imageStartY = composableEndY - imageHeight
+ Assert.assertEquals(bgColorArgb, getPixel(imageStartX + 2, imageStartY))
+ Assert.assertEquals(pathArgb, getPixel(imageStartX, imageStartY + 1))
+ Assert.assertEquals(pathArgb, getPixel(imageStartX + (imageWidth / 2) - 1,
+ imageStartY + (imageHeight / 2) + 1))
+ Assert.assertEquals(bgColorArgb, getPixel(imageStartX + (imageWidth / 2) - 2,
+ imageStartY + (imageHeight / 2) - 5))
+ Assert.assertEquals(pathArgb, getPixel(imageStartX, imageStartY + imageHeight - 1))
+ }
+ }
+
+ @Test
+ fun testImageMinSizeCentered() {
+ rule.setContent {
+ val density = DensityAmbient.current.density
+ val size = (containerSize * 2 / density).dp
+ Box(modifier = LayoutSize(size) + DrawBackground(Color.White) + LayoutAlign.Center) {
+ TestTag(contentTag) {
+ // The resultant Image composable should be sized to the minimum values here
+ // as [ColorPainter] has no intrinsic width or height
+ Image(painter = ColorPainter(Color.Red),
+ minWidth = (imageWidth / density).dp,
+ minHeight = (imageHeight / density).dp,
+ alignment = Alignment.Center
+ )
+ }
+ }
+ }
+
+ val imageColor = Color.Red.toArgb()
+ val containerBgColor = Color.White.toArgb()
+ findByTag(contentTag).captureToBitmap().apply {
+ val imageStartX = width / 2 - imageWidth / 2
+ val imageStartY = height / 2 - imageHeight / 2
+ Assert.assertEquals(containerBgColor, getPixel(imageStartX - 1, imageStartY - 1))
+ Assert.assertEquals(containerBgColor, getPixel(imageStartX + imageWidth + 1,
+ imageStartY - 1))
+ Assert.assertEquals(containerBgColor, getPixel(imageStartX + imageWidth + 1,
+ imageStartY + imageHeight + 1))
+ Assert.assertEquals(containerBgColor, getPixel(imageStartX - 1, imageStartY +
+ imageHeight + 1))
+
+ Assert.assertEquals(imageColor, getPixel(imageStartX, imageStartY))
+ Assert.assertEquals(imageColor, getPixel(imageStartX + imageWidth - 1,
+ imageStartY))
+ Assert.assertEquals(imageColor, getPixel(imageStartX + imageWidth - 1,
+ imageStartY + imageHeight - 1))
+ Assert.assertEquals(imageColor, getPixel(imageStartX, imageStartY +
+ imageHeight - 1))
+ }
+ }
+}
\ No newline at end of file
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/AdapterList.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/AdapterList.kt
index 921976a..00a423a 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/AdapterList.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/AdapterList.kt
@@ -18,25 +18,25 @@
import android.content.Context
import androidx.compose.Composable
-import androidx.compose.Compose
import androidx.compose.CompositionReference
import androidx.compose.FrameManager
+import androidx.compose.Untracked
import androidx.compose.compositionReference
import androidx.compose.remember
-import androidx.ui.core.Clip
import androidx.ui.core.Constraints
import androidx.ui.core.ContextAmbient
import androidx.ui.core.LayoutDirection
+import androidx.ui.core.DrawClipToBounds
import androidx.ui.core.LayoutNode
import androidx.ui.core.Measurable
import androidx.ui.core.MeasureScope
import androidx.ui.core.MeasuringIntrinsicsMeasureBlocks
import androidx.ui.core.Modifier
import androidx.ui.core.Ref
+import androidx.ui.core.subcomposeInto
import androidx.ui.foundation.gestures.DragDirection
import androidx.ui.foundation.gestures.Scrollable
import androidx.ui.foundation.gestures.ScrollableState
-import androidx.ui.foundation.shape.RectangleShape
import androidx.ui.unit.IntPx
import androidx.ui.unit.ipx
import androidx.ui.unit.px
@@ -316,7 +316,7 @@
// Remove no-longer-needed items from the start of the list
if (itemIndexOffset > firstComposedItem) {
- rootNode.emitRemoveAt(0, (itemIndexOffset - firstComposedItem).value)
+ rootNode.removeAt(0, (itemIndexOffset - firstComposedItem).value)
}
firstComposedItem = itemIndexOffset
@@ -329,7 +329,7 @@
// Remove no-longer-needed items from the end of the list
val layoutChildrenInNode = rootNode.layoutChildren.size
if (layoutChildrenInNode > numDesiredChildren) {
- rootNode.emitRemoveAt(
+ rootNode.removeAt(
// We've already removed the extras at the start, so the desired children
// start at index 0
index = numDesiredChildren,
@@ -423,7 +423,7 @@
layout(columnWidth, columnHeight) {
var top = 0.ipx
placeables.forEach { placeable ->
- placeable.place(0.ipx, top)
+ placeable.placeAbsolute(0.ipx, top)
top += placeable.height
}
}
@@ -436,7 +436,7 @@
// the others will be shifted forward. This accounts for these different methods of
// tracking.
val newLayoutIndex = if (atStart) 0 else layoutIndex.value
- rootNode.emitInsertAt(newLayoutIndex, node)
+ rootNode.insertAt(newLayoutIndex, node)
if (atEnd) {
lastComposedItem++
} else {
@@ -446,7 +446,8 @@
} else {
node = rootNode.layoutChildren[layoutIndex.value]
}
- Compose.subcomposeInto(node, context!!, compositionRef) {
+ // TODO(b/150390669): Review use of @Untracked
+ subcomposeInto(node, context!!, compositionRef) @Untracked {
itemCallback(data[dataIndex.value])
}
return node
@@ -477,13 +478,11 @@
Scrollable(dragDirection = DragDirection.Vertical, scrollableState = ScrollableState(
onScrollDeltaConsumptionRequested = state.onScrollDeltaConsumptionRequestedListener
)) {
- Clip(shape = RectangleShape) {
- androidx.ui.core.LayoutNode(
- modifier = modifier,
- ref = state.rootNodeRef,
- measureBlocks = state.measureBlocks
- )
- }
+ androidx.ui.core.LayoutNode(
+ modifier = modifier + DrawClipToBounds,
+ ref = state.rootNodeRef,
+ measureBlocks = state.measureBlocks
+ )
}
state.recomposeIfAttached()
-}
\ No newline at end of file
+}
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Box.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Box.kt
index 49f3529..dcadb84 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Box.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Box.kt
@@ -53,14 +53,14 @@
* `null`, there will be no border
* @param padding The padding to be applied inside Box, along its edges. Unless otherwise
* specified, content will be padded by the [Border.size], if [border] is provided
- * @param paddingLeft specific padding for left side. Setting this will override
- * [padding] for the left side
- * @param paddingTop specific padding for right side. Setting this will override
- * [padding] for the top side
- * @param paddingRight specific padding for top side. Setting this will override
- * [padding] for the right side
- * @param paddingBottom specific padding for bottom side. Setting this will override
- * [padding] for the bottom side
+ * @param paddingStart sets the padding of the start edge. Setting this will override [padding]
+ * for the start edge
+ * @param paddingTop sets the padding of the top edge. Setting this will override [padding] for
+ * the top edge
+ * @param paddingEnd sets the padding of the end edge. Setting this will override [padding] for
+ * the end edge
+ * @param paddingBottom sets the padding of the bottom edge. Setting this will override [padding]
+ * for the bottom edge
* @param gravity The gravity of the content inside Box
*/
@Composable
@@ -70,9 +70,9 @@
backgroundColor: Color = Color.Transparent,
border: Border? = null,
padding: Dp = border?.size ?: 0.dp,
- paddingLeft: Dp = Dp.Unspecified,
+ paddingStart: Dp = Dp.Unspecified,
paddingTop: Dp = Dp.Unspecified,
- paddingRight: Dp = Dp.Unspecified,
+ paddingEnd: Dp = Dp.Unspecified,
paddingBottom: Dp = Dp.Unspecified,
gravity: ContentGravity = ContentGravity.TopStart,
children: @Composable() () -> Unit = emptyContent()
@@ -91,11 +91,11 @@
children,
modifier + backgroundModifier + borderModifier
) { measurables, constraints, _ ->
- val leftPadding = if (paddingLeft != Dp.Unspecified) paddingLeft else padding
+ val startPadding = if (paddingStart != Dp.Unspecified) paddingStart else padding
val topPadding = if (paddingTop != Dp.Unspecified) paddingTop else padding
- val rightPadding = if (paddingRight != Dp.Unspecified) paddingRight else padding
+ val endPadding = if (paddingEnd != Dp.Unspecified) paddingEnd else padding
val bottomPadding = if (paddingBottom != Dp.Unspecified) paddingBottom else padding
- val totalHorizontal = leftPadding.toIntPx() + rightPadding.toIntPx()
+ val totalHorizontal = startPadding.toIntPx() + endPadding.toIntPx()
val totalVertical = topPadding.toIntPx() + bottomPadding.toIntPx()
val childConstraints = constraints
@@ -119,7 +119,7 @@
)
)
it.place(
- leftPadding.toIntPx() + position.x,
+ startPadding.toIntPx() + position.x,
topPadding.toIntPx() + position.y
)
}
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Clickable.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Clickable.kt
index 4463dc1..e2cbc54 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Clickable.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Clickable.kt
@@ -28,15 +28,17 @@
*
* @sample androidx.ui.foundation.samples.ClickableSample
*
- * @param onClick will be called when user clicked on the button. The children will not be
- * clickable when it is null.
+ * @param onClick will be called when user clicked on the button
+ * @param enabled Controls the enabled state. When `false`, this component will not be
+ * clickable
* @param consumeDownOnStart true means [PressReleasedGestureDetector] should consume
- * down events. Provide false if you have some visual feedback like Ripples,
- * as it will consume this events instead.
+ * down events. Provide false if you have some visual feedback like Ripples,
+ * as it will consume this events instead
*/
@Composable
fun Clickable(
- onClick: (() -> Unit)? = null,
+ onClick: () -> Unit,
+ enabled: Boolean = true,
onClickLabel: String? = null,
consumeDownOnStart: Boolean = false,
children: @Composable() () -> Unit
@@ -44,8 +46,8 @@
Semantics(
container = true,
properties = {
- enabled = (onClick != null)
- if (onClick != null) {
+ this.enabled = enabled
+ if (enabled) {
onClick(action = onClick, label = onClickLabel)
}
}
@@ -53,6 +55,7 @@
PressReleasedGestureDetector(
onRelease = onClick,
consumeDownOnStart = consumeDownOnStart,
+ enabled = enabled,
children = children
)
}
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Dialog.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Dialog.kt
index 9a9ab08..0179eb2 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Dialog.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Dialog.kt
@@ -22,7 +22,7 @@
import android.view.Window
import android.widget.FrameLayout
import androidx.compose.Composable
-import androidx.compose.disposeComposition
+import androidx.compose.Composition
import androidx.compose.remember
import androidx.compose.onActive
import androidx.compose.onCommit
@@ -66,6 +66,7 @@
private class DialogWrapper(context: Context, var onCloseRequest: () -> Unit) : Dialog(context) {
val frameLayout = FrameLayout(context)
+ private var composition: Composition? = null
init {
window!!.requestFeature(Window.FEATURE_NO_TITLE)
window!!.setBackgroundDrawableResource(android.R.color.transparent)
@@ -73,11 +74,11 @@
}
fun setContent(children: @Composable() () -> Unit) {
- frameLayout.setContent(children)
+ composition = frameLayout.setContent(children)
}
fun disposeComposition() {
- frameLayout.disposeComposition()
+ composition?.dispose()
}
override fun onTouchEvent(event: MotionEvent): Boolean {
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Image.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Image.kt
index 75e5fe7..f2d1307 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Image.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Image.kt
@@ -17,22 +17,134 @@
package androidx.ui.foundation
import androidx.compose.Composable
+import androidx.compose.remember
+import androidx.ui.core.Alignment
import androidx.ui.core.DensityAmbient
import androidx.ui.core.DrawModifier
+import androidx.ui.core.LayoutDirection
+import androidx.ui.core.LayoutDirectionAmbient
+import androidx.ui.core.Modifier
import androidx.ui.core.asModifier
import androidx.ui.graphics.BlendMode
import androidx.ui.graphics.Canvas
import androidx.ui.graphics.Color
import androidx.ui.graphics.ColorFilter
+import androidx.ui.graphics.DefaultAlpha
import androidx.ui.graphics.ImageAsset
import androidx.ui.graphics.ScaleFit
import androidx.ui.graphics.painter.ImagePainter
+import androidx.ui.graphics.painter.Painter
import androidx.ui.layout.LayoutSize
import androidx.ui.unit.Density
+import androidx.ui.unit.Dp
import androidx.ui.unit.PxSize
+import androidx.ui.unit.dp
import androidx.ui.unit.toRect
/**
+ * A composable that lays out and draws a given [ImageAsset]. This will attempt to
+ * size the composable according to the [ImageAsset]'s given width and height. However, an
+ * optional [Modifier] parameter can be provided to adjust sizing or draw additional content (ex.
+ * background). Any unspecified dimension will leverage the [ImageAsset]'s size as a minimum
+ * constraint.
+ *
+ * @sample androidx.ui.foundation.samples.ImageSample
+ * @sample androidx.ui.foundation.samples.ImageSamplePainterMinSize
+ *
+ * @param image The [ImageAsset] to draw.
+ * @param modifier Modifier used to adjust the layout algorithm or draw decoration content (ex.
+ * background)
+ * @param alignment Optional alignment parameter used to place the [ImageAsset] in the given
+ * bounds defined by the width and height.
+ * @param scaleFit Optional scale parameter used to determine the aspect ratio scaling to be used
+ * if the bounds are a different size from the intrinsic size of the [ImageAsset].
+ * @param alpha Optional opacity to be applied to the [ImageAsset] when it is rendered onscreen
+ * @param colorFilter Optional ColorFilter to apply for the [ImageAsset] when it is rendered
+ * onscreen
+ * @param layoutDirection Optional parameter indicating the content should be mirrored for right to
+ * left languages.
+ */
+@Composable
+fun Image(
+ image: ImageAsset,
+ modifier: Modifier = Modifier.None,
+ alignment: Alignment = Alignment.Center,
+ scaleFit: ScaleFit = ScaleFit.Fit,
+ alpha: Float = DefaultAlpha,
+ colorFilter: ColorFilter? = null,
+ layoutDirection: LayoutDirection = LayoutDirectionAmbient.current
+) {
+ val imagePainter = remember(image) { ImagePainter(image) }
+ // Min width/height are intentionally not provided in this call as they are consumed
+ // from the ImagePainter directly
+ Image(
+ painter = imagePainter,
+ modifier = modifier,
+ alignment = alignment,
+ scaleFit = scaleFit,
+ alpha = alpha,
+ colorFilter = colorFilter,
+ layoutDirection = layoutDirection
+ )
+}
+
+/**
+ * Creates a composable that lays out and draws a given [Painter]. This will attempt to size
+ * the composable according to the [Painter]'s intrinsic size. However, an optional [Modifier]
+ * parameter can be provided to adjust sizing or draw additional content (ex. background)
+ *
+ * @param painter to draw
+ * @param modifier Modifier used to adjust the layout algorithm or draw decoration content (ex.
+ * background)
+ * @param minWidth Minimum width used to size this Image composable. Useful for situations where
+ * the given Painter has no intrinsic size (ex. ColorPainter)
+ * @param minHeight Minimum height used to size this Image composable. Useful for situations where
+ * the given Painter has no intrinsic size (ex. ColorPainter)
+ * @param alignment Optional alignment parameter used to place the [Painter] in the given
+ * bounds defined by the width and height.
+ * @param scaleFit Optional scale parameter used to determine the aspect ratio scaling to be used
+ * if the bounds are a different size from the intrinsic size of the [Painter].
+ * @param alpha Optional opacity to be applied to the [Painter] when it is rendered onscreen
+ * the default renders the [Painter] completely opaque
+ * @param colorFilter Optional colorFilter to apply for the [Painter] when it is rendered onscreen
+ * @param layoutDirection Optional parameter indicating the content should be mirrored for right to
+ * left languages. The default value is extracted from [LayoutDirectionAmbient]
+ */
+@Composable
+fun Image(
+ painter: Painter,
+ modifier: Modifier = Modifier.None,
+ minWidth: Dp = Dp.Unspecified,
+ minHeight: Dp = Dp.Unspecified,
+ alignment: Alignment = Alignment.Center,
+ scaleFit: ScaleFit = ScaleFit.Fit,
+ alpha: Float = DefaultAlpha,
+ colorFilter: ColorFilter? = null,
+ layoutDirection: LayoutDirection = LayoutDirectionAmbient.current
+) {
+ val painterModifier = painter.asModifier(
+ alignment = alignment,
+ scaleFit = scaleFit,
+ alpha = alpha,
+ colorFilter = colorFilter,
+ rtl = layoutDirection == LayoutDirection.Rtl
+ )
+ // Enforce a minimum size if specified. This is used if the underlying painter does not
+ // have a minimum size, or it is smaller than the given minimum size
+ val hasSpecifiedMinWidth = minWidth != Dp.Unspecified
+ val hasSpecifiedMinHeight = minHeight != Dp.Unspecified
+ val hasSpecifiedMinSize = hasSpecifiedMinWidth && hasSpecifiedMinHeight
+ val minSizeModifier = when {
+ hasSpecifiedMinSize -> LayoutSize.Min(minWidth, minHeight)
+ hasSpecifiedMinWidth -> LayoutSize.Min(minWidth, 0.dp)
+ hasSpecifiedMinHeight -> LayoutSize.Min(0.dp, minHeight)
+ else -> Modifier.None
+ }
+
+ Box(modifier + minSizeModifier + ClipModifier + painterModifier)
+}
+
+/**
* Fits an image into the container with sizes equals to the image size, while maintaining
* the image aspect ratio.
* The image will be clipped if the aspect ratios of the image and the parent don't match.
@@ -41,9 +153,15 @@
*
* @param image The image to draw.
* @param tint The tint color to apply for the image.
+ *
+ * @deprecated use [Image] instead
*/
// TODO(Andrey) Temporary. Should be replaced with our proper Image component when it available
// TODO(Andrey, Matvei, Nader): Support other scale types b/141741141
+@Deprecated("SimpleImage has limited functionality and was a placeholder API until" +
+ "the preferred API for laying out and drawing an ImageAsset was finalized.",
+ ReplaceWith("Image(image)")
+)
@Composable
fun SimpleImage(
image: ImageAsset,
diff --git a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Scroller.kt b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Scroller.kt
index 8ddbc81..86ca69a 100644
--- a/ui/ui-foundation/src/main/java/androidx/ui/foundation/Scroller.kt
+++ b/ui/ui-foundation/src/main/java/androidx/ui/foundation/Scroller.kt
@@ -23,16 +23,15 @@
import androidx.compose.remember
import androidx.ui.core.Alignment
import androidx.ui.core.AnimationClockAmbient
-import androidx.ui.core.Clip
import androidx.ui.core.Constraints
+import androidx.ui.core.DrawClipToBounds
import androidx.ui.core.Layout
import androidx.ui.core.Modifier
-import androidx.ui.core.RepaintBoundary
+import androidx.ui.core.drawLayer
import androidx.ui.foundation.animation.FlingConfig
import androidx.ui.foundation.gestures.DragDirection
import androidx.ui.foundation.gestures.Scrollable
import androidx.ui.foundation.gestures.ScrollableState
-import androidx.ui.foundation.shape.RectangleShape
import androidx.ui.layout.Constraints
import androidx.ui.layout.Container
import androidx.ui.semantics.ScrollTo
@@ -261,13 +260,13 @@
child: @Composable() () -> Unit
) {
Layout(
- modifier = modifier,
+ modifier = modifier + DrawClipToBounds,
children = {
- Clip(RectangleShape) {
- Container(alignment = Alignment.TopStart) {
- RepaintBoundary(children = child)
- }
- }
+ Container(
+ alignment = Alignment.TopStart,
+ modifier = drawLayer(),
+ children = child
+ )
},
measureBlock = { measurables, constraints, _ ->
if (measurables.size > 1) {
diff --git a/ui/ui-framework/api/0.1.0-dev07.txt b/ui/ui-framework/api/0.1.0-dev07.txt
index e2ec317..49d0ad3 100644
--- a/ui/ui-framework/api/0.1.0-dev07.txt
+++ b/ui/ui-framework/api/0.1.0-dev07.txt
@@ -1,11 +1,25 @@
// Signature format: 3.0
-package androidx.ui.core {
+package androidx.compose {
- public final class AndroidViewCompatKt {
+ public final class Compose {
+ method @Deprecated @MainThread public androidx.compose.Composition composeInto(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @Deprecated @MainThread public androidx.compose.Composition composeInto(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @Deprecated @MainThread public void disposeComposition(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null);
+ method @Deprecated @MainThread public void disposeComposition(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null);
+ field public static final androidx.compose.Compose! INSTANCE;
}
+ public final class ComposerCompatKt {
+ method @Deprecated public static androidx.ui.node.UiComposer getComposer();
+ }
+
+}
+
+package androidx.ui.core {
+
public final class ClipKt {
- method public static inline void Clip(androidx.ui.graphics.Shape shape, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier drawClip(androidx.ui.graphics.Shape shape);
+ method public static androidx.ui.core.Modifier getDrawClipToBounds();
}
public final class DrawKt {
@@ -14,7 +28,7 @@
}
public final class DrawShadowKt {
- method public static inline void DrawShadow(androidx.ui.graphics.Shape shape, androidx.ui.unit.Dp elevation);
+ method public static androidx.ui.core.Modifier drawShadow(androidx.ui.graphics.Shape shape, androidx.ui.unit.Dp elevation, boolean clipToOutline = true, @FloatRange(from=0.0, to=1.0) float opacity = 1f);
}
public enum DropDownAlignment {
@@ -29,7 +43,7 @@
method public static androidx.ui.core.LayoutNode.MeasureBlocks MeasuringIntrinsicsMeasureBlocks(kotlin.jvm.functions.Function4<? super androidx.ui.core.MeasureScope,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,? super androidx.ui.core.LayoutDirection,? extends androidx.ui.core.MeasureScope.LayoutResult> measureBlock);
method public static inline void OnChildPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static inline void OnPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned);
- method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
+ method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function2<? super androidx.ui.core.Constraints,? super androidx.ui.core.LayoutDirection,kotlin.Unit> children);
}
public final class LayoutTag implements androidx.ui.core.LayoutTagParentData androidx.ui.core.ParentDataModifier {
@@ -65,7 +79,7 @@
}
public final class OpacityKt {
- method public static inline void Opacity(@FloatRange(from=0.0, to=1.0) float opacity, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier drawOpacity(@FloatRange(from=0.0, to=1.0) float opacity);
}
public final class PainterModifierKt {
@@ -87,7 +101,7 @@
public final class PopupKt {
method public static void DropdownPopup(androidx.ui.core.DropDownAlignment dropDownAlignment = androidx.ui.core.DropDownAlignment.Left, androidx.ui.unit.IntPxPosition offset = IntPxPosition(IntPx.Zero, IntPx.Zero), androidx.ui.core.PopupProperties popupProperties = androidx.ui.core.PopupProperties(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static void Popup(androidx.ui.core.Alignment alignment = Alignment.TopStart, androidx.ui.unit.IntPxPosition offset = IntPxPosition(IntPx.Zero, IntPx.Zero), androidx.ui.core.PopupProperties popupProperties = androidx.ui.core.PopupProperties(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static void disposeActivityComposition(android.app.Activity activity);
+ method @Deprecated public static void disposeActivityComposition(android.app.Activity activity);
method public static boolean isPopupLayout(android.view.View view, String? testTag = null);
}
@@ -129,6 +143,8 @@
public final class WrapperKt {
method public static void ComposeView(kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method @Deprecated public static void disposeComposition(android.view.ViewGroup);
+ method @Deprecated public static void disposeComposition(android.app.Activity);
method public static androidx.compose.ProvidableAmbient<androidx.ui.core.AndroidComposeView> getAndroidComposeViewAmbient();
method public static androidx.compose.ProvidableAmbient<androidx.animation.AnimationClockObservable> getAnimationClockAmbient();
method public static androidx.compose.ProvidableAmbient<androidx.ui.autofill.Autofill> getAutofillAmbient();
@@ -144,6 +160,9 @@
method public static androidx.compose.ProvidableAmbient<androidx.ui.input.TextInputService> getTextInputServiceAmbient();
method public static androidx.compose.Composition setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
method public static androidx.compose.Composition setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+ method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method public static androidx.compose.Composition setViewContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @MainThread public static androidx.compose.Composition subcomposeInto(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
}
}
@@ -466,6 +485,26 @@
}
+package androidx.ui.node {
+
+ public final class UiComposer extends androidx.compose.Composer<java.lang.Object> {
+ ctor public UiComposer(android.content.Context context, Object root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer);
+ method public inline <T extends android.view.View> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
+ method public inline <T extends android.view.ViewGroup> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public inline <T extends androidx.ui.core.ComponentNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
+ method public inline <T extends androidx.ui.core.ComponentNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public android.content.Context getContext();
+ method public Object getRoot();
+ }
+
+ public final class UiComposerKt {
+ }
+
+ public final class ViewInteropKt {
+ }
+
+}
+
package androidx.ui.res {
public final class ColorResourcesKt {
diff --git a/ui/ui-framework/api/api_lint.ignore b/ui/ui-framework/api/api_lint.ignore
index b9a7976..effbb61 100644
--- a/ui/ui-framework/api/api_lint.ignore
+++ b/ui/ui-framework/api/api_lint.ignore
@@ -13,6 +13,14 @@
Class should be named ScaleCallback
+ContextFirst: androidx.compose.Compose#composeInto(androidx.ui.core.ComponentNode, android.content.Context, androidx.compose.CompositionReference, kotlin.jvm.functions.Function0<kotlin.Unit>) parameter #1:
+ Context is distinct, so it must be the first argument (method `composeInto`)
+ContextFirst: androidx.compose.Compose#disposeComposition(androidx.ui.core.ComponentNode, android.content.Context, androidx.compose.CompositionReference) parameter #1:
+ Context is distinct, so it must be the first argument (method `disposeComposition`)
+ContextFirst: androidx.ui.core.WrapperKt#subcomposeInto(androidx.ui.core.ComponentNode, android.content.Context, androidx.compose.CompositionReference, kotlin.jvm.functions.Function0<kotlin.Unit>) parameter #1:
+ Context is distinct, so it must be the first argument (method `subcomposeInto`)
+
+
DocumentExceptions: androidx.ui.core.MultiComposableMeasurables#get(kotlin.jvm.functions.Function0<kotlin.Unit>):
Method MultiComposableMeasurables.get appears to be throwing java.lang.IllegalStateException; this should be listed in the documentation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
diff --git a/ui/ui-framework/api/current.txt b/ui/ui-framework/api/current.txt
index e2ec317..49d0ad3 100644
--- a/ui/ui-framework/api/current.txt
+++ b/ui/ui-framework/api/current.txt
@@ -1,11 +1,25 @@
// Signature format: 3.0
-package androidx.ui.core {
+package androidx.compose {
- public final class AndroidViewCompatKt {
+ public final class Compose {
+ method @Deprecated @MainThread public androidx.compose.Composition composeInto(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @Deprecated @MainThread public androidx.compose.Composition composeInto(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @Deprecated @MainThread public void disposeComposition(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null);
+ method @Deprecated @MainThread public void disposeComposition(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null);
+ field public static final androidx.compose.Compose! INSTANCE;
}
+ public final class ComposerCompatKt {
+ method @Deprecated public static androidx.ui.node.UiComposer getComposer();
+ }
+
+}
+
+package androidx.ui.core {
+
public final class ClipKt {
- method public static inline void Clip(androidx.ui.graphics.Shape shape, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier drawClip(androidx.ui.graphics.Shape shape);
+ method public static androidx.ui.core.Modifier getDrawClipToBounds();
}
public final class DrawKt {
@@ -14,7 +28,7 @@
}
public final class DrawShadowKt {
- method public static inline void DrawShadow(androidx.ui.graphics.Shape shape, androidx.ui.unit.Dp elevation);
+ method public static androidx.ui.core.Modifier drawShadow(androidx.ui.graphics.Shape shape, androidx.ui.unit.Dp elevation, boolean clipToOutline = true, @FloatRange(from=0.0, to=1.0) float opacity = 1f);
}
public enum DropDownAlignment {
@@ -29,7 +43,7 @@
method public static androidx.ui.core.LayoutNode.MeasureBlocks MeasuringIntrinsicsMeasureBlocks(kotlin.jvm.functions.Function4<? super androidx.ui.core.MeasureScope,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,? super androidx.ui.core.LayoutDirection,? extends androidx.ui.core.MeasureScope.LayoutResult> measureBlock);
method public static inline void OnChildPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static inline void OnPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned);
- method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
+ method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function2<? super androidx.ui.core.Constraints,? super androidx.ui.core.LayoutDirection,kotlin.Unit> children);
}
public final class LayoutTag implements androidx.ui.core.LayoutTagParentData androidx.ui.core.ParentDataModifier {
@@ -65,7 +79,7 @@
}
public final class OpacityKt {
- method public static inline void Opacity(@FloatRange(from=0.0, to=1.0) float opacity, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier drawOpacity(@FloatRange(from=0.0, to=1.0) float opacity);
}
public final class PainterModifierKt {
@@ -87,7 +101,7 @@
public final class PopupKt {
method public static void DropdownPopup(androidx.ui.core.DropDownAlignment dropDownAlignment = androidx.ui.core.DropDownAlignment.Left, androidx.ui.unit.IntPxPosition offset = IntPxPosition(IntPx.Zero, IntPx.Zero), androidx.ui.core.PopupProperties popupProperties = androidx.ui.core.PopupProperties(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static void Popup(androidx.ui.core.Alignment alignment = Alignment.TopStart, androidx.ui.unit.IntPxPosition offset = IntPxPosition(IntPx.Zero, IntPx.Zero), androidx.ui.core.PopupProperties popupProperties = androidx.ui.core.PopupProperties(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static void disposeActivityComposition(android.app.Activity activity);
+ method @Deprecated public static void disposeActivityComposition(android.app.Activity activity);
method public static boolean isPopupLayout(android.view.View view, String? testTag = null);
}
@@ -129,6 +143,8 @@
public final class WrapperKt {
method public static void ComposeView(kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method @Deprecated public static void disposeComposition(android.view.ViewGroup);
+ method @Deprecated public static void disposeComposition(android.app.Activity);
method public static androidx.compose.ProvidableAmbient<androidx.ui.core.AndroidComposeView> getAndroidComposeViewAmbient();
method public static androidx.compose.ProvidableAmbient<androidx.animation.AnimationClockObservable> getAnimationClockAmbient();
method public static androidx.compose.ProvidableAmbient<androidx.ui.autofill.Autofill> getAutofillAmbient();
@@ -144,6 +160,9 @@
method public static androidx.compose.ProvidableAmbient<androidx.ui.input.TextInputService> getTextInputServiceAmbient();
method public static androidx.compose.Composition setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
method public static androidx.compose.Composition setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+ method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method public static androidx.compose.Composition setViewContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @MainThread public static androidx.compose.Composition subcomposeInto(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
}
}
@@ -466,6 +485,26 @@
}
+package androidx.ui.node {
+
+ public final class UiComposer extends androidx.compose.Composer<java.lang.Object> {
+ ctor public UiComposer(android.content.Context context, Object root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer);
+ method public inline <T extends android.view.View> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
+ method public inline <T extends android.view.ViewGroup> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public inline <T extends androidx.ui.core.ComponentNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
+ method public inline <T extends androidx.ui.core.ComponentNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public android.content.Context getContext();
+ method public Object getRoot();
+ }
+
+ public final class UiComposerKt {
+ }
+
+ public final class ViewInteropKt {
+ }
+
+}
+
package androidx.ui.res {
public final class ColorResourcesKt {
diff --git a/ui/ui-framework/api/public_plus_experimental_0.1.0-dev07.txt b/ui/ui-framework/api/public_plus_experimental_0.1.0-dev07.txt
index e2ec317..49d0ad3 100644
--- a/ui/ui-framework/api/public_plus_experimental_0.1.0-dev07.txt
+++ b/ui/ui-framework/api/public_plus_experimental_0.1.0-dev07.txt
@@ -1,11 +1,25 @@
// Signature format: 3.0
-package androidx.ui.core {
+package androidx.compose {
- public final class AndroidViewCompatKt {
+ public final class Compose {
+ method @Deprecated @MainThread public androidx.compose.Composition composeInto(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @Deprecated @MainThread public androidx.compose.Composition composeInto(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @Deprecated @MainThread public void disposeComposition(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null);
+ method @Deprecated @MainThread public void disposeComposition(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null);
+ field public static final androidx.compose.Compose! INSTANCE;
}
+ public final class ComposerCompatKt {
+ method @Deprecated public static androidx.ui.node.UiComposer getComposer();
+ }
+
+}
+
+package androidx.ui.core {
+
public final class ClipKt {
- method public static inline void Clip(androidx.ui.graphics.Shape shape, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier drawClip(androidx.ui.graphics.Shape shape);
+ method public static androidx.ui.core.Modifier getDrawClipToBounds();
}
public final class DrawKt {
@@ -14,7 +28,7 @@
}
public final class DrawShadowKt {
- method public static inline void DrawShadow(androidx.ui.graphics.Shape shape, androidx.ui.unit.Dp elevation);
+ method public static androidx.ui.core.Modifier drawShadow(androidx.ui.graphics.Shape shape, androidx.ui.unit.Dp elevation, boolean clipToOutline = true, @FloatRange(from=0.0, to=1.0) float opacity = 1f);
}
public enum DropDownAlignment {
@@ -29,7 +43,7 @@
method public static androidx.ui.core.LayoutNode.MeasureBlocks MeasuringIntrinsicsMeasureBlocks(kotlin.jvm.functions.Function4<? super androidx.ui.core.MeasureScope,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,? super androidx.ui.core.LayoutDirection,? extends androidx.ui.core.MeasureScope.LayoutResult> measureBlock);
method public static inline void OnChildPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static inline void OnPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned);
- method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
+ method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function2<? super androidx.ui.core.Constraints,? super androidx.ui.core.LayoutDirection,kotlin.Unit> children);
}
public final class LayoutTag implements androidx.ui.core.LayoutTagParentData androidx.ui.core.ParentDataModifier {
@@ -65,7 +79,7 @@
}
public final class OpacityKt {
- method public static inline void Opacity(@FloatRange(from=0.0, to=1.0) float opacity, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier drawOpacity(@FloatRange(from=0.0, to=1.0) float opacity);
}
public final class PainterModifierKt {
@@ -87,7 +101,7 @@
public final class PopupKt {
method public static void DropdownPopup(androidx.ui.core.DropDownAlignment dropDownAlignment = androidx.ui.core.DropDownAlignment.Left, androidx.ui.unit.IntPxPosition offset = IntPxPosition(IntPx.Zero, IntPx.Zero), androidx.ui.core.PopupProperties popupProperties = androidx.ui.core.PopupProperties(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static void Popup(androidx.ui.core.Alignment alignment = Alignment.TopStart, androidx.ui.unit.IntPxPosition offset = IntPxPosition(IntPx.Zero, IntPx.Zero), androidx.ui.core.PopupProperties popupProperties = androidx.ui.core.PopupProperties(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static void disposeActivityComposition(android.app.Activity activity);
+ method @Deprecated public static void disposeActivityComposition(android.app.Activity activity);
method public static boolean isPopupLayout(android.view.View view, String? testTag = null);
}
@@ -129,6 +143,8 @@
public final class WrapperKt {
method public static void ComposeView(kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method @Deprecated public static void disposeComposition(android.view.ViewGroup);
+ method @Deprecated public static void disposeComposition(android.app.Activity);
method public static androidx.compose.ProvidableAmbient<androidx.ui.core.AndroidComposeView> getAndroidComposeViewAmbient();
method public static androidx.compose.ProvidableAmbient<androidx.animation.AnimationClockObservable> getAnimationClockAmbient();
method public static androidx.compose.ProvidableAmbient<androidx.ui.autofill.Autofill> getAutofillAmbient();
@@ -144,6 +160,9 @@
method public static androidx.compose.ProvidableAmbient<androidx.ui.input.TextInputService> getTextInputServiceAmbient();
method public static androidx.compose.Composition setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
method public static androidx.compose.Composition setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+ method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method public static androidx.compose.Composition setViewContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @MainThread public static androidx.compose.Composition subcomposeInto(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
}
}
@@ -466,6 +485,26 @@
}
+package androidx.ui.node {
+
+ public final class UiComposer extends androidx.compose.Composer<java.lang.Object> {
+ ctor public UiComposer(android.content.Context context, Object root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer);
+ method public inline <T extends android.view.View> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
+ method public inline <T extends android.view.ViewGroup> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public inline <T extends androidx.ui.core.ComponentNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
+ method public inline <T extends androidx.ui.core.ComponentNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public android.content.Context getContext();
+ method public Object getRoot();
+ }
+
+ public final class UiComposerKt {
+ }
+
+ public final class ViewInteropKt {
+ }
+
+}
+
package androidx.ui.res {
public final class ColorResourcesKt {
diff --git a/ui/ui-framework/api/public_plus_experimental_current.txt b/ui/ui-framework/api/public_plus_experimental_current.txt
index e2ec317..49d0ad3 100644
--- a/ui/ui-framework/api/public_plus_experimental_current.txt
+++ b/ui/ui-framework/api/public_plus_experimental_current.txt
@@ -1,11 +1,25 @@
// Signature format: 3.0
-package androidx.ui.core {
+package androidx.compose {
- public final class AndroidViewCompatKt {
+ public final class Compose {
+ method @Deprecated @MainThread public androidx.compose.Composition composeInto(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @Deprecated @MainThread public androidx.compose.Composition composeInto(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @Deprecated @MainThread public void disposeComposition(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null);
+ method @Deprecated @MainThread public void disposeComposition(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null);
+ field public static final androidx.compose.Compose! INSTANCE;
}
+ public final class ComposerCompatKt {
+ method @Deprecated public static androidx.ui.node.UiComposer getComposer();
+ }
+
+}
+
+package androidx.ui.core {
+
public final class ClipKt {
- method public static inline void Clip(androidx.ui.graphics.Shape shape, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier drawClip(androidx.ui.graphics.Shape shape);
+ method public static androidx.ui.core.Modifier getDrawClipToBounds();
}
public final class DrawKt {
@@ -14,7 +28,7 @@
}
public final class DrawShadowKt {
- method public static inline void DrawShadow(androidx.ui.graphics.Shape shape, androidx.ui.unit.Dp elevation);
+ method public static androidx.ui.core.Modifier drawShadow(androidx.ui.graphics.Shape shape, androidx.ui.unit.Dp elevation, boolean clipToOutline = true, @FloatRange(from=0.0, to=1.0) float opacity = 1f);
}
public enum DropDownAlignment {
@@ -29,7 +43,7 @@
method public static androidx.ui.core.LayoutNode.MeasureBlocks MeasuringIntrinsicsMeasureBlocks(kotlin.jvm.functions.Function4<? super androidx.ui.core.MeasureScope,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,? super androidx.ui.core.LayoutDirection,? extends androidx.ui.core.MeasureScope.LayoutResult> measureBlock);
method public static inline void OnChildPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static inline void OnPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned);
- method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
+ method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function2<? super androidx.ui.core.Constraints,? super androidx.ui.core.LayoutDirection,kotlin.Unit> children);
}
public final class LayoutTag implements androidx.ui.core.LayoutTagParentData androidx.ui.core.ParentDataModifier {
@@ -65,7 +79,7 @@
}
public final class OpacityKt {
- method public static inline void Opacity(@FloatRange(from=0.0, to=1.0) float opacity, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier drawOpacity(@FloatRange(from=0.0, to=1.0) float opacity);
}
public final class PainterModifierKt {
@@ -87,7 +101,7 @@
public final class PopupKt {
method public static void DropdownPopup(androidx.ui.core.DropDownAlignment dropDownAlignment = androidx.ui.core.DropDownAlignment.Left, androidx.ui.unit.IntPxPosition offset = IntPxPosition(IntPx.Zero, IntPx.Zero), androidx.ui.core.PopupProperties popupProperties = androidx.ui.core.PopupProperties(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static void Popup(androidx.ui.core.Alignment alignment = Alignment.TopStart, androidx.ui.unit.IntPxPosition offset = IntPxPosition(IntPx.Zero, IntPx.Zero), androidx.ui.core.PopupProperties popupProperties = androidx.ui.core.PopupProperties(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static void disposeActivityComposition(android.app.Activity activity);
+ method @Deprecated public static void disposeActivityComposition(android.app.Activity activity);
method public static boolean isPopupLayout(android.view.View view, String? testTag = null);
}
@@ -129,6 +143,8 @@
public final class WrapperKt {
method public static void ComposeView(kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method @Deprecated public static void disposeComposition(android.view.ViewGroup);
+ method @Deprecated public static void disposeComposition(android.app.Activity);
method public static androidx.compose.ProvidableAmbient<androidx.ui.core.AndroidComposeView> getAndroidComposeViewAmbient();
method public static androidx.compose.ProvidableAmbient<androidx.animation.AnimationClockObservable> getAnimationClockAmbient();
method public static androidx.compose.ProvidableAmbient<androidx.ui.autofill.Autofill> getAutofillAmbient();
@@ -144,6 +160,9 @@
method public static androidx.compose.ProvidableAmbient<androidx.ui.input.TextInputService> getTextInputServiceAmbient();
method public static androidx.compose.Composition setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
method public static androidx.compose.Composition setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+ method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method public static androidx.compose.Composition setViewContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @MainThread public static androidx.compose.Composition subcomposeInto(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
}
}
@@ -466,6 +485,26 @@
}
+package androidx.ui.node {
+
+ public final class UiComposer extends androidx.compose.Composer<java.lang.Object> {
+ ctor public UiComposer(android.content.Context context, Object root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer);
+ method public inline <T extends android.view.View> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
+ method public inline <T extends android.view.ViewGroup> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public inline <T extends androidx.ui.core.ComponentNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
+ method public inline <T extends androidx.ui.core.ComponentNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public android.content.Context getContext();
+ method public Object getRoot();
+ }
+
+ public final class UiComposerKt {
+ }
+
+ public final class ViewInteropKt {
+ }
+
+}
+
package androidx.ui.res {
public final class ColorResourcesKt {
diff --git a/ui/ui-framework/api/restricted_0.1.0-dev07.txt b/ui/ui-framework/api/restricted_0.1.0-dev07.txt
index e2ec317..218031d 100644
--- a/ui/ui-framework/api/restricted_0.1.0-dev07.txt
+++ b/ui/ui-framework/api/restricted_0.1.0-dev07.txt
@@ -1,11 +1,25 @@
// Signature format: 3.0
-package androidx.ui.core {
+package androidx.compose {
- public final class AndroidViewCompatKt {
+ public final class Compose {
+ method @Deprecated @MainThread public androidx.compose.Composition composeInto(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @Deprecated @MainThread public androidx.compose.Composition composeInto(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @Deprecated @MainThread public void disposeComposition(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null);
+ method @Deprecated @MainThread public void disposeComposition(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null);
+ field public static final androidx.compose.Compose! INSTANCE;
}
+ public final class ComposerCompatKt {
+ method @Deprecated public static androidx.ui.node.UiComposer getComposer();
+ }
+
+}
+
+package androidx.ui.core {
+
public final class ClipKt {
- method public static inline void Clip(androidx.ui.graphics.Shape shape, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier drawClip(androidx.ui.graphics.Shape shape);
+ method public static androidx.ui.core.Modifier getDrawClipToBounds();
}
public final class DrawKt {
@@ -14,7 +28,7 @@
}
public final class DrawShadowKt {
- method public static inline void DrawShadow(androidx.ui.graphics.Shape shape, androidx.ui.unit.Dp elevation);
+ method public static androidx.ui.core.Modifier drawShadow(androidx.ui.graphics.Shape shape, androidx.ui.unit.Dp elevation, boolean clipToOutline = true, @FloatRange(from=0.0, to=1.0) float opacity = 1f);
}
public enum DropDownAlignment {
@@ -29,7 +43,7 @@
method public static androidx.ui.core.LayoutNode.MeasureBlocks MeasuringIntrinsicsMeasureBlocks(kotlin.jvm.functions.Function4<? super androidx.ui.core.MeasureScope,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,? super androidx.ui.core.LayoutDirection,? extends androidx.ui.core.MeasureScope.LayoutResult> measureBlock);
method public static inline void OnChildPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static inline void OnPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned);
- method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
+ method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function2<? super androidx.ui.core.Constraints,? super androidx.ui.core.LayoutDirection,kotlin.Unit> children);
}
public final class LayoutTag implements androidx.ui.core.LayoutTagParentData androidx.ui.core.ParentDataModifier {
@@ -65,7 +79,7 @@
}
public final class OpacityKt {
- method public static inline void Opacity(@FloatRange(from=0.0, to=1.0) float opacity, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier drawOpacity(@FloatRange(from=0.0, to=1.0) float opacity);
}
public final class PainterModifierKt {
@@ -87,7 +101,7 @@
public final class PopupKt {
method public static void DropdownPopup(androidx.ui.core.DropDownAlignment dropDownAlignment = androidx.ui.core.DropDownAlignment.Left, androidx.ui.unit.IntPxPosition offset = IntPxPosition(IntPx.Zero, IntPx.Zero), androidx.ui.core.PopupProperties popupProperties = androidx.ui.core.PopupProperties(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static void Popup(androidx.ui.core.Alignment alignment = Alignment.TopStart, androidx.ui.unit.IntPxPosition offset = IntPxPosition(IntPx.Zero, IntPx.Zero), androidx.ui.core.PopupProperties popupProperties = androidx.ui.core.PopupProperties(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static void disposeActivityComposition(android.app.Activity activity);
+ method @Deprecated public static void disposeActivityComposition(android.app.Activity activity);
method public static boolean isPopupLayout(android.view.View view, String? testTag = null);
}
@@ -129,6 +143,8 @@
public final class WrapperKt {
method public static void ComposeView(kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method @Deprecated public static void disposeComposition(android.view.ViewGroup);
+ method @Deprecated public static void disposeComposition(android.app.Activity);
method public static androidx.compose.ProvidableAmbient<androidx.ui.core.AndroidComposeView> getAndroidComposeViewAmbient();
method public static androidx.compose.ProvidableAmbient<androidx.animation.AnimationClockObservable> getAnimationClockAmbient();
method public static androidx.compose.ProvidableAmbient<androidx.ui.autofill.Autofill> getAutofillAmbient();
@@ -144,6 +160,9 @@
method public static androidx.compose.ProvidableAmbient<androidx.ui.input.TextInputService> getTextInputServiceAmbient();
method public static androidx.compose.Composition setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
method public static androidx.compose.Composition setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+ method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method public static androidx.compose.Composition setViewContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @MainThread public static androidx.compose.Composition subcomposeInto(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
}
}
@@ -466,6 +485,35 @@
}
+package androidx.ui.node {
+
+ public final class UiComposer extends androidx.compose.Composer<java.lang.Object> {
+ ctor public UiComposer(android.content.Context context, Object root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer);
+ method public inline <T extends android.view.View> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
+ method public inline <T extends android.view.ViewGroup> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public inline <T extends androidx.ui.core.ComponentNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
+ method public inline <T extends androidx.ui.core.ComponentNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public android.content.Context getContext();
+ method public Object getRoot();
+ }
+
+ public final class UiComposerKt {
+ }
+
+ @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public interface ViewAdapter {
+ method public void didInsert(android.view.View view, android.view.ViewGroup parent);
+ method public void didUpdate(android.view.View view, android.view.ViewGroup parent);
+ method public int getId();
+ method public void willInsert(android.view.View view, android.view.ViewGroup parent);
+ property public abstract int id;
+ }
+
+ public final class ViewInteropKt {
+ method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public static <T extends androidx.ui.node.ViewAdapter> T getOrAddAdapter(android.view.View, int id, kotlin.jvm.functions.Function0<? extends T> factory);
+ }
+
+}
+
package androidx.ui.res {
public final class ColorResourcesKt {
diff --git a/ui/ui-framework/api/restricted_current.txt b/ui/ui-framework/api/restricted_current.txt
index e2ec317..218031d 100644
--- a/ui/ui-framework/api/restricted_current.txt
+++ b/ui/ui-framework/api/restricted_current.txt
@@ -1,11 +1,25 @@
// Signature format: 3.0
-package androidx.ui.core {
+package androidx.compose {
- public final class AndroidViewCompatKt {
+ public final class Compose {
+ method @Deprecated @MainThread public androidx.compose.Composition composeInto(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @Deprecated @MainThread public androidx.compose.Composition composeInto(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @Deprecated @MainThread public void disposeComposition(android.view.ViewGroup container, androidx.compose.CompositionReference? parent = null);
+ method @Deprecated @MainThread public void disposeComposition(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null);
+ field public static final androidx.compose.Compose! INSTANCE;
}
+ public final class ComposerCompatKt {
+ method @Deprecated public static androidx.ui.node.UiComposer getComposer();
+ }
+
+}
+
+package androidx.ui.core {
+
public final class ClipKt {
- method public static inline void Clip(androidx.ui.graphics.Shape shape, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier drawClip(androidx.ui.graphics.Shape shape);
+ method public static androidx.ui.core.Modifier getDrawClipToBounds();
}
public final class DrawKt {
@@ -14,7 +28,7 @@
}
public final class DrawShadowKt {
- method public static inline void DrawShadow(androidx.ui.graphics.Shape shape, androidx.ui.unit.Dp elevation);
+ method public static androidx.ui.core.Modifier drawShadow(androidx.ui.graphics.Shape shape, androidx.ui.unit.Dp elevation, boolean clipToOutline = true, @FloatRange(from=0.0, to=1.0) float opacity = 1f);
}
public enum DropDownAlignment {
@@ -29,7 +43,7 @@
method public static androidx.ui.core.LayoutNode.MeasureBlocks MeasuringIntrinsicsMeasureBlocks(kotlin.jvm.functions.Function4<? super androidx.ui.core.MeasureScope,? super java.util.List<? extends androidx.ui.core.Measurable>,? super androidx.ui.core.Constraints,? super androidx.ui.core.LayoutDirection,? extends androidx.ui.core.MeasureScope.LayoutResult> measureBlock);
method public static inline void OnChildPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned, kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static inline void OnPositioned(kotlin.jvm.functions.Function1<? super androidx.ui.core.LayoutCoordinates,kotlin.Unit> onPositioned);
- method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function1<? super androidx.ui.core.Constraints,kotlin.Unit> children);
+ method public static void WithConstraints(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function2<? super androidx.ui.core.Constraints,? super androidx.ui.core.LayoutDirection,kotlin.Unit> children);
}
public final class LayoutTag implements androidx.ui.core.LayoutTagParentData androidx.ui.core.ParentDataModifier {
@@ -65,7 +79,7 @@
}
public final class OpacityKt {
- method public static inline void Opacity(@FloatRange(from=0.0, to=1.0) float opacity, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.core.Modifier drawOpacity(@FloatRange(from=0.0, to=1.0) float opacity);
}
public final class PainterModifierKt {
@@ -87,7 +101,7 @@
public final class PopupKt {
method public static void DropdownPopup(androidx.ui.core.DropDownAlignment dropDownAlignment = androidx.ui.core.DropDownAlignment.Left, androidx.ui.unit.IntPxPosition offset = IntPxPosition(IntPx.Zero, IntPx.Zero), androidx.ui.core.PopupProperties popupProperties = androidx.ui.core.PopupProperties(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
method public static void Popup(androidx.ui.core.Alignment alignment = Alignment.TopStart, androidx.ui.unit.IntPxPosition offset = IntPxPosition(IntPx.Zero, IntPx.Zero), androidx.ui.core.PopupProperties popupProperties = androidx.ui.core.PopupProperties(), kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static void disposeActivityComposition(android.app.Activity activity);
+ method @Deprecated public static void disposeActivityComposition(android.app.Activity activity);
method public static boolean isPopupLayout(android.view.View view, String? testTag = null);
}
@@ -129,6 +143,8 @@
public final class WrapperKt {
method public static void ComposeView(kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method @Deprecated public static void disposeComposition(android.view.ViewGroup);
+ method @Deprecated public static void disposeComposition(android.app.Activity);
method public static androidx.compose.ProvidableAmbient<androidx.ui.core.AndroidComposeView> getAndroidComposeViewAmbient();
method public static androidx.compose.ProvidableAmbient<androidx.animation.AnimationClockObservable> getAnimationClockAmbient();
method public static androidx.compose.ProvidableAmbient<androidx.ui.autofill.Autofill> getAutofillAmbient();
@@ -144,6 +160,9 @@
method public static androidx.compose.ProvidableAmbient<androidx.ui.input.TextInputService> getTextInputServiceAmbient();
method public static androidx.compose.Composition setContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> content);
method public static androidx.compose.Composition setContent(android.view.ViewGroup, kotlin.jvm.functions.Function0<kotlin.Unit> content);
+ method public static androidx.compose.Composition setViewContent(android.view.ViewGroup, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method public static androidx.compose.Composition setViewContent(android.app.Activity, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
+ method @MainThread public static androidx.compose.Composition subcomposeInto(androidx.ui.core.ComponentNode container, android.content.Context context, androidx.compose.CompositionReference? parent = null, kotlin.jvm.functions.Function0<kotlin.Unit> composable);
}
}
@@ -466,6 +485,35 @@
}
+package androidx.ui.node {
+
+ public final class UiComposer extends androidx.compose.Composer<java.lang.Object> {
+ ctor public UiComposer(android.content.Context context, Object root, androidx.compose.SlotTable slotTable, androidx.compose.Recomposer recomposer);
+ method public inline <T extends android.view.View> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
+ method public inline <T extends android.view.ViewGroup> void emit(Object key, kotlin.jvm.functions.Function1<? super android.content.Context,? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public inline <T extends androidx.ui.core.ComponentNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update);
+ method public inline <T extends androidx.ui.core.ComponentNode> void emit(Object key, kotlin.jvm.functions.Function0<? extends T> ctor, kotlin.jvm.functions.Function1<? super androidx.compose.ComposerUpdater<java.lang.Object,T>,kotlin.Unit> update, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public android.content.Context getContext();
+ method public Object getRoot();
+ }
+
+ public final class UiComposerKt {
+ }
+
+ @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public interface ViewAdapter {
+ method public void didInsert(android.view.View view, android.view.ViewGroup parent);
+ method public void didUpdate(android.view.View view, android.view.ViewGroup parent);
+ method public int getId();
+ method public void willInsert(android.view.View view, android.view.ViewGroup parent);
+ property public abstract int id;
+ }
+
+ public final class ViewInteropKt {
+ method @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public static <T extends androidx.ui.node.ViewAdapter> T getOrAddAdapter(android.view.View, int id, kotlin.jvm.functions.Function0<? extends T> factory);
+ }
+
+}
+
package androidx.ui.res {
public final class ColorResourcesKt {
diff --git a/ui/ui-framework/build.gradle b/ui/ui-framework/build.gradle
index fe9f109..ebbe63a 100644
--- a/ui/ui-framework/build.gradle
+++ b/ui/ui-framework/build.gradle
@@ -36,7 +36,7 @@
// TODO: Non-Kotlin dependency, move to Android-specific code
implementation "androidx.core:core:1.0.2"
- api project(":compose:compose-runtime")
+ implementation project(":compose:compose-runtime")
api project(":ui:ui-core")
implementation project(":ui:ui-platform")
api project(":ui:ui-text")
@@ -81,3 +81,11 @@
useIR = true
}
}
+
+android {
+ buildTypes {
+ debug {
+ testCoverageEnabled = false // Breaks Kotlin compiler.
+ }
+ }
+}
\ No newline at end of file
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/PopupActivity.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/PopupActivity.kt
index 4d33f31..ef89672 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/PopupActivity.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/PopupActivity.kt
@@ -19,6 +19,7 @@
import android.app.Activity
import android.os.Bundle
import androidx.compose.Composable
+import androidx.compose.Composition
import androidx.compose.state
import androidx.ui.core.Alignment
import androidx.ui.core.DropDownAlignment
@@ -28,7 +29,6 @@
import androidx.ui.core.PopupProperties
import androidx.ui.core.Text
import androidx.ui.core.TextField
-import androidx.ui.core.disposeActivityComposition
import androidx.ui.core.setContent
import androidx.ui.foundation.Box
import androidx.ui.foundation.Clickable
@@ -54,10 +54,11 @@
import androidx.ui.unit.dp
class PopupActivity : Activity() {
+ private var composition: Composition? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContent {
+ composition = setContent {
val exampleIndex = state { 0 }
val totalExamples = 9
@@ -135,10 +136,8 @@
}
}
- // TODO(b/140396932): Replace with Activity.disposeComposition() when it will be working
- // properly
override fun onDestroy() {
- disposeActivityComposition(this)
+ composition?.dispose()
super.onDestroy()
}
}
@@ -465,7 +464,7 @@
onClick: (() -> Unit)? = null,
padding: Dp = 0.dp
) {
- Clickable(onClick = onClick) {
+ Clickable(onClick = onClick ?: {}, enabled = onClick != null) {
Box(LayoutGravity.Center, backgroundColor = color, padding = padding) {
Text(text)
}
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedLongPressDemo.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedLongPressDemo.kt
index 1dd6870..9e6a16f 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedLongPressDemo.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedLongPressDemo.kt
@@ -81,9 +81,9 @@
LongPressGestureDetector(onLongPress) {
Box(
- paddingLeft = paddingLeft,
+ paddingStart = paddingLeft,
paddingTop = paddingTop,
- paddingRight = paddingRight,
+ paddingEnd = paddingRight,
paddingBottom = paddingBottom,
backgroundColor = color,
gravity = ContentGravity.Center,
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedPressDemo.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedPressDemo.kt
index 1faa06f..7043b2a 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedPressDemo.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/NestedPressDemo.kt
@@ -110,9 +110,9 @@
LongPressGestureDetector(onLongPress) {
Box(
backgroundColor = color, border = Border(2.dp, BorderColor),
- paddingLeft = paddingLeft,
+ paddingStart = paddingLeft,
paddingTop = paddingTop,
- paddingRight = paddingRight,
+ paddingEnd = paddingRight,
paddingBottom = paddingBottom,
gravity = ContentGravity.Center,
children = children
diff --git a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/PopupDragActivity.kt b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/PopupDragActivity.kt
index a12dd4d..ca696c1 100644
--- a/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/PopupDragActivity.kt
+++ b/ui/ui-framework/integration-tests/framework-demos/src/main/java/androidx/ui/framework/demos/gestures/PopupDragActivity.kt
@@ -18,12 +18,12 @@
import android.app.Activity
import android.os.Bundle
+import androidx.compose.Composition
import androidx.compose.remember
import androidx.compose.state
import androidx.ui.core.Alignment
import androidx.ui.core.Popup
import androidx.ui.core.Text
-import androidx.ui.core.disposeActivityComposition
import androidx.ui.core.gesture.DragObserver
import androidx.ui.core.gesture.RawDragGestureDetector
import androidx.ui.core.setContent
@@ -32,7 +32,7 @@
import androidx.ui.foundation.shape.corner.CircleShape
import androidx.ui.graphics.Color
import androidx.ui.layout.LayoutSize
-import androidx.ui.layout.Wrap
+import androidx.ui.layout.Stack
import androidx.ui.text.TextStyle
import androidx.ui.text.style.TextAlign
import androidx.ui.unit.PxPosition
@@ -40,10 +40,11 @@
import androidx.ui.unit.round
class PopupDragActivity : Activity() {
+ private var composition: Composition? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- setContent {
+ composition = setContent {
val offset = state {
PxPosition.Origin
@@ -59,7 +60,7 @@
}
Popup(alignment = Alignment.TopStart, offset = offset.value.round()) {
- Wrap {
+ Stack {
RawDragGestureDetector(observer) {
Box(
LayoutSize(70.dp),
@@ -81,7 +82,7 @@
// TODO(b/140396932): Replace with Activity.disposeComposition() when it will be working
// properly
override fun onDestroy() {
- disposeActivityComposition(this)
+ composition?.dispose()
super.onDestroy()
}
}
\ No newline at end of file
diff --git a/ui/ui-framework/integration-tests/samples/src/main/java/androidx/ui/framework/samples/DrawShadowSample.kt b/ui/ui-framework/integration-tests/samples/src/main/java/androidx/ui/framework/samples/DrawShadowSample.kt
index 5f30f8d..40be66a 100644
--- a/ui/ui-framework/integration-tests/samples/src/main/java/androidx/ui/framework/samples/DrawShadowSample.kt
+++ b/ui/ui-framework/integration-tests/samples/src/main/java/androidx/ui/framework/samples/DrawShadowSample.kt
@@ -18,12 +18,14 @@
import androidx.annotation.Sampled
import androidx.compose.Composable
-import androidx.ui.core.DrawShadow
+import androidx.ui.core.drawShadow
+import androidx.ui.foundation.Box
import androidx.ui.foundation.shape.RectangleShape
+import androidx.ui.layout.LayoutSize
import androidx.ui.unit.dp
@Sampled
@Composable
fun DrawShadowSample() {
- DrawShadow(shape = RectangleShape, elevation = 12.dp)
+ Box(drawShadow(shape = RectangleShape, elevation = 12.dp) + LayoutSize(100.dp, 100.dp))
}
diff --git a/ui/ui-framework/integration-tests/samples/src/main/java/androidx/ui/framework/samples/OpacitySample.kt b/ui/ui-framework/integration-tests/samples/src/main/java/androidx/ui/framework/samples/OpacitySample.kt
index d2e2309..0175759 100644
--- a/ui/ui-framework/integration-tests/samples/src/main/java/androidx/ui/framework/samples/OpacitySample.kt
+++ b/ui/ui-framework/integration-tests/samples/src/main/java/androidx/ui/framework/samples/OpacitySample.kt
@@ -18,7 +18,7 @@
import androidx.annotation.Sampled
import androidx.compose.Composable
-import androidx.ui.core.Opacity
+import androidx.ui.core.drawOpacity
import androidx.ui.foundation.Box
import androidx.ui.graphics.Color
import androidx.ui.layout.LayoutSize
@@ -27,7 +27,5 @@
@Sampled
@Composable
fun OpacitySample() {
- Opacity(opacity = 0.5f) {
- Box(LayoutSize(100.dp), backgroundColor = Color.Red)
- }
+ Box(LayoutSize(100.dp) + drawOpacity(opacity = 0.5f), backgroundColor = Color.Red)
}
diff --git a/ui/ui-framework/integration-tests/samples/src/main/java/androidx/ui/framework/samples/WithConstraintsSample.kt b/ui/ui-framework/integration-tests/samples/src/main/java/androidx/ui/framework/samples/WithConstraintsSample.kt
index dcb4056..dae7fb2 100644
--- a/ui/ui-framework/integration-tests/samples/src/main/java/androidx/ui/framework/samples/WithConstraintsSample.kt
+++ b/ui/ui-framework/integration-tests/samples/src/main/java/androidx/ui/framework/samples/WithConstraintsSample.kt
@@ -28,7 +28,7 @@
@Sampled
@Composable
fun WithConstraintsSample() {
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
val rectangleHeight = 100.dp
val threshold = with(DensityAmbient.current) { (rectangleHeight * 2).toIntPx() }
if (constraints.maxHeight < threshold) {
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/HotReloadTests.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/HotReloadTests.kt
new file mode 100644
index 0000000..6cd0176
--- /dev/null
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/HotReloadTests.kt
@@ -0,0 +1,143 @@
+/*
+ * 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.
+ */
+
+@file:Suppress("USELESS_CAST", "UNUSED_PARAMETER", "UNUSED_VARIABLE")
+
+package androidx.ui.core
+
+import androidx.compose.Composable
+import androidx.test.filters.MediumTest
+import android.widget.LinearLayout
+import android.widget.TextView
+import androidx.test.rule.ActivityTestRule
+import androidx.ui.framework.test.TestActivity
+import androidx.ui.test.assertLabelEquals
+import androidx.ui.test.findByTag
+import org.junit.runners.JUnit4
+import org.junit.After
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertNotEquals
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+
+@MediumTest
+@RunWith(JUnit4::class)
+class HotReloadTests {
+ @After
+ fun teardown() {
+ clearRoots()
+ }
+
+ @get:Rule
+ val rule = ActivityTestRule<TestActivity>(TestActivity::class.java)
+
+ @Test
+ fun composeView() {
+ val activity = rule.activity
+ var value = "First value"
+
+ @Composable fun text(text: String, id: Int = -1) {
+ TextView(id = id, text = text)
+ }
+
+ @Composable fun column(children: @Composable() () -> Unit) {
+ LinearLayout { children() }
+ }
+
+ val composeLatch = CountDownLatch(1)
+
+ rule.runOnUiThread {
+ activity.setContent {
+ column {
+ text(text = "Hello", id = 101)
+ text(text = "World", id = 102)
+ text(text = value, id = 103)
+ }
+ }
+ composeLatch.countDown()
+ }
+
+ assert(composeLatch.await(1, TimeUnit.SECONDS))
+
+ assertEquals(activity.findViewById<TextView>(103).text, value)
+ value = "Second value"
+ assertNotEquals(activity.findViewById<TextView>(103).text, value)
+
+ val hotReloadLatch = CountDownLatch(1)
+
+ rule.runOnUiThread {
+ simulateHotReload(activity)
+ hotReloadLatch.countDown()
+ }
+
+ assert(hotReloadLatch.await(1, TimeUnit.SECONDS))
+
+ assertEquals(activity.findViewById<TextView>(103).text, value)
+ }
+
+ @Test
+ fun composeComponentNode() {
+ val activity = rule.activity
+ var value = "First value"
+
+ @Composable fun textNode(text: String, id: Int) {
+ TestTag(tag = "text$id") {
+ Text(text)
+ }
+ }
+
+ @Composable fun columnNode(children: @Composable() () -> Unit) {
+ children()
+ }
+
+ val composeLatch = CountDownLatch(1)
+
+ // Set the content of the view
+ rule.runOnUiThread {
+ activity.setContent {
+ columnNode {
+ textNode(text = value, id = 103)
+ }
+ }
+ composeLatch.countDown()
+ }
+
+ assert(composeLatch.await(1, TimeUnit.SECONDS))
+
+ fun target() = findByTag("text103")
+
+ // Assert that the composition has the correct value
+ target().assertLabelEquals(value)
+
+ value = "Second value"
+
+ val hotReloadLatch = CountDownLatch(1)
+
+ // Simulate hot-reload
+ rule.runOnUiThread {
+ simulateHotReload(activity)
+ hotReloadLatch.countDown()
+ }
+
+ assert(hotReloadLatch.await(1, TimeUnit.SECONDS))
+
+ // Detect tha tthe node changed
+ target().assertLabelEquals(value)
+ }
+}
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/PopupTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/PopupTest.kt
index 5ff94a6..69d786b1 100644
--- a/ui/ui-framework/src/androidTest/java/androidx/ui/core/PopupTest.kt
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/PopupTest.kt
@@ -105,6 +105,8 @@
// TODO(b/139861182): Remove all of this and provide helpers on ComposeTestRule
private fun popupMatches(viewMatcher: Matcher<in View>) {
+ // Make sure that current measurement/drawing is finished
+ composeTestRule.runOnIdleCompose { }
Espresso.onView(instanceOf(AndroidComposeView::class.java))
.inRoot(PopupLayoutMatcher())
.check(matches(viewMatcher))
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
index 67350ad..4fe4fcc 100644
--- a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidLayoutDrawTest.kt
@@ -27,29 +27,25 @@
import android.widget.FrameLayout
import androidx.annotation.RequiresApi
import androidx.compose.Composable
-import androidx.compose.Compose
import androidx.compose.FrameManager
import androidx.compose.Model
-import androidx.compose.Providers
import androidx.compose.emptyContent
+import androidx.compose.mutableStateOf
import androidx.compose.state
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.test.rule.ActivityTestRule
import androidx.ui.core.AndroidComposeView
import androidx.ui.core.Constraints
-import androidx.ui.core.ContextAmbient
-import androidx.ui.core.DensityAmbient
import androidx.ui.core.Draw
+import androidx.ui.core.DrawLayerProperties
import androidx.ui.core.DrawModifier
import androidx.ui.core.HorizontalAlignmentLine
import androidx.ui.core.Layout
import androidx.ui.core.LayoutDirection
-import androidx.ui.core.LayoutDirectionAmbient
import androidx.ui.core.LayoutModifier
import androidx.ui.core.LayoutTag
import androidx.ui.core.Measurable
-import androidx.ui.unit.Density
import androidx.ui.core.Modifier
import androidx.ui.core.OnPositioned
import androidx.ui.core.ParentData
@@ -58,6 +54,7 @@
import androidx.ui.core.RepaintBoundary
import androidx.ui.core.VerticalAlignmentLine
import androidx.ui.core.draw
+import androidx.ui.core.drawLayer
import androidx.ui.core.drawWithContent
import androidx.ui.core.globalPosition
import androidx.ui.core.offset
@@ -69,6 +66,7 @@
import androidx.ui.graphics.Color
import androidx.ui.graphics.Paint
import androidx.ui.graphics.PaintingStyle
+import androidx.ui.unit.Density
import androidx.ui.unit.IntPx
import androidx.ui.unit.IntPxPosition
import androidx.ui.unit.IntPxSize
@@ -465,21 +463,6 @@
}
}
- // TODO(lmr): refactor to use the globally provided one when it lands
- private fun Activity.compose(composable: @Composable() () -> Unit) {
- val root = AndroidComposeView(this)
-
- setContentView(root)
- Compose.composeInto(root.root, context = this) {
- Providers(
- ContextAmbient provides this,
- DensityAmbient provides Density(this),
- LayoutDirectionAmbient provides LayoutDirection.Ltr,
- children = composable
- )
- }
- }
-
// When a child's measure() is done within the layout, it should not affect the parent's
// size. The parent's layout shouldn't be called when the child's size changes
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
@@ -493,7 +476,7 @@
val layoutLatch = CountDownLatch(1)
activityTestRule.runOnUiThreadIR {
- activity.compose {
+ activity.setContent {
Layout(
modifier = draw { canvas, size ->
val paint = Paint()
@@ -1713,14 +1696,14 @@
SimpleRow {
for (i in 0 until 2) {
if (model.offset.value == i) {
- Wrap(size, size) {
+ Wrap(minWidth = size, minHeight = size) {
OnPositioned { coordinates ->
wrap1Position = coordinates.globalPosition.x
latch.countDown()
}
}
} else {
- Wrap(size, size) {
+ Wrap(minWidth = size, minHeight = size) {
OnPositioned { coordinates ->
wrap2Position = coordinates.globalPosition.x
latch.countDown()
@@ -2056,6 +2039,59 @@
assertTrue(drawlatch.await(1, TimeUnit.SECONDS))
}
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun layerModifier_scaleDraw() {
+ activityTestRule.runOnUiThread {
+ activity.setContentInFrameLayout {
+ FixedSize(
+ size = 30.ipx,
+ modifier = background(Color.Blue)
+ ) {
+ FixedSize(
+ size = 20.ipx,
+ modifier = PaddingModifier(5.ipx) + scale(0.5f) +
+ background(Color.Red) + latch(drawLatch)
+ ) {}
+ }
+ }
+ }
+ validateSquareColors(outerColor = Color.Blue, innerColor = Color.Red, size = 10)
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun layerModifier_scaleChange() {
+ val scale = mutableStateOf(1f)
+ val layerProperties = object : DrawLayerProperties {
+ override val scaleX: Float get() = scale.value
+ override val scaleY: Float get() = scale.value
+ }
+ activityTestRule.runOnUiThread {
+ activity.setContentInFrameLayout {
+ FixedSize(
+ size = 30.ipx,
+ modifier = background(Color.Blue)
+ ) {
+ FixedSize(
+ size = 10.ipx,
+ modifier = PaddingModifier(10.ipx) + drawLayer(layerProperties) +
+ background(Color.Red) + latch(drawLatch)
+ ) {}
+ }
+ }
+ }
+ validateSquareColors(outerColor = Color.Blue, innerColor = Color.Red, size = 10)
+
+ activityTestRule.runOnUiThread {
+ scale.value = 2f
+ }
+
+ activityTestRule.waitAndScreenShot().apply {
+ assertRect(Color.Red, size = 20, centerX = 15, centerY = 15)
+ }
+ }
+
private val AlignTopLeft = object : LayoutModifier {
override fun Density.modifyConstraints(
constraints: Constraints,
@@ -2372,9 +2408,10 @@
fun TwoMeasureLayout(
size: IntPx,
latch: CountDownLatch,
+ modifier: Modifier = Modifier.None,
children: @Composable() () -> Unit
) {
- Layout(children = children) { measurables, _, _ ->
+ Layout(modifier = modifier, children = children) { measurables, _, _ ->
val testConstraints = Constraints()
measurables.forEach { it.measure(testConstraints) }
val childConstraints = Constraints.fixed(size, size)
@@ -2395,8 +2432,13 @@
}
@Composable
-fun Position(size: IntPx, offset: OffsetModel, children: @Composable() () -> Unit) {
- Layout(children) { measurables, constraints, _ ->
+fun Position(
+ size: IntPx,
+ offset: OffsetModel,
+ modifier: Modifier = Modifier.None,
+ children: @Composable() () -> Unit
+) {
+ Layout(modifier = modifier, children = children) { measurables, constraints, _ ->
val placeables = measurables.map { m ->
m.measure(constraints)
}
@@ -2409,8 +2451,13 @@
}
@Composable
-fun Wrap(minWidth: IntPx = 0.ipx, minHeight: IntPx = 0.ipx, children: @Composable() () -> Unit) {
- Layout(children) { measurables, constraints, _ ->
+fun Wrap(
+ modifier: Modifier = Modifier.None,
+ minWidth: IntPx = 0.ipx,
+ minHeight: IntPx = 0.ipx,
+ children: @Composable() () -> Unit
+) {
+ Layout(modifier = modifier, children = children) { measurables, constraints, _ ->
val placeables = measurables.map { it.measure(constraints) }
val width = max(placeables.maxBy { it.width.value }?.width ?: 0.ipx, minWidth)
val height = max(placeables.maxBy { it.height.value }?.height ?: 0.ipx, minHeight)
@@ -2446,7 +2493,7 @@
onMaxPositionChanged: () -> Unit,
child: @Composable() () -> Unit
) {
- Layout(child, modifier) { measurables, constraints, _ ->
+ Layout(modifier = modifier, children = child) { measurables, constraints, _ ->
val childConstraints = constraints.copy(
maxHeight = constraints.maxHeight,
maxWidth = IntPx.Infinity
@@ -2462,8 +2509,12 @@
}
@Composable
-fun WrapForceRelayout(model: OffsetModel, children: @Composable() () -> Unit) {
- Layout(children) { measurables, constraints, _ ->
+fun WrapForceRelayout(
+ model: OffsetModel,
+ modifier: Modifier = Modifier.None,
+ children: @Composable() () -> Unit
+) {
+ Layout(modifier = modifier, children = children) { measurables, constraints, _ ->
val placeables = measurables.map { it.measure(constraints) }
val width = placeables.maxBy { it.width.value }?.width ?: 0.ipx
val height = placeables.maxBy { it.height.value }?.height ?: 0.ipx
@@ -2475,8 +2526,8 @@
}
@Composable
-fun SimpleRow(children: @Composable() () -> Unit) {
- Layout(children) { measurables, constraints, _ ->
+fun SimpleRow(modifier: Modifier = Modifier.None, children: @Composable() () -> Unit) {
+ Layout(modifier = modifier, children = children) { measurables, constraints, _ ->
var width = 0.ipx
var height = 0.ipx
val placeables = measurables.map {
@@ -2729,4 +2780,32 @@
fun DeprecatedDraw(onPaint: Density.(canvas: Canvas, parentSize: PxSize) -> Unit) {
@Suppress("DEPRECATION") // remove when b/147606015 is fixed
Draw(onPaint)
-}
\ No newline at end of file
+}
+
+fun scale(scale: Float) = LayoutScale(scale) + drawLayer(scaleX = scale, scaleY = scale)
+
+class LayoutScale(val scale: Float) : LayoutModifier {
+ override fun Density.modifyConstraints(
+ constraints: Constraints,
+ layoutDirection: LayoutDirection
+ ): Constraints {
+ return Constraints(
+ minWidth = constraints.minWidth / scale,
+ minHeight = constraints.minHeight / scale,
+ maxWidth = constraints.maxWidth / scale,
+ maxHeight = constraints.maxHeight / scale
+ )
+ }
+
+ override fun Density.modifySize(
+ constraints: Constraints,
+ layoutDirection: LayoutDirection,
+ childSize: IntPxSize
+ ): IntPxSize {
+ return IntPxSize(childSize.width * scale, childSize.height * scale)
+ }
+}
+
+fun latch(countDownLatch: CountDownLatch) = draw { _, _ ->
+ countDownLatch.countDown()
+}
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidViewCompatTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidViewCompatTest.kt
index 2209bce..a3bde5a 100644
--- a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidViewCompatTest.kt
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/AndroidViewCompatTest.kt
@@ -63,7 +63,7 @@
import org.junit.runners.JUnit4
/**
- * Corresponds to AndroidViewCompat.kt, testing the support for Android Views in Compose UI.
+ * Testing the support for Android Views in Compose UI.
*/
@SmallTest
@RunWith(JUnit4::class)
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/ClipTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/ClipTest.kt
index 1741f46..b5cf1da 100644
--- a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/ClipTest.kt
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/ClipTest.kt
@@ -18,18 +18,19 @@
import android.graphics.Bitmap
import android.os.Build
-import androidx.compose.Composable
-import androidx.compose.Untracked
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.test.rule.ActivityTestRule
-import androidx.ui.core.Clip
-import androidx.ui.core.Draw
+import androidx.ui.core.DrawClipToBounds
+import androidx.ui.core.Modifier
+import androidx.ui.core.draw
+import androidx.ui.core.drawClip
import androidx.ui.core.setContent
import androidx.ui.framework.test.TestActivity
import androidx.ui.geometry.RRect
import androidx.ui.geometry.Radius
import androidx.ui.geometry.Rect
+import androidx.ui.graphics.Canvas
import androidx.ui.graphics.Color
import androidx.ui.graphics.Outline
import androidx.ui.graphics.Paint
@@ -73,6 +74,17 @@
}
)
}
+ private val invertedTriangleShape = object : Shape {
+ override fun createOutline(size: PxSize, density: Density): Outline =
+ Outline.Generic(
+ Path().apply {
+ lineTo(size.width.value, 0f)
+ lineTo(size.width.value / 2f, size.height.value)
+ lineTo(0f, 0f)
+ close()
+ }
+ )
+ }
@Before
fun setup() {
@@ -86,12 +98,32 @@
fun simpleRectClip() {
rule.runOnUiThreadIR {
activity.setContent {
- FillColor(Color.Green)
- Padding(size = 10.ipx) {
- AtLeastSize(size = 10.ipx) {
- Clip(rectShape) {
- FillColor(Color.Cyan)
- }
+ Padding(size = 10.ipx, modifier = FillColor(Color.Green)) {
+ AtLeastSize(
+ size = 10.ipx,
+ modifier = drawClip(rectShape) + FillColor(Color.Cyan)
+ ) {
+ }
+ }
+ }
+ }
+
+ takeScreenShot(30).apply {
+ assertRect(Color.Cyan, size = 10)
+ assertRect(Color.Green, holeSize = 10)
+ }
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
+ fun simpleClipToBounds() {
+ rule.runOnUiThreadIR {
+ activity.setContent {
+ Padding(size = 10.ipx, modifier = FillColor(Color.Green)) {
+ AtLeastSize(
+ size = 10.ipx,
+ modifier = DrawClipToBounds + FillColor(Color.Cyan)
+ ) {
}
}
}
@@ -108,11 +140,11 @@
fun simpleRectClipWithModifiers() {
rule.runOnUiThreadIR {
activity.setContentInFrameLayout {
- FillColor(Color.Green)
- AtLeastSize(size = 10.ipx, modifier = PaddingModifier(10.ipx)) {
- Clip(rectShape) {
- FillColor(Color.Cyan)
- }
+ AtLeastSize(
+ size = 10.ipx,
+ modifier = FillColor(Color.Green) + PaddingModifier(10.ipx) +
+ drawClip(rectShape) + FillColor(Color.Cyan)
+ ) {
}
}
}
@@ -132,11 +164,10 @@
}
rule.runOnUiThreadIR {
activity.setContent {
- AtLeastSize(size = 30.ipx) {
- FillColor(Color.Green)
- Clip(shape) {
- FillColor(Color.Cyan)
- }
+ AtLeastSize(
+ size = 30.ipx,
+ modifier = FillColor(Color.Green) + drawClip(shape) + FillColor(Color.Cyan)
+ ) {
}
}
}
@@ -172,11 +203,9 @@
}
rule.runOnUiThreadIR {
activity.setContent {
- AtLeastSize(size = 30.ipx) {
- FillColor(Color.Green)
- Clip(shape) {
- FillColor(Color.Cyan)
- }
+ AtLeastSize(
+ size = 30.ipx,
+ modifier = FillColor(Color.Green) + drawClip(shape) + FillColor(Color.Cyan)) {
}
}
}
@@ -197,11 +226,10 @@
fun triangleClip() {
rule.runOnUiThreadIR {
activity.setContent {
- AtLeastSize(size = 30.ipx) {
- FillColor(Color.Green)
- Clip(triangleShape) {
- FillColor(Color.Cyan)
- }
+ AtLeastSize(
+ size = 30.ipx,
+ modifier = FillColor(Color.Green) + drawClip(triangleShape) +
+ FillColor(Color.Cyan)) {
}
}
}
@@ -229,11 +257,10 @@
}
rule.runOnUiThreadIR {
activity.setContent {
- AtLeastSize(size = 30.ipx) {
- FillColor(Color.Green)
- Clip(concaveShape) {
- FillColor(Color.Cyan)
- }
+ AtLeastSize(
+ size = 30.ipx,
+ modifier = FillColor(Color.Green) + drawClip(concaveShape) +
+ FillColor(Color.Cyan)) {
}
}
}
@@ -251,11 +278,10 @@
rule.runOnUiThreadIR {
activity.setContent {
- AtLeastSize(size = 30.ipx) {
- FillColor(Color.Green)
- Clip(model.value) {
- FillColor(Color.Cyan)
- }
+ AtLeastSize(
+ size = 30.ipx,
+ modifier = FillColor(Color.Green) + drawClip(model.value) +
+ FillColor(Color.Cyan)) {
}
}
}
@@ -287,11 +313,10 @@
rule.runOnUiThreadIR {
activity.setContent {
- FillColor(Color.Green)
- AtLeastSize(size = 30.ipx) {
- Clip(model.value) {
- FillColor(Color.Cyan)
- }
+ AtLeastSize(
+ size = 30.ipx,
+ modifier = FillColor(Color.Green) + drawClip(model.value) +
+ FillColor(Color.Cyan)) {
}
}
}
@@ -315,11 +340,10 @@
rule.runOnUiThreadIR {
activity.setContent {
- FillColor(Color.Green)
- AtLeastSize(size = 30.ipx) {
- Clip(model.value) {
- FillColor(Color.Cyan)
- }
+ AtLeastSize(
+ size = 30.ipx,
+ modifier = FillColor(Color.Green) + drawClip(model.value) +
+ FillColor(Color.Cyan)) {
}
}
}
@@ -338,19 +362,59 @@
@SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
@Test
+ fun switchBetweenDifferentPaths() {
+ val model = ValueModel<Shape>(triangleShape)
+ // to be replaced with a DrawModifier wrapped into remember, so the recomposition
+ // is not causing invalidation as the DrawModifier didn't change
+ val drawCallback: Density.(canvas: Canvas, parentSize: PxSize) -> Unit = { canvas, size ->
+ canvas.drawRect(
+ Rect(
+ -100f,
+ -100f,
+ size.width.value + 100f,
+ size.height.value + 100f
+ ), Paint().apply {
+ this.color = Color.Cyan
+ })
+ drawLatch.countDown()
+ }
+
+ rule.runOnUiThreadIR {
+ activity.setContent {
+ AtLeastSize(
+ size = 30.ipx,
+ modifier = background(Color.Green) + drawClip(model.value) + draw(drawCallback)
+ ) {
+ }
+ }
+ }
+
+ takeScreenShot(30).apply {
+ assertTriangle(Color.Cyan, Color.Green)
+ }
+
+ drawLatch = CountDownLatch(1)
+ rule.runOnUiThreadIR { model.value = invertedTriangleShape }
+
+ takeScreenShot(30).apply {
+ assertInvertedTriangle(Color.Cyan, Color.Green)
+ }
+ }
+
+ @SdkSuppress(minSdkVersion = Build.VERSION_CODES.O)
+ @Test
fun emitClipLater() {
val model = ValueModel(false)
rule.runOnUiThreadIR {
activity.setContent {
- FillColor(Color.Green)
- Padding(size = 10.ipx) {
- AtLeastSize(size = 10.ipx) {
- if (model.value) {
- Clip(rectShape) {
- FillColor(Color.Cyan)
- }
- }
+ Padding(size = 10.ipx, modifier = FillColor(Color.Green)) {
+ val modifier = if (model.value) {
+ drawClip(rectShape) + FillColor(Color.Cyan)
+ } else {
+ Modifier.None
+ }
+ AtLeastSize(size = 10.ipx, modifier = modifier) {
}
}
}
@@ -368,12 +432,8 @@
}
}
- // this should be converted to Modifier after LayerModifier are the thing
- @Composable
- private fun FillColor(color: Color) {
- @Suppress("DEPRECATION") // remove when b/147606015 is fixed
- // TODO(b/150390669): Review use of @Untracked
- Draw @Untracked { canvas, parentSize ->
+ private fun FillColor(color: Color): Modifier {
+ return draw { canvas, parentSize ->
canvas.drawRect(
Rect(
-100f,
@@ -416,6 +476,26 @@
assertColor(innerColor, center, 4)
}
+fun Bitmap.assertInvertedTriangle(innerColor: Color, outerColor: Color) {
+ Assert.assertEquals(width, height)
+ val center = (width - 1) / 2
+ val last = width - 1
+ // check center
+ assertColor(innerColor, center, center)
+ // check top corners
+ assertColor(outerColor, 0, 4)
+ assertColor(innerColor, 4, 4)
+ assertColor(outerColor, last, 4)
+ assertColor(innerColor, last - 4, 0)
+ // check bottom corners
+ assertColor(outerColor, 4, last - 4)
+ assertColor(outerColor, last - 4, last - 4)
+ // check bottom center
+ assertColor(outerColor, center - 4, last)
+ assertColor(outerColor, center + 4, last)
+ assertColor(innerColor, center, last - 4)
+}
+
fun Bitmap.assertColor(expectedColor: Color, x: Int, y: Int) {
val pixel = Color(getPixel(x, y))
assertColorsEqual(expectedColor, pixel) {
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/DrawShadowTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/DrawShadowTest.kt
index 49affdc..b03e6f0 100644
--- a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/DrawShadowTest.kt
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/DrawShadowTest.kt
@@ -24,10 +24,10 @@
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.test.rule.ActivityTestRule
-import androidx.ui.core.DrawShadow
-import androidx.ui.core.Opacity
+import androidx.ui.core.Modifier
import androidx.ui.core.RepaintBoundary
import androidx.ui.core.draw
+import androidx.ui.core.drawShadow
import androidx.ui.core.setContent
import androidx.ui.framework.test.TestActivity
import androidx.ui.graphics.Color
@@ -156,10 +156,10 @@
rule.runOnUiThreadIR {
activity.setContent {
AtLeastSize(size = 12.ipx, modifier = background(Color.White)) {
- Opacity(0.1f) {
- AtLeastSize(size = 10.ipx) {
- DrawShadow(rectShape, 4.dp)
- }
+ AtLeastSize(
+ size = 10.ipx,
+ modifier = drawShadow(rectShape, 4.dp, opacity = 0.5f)
+ ) {
}
}
}
@@ -171,8 +171,8 @@
// assert the shadow is still visible
assertNotEquals(shadowColor, Color.White)
// but the shadow is not as dark as it would be without opacity.
- // with full opacity it is around 0.85, with 10% opacity it is 0.98
- assertTrue(shadowColor.luminance() > 0.95f)
+ // with full opacity it is around 0.85, with 50% opacity it is 0.96
+ assertTrue(shadowColor.luminance() > 0.94f)
}
}
@@ -184,10 +184,12 @@
rule.runOnUiThreadIR {
activity.setContent {
AtLeastSize(size = 12.ipx, modifier = background(Color.White)) {
- AtLeastSize(size = 10.ipx) {
- if (model.value) {
- DrawShadow(rectShape, 8.dp)
- }
+ val shadow = if (model.value) {
+ drawShadow(rectShape, 8.dp)
+ } else {
+ Modifier.None
+ }
+ AtLeastSize(size = 10.ipx, modifier = shadow) {
}
}
}
@@ -207,8 +209,10 @@
@Composable
private fun ShadowContainer(elevation: State<Dp> = mutableStateOf(8.dp)) {
AtLeastSize(size = 12.ipx, modifier = background(Color.White)) {
- AtLeastSize(size = 10.ipx) {
- DrawShadow(rectShape, elevation.value)
+ AtLeastSize(
+ size = 10.ipx,
+ modifier = drawShadow(shape = rectShape, elevation = elevation.value)
+ ) {
}
}
}
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/OpacityTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/OpacityTest.kt
index 794b70a..303076b 100644
--- a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/OpacityTest.kt
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/OpacityTest.kt
@@ -23,16 +23,15 @@
import androidx.test.filters.SdkSuppress
import androidx.test.filters.SmallTest
import androidx.test.rule.ActivityTestRule
-import androidx.ui.core.Draw
import androidx.ui.core.Layout
-import androidx.ui.core.Opacity
+import androidx.ui.core.Modifier
+import androidx.ui.core.draw
+import androidx.ui.core.drawOpacity
import androidx.ui.core.setContent
import androidx.ui.framework.test.TestActivity
import androidx.ui.graphics.Color
-import androidx.ui.graphics.Paint
import androidx.ui.unit.ipx
import androidx.ui.unit.max
-import androidx.ui.unit.toRect
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
@@ -51,6 +50,7 @@
val rule = ActivityTestRule<TestActivity>(TestActivity::class.java)
private lateinit var activity: TestActivity
private lateinit var drawLatch: CountDownLatch
+ private val unlatch = draw { _, _ -> drawLatch.countDown() }
@Before
fun setup() {
@@ -65,11 +65,11 @@
val color = Color.LightGray
rule.runOnUiThreadIR {
activity.setContent {
- AtLeastSize(size = 10.ipx) {
- FillColor(Color.White)
- Opacity(opacity = 1f) {
- FillColor(color)
- }
+ AtLeastSize(size = 10.ipx,
+ modifier = background(Color.White) +
+ drawOpacity(1f) +
+ background(color) +
+ unlatch) {
}
}
}
@@ -85,11 +85,12 @@
val color = Color.LightGray
rule.runOnUiThreadIR {
activity.setContent {
- AtLeastSize(size = 10.ipx) {
- FillColor(Color.White)
- Opacity(opacity = 0f) {
- FillColor(color)
- }
+ AtLeastSize(size = 10.ipx,
+ modifier = background(Color.White) +
+ drawOpacity(0f) +
+ background(color) +
+ unlatch
+ ) {
}
}
}
@@ -105,15 +106,17 @@
val color = Color.Red
rule.runOnUiThreadIR {
activity.setContent {
- FillColor(Color.White)
- Row {
- AtLeastSize(size = 10.ipx) {
- Opacity(opacity = 0.5f) {
- FillColor(color)
- }
+ Row(background(Color.White)) {
+ AtLeastSize(size = 10.ipx,
+ modifier = background(Color.White) +
+ drawOpacity(0.5f) +
+ background(color) +
+ unlatch
+ ) {
}
- AtLeastSize(size = 10.ipx) {
- FillColor(color.copy(alpha = 0.5f))
+ AtLeastSize(size = 10.ipx,
+ modifier = background(color.copy(alpha = 0.5f))
+ ) {
}
}
}
@@ -132,17 +135,17 @@
rule.runOnUiThreadIR {
activity.setContent {
- AtLeastSize(size = 10.ipx) {
- FillColor(Color.White)
- Opacity(opacity = model.value) {
- FillColor(color)
- }
+ AtLeastSize(size = 10.ipx,
+ modifier = background(Color.White) +
+ drawOpacity(model.value) +
+ unlatch +
+ background(color)
+ ) {
}
}
}
assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
- drawLatch = CountDownLatch(1)
rule.runOnUiThreadIR {
model.value = 1f
}
@@ -160,19 +163,18 @@
rule.runOnUiThreadIR {
activity.setContent {
- AtLeastSize(size = 10.ipx) {
- FillColor(Color.White)
- Opacity(1f) {
- Opacity(opacity = opacity) {
- FillColor(color)
- }
- }
+ AtLeastSize(size = 10.ipx,
+ modifier = background(Color.White) +
+ drawOpacity(1f) +
+ drawOpacity(opacity) +
+ unlatch +
+ background(color)
+ ) {
}
}
}
assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
- drawLatch = CountDownLatch(1)
rule.runOnUiThreadIR {
opacity = 1f
}
@@ -189,13 +191,16 @@
rule.runOnUiThreadIR {
activity.setContent {
- AtLeastSize(size = 10.ipx) {
- FillColor(Color.White)
- if (model.value) {
- Opacity(opacity = 0f) {
- FillColor(Color.Green)
- }
- }
+ AtLeastSize(size = 10.ipx,
+ modifier = background(Color.White) +
+ if (model.value) {
+ drawOpacity(0f) +
+ background(Color.Green)
+ } else {
+ Modifier.None
+ } +
+ unlatch
+ ) {
}
}
}
@@ -211,18 +216,6 @@
}
}
- // this should be converted to Modifier after LayerModifier are the thing
- @Composable
- private fun FillColor(color: Color) {
- @Suppress("DEPRECATION") // remove when b/147606015 is fixed
- Draw { canvas, parentSize ->
- canvas.drawRect(parentSize.toRect(), Paint().apply {
- this.color = color
- })
- drawLatch.countDown()
- }
- }
-
private fun takeScreenShot(width: Int, height: Int = width): Bitmap {
assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
val bitmap = rule.waitAndScreenShot()
@@ -233,8 +226,8 @@
}
@Composable
-fun Row(children: @Composable() () -> Unit) {
- Layout(children) { measurables, constraints, _ ->
+fun Row(modifier: Modifier = Modifier.None, children: @Composable() () -> Unit) {
+ Layout(modifier = modifier, children = children) { measurables, constraints, _ ->
val placeables = measurables.map { it.measure(constraints) }
var width = 0.ipx
var height = 0.ipx
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/RtlLayoutTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/RtlLayoutTest.kt
new file mode 100644
index 0000000..8d40221
--- /dev/null
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/RtlLayoutTest.kt
@@ -0,0 +1,178 @@
+/*
+ * 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.ui.core.test
+
+import androidx.compose.Composable
+import androidx.test.filters.SmallTest
+import androidx.test.rule.ActivityTestRule
+import androidx.ui.core.Layout
+import androidx.ui.core.LayoutDirection
+import androidx.ui.core.LayoutModifier
+import androidx.ui.core.OnPositioned
+import androidx.ui.core.Ref
+import androidx.ui.core.setContent
+import androidx.ui.unit.Density
+import androidx.ui.unit.PxPosition
+import androidx.ui.unit.ipx
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+
+@SmallTest
+@RunWith(JUnit4::class)
+class RtlLayoutTest {
+ @get:Rule
+ val activityTestRule = ActivityTestRule<androidx.ui.framework.test.TestActivity>(
+ androidx.ui.framework.test.TestActivity::class.java
+ )
+ private lateinit var activity: androidx.ui.framework.test.TestActivity
+ internal lateinit var density: Density
+ internal lateinit var countDownLatch: CountDownLatch
+ internal lateinit var position: Array<Ref<PxPosition>>
+ private val size = 100.ipx
+
+ @Before
+ fun setup() {
+ activity = activityTestRule.activity
+ density = Density(activity)
+ activity.hasFocusLatch.await(5, TimeUnit.SECONDS)
+ position = Array(3) { Ref<PxPosition>() }
+ countDownLatch = CountDownLatch(3)
+ }
+
+ @Test
+ fun customLayout_absolutePositioning() = with(density) {
+ activityTestRule.runOnUiThreadIR {
+ activity.setContent {
+ CustomLayout(true, LayoutDirection.Ltr)
+ }
+ }
+
+ countDownLatch.await(1, TimeUnit.SECONDS)
+ Assert.assertEquals(PxPosition(0.ipx, 0.ipx), position[0].value)
+ Assert.assertEquals(PxPosition(size, size), position[1].value)
+ Assert.assertEquals(
+ PxPosition(size * 2, size * 2),
+ position[2].value
+ )
+ }
+
+ @Test
+ fun customLayout_absolutePositioning_rtl() = with(density) {
+ activityTestRule.runOnUiThreadIR {
+ activity.setContent {
+ CustomLayout(true, LayoutDirection.Rtl)
+ }
+ }
+
+ countDownLatch.await(1, TimeUnit.SECONDS)
+ Assert.assertEquals(PxPosition(0.ipx, 0.ipx), position[0].value)
+ Assert.assertEquals(PxPosition(size, size), position[1].value)
+ Assert.assertEquals(
+ PxPosition(size * 2, size * 2),
+ position[2].value
+ )
+ }
+
+ @Test
+ fun customLayout_positioning() = with(density) {
+ activityTestRule.runOnUiThreadIR {
+ activity.setContent {
+ CustomLayout(false, LayoutDirection.Ltr)
+ }
+ }
+
+ countDownLatch.await(1, TimeUnit.SECONDS)
+ Assert.assertEquals(PxPosition(0.ipx, 0.ipx), position[0].value)
+ Assert.assertEquals(PxPosition(size, size), position[1].value)
+ Assert.assertEquals(
+ PxPosition(size * 2, size * 2),
+ position[2].value
+ )
+ }
+
+ @Test
+ fun customLayout_positioning_rtl() = with(density) {
+ activityTestRule.runOnUiThreadIR {
+ activity.setContent {
+ CustomLayout(false, LayoutDirection.Rtl)
+ }
+ }
+
+ countDownLatch.await(1, TimeUnit.SECONDS)
+
+ countDownLatch.await(1, TimeUnit.SECONDS)
+ Assert.assertEquals(PxPosition(size * 2, 0.ipx), position[0].value)
+ Assert.assertEquals(PxPosition(size, size), position[1].value)
+ Assert.assertEquals(PxPosition(0.ipx, size * 2), position[2].value)
+ }
+
+ @Composable
+ private fun CustomLayout(
+ absolutePositioning: Boolean,
+ testLayoutDirection: LayoutDirection
+ ) {
+ val modifier = object : LayoutModifier {
+ override fun Density.modifyLayoutDirection(layoutDirection: LayoutDirection) =
+ testLayoutDirection
+ }
+ Layout(
+ children = @Composable {
+ FixedSize(size) {
+ SaveLayoutInfo(position[0], countDownLatch)
+ }
+ FixedSize(size) {
+ SaveLayoutInfo(position[1], countDownLatch)
+ }
+ FixedSize(size) {
+ SaveLayoutInfo(position[2], countDownLatch)
+ }
+ },
+ modifier = modifier
+ ) { measurables, constraints, _ ->
+ val placeables = measurables.map { it.measure(constraints) }
+ val width = placeables.fold(0.ipx) { sum, p -> sum + p.width }
+ val height = placeables.fold(0.ipx) { sum, p -> sum + p.height }
+ layout(width, height) {
+ var x = 0.ipx
+ var y = 0.ipx
+ for (placeable in placeables) {
+ if (absolutePositioning) {
+ placeable.placeAbsolute(PxPosition(x, y))
+ } else {
+ placeable.place(PxPosition(x, y))
+ }
+ x += placeable.width
+ y += placeable.height
+ }
+ }
+ }
+ }
+
+ @Composable
+ private fun SaveLayoutInfo(position: Ref<PxPosition>, countDownLatch: CountDownLatch) {
+ OnPositioned {
+ position.value = it.localToGlobal(PxPosition(0.ipx, 0.ipx))
+ countDownLatch.countDown()
+ }
+ }
+}
\ No newline at end of file
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/WithConstraintsTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/WithConstraintsTest.kt
index 369f534..e8152fa 100644
--- a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/WithConstraintsTest.kt
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/WithConstraintsTest.kt
@@ -27,10 +27,13 @@
import androidx.test.rule.ActivityTestRule
import androidx.ui.core.Constraints
import androidx.ui.core.Layout
+import androidx.ui.core.LayoutDirection
+import androidx.ui.core.LayoutModifier
import androidx.ui.core.MeasureBlock
import androidx.ui.core.Modifier
import androidx.ui.core.OnPositioned
import androidx.ui.core.Ref
+import androidx.ui.core.TextFieldDelegate.Companion.layout
import androidx.ui.core.WithConstraints
import androidx.ui.core.draw
import androidx.ui.core.setContent
@@ -38,8 +41,10 @@
import androidx.ui.graphics.Color
import androidx.ui.graphics.Paint
import androidx.ui.graphics.vector.DrawVector
+import androidx.ui.unit.Density
import androidx.ui.unit.IntPx
import androidx.ui.unit.IntPxSize
+import androidx.ui.unit.PxPosition
import androidx.ui.unit.ipx
import androidx.ui.unit.px
import androidx.ui.unit.toRect
@@ -85,13 +90,13 @@
val secondChildConstraints = Ref<Constraints>()
rule.runOnUiThreadIR {
activity.setContentInFrameLayout {
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
topConstraints.value = constraints
Padding(size = size) {
val drawModifier = draw { _, _ ->
countDownLatch.countDown()
}
- WithConstraints(drawModifier) { constraints ->
+ WithConstraints(drawModifier) { constraints, _ ->
paddedConstraints.value = constraints
Layout(measureBlock = { _, childConstraints, _ ->
firstChildConstraints.value = childConstraints
@@ -129,7 +134,7 @@
rule.runOnUiThreadIR {
activity.setContentInFrameLayout {
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
val outerModifier = draw { canvas, size ->
val paint = Paint()
paint.color = model.outerColor
@@ -214,7 +219,7 @@
rule.runOnUiThreadIR {
activity.setContent {
- WithConstraints {
+ WithConstraints { _, _ ->
// this block is called as a subcomposition from LayoutNode.measure()
// DrawVector introduces additional subcomposition which is closing the
// current frame and opens a new one. our model reads during measure()
@@ -246,7 +251,7 @@
rule.runOnUiThreadIR {
activity.setContentInFrameLayout {
- WithConstraints {
+ WithConstraints { _, _ ->
recompositionsCount1++
Container(100.ipx, 100.ipx) {
model.value // model read
@@ -274,7 +279,7 @@
rule.runOnUiThreadIR {
activity.setContentInFrameLayout {
ChangingConstraintsLayout(model) {
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
actualConstraints = constraints
assertEquals(1, latch.count)
latch.countDown()
@@ -304,7 +309,7 @@
rule.runOnUiThreadIR {
activity.setContentInFrameLayout {
Container(width = 200.ipx, height = 200.ipx) {
- WithConstraints {
+ WithConstraints { _, _ ->
OnPositioned {
// OnPositioned can be fired multiple times with the same value
// for example when requestLayout() was triggered on ComposeView.
@@ -355,7 +360,7 @@
activity.setContentInFrameLayout {
Container(100.ipx, 100.ipx, backgroundModifier(Color.Red)) {
ChangingConstraintsLayout(model) {
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
Container(100.ipx, 100.ipx) {
Container(100.ipx, 100.ipx) {
Layout(
@@ -394,7 +399,7 @@
rule.runOnUiThread {
activity.setContentInFrameLayout {
Container(width = 100.ipx, height = 100.ipx) {
- WithConstraints {
+ WithConstraints { _, _ ->
// this replicates the popular pattern we currently use
// where we save some data calculated in the measuring block
// and then use it in the next composition frame
@@ -431,7 +436,7 @@
// this component changes the constraints which triggers subcomposition
// within onMeasure block
ChangingConstraintsLayout(model) {
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
if (constraints.maxWidth == 100.ipx) {
// we will stop emmitting this layouts after constraints change
// Additional Container is needed so the Layout will be
@@ -492,7 +497,7 @@
}
layout(100.ipx, 100.ipx) {}
}
- WithConstraints {}
+ WithConstraints { _, _ -> }
}
}
assertTrue(drawlatch.await(1, TimeUnit.SECONDS))
@@ -511,7 +516,7 @@
assertEquals(1, outerComposeLatch.count)
outerComposeLatch.countDown()
Layout(children = {
- WithConstraints {
+ WithConstraints { _, _ ->
assertEquals(1, innerComposeLatch.count)
innerComposeLatch.countDown()
Layout(children = emptyContent()) { _, _, _ ->
@@ -548,7 +553,7 @@
activity.setContent {
val state = state { 0 }
ContainerChildrenAffectsParentSize(100.ipx, 100.ipx) {
- WithConstraints {
+ WithConstraints { _, _ ->
Layout(
children = {},
modifier = countdownLatchBackgroundModifier(Color.Transparent)
@@ -561,7 +566,7 @@
}
}
Container(100.ipx, 100.ipx) {
- WithConstraints {}
+ WithConstraints { _, _ -> }
}
}
}
@@ -572,6 +577,63 @@
// so nothing else to assert, apart from not crashing
}
+ @Test
+ fun withConstraints_getsCorrectLayoutDirection() {
+ var latch = CountDownLatch(1)
+ var resultLayoutDirection: LayoutDirection? = null
+ rule.runOnUiThreadIR {
+ activity.setContent {
+ Layout(
+ children = @Composable {
+ WithConstraints { _, layoutDirection ->
+ resultLayoutDirection = layoutDirection
+ }
+ },
+ modifier = layoutDirectionModifier(LayoutDirection.Rtl)
+ ) { m, c, _ ->
+ val p = m.first().measure(c)
+ layout(0.ipx, 0.ipx) {
+ p.place(PxPosition.Origin)
+ latch.countDown()
+ }
+ }
+ }
+ }
+
+ assertTrue(latch.await(1, TimeUnit.SECONDS))
+ assertEquals(LayoutDirection.Rtl, resultLayoutDirection)
+ }
+
+ @Test
+ fun withConstraints_layoutDirectionSetByModifier() {
+ var latch = CountDownLatch(1)
+ var resultLayoutDirection: LayoutDirection? = null
+ rule.runOnUiThreadIR {
+ activity.setContent {
+ Layout(
+ children = @Composable {
+ WithConstraints(
+ modifier = layoutDirectionModifier(LayoutDirection.Rtl)
+ ) { _, layoutDirection ->
+ resultLayoutDirection = layoutDirection
+ latch.countDown()
+ }
+ },
+ modifier = layoutDirectionModifier(LayoutDirection.Ltr)
+ ) { m, c, _ ->
+ val p = m.first().measure(c)
+ layout(0.ipx, 0.ipx) {
+ p.place(PxPosition.Origin)
+ latch.countDown()
+ }
+ }
+ }
+ }
+
+ assertTrue(latch.await(1, TimeUnit.SECONDS))
+ assertEquals(LayoutDirection.Rtl, resultLayoutDirection)
+ }
+
private fun takeScreenShot(size: Int): Bitmap {
assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
val bitmap = rule.waitAndScreenShot()
@@ -587,12 +649,16 @@
canvas.drawRect(size.toRect(), paint)
drawLatch.countDown()
}
+
+ private fun layoutDirectionModifier(ld: LayoutDirection) = object : LayoutModifier {
+ override fun Density.modifyLayoutDirection(layoutDirection: LayoutDirection) = ld
+ }
}
@Composable
private fun TestLayout(@Suppress("UNUSED_PARAMETER") someInput: Int) {
Layout(children = {
- WithConstraints {
+ WithConstraints { _, _ ->
NeedsOtherMeasurementComposable(10.ipx)
}
}) { measurables, constraints, _ ->
diff --git a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/WrapperTest.kt b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/WrapperTest.kt
index 7d470cf..8360f75 100644
--- a/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/WrapperTest.kt
+++ b/ui/ui-framework/src/androidTest/java/androidx/ui/core/test/WrapperTest.kt
@@ -21,8 +21,8 @@
import androidx.compose.Recompose
import androidx.compose.onActive
import androidx.compose.onCommit
-import androidx.compose.setViewContent
import androidx.ui.core.ComposeView
+import androidx.ui.core.setViewContent
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Before
diff --git a/ui/ui-framework/src/main/java/androidx/compose/Compose.kt b/ui/ui-framework/src/main/java/androidx/compose/Compose.kt
new file mode 100644
index 0000000..ee6f62e
--- /dev/null
+++ b/ui/ui-framework/src/main/java/androidx/compose/Compose.kt
@@ -0,0 +1,144 @@
+/*
+ * 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.compose
+
+import android.content.Context
+import android.view.ViewGroup
+import androidx.annotation.MainThread
+import androidx.ui.core.ComponentNode
+import androidx.ui.core.UiComposition
+import androidx.ui.core.findComposition
+import androidx.ui.core.setViewContent
+
+object Compose {
+ /**
+ * This method is the way to initiate a composition. The [composable] passed in will be executed
+ * to compose the children of the passed in [container]. Optionally, a [parent]
+ * [CompositionReference] can be provided to make the composition behave as a sub-composition of
+ * the parent. The children of [container] will be updated and maintained by the time this
+ * method returns.
+ *
+ * It is important to call [Composition.dispose] whenever this view is no longer needed in order
+ * to release resources.
+ *
+ * @param container The view whose children is being composed.
+ * @param parent The parent composition reference, if applicable. Default is null.
+ * @param composable The composable function intended to compose the children of [container].
+ *
+ * @see Composition.dispose
+ * @see Composable
+ */
+ @MainThread
+ @Deprecated(
+ "use setContent",
+ replaceWith = ReplaceWith("ViewGroup#setContent")
+ )
+ fun composeInto(
+ container: ViewGroup,
+ parent: CompositionReference? = null,
+ composable: @Composable() () -> Unit
+ ): Composition = container.setViewContent(parent, composable)
+
+ /**
+ * Disposes any composition previously run with [container] as the root. This will
+ * release any resources that have been built around the composition, including all [onDispose]
+ * callbacks that have been registered with [CompositionLifecycleObserver] objects.
+ *
+ * It is important to call this for any [composeInto] call that is made, or else you may have
+ * memory leaks in your application.
+ *
+ * @param container The view that was passed into [composeInto] as the root container of the composition
+ * @param parent The parent composition reference, if applicable.
+ *
+ * @see composeInto
+ * @see CompositionLifecycleObserver
+ */
+ @Suppress("UNUSED_PARAMETER")
+ @MainThread
+ @Deprecated(
+ "disposing should be done with the Composition object returned by setContent",
+ replaceWith = ReplaceWith("Composition#dispose()")
+ )
+ fun disposeComposition(container: ViewGroup, parent: CompositionReference? = null) {
+ findComposition(container)?.dispose()
+ }
+
+ /**
+ * This method is the way to initiate a composition. The [composable] passed in will be executed
+ * to compose the children of the passed in [container]. Optionally, a [parent]
+ * [CompositionReference] can be provided to make the composition behave as a sub-composition of
+ * the parent. The children of [container] will be updated and maintained by the time this
+ * method returns.
+ *
+ * It is important to call [Composition.dispose] whenever this view is no longer needed in order
+ * to release resources.
+ *
+ * @param container The emittable whose children is being composed.
+ * @param context The android [Context] to associate with this composition.
+ * @param parent The parent composition reference, if applicable. Default is null.
+ * @param composable The composable function intended to compose the children of [container].
+ *
+ * @see Composition.dispose
+ * @see Composable
+ */
+ @MainThread
+ @Deprecated(
+ "use setContent",
+ replaceWith = ReplaceWith("ViewGroup#setContent")
+ )
+ fun composeInto(
+ container: ComponentNode,
+ context: Context,
+ parent: CompositionReference? = null,
+ composable: @Composable() () -> Unit
+ ): Composition {
+ val composition = findComposition(container)
+ ?: UiComposition(container, context, parent)
+ composition.compose(composable)
+ return composition
+ }
+
+ /**
+ * Disposes any composition previously run with [container] as the root. This will
+ * release any resources that have been built around the composition, including all [onDispose]
+ * callbacks that have been registered with [CompositionLifecycleObserver] objects.
+ *
+ * It is important to call this for any [composeInto] call that is made, or else you may have
+ * memory leaks in your application.
+ *
+ * @param container The view that was passed into [composeInto] as the root container of the composition
+ * @param context The android [Context] associated with the composition
+ * @param parent The parent composition reference, if applicable.
+ *
+ * @see composeInto
+ * @see CompositionLifecycleObserver
+ */
+ @MainThread
+ @Suppress("UNUSED_PARAMETER")
+ @Deprecated(
+ "disposing should be done with the Composition object returned by setContent",
+ replaceWith = ReplaceWith("Composition#dispose()")
+ )
+ fun disposeComposition(
+ container: ComponentNode,
+ context: Context,
+ parent: CompositionReference? = null
+ ) {
+ // temporary easy way to call correct lifecycles on everything
+ findComposition(container)?.dispose()
+ }
+}
\ No newline at end of file
diff --git a/ui/ui-framework/src/main/java/androidx/compose/ComposerCompat.kt b/ui/ui-framework/src/main/java/androidx/compose/ComposerCompat.kt
new file mode 100644
index 0000000..417a99e
--- /dev/null
+++ b/ui/ui-framework/src/main/java/androidx/compose/ComposerCompat.kt
@@ -0,0 +1,32 @@
+/*
+ * 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.compose
+
+import androidx.ui.node.UiComposer
+
+// NOTE(lmr): This API is no longer needed in any way by the compiler, but we still need this API
+// to be here to support versions of Android Studio that are still looking for it. Without it,
+// valid composable code will look broken in the IDE. Remove this after we have left some time to
+// get all versions of Studio upgraded.
+@Deprecated(
+ "This property should not be called directly. It is only used by the compiler.",
+ replaceWith = ReplaceWith("currentComposer")
+)
+val composer: UiComposer
+ get() = error(
+ "This property should not be called directly. It is only used by the compiler."
+ )
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/AndroidViewCompat.kt b/ui/ui-framework/src/main/java/androidx/ui/core/AndroidViewCompat.kt
deleted file mode 100644
index 0d5d82e..0000000
--- a/ui/ui-framework/src/main/java/androidx/ui/core/AndroidViewCompat.kt
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * 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.ui.core
-
-import android.view.View
-import android.view.ViewGroup.LayoutParams.MATCH_PARENT
-import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
-import androidx.ui.unit.IntPx
-import androidx.ui.unit.ipx
-import androidx.ui.unit.isFinite
-
-/**
- * Adapter from [View] to [ComponentNode].
- */
-internal val AndroidViewAdapter: (Any, Any) -> Any? = { parent, child ->
- if (parent is ComponentNode) {
- (child as? View)?.toComponentNode()
- } else {
- null
- }
-}
-
-/**
- * Builds a [ComponentNode] tree representation for an Android [View].
- * The component nodes will proxy the Compose core calls to the [View].
- */
-private fun View.toComponentNode(): ComponentNode {
- // TODO(soboleva): add layout direction here?
- // TODO(popam): forward pointer input, accessibility, focus
- // Prepare layout node that proxies measure and layout passes to the View.
- val layoutNode = LayoutNode()
- layoutNode.modifier = draw { canvas, _ ->
- draw(canvas.nativeCanvas)
- }
- layoutNode.onAttach = { owner ->
- (owner as? AndroidOwner)?.addAndroidView(this, layoutNode)
- }
- layoutNode.onDetach = { owner ->
- (owner as? AndroidOwner)?.removeAndroidView(this)
- }
- layoutNode.measureBlocks = object : LayoutNode.NoIntrinsicsMeasureBlocks(
- "Intrinsics not supported for Android views"
- ) {
- override fun measure(
- measureScope: MeasureScope,
- measurables: List<Measurable>,
- constraints: Constraints,
- layoutDirection: LayoutDirection
- ): MeasureScope.LayoutResult {
- if (constraints.minWidth != 0.ipx) {
- minimumWidth = constraints.minWidth.value
- }
- if (constraints.minHeight != 0.ipx) {
- minimumHeight = constraints.minHeight.value
- }
- // TODO (soboleva): native view should get LD value from Compose?
- measure(
- obtainMeasureSpec(constraints.minWidth, constraints.maxWidth, layoutParams.width),
- obtainMeasureSpec(constraints.minHeight, constraints.maxHeight, layoutParams.height)
- )
- return measureScope.layout(measuredWidth.ipx, measuredHeight.ipx) {
- layout(
- 0,
- 0,
- measuredWidth,
- measuredHeight
- )
- }
- }
- }
- return layoutNode
-}
-
-/**
- * Intersects [Constraints] and [View] LayoutParams to obtain the suitable [View.MeasureSpec]
- * for measuring the [View].
- */
-private fun obtainMeasureSpec(
- min: IntPx,
- max: IntPx,
- preferred: Int
-): Int = when {
- preferred >= 0 || min == max -> {
- // Fixed size due to fixed size layout param or fixed constraints.
- View.MeasureSpec.makeMeasureSpec(
- preferred.coerceIn(min.value, max.value),
- View.MeasureSpec.EXACTLY
- )
- }
- preferred == WRAP_CONTENT && max.isFinite() -> {
- // Wrap content layout param with finite max constraint. If max constraint is infinite,
- // we will measure the child with UNSPECIFIED.
- View.MeasureSpec.makeMeasureSpec(max.value, View.MeasureSpec.AT_MOST)
- }
- preferred == MATCH_PARENT && max.isFinite() -> {
- // Match parent layout param, so we force the child to fill the available space.
- View.MeasureSpec.makeMeasureSpec(max.value, View.MeasureSpec.EXACTLY)
- }
- else -> {
- // max constraint is infinite and layout param is WRAP_CONTENT or MATCH_PARENT.
- View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
- }
-}
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/Clip.kt b/ui/ui-framework/src/main/java/androidx/ui/core/Clip.kt
index 7e44c01..72e3ee0 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/Clip.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/Clip.kt
@@ -16,17 +16,15 @@
package androidx.ui.core
-import androidx.compose.Composable
import androidx.ui.graphics.Shape
/**
- * Clips the children with the provided shape.
- *
- * @param shape the [Shape] used for clipping.
+ * Clips the content to the bounds of the layer.
*/
-@Composable
-inline fun Clip(shape: Shape, crossinline children: @Composable() () -> Unit) {
- RepaintBoundaryNode(name = null, shape = shape, clipToShape = true) {
- children()
- }
-}
\ No newline at end of file
+val DrawClipToBounds: Modifier = drawLayer(clipToBounds = true)
+
+/**
+ * Clips the content to [shape].
+ */
+fun drawClip(shape: Shape): Modifier =
+ drawLayer(clipToBounds = false, clipToOutline = true, outlineShape = shape)
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/DrawShadow.kt b/ui/ui-framework/src/main/java/androidx/ui/core/DrawShadow.kt
index 241f677..ba42bd6 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/DrawShadow.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/DrawShadow.kt
@@ -16,13 +16,14 @@
package androidx.ui.core
+import androidx.annotation.FloatRange
import androidx.compose.Composable
import androidx.ui.graphics.Shape
import androidx.ui.unit.Dp
/**
- * Draws the shadow. The [elevation] defines the visual dept of the physical object.
- * The physical object has a shape specified by [shape].
+ * Creates a [DrawLayerModifier] that draws the shadow. The [elevation] defines the visual depth of
+ * the physical object. The physical object has a shape specified by [shape].
*
* Example usage:
*
@@ -30,9 +31,23 @@
*
* @param elevation The z-coordinate at which to place this physical object.
* @param shape Defines a shape of the physical object
+ * @param clipToOutline When active, the content drawing clips to the outline.
+ * @param opacity The opacity of the layer, including the shadow.
*/
@Composable
-@Suppress("NOTHING_TO_INLINE")
-inline fun DrawShadow(shape: Shape, elevation: Dp) {
- RepaintBoundaryNode(name = null, shape = shape, elevation = elevation)
+fun drawShadow(
+ shape: Shape,
+ elevation: Dp,
+ clipToOutline: Boolean = true,
+ @FloatRange(from = 0.0, to = 1.0) opacity: Float = 1f
+): Modifier {
+ with(DensityAmbient.current) {
+ return drawLayer(
+ outlineShape = shape,
+ elevation = elevation.toPx().value,
+ clipToOutline = clipToOutline,
+ alpha = opacity,
+ clipToBounds = false
+ )
+ }
}
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/Layout.kt b/ui/ui-framework/src/main/java/androidx/ui/core/Layout.kt
index be945ab..93a8d13 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/Layout.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/Layout.kt
@@ -18,9 +18,9 @@
import android.content.Context
import androidx.compose.Composable
-import androidx.compose.Compose
import androidx.compose.CompositionReference
import androidx.compose.FrameManager
+import androidx.compose.Untracked
import androidx.compose.compositionReference
import androidx.compose.emptyContent
import androidx.compose.remember
@@ -458,7 +458,7 @@
@Composable
fun WithConstraints(
modifier: Modifier = Modifier.None,
- children: @Composable() (Constraints) -> Unit
+ children: @Composable() (Constraints, LayoutDirection) -> Unit
) {
val state = remember { WithConstrainsState() }
state.children = children
@@ -485,7 +485,7 @@
var context: Context? = null
val nodeRef = Ref<LayoutNode>()
var lastConstraints: Constraints? = null
- var children: @Composable() (Constraints) -> Unit = {}
+ var children: @Composable() (Constraints, LayoutDirection) -> Unit = { _, _ -> }
var forceRecompose = false
val measureBlocks = object : LayoutNode.NoIntrinsicsMeasureBlocks(
error = "Intrinsic measurements are not supported by WithConstraints"
@@ -528,8 +528,9 @@
fun subcompose() {
val node = nodeRef.value!!
val constraints = lastConstraints!!
- Compose.subcomposeInto(node, context!!, compositionRef) {
- children(constraints)
+ // TODO(b/150390669): Review use of @Untracked
+ subcomposeInto(node, context!!, compositionRef) @Untracked {
+ children(constraints, node.layoutDirection!!)
}
forceRecompose = false
}
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/Opacity.kt b/ui/ui-framework/src/main/java/androidx/ui/core/Opacity.kt
index 052ab0d..3891d92 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/Opacity.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/Opacity.kt
@@ -17,7 +17,6 @@
package androidx.ui.core
import androidx.annotation.FloatRange
-import androidx.compose.Composable
/**
* Makes its children partially transparent.
@@ -28,12 +27,7 @@
*
* @param opacity the fraction of children's alpha value.
*/
-@Composable
-inline fun Opacity(
- @FloatRange(from = 0.0, to = 1.0) opacity: Float,
- crossinline children: @Composable() () -> Unit
-) {
- RepaintBoundaryNode(name = null, opacity = opacity) {
- children()
- }
-}
\ No newline at end of file
+fun drawOpacity(
+ @FloatRange(from = 0.0, to = 1.0) opacity: Float
+): Modifier =
+ drawLayer(alpha = opacity)
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/Popup.kt b/ui/ui-framework/src/main/java/androidx/ui/core/Popup.kt
index 9f9bf9d..1cbec58 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/Popup.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/Popup.kt
@@ -27,10 +27,10 @@
import android.widget.FrameLayout
import androidx.compose.Composable
import androidx.compose.Compose
+import androidx.compose.Composition
import androidx.compose.Immutable
import androidx.compose.Providers
import androidx.compose.ambientOf
-import androidx.compose.disposeComposition
import androidx.compose.escapeCompose
import androidx.compose.onCommit
import androidx.compose.onDispose
@@ -152,6 +152,8 @@
}
popupLayout.calculatePopupPosition = calculatePopupPosition
+ var composition: Composition? = null
+
// Get the parent's global position and size
OnPositioned { coordinates ->
// Get the global position of the parent
@@ -166,7 +168,7 @@
}
onCommit {
- popupLayout.setContent {
+ composition = popupLayout.setContent {
OnChildPositioned({
// Get the size of the content
popupLayout.popupPositionProperties.childrenSize = it.size.toPxSize()
@@ -178,7 +180,7 @@
}
onDispose {
- popupLayout.disposeComposition()
+ composition?.dispose()
// Remove the window
popupLayout.dismiss()
}
@@ -404,12 +406,17 @@
/**
* Disposes the root view of the Activity.
*/
+@Deprecated(
+ "disposing should be done with the Composition object returned by setContent",
+ replaceWith = ReplaceWith("Composition#dispose()")
+)
fun disposeActivityComposition(activity: Activity) {
val composeView = activity.window.decorView
.findViewById<ViewGroup>(android.R.id.content)
.getChildAt(0) as? AndroidComposeView
?: error("No root view found")
+ @Suppress("DEPRECATION")
Compose.disposeComposition(composeView.root, activity, null)
}
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/Wrapper.kt b/ui/ui-framework/src/main/java/androidx/ui/core/Wrapper.kt
index 854e6db..2141e17 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/Wrapper.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/Wrapper.kt
@@ -15,23 +15,26 @@
*/
package androidx.ui.core
+import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.res.Configuration
+import android.view.View
import android.view.ViewGroup
+import android.widget.FrameLayout
import androidx.animation.AnimationClockObservable
-import androidx.animation.DefaultAnimationClock
+import androidx.animation.rootAnimationClockFactory
+import androidx.annotation.MainThread
import androidx.ui.core.input.FocusManager
import androidx.ui.input.TextInputService
import androidx.compose.Composable
-import androidx.compose.Compose
import androidx.compose.Composition
import androidx.compose.CompositionReference
import androidx.compose.FrameManager
import androidx.compose.Observe
import androidx.compose.Providers
import androidx.compose.StructurallyEqual
-import androidx.compose.ViewComposer
+import androidx.compose.Untracked
import androidx.compose.ambientOf
import androidx.compose.compositionReference
import androidx.compose.currentComposer
@@ -43,11 +46,228 @@
import androidx.ui.autofill.AutofillTree
import androidx.ui.core.hapticfeedback.HapticFeedback
import androidx.ui.core.selection.SelectionContainer
+import androidx.ui.node.UiComposer
import androidx.ui.text.font.Font
import androidx.ui.unit.Density
import kotlinx.coroutines.Dispatchers
+import org.jetbrains.annotations.TestOnly
+import java.util.WeakHashMap
import kotlin.coroutines.CoroutineContext
+private val TAG_COMPOSITION = "androidx.compose.Composition".hashCode()
+private val ROOT_COMPONENTNODES = WeakHashMap<ComponentNode, Composition>()
+private val ROOT_VIEWGROUPS = WeakHashMap<ViewGroup, Composition>()
+
+/**
+ * Apply Code Changes will invoke the two functions before and after a code swap.
+ *
+ * This forces the whole view hierarchy to be redrawn to invoke any code change that was
+ * introduce in the code swap.
+ *
+ * All these are private as within JVMTI / JNI accessibility is mostly a formality.
+ */
+// NOTE(lmr): right now, this class only takes into account Emittables and Views composed using
+// compose. In reality, there might be more (ie, Vectors), and we should figure out a more
+// holistic way to capture those as well.
+private class HotReloader {
+ companion object {
+ private var compositions = mutableListOf<Pair<Composition, @Composable() () -> Unit>>()
+
+ @TestOnly
+ fun clearRoots() {
+ ROOT_COMPONENTNODES.clear()
+ ROOT_VIEWGROUPS.clear()
+ }
+
+ // Called before Dex Code Swap
+ @Suppress("UNUSED_PARAMETER")
+ private fun saveStateAndDispose(context: Any) {
+ compositions.clear()
+
+ val componentNodes = ROOT_COMPONENTNODES.entries.toSet()
+
+ for ((_, composition) in componentNodes) {
+ compositions.add(composition to composition.composable)
+ }
+ for ((_, composition) in componentNodes) {
+ if (composition.isRoot) {
+ composition.dispose()
+ }
+ }
+
+ val viewRoots = ROOT_VIEWGROUPS.entries.toSet()
+
+ for ((_, composition) in viewRoots) {
+ compositions.add(composition to composition.composable)
+ }
+ for ((_, composition) in viewRoots) {
+ if (composition.isRoot) {
+ composition.dispose()
+ }
+ }
+ }
+
+ // Called after Dex Code Swap
+ @Suppress("UNUSED_PARAMETER")
+ private fun loadStateAndCompose(context: Any) {
+ for ((composition, composable) in compositions) {
+ composition.composable = composable
+ }
+
+ for ((composition, composable) in compositions) {
+ if (composition.isRoot) {
+ composition.compose(composable)
+ }
+ }
+
+ compositions.clear()
+ }
+
+ @TestOnly
+ internal fun simulateHotReload(context: Any) {
+ saveStateAndDispose(context)
+ loadStateAndCompose(context)
+ }
+ }
+}
+
+/**
+ * @suppress
+ */
+@TestOnly
+fun simulateHotReload(context: Any) = HotReloader.simulateHotReload(context)
+
+/**
+ * @suppress
+ */
+@TestOnly
+fun clearRoots() = HotReloader.clearRoots()
+
+internal fun findComposition(view: View): Composition? {
+ return view.getTag(TAG_COMPOSITION) as? Composition
+}
+
+internal fun storeComposition(view: View, composition: Composition) {
+ view.setTag(TAG_COMPOSITION, composition)
+ if (view is ViewGroup)
+ ROOT_VIEWGROUPS[view] = composition
+}
+
+internal fun removeRoot(view: View) {
+ view.setTag(TAG_COMPOSITION, null)
+ if (view is ViewGroup)
+ ROOT_VIEWGROUPS.remove(view)
+}
+
+internal fun findComposition(node: ComponentNode): Composition? {
+ return ROOT_COMPONENTNODES[node]
+}
+
+private fun storeComposition(node: ComponentNode, composition: Composition) {
+ ROOT_COMPONENTNODES[node] = composition
+}
+
+/**
+ * Composes the children of the view with the passed in [composable].
+ *
+ * @see setViewContent
+ * @see Composition.dispose
+ */
+// TODO: Remove this API when View/ComponentNode mixed trees work
+fun ViewGroup.setViewContent(
+ parent: CompositionReference? = null,
+ composable: @Composable() () -> Unit
+): Composition {
+ val composition = findComposition(this)
+ ?: UiComposition(this, context, parent).also {
+ removeAllViews()
+ }
+ composition.compose(composable)
+ return composition
+}
+
+/**
+ * Sets the contentView of an activity to a FrameLayout, and composes the contents of the layout
+ * with the passed in [composable].
+ *
+ * @see setContent
+ * @see Activity.setContentView
+ */
+// TODO: Remove this API when View/ComponentNode mixed trees work
+fun Activity.setViewContent(composable: @Composable() () -> Unit): Composition {
+ // TODO(lmr): add ambients here, or remove API entirely if we can
+ // If there is already a FrameLayout in the root, we assume we want to compose
+ // into it instead of create a new one. This allows for `setContent` to be
+ // called multiple times.
+ val root = window
+ .decorView
+ .findViewById<ViewGroup>(android.R.id.content)
+ .getChildAt(0) as? ViewGroup
+ ?: FrameLayout(this).also { setContentView(it) }
+ return root.setViewContent(null, composable)
+}
+
+/**
+ * @suppress
+ */
+@TestOnly
+fun makeCompositionForTesting(
+ root: Any,
+ context: Context,
+ parent: CompositionReference? = null
+): Composition = UiComposition(
+ root,
+ context,
+ parent
+)
+
+internal class UiComposition(
+ private val root: Any,
+ private val context: Context,
+ parent: CompositionReference? = null
+) : Composition(
+ { slots, recomposer ->
+ UiComposer(
+ context,
+ root,
+ slots,
+ recomposer
+ )
+ },
+ parent
+) {
+ init {
+ when (root) {
+ is ViewGroup -> storeComposition(root, this)
+ is ComponentNode -> storeComposition(root, this)
+ }
+ }
+
+ override fun dispose() {
+ super.dispose()
+ when (root) {
+ is ViewGroup -> removeRoot(root)
+ is ComponentNode -> ROOT_COMPONENTNODES.remove(root)
+ }
+ }
+}
+
+// TODO(chuckj): This is a temporary work-around until subframes exist so that
+// nextFrame() inside recompose() doesn't really start a new frame, but a new subframe
+// instead.
+@MainThread
+fun subcomposeInto(
+ container: ComponentNode,
+ context: Context,
+ parent: CompositionReference? = null,
+ composable: @Composable() () -> Unit
+): Composition {
+ val composition = findComposition(container)
+ ?: UiComposition(container, context, parent)
+ composition.compose(composable)
+ return composition
+}
+
/**
* Composes a view containing ui composables into a view composition.
* <p>
@@ -75,26 +295,26 @@
// `cc.recomposeSync()` which will only recompose the invalidations in the child context,
// which means it *will not* call `children()` again if it doesn't have to.
Observe {
+ mapOf(123 to 234)
reference = compositionReference()
cc?.recomposeSync()
onPreCommit(true) {
onDispose {
- rootRef.value?.let {
- val layoutRootNode = it.root
- val context = it.context
- Compose.disposeComposition(layoutRootNode, context)
- }
+ cc?.dispose()
}
}
}
val rootLayoutNode = rootRef.value?.root ?: error("Failed to create root platform view")
- val context = rootRef.value?.context ?: (currentComposer as ViewComposer).context
+ val context = rootRef.value?.context ?: (currentComposer as UiComposer).context
// If this value is inlined where it is used, an error that includes 'Precise Reference:
// kotlinx.coroutines.Dispatchers' not instance of 'Precise Reference: androidx.compose.Ambient'.
val coroutineContext = Dispatchers.Main
- cc =
- Compose.composeInto(container = rootLayoutNode, context = context, parent = reference) {
+ cc = subcomposeInto(
+ container = rootLayoutNode,
+ context = context,
+ parent = reference
+ ) @Untracked {
WrapWithAmbients(rootRef.value!!, context, coroutineContext, children)
}
}
@@ -115,10 +335,48 @@
.getChildAt(0) as? AndroidComposeView
?: AndroidComposeView(this).also { setContentView(it) }
+ // TODO(lmr): setup lifecycle-based dispose since we have Activity here
+
return doSetContent(composeView, this, content)
}
/**
+ * Disposes of a composition of the children of this view. This is a convenience method around
+ * [Composition.dispose].
+ *
+ * @see Composition.dispose
+ * @see setContent
+ */
+@Deprecated(
+ "disposing should be done with the Composition object returned by setContent",
+ replaceWith = ReplaceWith("Composition#dispose()")
+)
+fun ViewGroup.disposeComposition() {
+ findComposition(this)?.dispose()
+}
+
+/**
+ * Disposes of a composition that was started using [setContent]. This is a convenience method
+ * around [Composition.dispose].
+ *
+ * @see setContent
+ * @see Composition.dispose
+ */
+@Deprecated(
+ "disposing should be done with the Composition object returned by setContent",
+ replaceWith = ReplaceWith("Composition#dispose()")
+)
+fun Activity.disposeComposition() {
+ val view = window
+ .decorView
+ .findViewById<ViewGroup>(android.R.id.content)
+ .getChildAt(0) as? ViewGroup
+ ?: error("No root view found")
+ val composition = findComposition(view) ?: error("No composition found")
+ composition.dispose()
+}
+
+/**
* We want text/image selection to be enabled by default and disabled per widget. Therefore a root
* level [SelectionContainer] is installed at the root.
*/
@@ -145,14 +403,18 @@
composeView: AndroidComposeView,
context: Context,
content: @Composable() () -> Unit
-): Composition = Compose.composeInto(composeView.root, context) {
- val currentComposer = currentComposer as ViewComposer
- remember { currentComposer.adapters?.register(AndroidViewAdapter) }
- WrapWithAmbients(composeView, context, Dispatchers.Main) {
- WrapWithSelectionContainer(content)
+): Composition {
+ val composition = findComposition(composeView.root)
+ ?: UiComposition(composeView.root, context, null)
+ composition.compose {
+ WrapWithAmbients(composeView, context, Dispatchers.Main) {
+ WrapWithSelectionContainer(content)
+ }
}
+ return composition
}
+@SuppressLint("UnnecessaryLambdaCreation")
@Composable
private fun WrapWithAmbients(
composeView: AndroidComposeView,
@@ -184,7 +446,7 @@
else -> LayoutDirection.Ltr
}
- val defaultAnimationClock = remember { DefaultAnimationClock() }
+ val rootAnimationClock = remember { rootAnimationClockFactory() }
Providers(
ContextAmbient provides context,
@@ -198,7 +460,7 @@
ConfigurationAmbient provides context.applicationContext.resources.configuration,
AndroidComposeViewAmbient provides composeView,
LayoutDirectionAmbient provides layoutDirection,
- AnimationClockAmbient provides defaultAnimationClock,
+ AnimationClockAmbient provides rootAnimationClock,
children = content
)
}
diff --git a/ui/ui-framework/src/main/java/androidx/ui/core/selection/SelectionContainer.kt b/ui/ui-framework/src/main/java/androidx/ui/core/selection/SelectionContainer.kt
index a9d36e7..ccfdc53 100644
--- a/ui/ui-framework/src/main/java/androidx/ui/core/selection/SelectionContainer.kt
+++ b/ui/ui-framework/src/main/java/androidx/ui/core/selection/SelectionContainer.kt
@@ -180,7 +180,7 @@
layout(width, height) {
placeables.forEach { placeable ->
- placeable.place(0.ipx, 0.ipx)
+ placeable.placeAbsolute(0.ipx, 0.ipx)
}
}
}
@@ -235,7 +235,7 @@
containerHeight - it.height
)
)
- it.place(
+ it.placeAbsolute(
position.x,
position.y
)
diff --git a/ui/ui-framework/src/main/java/androidx/ui/node/UiComposer.kt b/ui/ui-framework/src/main/java/androidx/ui/node/UiComposer.kt
new file mode 100644
index 0000000..27bf1c9
--- /dev/null
+++ b/ui/ui-framework/src/main/java/androidx/ui/node/UiComposer.kt
@@ -0,0 +1,229 @@
+/*
+ * 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.ui.node
+
+import android.content.Context
+import android.view.View
+import android.view.ViewGroup
+import androidx.compose.Applier
+import androidx.compose.ApplyAdapter
+import androidx.compose.Composer
+import androidx.compose.ComposerUpdater
+import androidx.compose.FrameManager
+import androidx.compose.Recomposer
+import androidx.compose.SlotTable
+import androidx.ui.core.ComponentNode
+
+// TODO: evaluate if this class is necessary or not
+private class Stack<T> {
+ private val backing = ArrayList<T>()
+
+ val size: Int get() = backing.size
+
+ fun push(value: T) = backing.add(value)
+ fun pop(): T = backing.removeAt(size - 1)
+ fun peek(): T = backing[size - 1]
+ fun isEmpty() = backing.isEmpty()
+ fun isNotEmpty() = !isEmpty()
+ fun clear() = backing.clear()
+}
+
+private fun invalidNode(node: Any): Nothing =
+ error("Unsupported node type ${node.javaClass.simpleName}")
+
+internal class UiApplyAdapter : ApplyAdapter<Any> {
+ private data class PendingInsert(val index: Int, val instance: Any)
+
+ private val pendingInserts =
+ Stack<PendingInsert>()
+
+ override fun Any.start(instance: Any) {}
+ override fun Any.insertAt(index: Int, instance: Any) {
+ pendingInserts.push(
+ PendingInsert(
+ index,
+ instance
+ )
+ )
+ }
+
+ override fun Any.removeAt(index: Int, count: Int) {
+ when (this) {
+ is ViewGroup -> removeViews(index, count)
+ is ComponentNode -> removeAt(index, count)
+ else -> invalidNode(this)
+ }
+ }
+
+ override fun Any.move(from: Int, to: Int, count: Int) {
+ when (this) {
+ is ViewGroup -> {
+ if (from > to) {
+ var currentFrom = from
+ var currentTo = to
+ repeat(count) {
+ val view = getChildAt(currentFrom)
+ removeViewAt(currentFrom)
+ addView(view, currentTo)
+ currentFrom++
+ currentTo++
+ }
+ } else {
+ repeat(count) {
+ val view = getChildAt(from)
+ removeViewAt(from)
+ addView(view, to - 1)
+ }
+ }
+ }
+ is ComponentNode -> {
+ move(from, to, count)
+ }
+ else -> invalidNode(this)
+ }
+ }
+
+ override fun Any.end(instance: Any, parent: Any) {
+ val adapter = when (instance) {
+ is View -> instance.getViewAdapterIfExists()
+ else -> null
+ }
+ if (pendingInserts.isNotEmpty()) {
+ val pendingInsert = pendingInserts.peek()
+ if (pendingInsert.instance == instance) {
+ val index = pendingInsert.index
+ pendingInserts.pop()
+
+ when (parent) {
+ is ViewGroup ->
+ when (instance) {
+ is View -> {
+ adapter?.willInsert(instance, parent)
+ parent.addView(instance, index)
+ adapter?.didInsert(instance, parent)
+ }
+// is ComponentNode -> {
+// val adaptedView = adapters?.adapt(parent, instance) as? View
+// ?: error(
+// "Could not convert ${
+// instance.javaClass.simpleName
+// } to a View"
+// )
+// adapter?.willInsert(adaptedView, parent)
+// parent.addView(adaptedView, index)
+// adapter?.didInsert(adaptedView, parent)
+// }
+ else -> invalidNode(instance)
+ }
+ is ComponentNode ->
+ when (instance) {
+ is View -> parent.insertAt(
+ index,
+ instance.toComponentNode()
+ )
+ is ComponentNode -> parent.insertAt(index, instance)
+ else -> invalidNode(instance)
+ }
+ else -> invalidNode(parent)
+ }
+ return
+ }
+ }
+ if (parent is ViewGroup)
+ adapter?.didUpdate(instance as View, parent)
+ }
+}
+
+class UiComposer(
+ val context: Context,
+ val root: Any,
+ slotTable: SlotTable,
+ recomposer: Recomposer
+) : Composer<Any>(
+ slotTable,
+ Applier(
+ root,
+ UiApplyAdapter()
+ ),
+ recomposer
+) {
+ init {
+ FrameManager.ensureStarted()
+ }
+
+ @Suppress("UNCHECKED_CAST")
+ inline fun <T : View> emit(
+ key: Any,
+ /*crossinline*/
+ ctor: (context: Context) -> T,
+ update: UiUpdater<T>.() -> Unit
+ ) {
+ startNode(key)
+ val node = if (inserting) ctor(context).also { emitNode(it) }
+ else useNode() as T
+ UiUpdater(this, node).update()
+ endNode()
+ }
+
+ @Suppress("UNCHECKED_CAST")
+ inline fun <T : ViewGroup> emit(
+ key: Any,
+ /*crossinline*/
+ ctor: (context: Context) -> T,
+ update: UiUpdater<T>.() -> Unit,
+ children: () -> Unit
+ ) {
+ startNode(key)
+ val node = if (inserting) ctor(context).also { emitNode(it) }
+ else useNode() as T
+ UiUpdater(this, node).update()
+ children()
+ endNode()
+ }
+
+ @Suppress("UNCHECKED_CAST")
+ inline fun <T : ComponentNode> emit(
+ key: Any,
+ /*crossinline*/
+ ctor: () -> T,
+ update: UiUpdater<T>.() -> Unit
+ ) {
+ startNode(key)
+ val node = if (inserting) ctor().also { emitNode(it) }
+ else useNode() as T
+ UiUpdater(this, node).update()
+ endNode()
+ }
+
+ @Suppress("UNCHECKED_CAST")
+ inline fun <T : ComponentNode> emit(
+ key: Any,
+ /*crossinline*/
+ ctor: () -> T,
+ update: UiUpdater<T>.() -> Unit,
+ children: () -> Unit
+ ) {
+ startNode(key)
+ val node = if (inserting) ctor().also { emitNode(it) }
+ else useNode() as T
+ UiUpdater(this, node).update()
+ children()
+ endNode()
+ }
+}
+
+typealias UiUpdater<T> = ComposerUpdater<Any, T>
\ No newline at end of file
diff --git a/ui/ui-framework/src/main/java/androidx/ui/node/ViewInterop.kt b/ui/ui-framework/src/main/java/androidx/ui/node/ViewInterop.kt
new file mode 100644
index 0000000..c4f2637
--- /dev/null
+++ b/ui/ui-framework/src/main/java/androidx/ui/node/ViewInterop.kt
@@ -0,0 +1,195 @@
+/*
+ * 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.ui.node
+
+import android.view.View
+import android.view.ViewGroup
+import androidx.annotation.RestrictTo
+import androidx.ui.core.AndroidOwner
+import androidx.ui.core.ComponentNode
+import androidx.ui.core.Constraints
+import androidx.ui.core.LayoutDirection
+import androidx.ui.core.LayoutNode
+import androidx.ui.core.Measurable
+import androidx.ui.core.MeasureScope
+import androidx.ui.unit.IntPx
+import androidx.ui.unit.ipx
+import androidx.ui.unit.isFinite
+
+/**
+ * @hide
+ */
+// TODO(b/150806128): We should decide if we want to make this public API or not. Right now it is needed
+// for convenient LayoutParams usage in compose with views.
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+interface ViewAdapter {
+ val id: Int
+ fun willInsert(view: View, parent: ViewGroup)
+ fun didInsert(view: View, parent: ViewGroup)
+ fun didUpdate(view: View, parent: ViewGroup)
+}
+
+/**
+ * @hide
+ */
+// TODO(b/150806128): We should decide if we want to make this public API or not. Right now it is needed
+// for convenient LayoutParams usage in compose with views.
+@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
+fun <T : ViewAdapter> View.getOrAddAdapter(id: Int, factory: () -> T): T {
+ return getViewAdapter().get(id, factory)
+}
+
+/**
+ * Intersects [Constraints] and [View] LayoutParams to obtain the suitable [View.MeasureSpec]
+ * for measuring the [View].
+ */
+private fun obtainMeasureSpec(
+ min: IntPx,
+ max: IntPx,
+ preferred: Int
+): Int = when {
+ preferred >= 0 || min == max -> {
+ // Fixed size due to fixed size layout param or fixed constraints.
+ View.MeasureSpec.makeMeasureSpec(
+ preferred.coerceIn(min.value, max.value),
+ View.MeasureSpec.EXACTLY
+ )
+ }
+ preferred == ViewGroup.LayoutParams.WRAP_CONTENT && max.isFinite() -> {
+ // Wrap content layout param with finite max constraint. If max constraint is infinite,
+ // we will measure the child with UNSPECIFIED.
+ View.MeasureSpec.makeMeasureSpec(max.value, View.MeasureSpec.AT_MOST)
+ }
+ preferred == ViewGroup.LayoutParams.MATCH_PARENT && max.isFinite() -> {
+ // Match parent layout param, so we force the child to fill the available space.
+ View.MeasureSpec.makeMeasureSpec(max.value, View.MeasureSpec.EXACTLY)
+ }
+ else -> {
+ // max constraint is infinite and layout param is WRAP_CONTENT or MATCH_PARENT.
+ View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
+ }
+}
+
+/**
+ * Builds a [ComponentNode] tree representation for an Android [View].
+ * The component nodes will proxy the Compose core calls to the [View].
+ */
+internal fun View.toComponentNode(): ComponentNode {
+ // TODO(soboleva): add layout direction here?
+ // TODO(popam): forward pointer input, accessibility, focus
+ // Prepare layout node that proxies measure and layout passes to the View.
+ val layoutNode = LayoutNode()
+ layoutNode.modifier = androidx.ui.core.draw { canvas, _ ->
+ draw(canvas.nativeCanvas)
+ }
+ layoutNode.onAttach = { owner ->
+ (owner as? AndroidOwner)?.addAndroidView(this, layoutNode)
+ }
+ layoutNode.onDetach = { owner ->
+ (owner as? AndroidOwner)?.removeAndroidView(this)
+ }
+ layoutNode.measureBlocks = object : LayoutNode.NoIntrinsicsMeasureBlocks(
+ "Intrinsics not supported for Android views"
+ ) {
+ override fun measure(
+ measureScope: MeasureScope,
+ measurables: List<Measurable>,
+ constraints: Constraints,
+ layoutDirection: LayoutDirection
+ ): MeasureScope.LayoutResult {
+ if (constraints.minWidth != 0.ipx) {
+ minimumWidth = constraints.minWidth.value
+ }
+ if (constraints.minHeight != 0.ipx) {
+ minimumHeight = constraints.minHeight.value
+ }
+ // TODO (soboleva): native view should get LD value from Compose?
+ measure(
+ obtainMeasureSpec(
+ constraints.minWidth,
+ constraints.maxWidth,
+ layoutParams.width
+ ),
+ obtainMeasureSpec(
+ constraints.minHeight,
+ constraints.maxHeight,
+ layoutParams.height
+ )
+ )
+ return measureScope.layout(measuredWidth.ipx, measuredHeight.ipx) {
+ layout(
+ 0,
+ 0,
+ measuredWidth,
+ measuredHeight
+ )
+ }
+ }
+ }
+ return layoutNode
+}
+
+internal class MergedViewAdapter : ViewAdapter {
+ override val id = 0
+ val adapters = mutableListOf<ViewAdapter>()
+
+ inline fun <T : ViewAdapter> get(id: Int, factory: () -> T): T {
+ @Suppress("UNCHECKED_CAST")
+ val existing = adapters.firstOrNull { it.id == id } as? T
+ if (existing != null) return existing
+ val next = factory()
+ adapters.add(next)
+ return next
+ }
+
+ override fun willInsert(view: View, parent: ViewGroup) {
+ for (adapter in adapters) adapter.willInsert(view, parent)
+ }
+
+ override fun didInsert(view: View, parent: ViewGroup) {
+ for (adapter in adapters) adapter.didInsert(view, parent)
+ }
+
+ override fun didUpdate(view: View, parent: ViewGroup) {
+ for (adapter in adapters) adapter.didUpdate(view, parent)
+ }
+}
+
+/**
+ * This function will take in a string and pass back a valid resource identifier for
+ * View.setTag(...). We should eventually move this to a resource id that's actually generated via
+ * AAPT but doing that in this project is proving to be complicated, so for now I'm just doing this
+ * as a stop-gap.
+ */
+internal fun tagKey(key: String): Int {
+ return (3 shl 24) or key.hashCode()
+}
+
+private val viewAdaptersKey = tagKey("ViewAdapter")
+
+internal fun View.getViewAdapterIfExists(): MergedViewAdapter? {
+ return getTag(viewAdaptersKey) as? MergedViewAdapter
+}
+
+internal fun View.getViewAdapter(): MergedViewAdapter {
+ var adapter = getTag(viewAdaptersKey) as? MergedViewAdapter
+ if (adapter == null) {
+ adapter = MergedViewAdapter()
+ setTag(viewAdaptersKey, adapter)
+ }
+ return adapter
+}
\ No newline at end of file
diff --git a/ui/ui-geometry/api/0.1.0-dev07.txt b/ui/ui-geometry/api/0.1.0-dev07.txt
index ea43f9d..4ad12c3 100644
--- a/ui/ui-geometry/api/0.1.0-dev07.txt
+++ b/ui/ui-geometry/api/0.1.0-dev07.txt
@@ -107,6 +107,7 @@
method public static boolean isEmpty(androidx.ui.geometry.RRect);
method public static boolean isFinite(androidx.ui.geometry.RRect);
method public static boolean isRect(androidx.ui.geometry.RRect);
+ method public static boolean isSimple(androidx.ui.geometry.RRect);
method public static boolean isStadium(androidx.ui.geometry.RRect);
method public static androidx.ui.geometry.RRect lerp(androidx.ui.geometry.RRect start, androidx.ui.geometry.RRect stop, float fraction);
method public static androidx.ui.geometry.Rect middleRect(androidx.ui.geometry.RRect);
diff --git a/ui/ui-geometry/api/current.txt b/ui/ui-geometry/api/current.txt
index ea43f9d..4ad12c3 100644
--- a/ui/ui-geometry/api/current.txt
+++ b/ui/ui-geometry/api/current.txt
@@ -107,6 +107,7 @@
method public static boolean isEmpty(androidx.ui.geometry.RRect);
method public static boolean isFinite(androidx.ui.geometry.RRect);
method public static boolean isRect(androidx.ui.geometry.RRect);
+ method public static boolean isSimple(androidx.ui.geometry.RRect);
method public static boolean isStadium(androidx.ui.geometry.RRect);
method public static androidx.ui.geometry.RRect lerp(androidx.ui.geometry.RRect start, androidx.ui.geometry.RRect stop, float fraction);
method public static androidx.ui.geometry.Rect middleRect(androidx.ui.geometry.RRect);
diff --git a/ui/ui-geometry/api/public_plus_experimental_0.1.0-dev07.txt b/ui/ui-geometry/api/public_plus_experimental_0.1.0-dev07.txt
index ea43f9d..4ad12c3 100644
--- a/ui/ui-geometry/api/public_plus_experimental_0.1.0-dev07.txt
+++ b/ui/ui-geometry/api/public_plus_experimental_0.1.0-dev07.txt
@@ -107,6 +107,7 @@
method public static boolean isEmpty(androidx.ui.geometry.RRect);
method public static boolean isFinite(androidx.ui.geometry.RRect);
method public static boolean isRect(androidx.ui.geometry.RRect);
+ method public static boolean isSimple(androidx.ui.geometry.RRect);
method public static boolean isStadium(androidx.ui.geometry.RRect);
method public static androidx.ui.geometry.RRect lerp(androidx.ui.geometry.RRect start, androidx.ui.geometry.RRect stop, float fraction);
method public static androidx.ui.geometry.Rect middleRect(androidx.ui.geometry.RRect);
diff --git a/ui/ui-geometry/api/public_plus_experimental_current.txt b/ui/ui-geometry/api/public_plus_experimental_current.txt
index ea43f9d..4ad12c3 100644
--- a/ui/ui-geometry/api/public_plus_experimental_current.txt
+++ b/ui/ui-geometry/api/public_plus_experimental_current.txt
@@ -107,6 +107,7 @@
method public static boolean isEmpty(androidx.ui.geometry.RRect);
method public static boolean isFinite(androidx.ui.geometry.RRect);
method public static boolean isRect(androidx.ui.geometry.RRect);
+ method public static boolean isSimple(androidx.ui.geometry.RRect);
method public static boolean isStadium(androidx.ui.geometry.RRect);
method public static androidx.ui.geometry.RRect lerp(androidx.ui.geometry.RRect start, androidx.ui.geometry.RRect stop, float fraction);
method public static androidx.ui.geometry.Rect middleRect(androidx.ui.geometry.RRect);
diff --git a/ui/ui-geometry/api/restricted_0.1.0-dev07.txt b/ui/ui-geometry/api/restricted_0.1.0-dev07.txt
index ea43f9d..4ad12c3 100644
--- a/ui/ui-geometry/api/restricted_0.1.0-dev07.txt
+++ b/ui/ui-geometry/api/restricted_0.1.0-dev07.txt
@@ -107,6 +107,7 @@
method public static boolean isEmpty(androidx.ui.geometry.RRect);
method public static boolean isFinite(androidx.ui.geometry.RRect);
method public static boolean isRect(androidx.ui.geometry.RRect);
+ method public static boolean isSimple(androidx.ui.geometry.RRect);
method public static boolean isStadium(androidx.ui.geometry.RRect);
method public static androidx.ui.geometry.RRect lerp(androidx.ui.geometry.RRect start, androidx.ui.geometry.RRect stop, float fraction);
method public static androidx.ui.geometry.Rect middleRect(androidx.ui.geometry.RRect);
diff --git a/ui/ui-geometry/api/restricted_current.txt b/ui/ui-geometry/api/restricted_current.txt
index ea43f9d..4ad12c3 100644
--- a/ui/ui-geometry/api/restricted_current.txt
+++ b/ui/ui-geometry/api/restricted_current.txt
@@ -107,6 +107,7 @@
method public static boolean isEmpty(androidx.ui.geometry.RRect);
method public static boolean isFinite(androidx.ui.geometry.RRect);
method public static boolean isRect(androidx.ui.geometry.RRect);
+ method public static boolean isSimple(androidx.ui.geometry.RRect);
method public static boolean isStadium(androidx.ui.geometry.RRect);
method public static androidx.ui.geometry.RRect lerp(androidx.ui.geometry.RRect start, androidx.ui.geometry.RRect stop, float fraction);
method public static androidx.ui.geometry.Rect middleRect(androidx.ui.geometry.RRect);
diff --git a/ui/ui-geometry/src/main/java/androidx/ui/geometry/RRect.kt b/ui/ui-geometry/src/main/java/androidx/ui/geometry/RRect.kt
index e2a0142..6ba68ed 100644
--- a/ui/ui-geometry/src/main/java/androidx/ui/geometry/RRect.kt
+++ b/ui/ui-geometry/src/main/java/androidx/ui/geometry/RRect.kt
@@ -542,6 +542,19 @@
fun RRect.center(): Offset = Offset((left + width / 2.0f), (top + height / 2.0f))
/**
+ * Returns `true` if the rounded rectangle have the same radii in both the horizontal and vertical
+ * direction for all corners.
+ */
+val RRect.isSimple: Boolean
+ get() = topLeftRadiusX == topLeftRadiusY &&
+ topLeftRadiusX == topRightRadiusX &&
+ topLeftRadiusX == topRightRadiusY &&
+ topLeftRadiusX == bottomRightRadiusX &&
+ topLeftRadiusX == bottomRightRadiusY &&
+ topLeftRadiusX == bottomLeftRadiusX &&
+ topLeftRadiusX == bottomLeftRadiusY
+
+/**
* Linearly interpolate between two rounded rectangles.
*
* The [fraction] argument represents position on the timeline, with 0.0 meaning
diff --git a/ui/ui-graphics/src/androidTest/java/androidx/ui/graphics/AndroidCanvasTest.kt b/ui/ui-graphics/src/androidTest/java/androidx/ui/graphics/AndroidCanvasTest.kt
index 89496a1..398f6b4 100644
--- a/ui/ui-graphics/src/androidTest/java/androidx/ui/graphics/AndroidCanvasTest.kt
+++ b/ui/ui-graphics/src/androidTest/java/androidx/ui/graphics/AndroidCanvasTest.kt
@@ -71,6 +71,9 @@
}
assertTrue(drawLatch.await(1, TimeUnit.SECONDS))
+ // Not sure why this test is flaky, so this is just going to make sure that
+ // the drawn content can get onto the screen before we capture the bitmap.
+ activityTestRule.runOnUiThread { }
val bitmap = groupView!!.captureToBitmap()
assertEquals(Color.WHITE, bitmap.getPixel(0, 0))
assertEquals(Color.WHITE, bitmap.getPixel(9, 9))
diff --git a/ui/ui-layout/api/0.1.0-dev07.txt b/ui/ui-layout/api/0.1.0-dev07.txt
index 517c16a..494dfaf 100644
--- a/ui/ui-layout/api/0.1.0-dev07.txt
+++ b/ui/ui-layout/api/0.1.0-dev07.txt
@@ -294,6 +294,16 @@
method @Deprecated public androidx.ui.core.Modifier wraps(androidx.ui.core.Modifier other);
}
+ public final class LayoutOffset implements androidx.ui.core.LayoutModifier {
+ ctor public LayoutOffset(androidx.ui.unit.Dp x, androidx.ui.unit.Dp y);
+ method public androidx.ui.unit.Dp component1();
+ method public androidx.ui.unit.Dp component2();
+ method public androidx.ui.layout.LayoutOffset copy(androidx.ui.unit.Dp x, androidx.ui.unit.Dp y);
+ method public androidx.ui.unit.Dp getX();
+ method public androidx.ui.unit.Dp getY();
+ method public androidx.ui.unit.IntPxPosition modifyPosition(androidx.ui.unit.Density, androidx.ui.unit.IntPxSize childSize, androidx.ui.unit.IntPxSize containerSize, androidx.ui.core.LayoutDirection layoutDirection);
+ }
+
public final class LayoutPadding implements androidx.ui.core.LayoutModifier {
ctor public LayoutPadding(androidx.ui.unit.Dp start, androidx.ui.unit.Dp top, androidx.ui.unit.Dp end, androidx.ui.unit.Dp bottom);
ctor public LayoutPadding();
@@ -606,7 +616,7 @@
}
public final class WrapKt {
- method public static void Wrap(androidx.ui.core.Alignment alignment = Alignment.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method @Deprecated public static void Wrap(androidx.ui.core.Alignment alignment = Alignment.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
}
diff --git a/ui/ui-layout/api/current.txt b/ui/ui-layout/api/current.txt
index 517c16a..494dfaf 100644
--- a/ui/ui-layout/api/current.txt
+++ b/ui/ui-layout/api/current.txt
@@ -294,6 +294,16 @@
method @Deprecated public androidx.ui.core.Modifier wraps(androidx.ui.core.Modifier other);
}
+ public final class LayoutOffset implements androidx.ui.core.LayoutModifier {
+ ctor public LayoutOffset(androidx.ui.unit.Dp x, androidx.ui.unit.Dp y);
+ method public androidx.ui.unit.Dp component1();
+ method public androidx.ui.unit.Dp component2();
+ method public androidx.ui.layout.LayoutOffset copy(androidx.ui.unit.Dp x, androidx.ui.unit.Dp y);
+ method public androidx.ui.unit.Dp getX();
+ method public androidx.ui.unit.Dp getY();
+ method public androidx.ui.unit.IntPxPosition modifyPosition(androidx.ui.unit.Density, androidx.ui.unit.IntPxSize childSize, androidx.ui.unit.IntPxSize containerSize, androidx.ui.core.LayoutDirection layoutDirection);
+ }
+
public final class LayoutPadding implements androidx.ui.core.LayoutModifier {
ctor public LayoutPadding(androidx.ui.unit.Dp start, androidx.ui.unit.Dp top, androidx.ui.unit.Dp end, androidx.ui.unit.Dp bottom);
ctor public LayoutPadding();
@@ -606,7 +616,7 @@
}
public final class WrapKt {
- method public static void Wrap(androidx.ui.core.Alignment alignment = Alignment.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method @Deprecated public static void Wrap(androidx.ui.core.Alignment alignment = Alignment.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
}
diff --git a/ui/ui-layout/api/public_plus_experimental_0.1.0-dev07.txt b/ui/ui-layout/api/public_plus_experimental_0.1.0-dev07.txt
index 517c16a..494dfaf 100644
--- a/ui/ui-layout/api/public_plus_experimental_0.1.0-dev07.txt
+++ b/ui/ui-layout/api/public_plus_experimental_0.1.0-dev07.txt
@@ -294,6 +294,16 @@
method @Deprecated public androidx.ui.core.Modifier wraps(androidx.ui.core.Modifier other);
}
+ public final class LayoutOffset implements androidx.ui.core.LayoutModifier {
+ ctor public LayoutOffset(androidx.ui.unit.Dp x, androidx.ui.unit.Dp y);
+ method public androidx.ui.unit.Dp component1();
+ method public androidx.ui.unit.Dp component2();
+ method public androidx.ui.layout.LayoutOffset copy(androidx.ui.unit.Dp x, androidx.ui.unit.Dp y);
+ method public androidx.ui.unit.Dp getX();
+ method public androidx.ui.unit.Dp getY();
+ method public androidx.ui.unit.IntPxPosition modifyPosition(androidx.ui.unit.Density, androidx.ui.unit.IntPxSize childSize, androidx.ui.unit.IntPxSize containerSize, androidx.ui.core.LayoutDirection layoutDirection);
+ }
+
public final class LayoutPadding implements androidx.ui.core.LayoutModifier {
ctor public LayoutPadding(androidx.ui.unit.Dp start, androidx.ui.unit.Dp top, androidx.ui.unit.Dp end, androidx.ui.unit.Dp bottom);
ctor public LayoutPadding();
@@ -606,7 +616,7 @@
}
public final class WrapKt {
- method public static void Wrap(androidx.ui.core.Alignment alignment = Alignment.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method @Deprecated public static void Wrap(androidx.ui.core.Alignment alignment = Alignment.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
}
diff --git a/ui/ui-layout/api/public_plus_experimental_current.txt b/ui/ui-layout/api/public_plus_experimental_current.txt
index 517c16a..494dfaf 100644
--- a/ui/ui-layout/api/public_plus_experimental_current.txt
+++ b/ui/ui-layout/api/public_plus_experimental_current.txt
@@ -294,6 +294,16 @@
method @Deprecated public androidx.ui.core.Modifier wraps(androidx.ui.core.Modifier other);
}
+ public final class LayoutOffset implements androidx.ui.core.LayoutModifier {
+ ctor public LayoutOffset(androidx.ui.unit.Dp x, androidx.ui.unit.Dp y);
+ method public androidx.ui.unit.Dp component1();
+ method public androidx.ui.unit.Dp component2();
+ method public androidx.ui.layout.LayoutOffset copy(androidx.ui.unit.Dp x, androidx.ui.unit.Dp y);
+ method public androidx.ui.unit.Dp getX();
+ method public androidx.ui.unit.Dp getY();
+ method public androidx.ui.unit.IntPxPosition modifyPosition(androidx.ui.unit.Density, androidx.ui.unit.IntPxSize childSize, androidx.ui.unit.IntPxSize containerSize, androidx.ui.core.LayoutDirection layoutDirection);
+ }
+
public final class LayoutPadding implements androidx.ui.core.LayoutModifier {
ctor public LayoutPadding(androidx.ui.unit.Dp start, androidx.ui.unit.Dp top, androidx.ui.unit.Dp end, androidx.ui.unit.Dp bottom);
ctor public LayoutPadding();
@@ -606,7 +616,7 @@
}
public final class WrapKt {
- method public static void Wrap(androidx.ui.core.Alignment alignment = Alignment.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method @Deprecated public static void Wrap(androidx.ui.core.Alignment alignment = Alignment.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
}
diff --git a/ui/ui-layout/api/restricted_0.1.0-dev07.txt b/ui/ui-layout/api/restricted_0.1.0-dev07.txt
index 517c16a..494dfaf 100644
--- a/ui/ui-layout/api/restricted_0.1.0-dev07.txt
+++ b/ui/ui-layout/api/restricted_0.1.0-dev07.txt
@@ -294,6 +294,16 @@
method @Deprecated public androidx.ui.core.Modifier wraps(androidx.ui.core.Modifier other);
}
+ public final class LayoutOffset implements androidx.ui.core.LayoutModifier {
+ ctor public LayoutOffset(androidx.ui.unit.Dp x, androidx.ui.unit.Dp y);
+ method public androidx.ui.unit.Dp component1();
+ method public androidx.ui.unit.Dp component2();
+ method public androidx.ui.layout.LayoutOffset copy(androidx.ui.unit.Dp x, androidx.ui.unit.Dp y);
+ method public androidx.ui.unit.Dp getX();
+ method public androidx.ui.unit.Dp getY();
+ method public androidx.ui.unit.IntPxPosition modifyPosition(androidx.ui.unit.Density, androidx.ui.unit.IntPxSize childSize, androidx.ui.unit.IntPxSize containerSize, androidx.ui.core.LayoutDirection layoutDirection);
+ }
+
public final class LayoutPadding implements androidx.ui.core.LayoutModifier {
ctor public LayoutPadding(androidx.ui.unit.Dp start, androidx.ui.unit.Dp top, androidx.ui.unit.Dp end, androidx.ui.unit.Dp bottom);
ctor public LayoutPadding();
@@ -606,7 +616,7 @@
}
public final class WrapKt {
- method public static void Wrap(androidx.ui.core.Alignment alignment = Alignment.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method @Deprecated public static void Wrap(androidx.ui.core.Alignment alignment = Alignment.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
}
diff --git a/ui/ui-layout/api/restricted_current.txt b/ui/ui-layout/api/restricted_current.txt
index 517c16a..494dfaf 100644
--- a/ui/ui-layout/api/restricted_current.txt
+++ b/ui/ui-layout/api/restricted_current.txt
@@ -294,6 +294,16 @@
method @Deprecated public androidx.ui.core.Modifier wraps(androidx.ui.core.Modifier other);
}
+ public final class LayoutOffset implements androidx.ui.core.LayoutModifier {
+ ctor public LayoutOffset(androidx.ui.unit.Dp x, androidx.ui.unit.Dp y);
+ method public androidx.ui.unit.Dp component1();
+ method public androidx.ui.unit.Dp component2();
+ method public androidx.ui.layout.LayoutOffset copy(androidx.ui.unit.Dp x, androidx.ui.unit.Dp y);
+ method public androidx.ui.unit.Dp getX();
+ method public androidx.ui.unit.Dp getY();
+ method public androidx.ui.unit.IntPxPosition modifyPosition(androidx.ui.unit.Density, androidx.ui.unit.IntPxSize childSize, androidx.ui.unit.IntPxSize containerSize, androidx.ui.core.LayoutDirection layoutDirection);
+ }
+
public final class LayoutPadding implements androidx.ui.core.LayoutModifier {
ctor public LayoutPadding(androidx.ui.unit.Dp start, androidx.ui.unit.Dp top, androidx.ui.unit.Dp end, androidx.ui.unit.Dp bottom);
ctor public LayoutPadding();
@@ -606,7 +616,7 @@
}
public final class WrapKt {
- method public static void Wrap(androidx.ui.core.Alignment alignment = Alignment.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method @Deprecated public static void Wrap(androidx.ui.core.Alignment alignment = Alignment.TopStart, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
}
diff --git a/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/ComplexLayoutDemos.kt b/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/ComplexLayoutDemos.kt
index adf6b6b..ef99000 100644
--- a/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/ComplexLayoutDemos.kt
+++ b/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/ComplexLayoutDemos.kt
@@ -21,7 +21,7 @@
import androidx.ui.core.Text
import androidx.ui.graphics.Color
import androidx.ui.layout.AlignmentLineOffset
-import androidx.ui.layout.Wrap
+import androidx.ui.layout.Stack
import androidx.ui.foundation.DrawBackground
import androidx.ui.unit.dp
@@ -39,7 +39,7 @@
@Composable
fun ComplexLayoutDemos() {
- Wrap {
+ Stack {
AlignmentLineOffsetUsage()
}
}
diff --git a/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/RtlDemos.kt b/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/RtlDemos.kt
index d6fbaea..c0ec5f8 100644
--- a/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/RtlDemos.kt
+++ b/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/RtlDemos.kt
@@ -19,7 +19,12 @@
import android.app.Activity
import android.os.Bundle
import androidx.compose.Composable
+import androidx.ui.core.DensityAmbient
+import androidx.ui.core.Layout
+import androidx.ui.core.LayoutDirection
+import androidx.ui.core.Modifier
import androidx.ui.core.Text
+import androidx.ui.core.WithConstraints
import androidx.ui.core.setContent
import androidx.ui.graphics.Color
import androidx.ui.layout.Column
@@ -31,7 +36,9 @@
import androidx.ui.layout.Stack
import androidx.ui.foundation.DrawBackground
import androidx.ui.layout.LayoutDirectionModifier
+import androidx.ui.unit.IntPxPosition
import androidx.ui.unit.dp
+import androidx.ui.unit.ipx
class RtlDemosActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
@@ -42,16 +49,24 @@
testText()
Text("ROW", LayoutGravity.Center)
testRow()
- Text("ROW WITH MODIFIER", LayoutGravity.Center)
+ Text("ROW WITH LTR MODIFIER", LayoutGravity.Center)
testRow_modifier()
Text("RELATIVE TO SIBLINGS", LayoutGravity.Center)
testSiblings()
+ Text("PLACE WITH AUTO RTL SUPPORT IN CUSTOM LAYOUT", LayoutGravity.Center)
+ CustomLayout(true)
+ Text("PLACE WITHOUT RTL SUPPORT IN CUSTOM LAYOUT", LayoutGravity.Center)
+ CustomLayout(false)
+ Text("WITH CONSTRAINTS", LayoutGravity.Center)
+ LayoutWithConstraints(LayoutDirectionModifier.Ltr, "LD: LTR modifier")
+ LayoutWithConstraints(LayoutDirectionModifier.Rtl, "LD: RTL modifier")
+ LayoutWithConstraints(text = "LD: locale")
}
}
}
}
-val boxSize = LayoutSize(50.dp, 50.dp)
+val boxSize = LayoutSize(50.dp, 30.dp)
val size = LayoutSize(10.dp, 10.dp)
@Composable
@@ -86,9 +101,9 @@
fun testText() {
Column {
Row {
- Stack(boxSize + DrawBackground(Color.Red)) {}
- Stack(boxSize + DrawBackground(Color.Green)) {}
- Stack(boxSize + DrawBackground(Color.Blue)) {}
+ Stack(size + DrawBackground(Color.Red)) {}
+ Stack(size + DrawBackground(Color.Green)) {}
+ Stack(size + DrawBackground(Color.Blue)) {}
}
Text("Text.")
Text("Width filled text.", LayoutWidth.Fill)
@@ -115,4 +130,45 @@
LayoutGravity.RelativeToSiblings { p -> p.width / 4 }
) {}
}
+}
+
+@Composable
+fun CustomLayout(rtlSupport: Boolean) {
+ Layout(children = @Composable {
+ Stack(boxSize + DrawBackground(Color.Red)) {}
+ Stack(boxSize + DrawBackground(Color.Green)) {}
+ Stack(boxSize + DrawBackground(Color.Blue)) {}
+ }) { measurables, constraints, _ ->
+ val p = measurables.map { e ->
+ e.measure(constraints.copy(minWidth = 0.ipx, minHeight = 0.ipx))
+ }
+ val w = p.fold(0.ipx) { sum, e -> sum + e.width }
+ val h = p.maxBy { it.height }!!.height
+ layout(w, h) {
+ var xPosition = 0.ipx
+ for (child in p) {
+ child.placeAbsolute(IntPxPosition(xPosition, 0.ipx))
+ if (rtlSupport) {
+ child.place(IntPxPosition(xPosition, 0.ipx))
+ } else {
+ child.placeAbsolute(IntPxPosition(xPosition, 0.ipx))
+ }
+ xPosition += child.width
+ }
+ }
+ }
+}
+
+@Composable
+fun LayoutWithConstraints(modifier: Modifier = Modifier.None, text: String) {
+ WithConstraints(modifier) { constraints, direction ->
+ with(DensityAmbient.current) {
+ val w = (constraints.maxWidth / 3).toDp()
+ val h = (constraints.maxHeight / 2).toDp()
+ val color = if (direction == LayoutDirection.Ltr) Color.Red else Color.Magenta
+ Stack(LayoutSize(w, h) + DrawBackground(color)) {
+ Text(text, LayoutGravity.Center)
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/TableActivity.kt b/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/TableActivity.kt
index b8276d6..9b73692 100644
--- a/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/TableActivity.kt
+++ b/ui/ui-layout/integration-tests/layout-demos/src/main/java/androidx/ui/layout/demos/TableActivity.kt
@@ -19,7 +19,7 @@
import android.app.Activity
import android.os.Bundle
import androidx.ui.core.setContent
-import androidx.ui.layout.Wrap
+import androidx.ui.layout.Stack
import androidx.ui.layout.samples.TableWithDecorations
class TableActivity : Activity() {
@@ -27,7 +27,7 @@
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
- Wrap {
+ Stack {
TableWithDecorations()
}
}
diff --git a/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/AlignSample.kt b/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/AlignSample.kt
index 396908a..92cbc55 100644
--- a/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/AlignSample.kt
+++ b/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/AlignSample.kt
@@ -20,7 +20,6 @@
import androidx.compose.Composable
import androidx.ui.foundation.Box
import androidx.ui.graphics.Color
-import androidx.ui.layout.Center
import androidx.ui.layout.Column
import androidx.ui.layout.LayoutAlign
import androidx.ui.layout.LayoutGravity
diff --git a/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/IntrinsicSample.kt b/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/IntrinsicSample.kt
index ac529c8..6c00aa0 100644
--- a/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/IntrinsicSample.kt
+++ b/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/IntrinsicSample.kt
@@ -31,7 +31,7 @@
import androidx.ui.layout.MinIntrinsicHeight
import androidx.ui.layout.MinIntrinsicWidth
import androidx.ui.layout.Row
-import androidx.ui.layout.Wrap
+import androidx.ui.layout.Stack
import androidx.ui.unit.dp
/**
@@ -40,13 +40,13 @@
* Here [MinIntrinsicWidth] is adding a speculative width measurement pass for the [Column],
* whose minimum intrinsic width will correspond to the preferred width of the largest
* [Box]. Then [MinIntrinsicWidth] will measure the [Column] with tight width, the same
- * as the premeasured minimum intrinsic width, which due to [LayoutExpandedWidth] will force
+ * as the premeasured minimum intrinsic width, which due to [LayoutWidth.Fill] will force
* the [Box]'s to use the same width.
*/
@Sampled
@Composable
fun SameWidthBoxes() {
- Wrap {
+ Stack {
MinIntrinsicWidth {
Column(LayoutHeight.Fill) {
Box(
@@ -73,13 +73,13 @@
* Here [MinIntrinsicHeight] is adding a speculative height measurement pass for the [Row],
* whose minimum intrinsic height will correspond to the height of the largest [Text]. Then
* [MinIntrinsicHeight] will measure the [Row] with tight height, the same as the premeasured
- * minimum intrinsic height, which due to [LayoutExpandedHeight] will force the [Text]s and
+ * minimum intrinsic height, which due to [LayoutHeight.Fill] will force the [Text]s and
* the divider to use the same height.
*/
@Sampled
@Composable
fun MatchParentDividerForText() {
- Wrap {
+ Stack {
MinIntrinsicHeight {
Row {
Text(
@@ -103,13 +103,13 @@
* Here [MaxIntrinsicWidth] is adding a speculative width measurement pass for the [Column],
* whose maximum intrinsic width will correspond to the preferred width of the largest
* [Box]. Then [MaxIntrinsicWidth] will measure the [Column] with tight width, the same
- * as the premeasured maximum intrinsic width, which due to [LayoutExpandedWidth] modifiers will
+ * as the premeasured maximum intrinsic width, which due to [LayoutWidth.Fill] modifiers will
* force the [Box]s to use the same width.
*/
@Sampled
@Composable
fun SameWidthTextBoxes() {
- Wrap {
+ Stack {
MaxIntrinsicWidth {
Column(LayoutHeight.Fill) {
Box(LayoutWidth.Fill, backgroundColor = Color.Gray) {
@@ -133,13 +133,13 @@
* Here [MaxIntrinsicHeight] is adding a speculative height measurement pass for the [Row], whose
* maximum intrinsic height will correspond to the height of the taller [LayoutAspectRatio]. Then
* [MaxIntrinsicHeight] will measure the [Row] with tight height, the same as the premeasured
- * maximum intrinsic height, which due to [LayoutExpandedHeight] modifier will force the
+ * maximum intrinsic height, which due to [LayoutHeight.Fill] modifier will force the
* [LayoutAspectRatio]s and the divider to use the same height.
*/
@Sampled
@Composable
fun MatchParentDividerForAspectRatio() {
- Wrap {
+ Stack {
MaxIntrinsicHeight {
Row {
val modifier = LayoutHeight.Fill + LayoutFlexible(1f)
diff --git a/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/LayoutOffsetSample.kt b/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/LayoutOffsetSample.kt
new file mode 100644
index 0000000..f51bb0c
--- /dev/null
+++ b/ui/ui-layout/integration-tests/samples/src/main/java/androidx/ui/layout/samples/LayoutOffsetSample.kt
@@ -0,0 +1,37 @@
+/*
+ * 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.ui.layout.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.Composable
+import androidx.ui.core.Text
+import androidx.ui.layout.LayoutAlign
+import androidx.ui.layout.LayoutOffset
+import androidx.ui.layout.LayoutSize
+import androidx.ui.unit.dp
+
+@Sampled
+@Composable
+fun LayoutOffsetModifier() {
+ // This text will be offset (10.dp, 20.dp) from the center of the available space.
+ Text(
+ "Layout offset modifier sample",
+ LayoutSize.Fill +
+ LayoutAlign.Center +
+ LayoutOffset(10.dp, 20.dp)
+ )
+}
diff --git a/ui/ui-layout/src/androidTest/AndroidManifest.xml b/ui/ui-layout/src/androidTest/AndroidManifest.xml
index b39c2a9..2a7fbad 100644
--- a/ui/ui-layout/src/androidTest/AndroidManifest.xml
+++ b/ui/ui-layout/src/androidTest/AndroidManifest.xml
@@ -33,5 +33,8 @@
android:name="androidx.ui.layout.test.TestActivity"
android:theme="@android:style/Theme.Material.NoActionBar.Fullscreen" />
+ <activity
+ android:name="android.app.Activity"
+ android:theme="@android:style/Theme.Material.NoActionBar.Fullscreen" />
</application>
</manifest>
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AlignmentLineTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AlignmentLineTest.kt
index 75cad62..1b648e8 100644
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AlignmentLineTest.kt
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/AlignmentLineTest.kt
@@ -26,7 +26,7 @@
import androidx.ui.layout.AlignmentLineOffset
import androidx.ui.layout.CenterAlignmentLine
import androidx.ui.layout.DpConstraints
-import androidx.ui.layout.Wrap
+import androidx.ui.layout.Stack
import androidx.ui.unit.IntPxSize
import androidx.ui.unit.PxPosition
import androidx.ui.unit.dp
@@ -57,7 +57,7 @@
val childSize = Ref<IntPxSize>()
val childPosition = Ref<PxPosition>()
show {
- Wrap {
+ Stack {
AlignmentLineOffset(testLine, before = beforeDp, after = afterDp) {
SaveLayoutInfo(parentSize, Ref(), layoutLatch)
Layout({ SaveLayoutInfo(childSize, childPosition, layoutLatch) }) { _, _, _ ->
@@ -96,7 +96,7 @@
val childSize = Ref<IntPxSize>()
val childPosition = Ref<PxPosition>()
show {
- Wrap {
+ Stack {
AlignmentLineOffset(testLine, before = beforeDp, after = afterDp) {
SaveLayoutInfo(parentSize, Ref(), layoutLatch)
Layout({ SaveLayoutInfo(childSize, childPosition, layoutLatch) }) { _, _, _ ->
@@ -132,7 +132,7 @@
val childSize = Ref<IntPxSize>()
val childPosition = Ref<PxPosition>()
show {
- Wrap {
+ Stack {
AlignmentLineOffset(testLine, before = beforeDp, after = afterDp) {
SaveLayoutInfo(parentSize, Ref(), layoutLatch)
Layout({ SaveLayoutInfo(childSize, childPosition, layoutLatch) }) { _, _, _ ->
@@ -164,7 +164,7 @@
val childSize = Ref<IntPxSize>()
val childPosition = Ref<PxPosition>()
show {
- Wrap {
+ Stack {
AlignmentLineOffset(testLine, before = beforeDp, after = afterDp) {
SaveLayoutInfo(parentSize, Ref(), layoutLatch)
Layout({ SaveLayoutInfo(childSize, childPosition, layoutLatch) }) { _, _, _ ->
@@ -197,7 +197,7 @@
val childSize = Ref<IntPxSize>()
val childPosition = Ref<PxPosition>()
show {
- Wrap {
+ Stack {
ConstrainedBox(DpConstraints(maxWidth = maxWidth)) {
AlignmentLineOffset(testLine, before = beforeDp, after = afterDp) {
SaveLayoutInfo(parentSize, Ref(), layoutLatch)
@@ -239,7 +239,7 @@
val childSize = Ref<IntPxSize>()
val childPosition = Ref<PxPosition>()
show {
- Wrap {
+ Stack {
ConstrainedBox(DpConstraints(maxHeight = maxHeight)) {
AlignmentLineOffset(testLine, before = beforeDp, after = afterDp) {
SaveLayoutInfo(parentSize, Ref(), layoutLatch)
@@ -273,10 +273,10 @@
val latch = CountDownLatch(1)
val minHeight = 10.dp
show {
- Wrap {
+ Stack {
ConstrainedBox(DpConstraints(minHeight = minHeight)) {
AlignmentLineOffset(testLine) {
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
Assert.assertEquals(minHeight.toIntPx(), constraints.minHeight)
latch.countDown()
}
@@ -293,10 +293,10 @@
val latch = CountDownLatch(1)
val minWidth = 10.dp
show {
- Wrap {
+ Stack {
ConstrainedBox(DpConstraints(minWidth = minWidth)) {
AlignmentLineOffset(testLine) {
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
Assert.assertEquals(minWidth.toIntPx(), constraints.minWidth)
latch.countDown()
}
@@ -313,10 +313,10 @@
val latch = CountDownLatch(1)
val minHeight = 10.dp
show {
- Wrap {
+ Stack {
ConstrainedBox(DpConstraints(minHeight = minHeight)) {
CenterAlignmentLine(testLine) {
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
Assert.assertEquals(minHeight.toIntPx(), constraints.minHeight)
latch.countDown()
}
@@ -333,10 +333,10 @@
val latch = CountDownLatch(1)
val minWidth = 10.dp
show {
- Wrap {
+ Stack {
ConstrainedBox(DpConstraints(minWidth = minWidth)) {
CenterAlignmentLine(testLine) {
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
Assert.assertEquals(minWidth.toIntPx(), constraints.minWidth)
latch.countDown()
}
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ConstraintLayoutTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ConstraintLayoutTest.kt
new file mode 100644
index 0000000..906e9ca
--- /dev/null
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ConstraintLayoutTest.kt
@@ -0,0 +1,147 @@
+/*
+ * 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.ui.layout.test
+
+import androidx.compose.Composable
+import androidx.test.filters.SmallTest
+import androidx.ui.core.LayoutTag
+import androidx.ui.core.Ref
+import androidx.ui.layout.LayoutDirectionModifier
+import androidx.ui.layout.LayoutSize
+import androidx.ui.layout.Stack
+import androidx.ui.layout.constraintlayout.ConstraintLayout
+import androidx.ui.layout.constraintlayout.ConstraintSet
+import androidx.ui.unit.IntPxSize
+import androidx.ui.unit.PxPosition
+import androidx.ui.unit.ipx
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
+
+@SmallTest
+@RunWith(JUnit4::class)
+class ConstraintLayoutTest : LayoutTest() {
+ private val boxSize = 100.ipx
+ private val offset = 150.ipx
+
+ @Test
+ fun testConstraintLayout() {
+ val position = Array(3) { Ref<PxPosition>() }
+ val size = Array(3) { Ref<IntPxSize>() }
+ val countDownLatch = CountDownLatch(3)
+
+ show {
+ TestLayout(size, position, countDownLatch)
+ }
+
+ assertTrue(countDownLatch.await(1, TimeUnit.SECONDS))
+ val root = findAndroidComposeView()
+ waitForDraw(root)
+ val rootWidth = root.width.ipx
+ val rootHeight = root.height.ipx
+
+ assertEquals(
+ PxPosition((rootWidth - boxSize) / 2, (rootHeight - boxSize) / 2),
+ position[0].value
+ )
+ assertEquals(
+ PxPosition(rootWidth / 2 + offset, (rootHeight - boxSize) / 2 - boxSize),
+ position[1].value
+ )
+ assertEquals(
+ PxPosition(offset, rootHeight - boxSize - offset),
+ position[2].value
+ )
+ }
+
+ @Test
+ fun testConstraintLayout_rtl() {
+ val position = Array(3) { Ref<PxPosition>() }
+ val size = Array(3) { Ref<IntPxSize>() }
+ val countDownLatch = CountDownLatch(3)
+
+ show {
+ Stack(LayoutSize.Fill + LayoutDirectionModifier.Rtl) {
+ TestLayout(size, position, countDownLatch)
+ }
+ }
+
+ assertTrue(countDownLatch.await(1, TimeUnit.SECONDS))
+ val root = findAndroidComposeView()
+ waitForDraw(root)
+ val rootWidth = root.width.ipx
+ val rootHeight = root.height.ipx
+
+ assertEquals(
+ PxPosition((rootWidth - boxSize) / 2, (rootHeight - boxSize) / 2),
+ position[0].value
+ )
+ assertEquals(
+ PxPosition(rootWidth / 2 - offset - boxSize, (rootHeight - boxSize) / 2 - boxSize),
+ position[1].value
+ )
+ assertEquals(
+ PxPosition(rootWidth - offset - boxSize, rootHeight - boxSize - offset),
+ position[2].value
+ )
+ }
+
+ @Composable
+ private fun TestLayout(
+ size: Array<Ref<IntPxSize>>,
+ position: Array<Ref<PxPosition>>,
+ countDownLatch: CountDownLatch
+ ) = with(density) {
+ val boxSize = boxSize.toDp()
+ ConstraintLayout(
+ ConstraintSet {
+ val box1 = tag("box1")
+ val box2 = tag("box2")
+ val box3 = tag("box3")
+
+ box1.center()
+
+ val half = createGuidelineFromLeft(percent = 0.5f)
+ box2.apply {
+ left constrainTo half
+ left.margin = offset.toDp()
+ bottom constrainTo box1.top
+ }
+
+ box3.apply {
+ left constrainTo parent.left
+ left.margin = offset.toDp()
+ bottom constrainTo parent.bottom
+ bottom.margin = offset.toDp()
+ }
+ }
+ ) {
+ Stack(LayoutTag("box1") + LayoutSize(boxSize, boxSize)) {
+ SaveLayoutInfo(size[0], position[0], countDownLatch)
+ }
+ Stack(LayoutTag("box2") + LayoutSize(boxSize, boxSize)) {
+ SaveLayoutInfo(size[1], position[1], countDownLatch)
+ }
+ Stack(LayoutTag("box3") + LayoutSize(boxSize, boxSize)) {
+ SaveLayoutInfo(size[2], position[2], countDownLatch)
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ContainerTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ContainerTest.kt
index 424c7c1..f41126e 100644
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ContainerTest.kt
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/ContainerTest.kt
@@ -32,7 +32,7 @@
import androidx.ui.layout.LayoutSize
import androidx.ui.layout.Row
import androidx.ui.layout.Spacer
-import androidx.ui.layout.Wrap
+import androidx.ui.layout.Stack
import androidx.ui.unit.Dp
import androidx.ui.unit.IntPx
import androidx.ui.unit.IntPxSize
@@ -306,7 +306,7 @@
var containerSize: IntPxSize? = null
val latch = CountDownLatch(1)
show {
- Wrap {
+ Stack {
Container(padding = edgeInsets) {
Spacer(LayoutSize(width = childSizeDp, height = childSizeDp))
OnPositioned(onPositioned = { coordinates ->
@@ -331,7 +331,7 @@
var childCoordinates: LayoutCoordinates? = null
val latch = CountDownLatch(1)
show {
- Wrap {
+ Stack {
Container(width = containerSize, height = containerSize, padding = edgeInsets) {
OnChildPositioned(onPositioned = { coordinates ->
childCoordinates = coordinates
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/FlexTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/FlexTest.kt
index d8ba7b9..2822e85 100644
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/FlexTest.kt
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/FlexTest.kt
@@ -48,7 +48,7 @@
import androidx.ui.layout.LayoutWidth
import androidx.ui.layout.Row
import androidx.ui.layout.Spacer
-import androidx.ui.layout.Wrap
+import androidx.ui.layout.Stack
import androidx.ui.unit.Dp
import androidx.ui.unit.IntPx
import androidx.ui.unit.IntPxSize
@@ -1286,11 +1286,11 @@
WithInfiniteConstraints {
ConstrainedBox(DpConstraints(minWidth = rowMinWidth)) {
Row {
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
assertEquals(Constraints(), constraints)
FixedSizeLayout(inflexibleChildWidth.toIntPx(), 0.ipx, mapOf())
}
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
assertEquals(Constraints(), constraints)
FixedSizeLayout(inflexibleChildWidth.toIntPx(), 0.ipx, mapOf())
}
@@ -1321,7 +1321,7 @@
val childHeight = 100.dp
val latch = CountDownLatch(1)
show {
- Wrap {
+ Stack {
ConstrainedBox(
DpConstraints(
minWidth = availableWidth,
@@ -1331,7 +1331,7 @@
)
) {
Row {
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
assertEquals(
Constraints(
maxWidth = availableWidth.toIntPx(),
@@ -1341,7 +1341,7 @@
)
FixedSizeLayout(childWidth.toIntPx(), childHeight.toIntPx(), mapOf())
}
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
assertEquals(
Constraints(
maxWidth = availableWidth.toIntPx() - childWidth.toIntPx(),
@@ -1752,11 +1752,11 @@
WithInfiniteConstraints {
ConstrainedBox(DpConstraints(minHeight = columnMinHeight)) {
Column {
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
assertEquals(Constraints(), constraints)
FixedSizeLayout(0.ipx, inflexibleChildHeight.toIntPx(), mapOf())
}
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
assertEquals(Constraints(), constraints)
FixedSizeLayout(0.ipx, inflexibleChildHeight.toIntPx(), mapOf())
}
@@ -1786,7 +1786,7 @@
val childHeight = 100.dp
val latch = CountDownLatch(1)
show {
- Wrap {
+ Stack {
ConstrainedBox(
DpConstraints(
minWidth = availableWidth,
@@ -1796,7 +1796,7 @@
)
) {
Column {
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
assertEquals(
Constraints(
maxWidth = availableWidth.toIntPx(),
@@ -1806,7 +1806,7 @@
)
FixedSizeLayout(childWidth.toIntPx(), childHeight.toIntPx(), mapOf())
}
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
assertEquals(
Constraints(
maxWidth = availableWidth.toIntPx(),
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/LayoutOffsetTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/LayoutOffsetTest.kt
new file mode 100644
index 0000000..1bdfa66
--- /dev/null
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/LayoutOffsetTest.kt
@@ -0,0 +1,98 @@
+/*
+ * 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.ui.layout.test
+
+import androidx.test.filters.SmallTest
+import androidx.ui.core.OnPositioned
+import androidx.ui.core.TestTag
+import androidx.ui.core.globalPosition
+import androidx.ui.layout.LayoutAlign
+import androidx.ui.layout.LayoutDirectionModifier
+import androidx.ui.layout.LayoutOffset
+import androidx.ui.layout.LayoutWidth
+import androidx.ui.layout.Stack
+import androidx.ui.test.createComposeRule
+import androidx.ui.test.findByTag
+import androidx.ui.unit.dp
+import androidx.ui.unit.ipx
+import androidx.ui.unit.round
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+class LayoutOffsetTest : LayoutTest() {
+ @get:Rule
+ val composeTestRule = createComposeRule()
+
+ @Test
+ fun positionIsModified() = with(density) {
+ val offsetX = 10.dp
+ val offsetY = 20.dp
+ var positionX = 0.ipx
+ var positionY = 0.ipx
+ composeTestRule.setContent {
+ TestTag("stack") {
+ Stack(LayoutAlign.TopStart + LayoutOffset(offsetX, offsetY)) {
+ OnPositioned { coordinates ->
+ positionX = coordinates.globalPosition.x.round()
+ positionY = coordinates.globalPosition.y.round()
+ }
+ }
+ }
+ }
+
+ findByTag("stack").assertExists()
+ composeTestRule.runOnIdleCompose {
+ assertEquals(offsetX.toIntPx(), positionX)
+ assertEquals(offsetY.toIntPx(), positionY)
+ }
+ }
+
+ @Test
+ fun positionIsModified_rtl() = with(density) {
+ val containerWidth = 30.dp
+ val offsetX = 10.dp
+ val offsetY = 20.dp
+ var positionX = 0.ipx
+ var positionY = 0.ipx
+ composeTestRule.setContent {
+ TestTag("stack") {
+ Stack(
+ LayoutDirectionModifier.Rtl +
+ LayoutAlign.TopEnd +
+ LayoutWidth(containerWidth) +
+ LayoutAlign.TopStart +
+ LayoutOffset(offsetX, offsetY)
+ ) {
+ OnPositioned { coordinates ->
+ positionX = coordinates.globalPosition.x.round()
+ positionY = coordinates.globalPosition.y.round()
+ }
+ }
+ }
+ }
+
+ findByTag("stack").assertExists()
+ composeTestRule.runOnIdleCompose {
+ assertEquals(containerWidth.toIntPx() - offsetX.toIntPx(), positionX)
+ assertEquals(offsetY.toIntPx(), positionY)
+ }
+ }
+}
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/LayoutPaddingTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/LayoutPaddingTest.kt
index c98feef..0b6decf 100644
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/LayoutPaddingTest.kt
+++ b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/LayoutPaddingTest.kt
@@ -53,6 +53,38 @@
class LayoutPaddingTest : LayoutTest() {
/**
+ * Tests that negative start padding is not allowed.
+ */
+ @Test(expected = IllegalArgumentException::class)
+ fun negativeStartPadding_throws() {
+ LayoutPadding(start = -1f.dp)
+ }
+
+ /**
+ * Tests that negative top padding is not allowed.
+ */
+ @Test(expected = IllegalArgumentException::class)
+ fun negativeTopPadding_throws() {
+ LayoutPadding(top = -1f.dp)
+ }
+
+ /**
+ * Tests that negative end padding is not allowed.
+ */
+ @Test(expected = IllegalArgumentException::class)
+ fun negativeEndPadding_throws() {
+ LayoutPadding(end = -1f.dp)
+ }
+
+ /**
+ * Tests that negative bottom padding is not allowed.
+ */
+ @Test(expected = IllegalArgumentException::class)
+ fun negativeBottomPadding_throws() {
+ LayoutPadding(bottom = -1f.dp)
+ }
+
+ /**
* Tests that the [LayoutPadding]-all and [LayoutPadding] factories return equivalent modifiers.
*/
@Test
diff --git a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/WrapTest.kt b/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/WrapTest.kt
deleted file mode 100644
index 9f26437..0000000
--- a/ui/ui-layout/src/androidTest/java/androidx/ui/layout/test/WrapTest.kt
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Copyright 2019 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.ui.layout.test
-
-import androidx.compose.Composable
-import androidx.test.filters.SmallTest
-import androidx.ui.core.Alignment
-import androidx.ui.core.OnChildPositioned
-import androidx.ui.core.Ref
-import androidx.ui.layout.Align
-import androidx.ui.layout.Container
-import androidx.ui.layout.DpConstraints
-import androidx.ui.layout.LayoutAspectRatio
-import androidx.ui.layout.Wrap
-import androidx.ui.unit.IntPx
-import androidx.ui.unit.IntPxSize
-import androidx.ui.unit.PxPosition
-import androidx.ui.unit.dp
-import androidx.ui.unit.px
-import org.junit.Assert.assertEquals
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.junit.runners.JUnit4
-import java.util.concurrent.CountDownLatch
-import java.util.concurrent.TimeUnit
-
-@SmallTest
-@RunWith(JUnit4::class)
-class WrapTest : LayoutTest() {
- @Test
- fun testWrap() = with(density) {
- val sizeDp = 50.dp
- val size = sizeDp.toIntPx()
-
- val positionedLatch = CountDownLatch(2)
- val wrapSize = Ref<IntPxSize>()
- val childSize = Ref<IntPxSize>()
- val childPosition = Ref<PxPosition>()
- show {
- Align(alignment = Alignment.TopStart) {
- OnChildPositioned(onPositioned = { coordinates ->
- wrapSize.value = coordinates.size
- positionedLatch.countDown()
- }) {
- Wrap {
- Container(width = sizeDp, height = sizeDp) {
- SaveLayoutInfo(
- size = childSize,
- position = childPosition,
- positionedLatch = positionedLatch
- )
- }
- }
- }
- }
- }
- positionedLatch.await(1, TimeUnit.SECONDS)
-
- assertEquals(IntPxSize(size, size), wrapSize.value)
- assertEquals(IntPxSize(size, size), childSize.value)
- assertEquals(PxPosition(0.px, 0.px), childPosition.value)
- }
-
- @Test
- fun testWrap_respectsMinConstraints() = with(density) {
- val sizeDp = 50.dp
- val size = sizeDp.toIntPx()
- val doubleSizeDp = sizeDp * 2
- val doubleSize = doubleSizeDp.toIntPx()
-
- val positionedLatch = CountDownLatch(2)
- val wrapSize = Ref<IntPxSize>()
- val childSize = Ref<IntPxSize>()
- val childPosition = Ref<PxPosition>()
- show {
- Align(alignment = Alignment.TopStart) {
- OnChildPositioned(onPositioned = { coordinates ->
- wrapSize.value = coordinates.size
- positionedLatch.countDown()
- }) {
- val constraints =
- DpConstraints(minWidth = doubleSizeDp, minHeight = doubleSizeDp)
- ConstrainedBox(constraints = constraints) {
- Wrap {
- Container(width = sizeDp, height = sizeDp) {
- SaveLayoutInfo(
- size = childSize,
- position = childPosition,
- positionedLatch = positionedLatch
- )
- }
- }
- }
- }
- }
- }
- positionedLatch.await(1, TimeUnit.SECONDS)
-
- assertEquals(IntPxSize(doubleSize, doubleSize), wrapSize.value)
- assertEquals(IntPxSize(size, size), childSize.value)
- assertEquals(PxPosition(0.px, 0.px), childPosition.value)
- }
-
- @Test
- fun testWrap_respectsMinConstraintsAndAlignment() = with(density) {
- val sizeDp = 50.dp
- val size = sizeDp.toIntPx()
- val doubleSizeDp = sizeDp * 2
- val doubleSize = doubleSizeDp.toIntPx()
-
- val positionedLatch = CountDownLatch(2)
- val wrapSize = Ref<IntPxSize>()
- val childSize = Ref<IntPxSize>()
- val childPosition = Ref<PxPosition>()
- show {
- Align(alignment = Alignment.TopStart) {
- OnChildPositioned(onPositioned = { coordinates ->
- wrapSize.value = coordinates.size
- positionedLatch.countDown()
- }) {
- val constraints = DpConstraints(
- minWidth = doubleSizeDp,
- minHeight = doubleSizeDp
- )
- ConstrainedBox(constraints = constraints) {
- Wrap(alignment = Alignment.Center) {
- Container(width = sizeDp, height = sizeDp) {
- SaveLayoutInfo(
- size = childSize,
- position = childPosition,
- positionedLatch = positionedLatch
- )
- }
- }
- }
- }
- }
- }
- positionedLatch.await(1, TimeUnit.SECONDS)
-
- assertEquals(IntPxSize(doubleSize, doubleSize), wrapSize.value)
- assertEquals(IntPxSize(size, size), childSize.value)
- assertEquals(PxPosition(size / 2, size / 2), childPosition.value)
- }
-
- @Test
- fun testWrap_hasCorrectIntrinsicMeasurements() = with(density) {
- testIntrinsics(@Composable {
- Wrap {
- Container(modifier = LayoutAspectRatio(2f)) { }
- }
- }) { minIntrinsicWidth, minIntrinsicHeight, maxIntrinsicWidth, maxIntrinsicHeight ->
- // Min width.
- assertEquals(25.dp.toIntPx() * 2, minIntrinsicWidth(25.dp.toIntPx()))
- assertEquals(0.dp.toIntPx(), minIntrinsicWidth(IntPx.Infinity))
- // Min height.
- assertEquals(50.dp.toIntPx() / 2, minIntrinsicHeight(50.dp.toIntPx()))
- assertEquals(0.dp.toIntPx(), minIntrinsicHeight(IntPx.Infinity))
- // Max width.
- assertEquals(25.dp.toIntPx() * 2, maxIntrinsicWidth(25.dp.toIntPx()))
- assertEquals(0.dp.toIntPx(), maxIntrinsicWidth(IntPx.Infinity))
- // Max height.
- assertEquals(50.dp.toIntPx() / 2, maxIntrinsicHeight(50.dp.toIntPx()))
- assertEquals(0.dp.toIntPx(), maxIntrinsicHeight(IntPx.Infinity))
- }
- }
-
- @Test
- fun testWrap_hasCorrectIntrinsicMeasurements_whenNoChildren() = with(density) {
- testIntrinsics(@Composable {
- Wrap { }
- }) { minIntrinsicWidth, minIntrinsicHeight, maxIntrinsicWidth, maxIntrinsicHeight ->
- // Min width.
- assertEquals(0.dp.toIntPx(), minIntrinsicWidth(25.dp.toIntPx()))
- // Min height.
- assertEquals(0.dp.toIntPx(), minIntrinsicHeight(25.dp.toIntPx()))
- // Max width.
- assertEquals(0.dp.toIntPx(), maxIntrinsicWidth(25.dp.toIntPx()))
- // Max height.
- assertEquals(0.dp.toIntPx(), maxIntrinsicHeight(25.dp.toIntPx()))
- }
- }
-}
\ No newline at end of file
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Align.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Align.kt
index be37264..ae38396 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Align.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Align.kt
@@ -37,9 +37,7 @@
* or wrap content otherwise.
*
* For a composable that just does center alignment, see [Center].
- * For a composable that does alignment and tries to be the same size as its child, see [Wrap].
* @see Center
- * @see Wrap
*/
@Composable
// TODO (b/145599478): remove usages of Align and Center, and fully deprecate them
@@ -81,9 +79,7 @@
* constraints, or wrap content otherwise.
*
* For a composable that supports other alignments than just center, see [Align].
- * For a composable that does alignment and tries to be the same size as its child, see [Wrap].
* @see Align
- * @see Wrap
*/
@Composable
fun Center(children: @Composable() () -> Unit) {
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/AlignmentLine.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/AlignmentLine.kt
index e6ac2bd..100d09b 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/AlignmentLine.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/AlignmentLine.kt
@@ -77,7 +77,7 @@
layout(containerWidth, containerHeight) {
val x = if (alignmentLine.horizontal) 0.ipx else paddingBefore
val y = if (alignmentLine.horizontal) paddingBefore else 0.ipx
- placeable.place(x, y)
+ placeable.placeAbsolute(x, y)
}
}
}
@@ -145,7 +145,7 @@
} else {
centeredPosition.y
}
- placeable.place(childX, childY)
+ placeable.placeAbsolute(childX, childY)
}
}
}
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/ConstraintLayout.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/ConstraintLayout.kt
index e81be44..41a7a4f 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/ConstraintLayout.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/ConstraintLayout.kt
@@ -646,6 +646,7 @@
for (child in root.children) {
val measurable = child.companionWidget
if (measurable !is Measurable) continue
+ // TODO(popam): check if measurer's rtl support should be used instead
placeables[measurable]?.place(IntPx(child.x), IntPx(child.y))
}
}
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Flex.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Flex.kt
index 227cecf..d7bf63d 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Flex.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Flex.kt
@@ -859,9 +859,9 @@
}
}
if (orientation == LayoutOrientation.Horizontal) {
- placeable.place(mainAxisPositions[index], crossAxis)
+ placeable.placeAbsolute(mainAxisPositions[index], crossAxis)
} else {
- placeable.place(crossAxis, mainAxisPositions[index])
+ placeable.placeAbsolute(crossAxis, mainAxisPositions[index])
}
}
}
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Flow.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Flow.kt
index cbec9c2..a86f39a 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Flow.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Flow.kt
@@ -257,12 +257,12 @@
).y
}
if (orientation == LayoutOrientation.Horizontal) {
- placeable.place(
+ placeable.placeAbsolute(
x = mainAxisPositions[j],
y = crossAxisPositions[i] + crossAxis
)
} else {
- placeable.place(
+ placeable.placeAbsolute(
x = crossAxisPositions[i] + crossAxis,
y = mainAxisPositions[j]
)
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Intrinsic.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Intrinsic.kt
index 5aaa3d5..e7ec344 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Intrinsic.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Intrinsic.kt
@@ -60,7 +60,7 @@
Constraints.fixedWidth(width).enforce(constraints)
)
layout(placeable?.width ?: 0.ipx, placeable?.height ?: 0.ipx) {
- placeable?.place(0.ipx, 0.ipx)
+ placeable?.placeAbsolute(0.ipx, 0.ipx)
}
}
}
@@ -105,7 +105,7 @@
Constraints.fixedHeight(height).enforce(constraints)
)
layout(placeable?.width ?: 0.ipx, placeable?.height ?: 0.ipx) {
- placeable?.place(0.ipx, 0.ipx)
+ placeable?.placeAbsolute(0.ipx, 0.ipx)
}
}
}
@@ -150,7 +150,7 @@
Constraints.fixedWidth(width).enforce(constraints)
)
layout(placeable?.width ?: 0.ipx, placeable?.height ?: 0.ipx) {
- placeable?.place(0.ipx, 0.ipx)
+ placeable?.placeAbsolute(0.ipx, 0.ipx)
}
}
}
@@ -195,7 +195,7 @@
Constraints.fixedHeight(height).enforce(constraints)
)
layout(placeable?.width ?: 0.ipx, placeable?.height ?: 0.ipx) {
- placeable?.place(0.ipx, 0.ipx)
+ placeable?.placeAbsolute(0.ipx, 0.ipx)
}
}
}
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/LayoutOffset.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/LayoutOffset.kt
new file mode 100644
index 0000000..5c0d0f1
--- /dev/null
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/LayoutOffset.kt
@@ -0,0 +1,52 @@
+/*
+ * 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.ui.layout
+
+import androidx.ui.core.LayoutDirection
+import androidx.ui.core.LayoutModifier
+import androidx.ui.unit.Density
+import androidx.ui.unit.Dp
+import androidx.ui.unit.IntPxPosition
+import androidx.ui.unit.IntPxSize
+
+/**
+ * A [LayoutModifier] that offsets the position of the wrapped layout with the given
+ * horizontal and vertical offsets. The offsets can be positive as well as non positive.
+ * If the position of the wrapped layout on screen is (posx, posy) and the offsets are [x] and [y],
+ * by applying this modifier the position will become (posx + x, posy + y) if the current
+ * layout direction is LTR, or (posx - x, posy + y) otherwise.
+ * The [LayoutOffset] modifier should always be used instead of [LayoutPadding] whenever only the
+ * position of the wrapped layout should be modified, since using [LayoutPadding] will also affect
+ * the size of the wrapped layout. Also note that [LayoutPadding] cannot be used with negative
+ * padding in order to achieve negative offsets.
+ *
+ * Example usage:
+ * @sample androidx.ui.layout.samples.LayoutOffsetModifier
+ *
+ * @param x The horizontal offset added to the position of the wrapped layout
+ * @param y The vertical offset added to the position of the wrapped layout
+ */
+data class LayoutOffset(val x: Dp, val y: Dp) : LayoutModifier {
+ override fun Density.modifyPosition(
+ childSize: IntPxSize,
+ containerSize: IntPxSize,
+ layoutDirection: LayoutDirection
+ ) = IntPxPosition(
+ (if (layoutDirection == LayoutDirection.Ltr) x else -x).toIntPx(),
+ y.toIntPx()
+ )
+}
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Padding.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Padding.kt
index bcd96c4..cc53490 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Padding.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Padding.kt
@@ -28,10 +28,19 @@
import androidx.ui.unit.dp
/**
- * Layout modifier that applies the same padding of [all] dp on each side of the target layout.
+ * Layout modifier that applies the same padding of [all] dp on each side of the wrapped layout.
+ * The requested padding will be subtracted from the available space before the wrapped layout has
+ * the chance to choose its own size, so conceptually the padding has higher priority to occupy
+ * the available space than the content.
+ * If you only need to modify the position of the wrapped layout without affecting its size
+ * as described above, you should use the [LayoutOffset] modifier instead.
+ * Also note that padding must be non-negative. If you consider using negative (or positive)
+ * padding to offset the wrapped layout, [LayoutOffset] should be used.
*
* Example usage:
* @sample androidx.ui.layout.samples.LayoutPaddingAllModifier
+ *
+ * @see LayoutOffset
*/
fun LayoutPadding(all: Dp): LayoutPadding = LayoutPadding(
start = all,
@@ -41,11 +50,19 @@
)
/**
- * A [LayoutModifier] that adds [start], [top], [end] and [bottom] padding
- * to the wrapped layout.
+ * A [LayoutModifier] that adds [start], [top], [end] and [bottom] padding to the wrapped layout.
+ * The requested padding will be subtracted from the available space before the wrapped layout has
+ * the chance to choose its own size, so conceptually the padding has higher priority to occupy
+ * the available space than the content.
+ * If you only need to modify the position of the wrapped layout without affecting its size
+ * as described above, you should use the [LayoutOffset] modifier instead.
+ * Also note that padding must be non-negative. If you consider using negative (or positive)
+ * padding to offset the wrapped layout, [LayoutOffset] should be used.
*
* Example usage:
* @sample androidx.ui.layout.samples.LayoutPaddingModifier
+ *
+ * @see LayoutOffset
*/
data class LayoutPadding(
val start: Dp = 0.dp,
@@ -53,6 +70,13 @@
val end: Dp = 0.dp,
val bottom: Dp = 0.dp
) : LayoutModifier {
+ init {
+ require(
+ start.value >= 0f && top.value >= 0f && end.value >= 0f && bottom.value >= 0f,
+ PaddingMustBeNonNegative
+ )
+ }
+
override fun Density.modifyConstraints(
constraints: Constraints,
layoutDirection: LayoutDirection
@@ -81,6 +105,10 @@
} else {
IntPxPosition(end.toIntPx(), top.toIntPx())
}
+
+ internal companion object {
+ val PaddingMustBeNonNegative = { "Padding must be non-negative" }
+ }
}
/**
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Stack.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Stack.kt
index 9d48b87..46cc732 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Stack.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Stack.kt
@@ -86,7 +86,7 @@
),
layoutDirection
)
- placeable.place(position.x, position.y)
+ placeable.placeAbsolute(position.x, position.y)
}
}
}
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Table.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Table.kt
index b7b8d7c..aa4ec1d 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Table.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Table.kt
@@ -611,7 +611,7 @@
height = rowHeights[row] - it.height
)
)
- it.place(
+ it.placeAbsolute(
x = columnOffsets[column] + position.x,
y = rowOffsets[row] + position.y
)
@@ -621,7 +621,7 @@
val decorationConstraints =
Constraints.fixed(tableSize.width, tableSize.height)
measurables.filter { it.rowIndex == null }.forEach {
- it.measure(decorationConstraints).place(IntPx.Zero, IntPx.Zero)
+ it.measure(decorationConstraints).placeAbsolute(IntPx.Zero, IntPx.Zero)
}
}
}
diff --git a/ui/ui-layout/src/main/java/androidx/ui/layout/Wrap.kt b/ui/ui-layout/src/main/java/androidx/ui/layout/Wrap.kt
index bdb8350..8c28f22 100644
--- a/ui/ui-layout/src/main/java/androidx/ui/layout/Wrap.kt
+++ b/ui/ui-layout/src/main/java/androidx/ui/layout/Wrap.kt
@@ -33,6 +33,10 @@
* For a composable that does alignment and tries to be as large as possible, see [Align].
*/
@Composable
+@Deprecated(
+ "Wrap is deprecated. Use the LayoutAlign modifier or Stack instead.",
+ ReplaceWith("Stack(children)")
+)
fun Wrap(alignment: Alignment = Alignment.TopStart, children: @Composable() () -> Unit) {
Layout(children) { measurables, constraints, _ ->
val measurable = measurables.firstOrNull()
diff --git a/ui/ui-material/api/0.1.0-dev07.txt b/ui/ui-material/api/0.1.0-dev07.txt
index a201912..b3147bb 100644
--- a/ui/ui-material/api/0.1.0-dev07.txt
+++ b/ui/ui-material/api/0.1.0-dev07.txt
@@ -36,10 +36,20 @@
method public static void BottomNavigationItem(androidx.ui.layout.RowScope, kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> text = emptyContent(), boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onSelected, androidx.ui.core.Modifier modifier = Modifier.None, boolean alwaysShowLabels = true, androidx.ui.graphics.Color activeColor = contentColor(), androidx.ui.graphics.Color inactiveColor = MaterialTheme.emphasisLevels().medium.emphasize(activeColor));
}
+ public final class Button {
+ method public androidx.ui.layout.EdgeInsets getDefaultInnerPadding();
+ property public final androidx.ui.layout.EdgeInsets DefaultInnerPadding;
+ field public static final androidx.ui.material.Button! INSTANCE;
+ }
+
public final class ButtonKt {
- method public static void Button(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().primary, androidx.ui.graphics.Color contentColor = contentColorFor(backgroundColor), androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 2.dp, androidx.ui.layout.EdgeInsets paddings = ButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static inline void OutlinedButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = Border(1.dp, MaterialTheme.colors().onSurface.copy(OutlinedStrokeOpacity)), androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.layout.EdgeInsets paddings = ButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static inline void TextButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.layout.EdgeInsets paddings = TextButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 2.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().primary, androidx.ui.graphics.Color contentColor = contentColorFor(backgroundColor), androidx.ui.layout.EdgeInsets innerPadding = Button.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static inline void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = Border(1.dp, MaterialTheme.colors().onSurface.copy(OutlinedStrokeOpacity)), androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.layout.EdgeInsets innerPadding = Button.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static inline void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.layout.EdgeInsets innerPadding = TextButton.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ }
+
+ public final class CardKt {
+ method public static void Card(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = card, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 1.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class CheckboxKt {
@@ -145,25 +155,22 @@
public final class EmphasisKt {
method public static void ProvideEmphasis(androidx.ui.material.Emphasis emphasis, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static androidx.compose.ProvidableAmbient<androidx.ui.material.EmphasisLevels> getEmphasisAmbient();
+ method public static androidx.compose.Ambient<androidx.ui.material.EmphasisLevels> getEmphasisAmbient();
}
- public final class EmphasisLevels {
- ctor public EmphasisLevels(androidx.ui.material.Emphasis high, androidx.ui.material.Emphasis medium, androidx.ui.material.Emphasis disabled);
- ctor public EmphasisLevels();
- method public androidx.ui.material.Emphasis component1();
- method public androidx.ui.material.Emphasis component2();
- method public androidx.ui.material.Emphasis component3();
- method public androidx.ui.material.EmphasisLevels copy(androidx.ui.material.Emphasis high, androidx.ui.material.Emphasis medium, androidx.ui.material.Emphasis disabled);
+ public interface EmphasisLevels {
method public androidx.ui.material.Emphasis getDisabled();
method public androidx.ui.material.Emphasis getHigh();
method public androidx.ui.material.Emphasis getMedium();
+ property public abstract androidx.ui.material.Emphasis disabled;
+ property public abstract androidx.ui.material.Emphasis high;
+ property public abstract androidx.ui.material.Emphasis medium;
}
public final class FloatingActionButtonKt {
- method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.unit.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static void FloatingActionButton(androidx.ui.graphics.ImageAsset icon, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
- method public static void FloatingActionButton(String text, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.ImageAsset? icon = null, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
+ method public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void FloatingActionButton(androidx.ui.graphics.ImageAsset icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
+ method public static void FloatingActionButton(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.ImageAsset? icon = null, androidx.ui.text.TextStyle? textStyle = null, boolean enabled = true, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
}
public final class IconButtonKt {
@@ -263,6 +270,11 @@
method public static androidx.ui.graphics.Color snackbarPrimaryColorFor(androidx.ui.material.ColorPalette colors);
}
+ public final class SurfaceKt {
+ method public static void Surface(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.graphics.Color getPrimarySurface(androidx.ui.material.ColorPalette);
+ }
+
public final class SwitchKt {
method public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, androidx.ui.graphics.Color color = MaterialTheme.colors().secondaryVariant);
}
@@ -291,6 +303,12 @@
property public final androidx.ui.unit.IntPx right;
}
+ public final class TextButton {
+ method public androidx.ui.layout.EdgeInsets getDefaultInnerPadding();
+ property public final androidx.ui.layout.EdgeInsets DefaultInnerPadding;
+ field public static final androidx.ui.material.TextButton! INSTANCE;
+ }
+
public final class Typography {
ctor public Typography(androidx.ui.text.TextStyle h1, androidx.ui.text.TextStyle h2, androidx.ui.text.TextStyle h3, androidx.ui.text.TextStyle h4, androidx.ui.text.TextStyle h5, androidx.ui.text.TextStyle h6, androidx.ui.text.TextStyle subtitle1, androidx.ui.text.TextStyle subtitle2, androidx.ui.text.TextStyle body1, androidx.ui.text.TextStyle body2, androidx.ui.text.TextStyle button, androidx.ui.text.TextStyle caption, androidx.ui.text.TextStyle overline);
ctor public Typography();
@@ -376,16 +394,3 @@
}
-package androidx.ui.material.surface {
-
- public final class CardKt {
- method public static void Card(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = card, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 1.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- }
-
- public final class SurfaceKt {
- method public static void Surface(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static androidx.ui.graphics.Color getPrimarySurface(androidx.ui.material.ColorPalette);
- }
-
-}
-
diff --git a/ui/ui-material/api/current.txt b/ui/ui-material/api/current.txt
index a201912..b3147bb 100644
--- a/ui/ui-material/api/current.txt
+++ b/ui/ui-material/api/current.txt
@@ -36,10 +36,20 @@
method public static void BottomNavigationItem(androidx.ui.layout.RowScope, kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> text = emptyContent(), boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onSelected, androidx.ui.core.Modifier modifier = Modifier.None, boolean alwaysShowLabels = true, androidx.ui.graphics.Color activeColor = contentColor(), androidx.ui.graphics.Color inactiveColor = MaterialTheme.emphasisLevels().medium.emphasize(activeColor));
}
+ public final class Button {
+ method public androidx.ui.layout.EdgeInsets getDefaultInnerPadding();
+ property public final androidx.ui.layout.EdgeInsets DefaultInnerPadding;
+ field public static final androidx.ui.material.Button! INSTANCE;
+ }
+
public final class ButtonKt {
- method public static void Button(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().primary, androidx.ui.graphics.Color contentColor = contentColorFor(backgroundColor), androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 2.dp, androidx.ui.layout.EdgeInsets paddings = ButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static inline void OutlinedButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = Border(1.dp, MaterialTheme.colors().onSurface.copy(OutlinedStrokeOpacity)), androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.layout.EdgeInsets paddings = ButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static inline void TextButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.layout.EdgeInsets paddings = TextButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 2.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().primary, androidx.ui.graphics.Color contentColor = contentColorFor(backgroundColor), androidx.ui.layout.EdgeInsets innerPadding = Button.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static inline void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = Border(1.dp, MaterialTheme.colors().onSurface.copy(OutlinedStrokeOpacity)), androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.layout.EdgeInsets innerPadding = Button.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static inline void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.layout.EdgeInsets innerPadding = TextButton.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ }
+
+ public final class CardKt {
+ method public static void Card(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = card, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 1.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class CheckboxKt {
@@ -145,25 +155,22 @@
public final class EmphasisKt {
method public static void ProvideEmphasis(androidx.ui.material.Emphasis emphasis, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static androidx.compose.ProvidableAmbient<androidx.ui.material.EmphasisLevels> getEmphasisAmbient();
+ method public static androidx.compose.Ambient<androidx.ui.material.EmphasisLevels> getEmphasisAmbient();
}
- public final class EmphasisLevels {
- ctor public EmphasisLevels(androidx.ui.material.Emphasis high, androidx.ui.material.Emphasis medium, androidx.ui.material.Emphasis disabled);
- ctor public EmphasisLevels();
- method public androidx.ui.material.Emphasis component1();
- method public androidx.ui.material.Emphasis component2();
- method public androidx.ui.material.Emphasis component3();
- method public androidx.ui.material.EmphasisLevels copy(androidx.ui.material.Emphasis high, androidx.ui.material.Emphasis medium, androidx.ui.material.Emphasis disabled);
+ public interface EmphasisLevels {
method public androidx.ui.material.Emphasis getDisabled();
method public androidx.ui.material.Emphasis getHigh();
method public androidx.ui.material.Emphasis getMedium();
+ property public abstract androidx.ui.material.Emphasis disabled;
+ property public abstract androidx.ui.material.Emphasis high;
+ property public abstract androidx.ui.material.Emphasis medium;
}
public final class FloatingActionButtonKt {
- method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.unit.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static void FloatingActionButton(androidx.ui.graphics.ImageAsset icon, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
- method public static void FloatingActionButton(String text, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.ImageAsset? icon = null, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
+ method public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void FloatingActionButton(androidx.ui.graphics.ImageAsset icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
+ method public static void FloatingActionButton(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.ImageAsset? icon = null, androidx.ui.text.TextStyle? textStyle = null, boolean enabled = true, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
}
public final class IconButtonKt {
@@ -263,6 +270,11 @@
method public static androidx.ui.graphics.Color snackbarPrimaryColorFor(androidx.ui.material.ColorPalette colors);
}
+ public final class SurfaceKt {
+ method public static void Surface(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.graphics.Color getPrimarySurface(androidx.ui.material.ColorPalette);
+ }
+
public final class SwitchKt {
method public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, androidx.ui.graphics.Color color = MaterialTheme.colors().secondaryVariant);
}
@@ -291,6 +303,12 @@
property public final androidx.ui.unit.IntPx right;
}
+ public final class TextButton {
+ method public androidx.ui.layout.EdgeInsets getDefaultInnerPadding();
+ property public final androidx.ui.layout.EdgeInsets DefaultInnerPadding;
+ field public static final androidx.ui.material.TextButton! INSTANCE;
+ }
+
public final class Typography {
ctor public Typography(androidx.ui.text.TextStyle h1, androidx.ui.text.TextStyle h2, androidx.ui.text.TextStyle h3, androidx.ui.text.TextStyle h4, androidx.ui.text.TextStyle h5, androidx.ui.text.TextStyle h6, androidx.ui.text.TextStyle subtitle1, androidx.ui.text.TextStyle subtitle2, androidx.ui.text.TextStyle body1, androidx.ui.text.TextStyle body2, androidx.ui.text.TextStyle button, androidx.ui.text.TextStyle caption, androidx.ui.text.TextStyle overline);
ctor public Typography();
@@ -376,16 +394,3 @@
}
-package androidx.ui.material.surface {
-
- public final class CardKt {
- method public static void Card(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = card, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 1.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- }
-
- public final class SurfaceKt {
- method public static void Surface(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static androidx.ui.graphics.Color getPrimarySurface(androidx.ui.material.ColorPalette);
- }
-
-}
-
diff --git a/ui/ui-material/api/public_plus_experimental_0.1.0-dev07.txt b/ui/ui-material/api/public_plus_experimental_0.1.0-dev07.txt
index a201912..b3147bb 100644
--- a/ui/ui-material/api/public_plus_experimental_0.1.0-dev07.txt
+++ b/ui/ui-material/api/public_plus_experimental_0.1.0-dev07.txt
@@ -36,10 +36,20 @@
method public static void BottomNavigationItem(androidx.ui.layout.RowScope, kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> text = emptyContent(), boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onSelected, androidx.ui.core.Modifier modifier = Modifier.None, boolean alwaysShowLabels = true, androidx.ui.graphics.Color activeColor = contentColor(), androidx.ui.graphics.Color inactiveColor = MaterialTheme.emphasisLevels().medium.emphasize(activeColor));
}
+ public final class Button {
+ method public androidx.ui.layout.EdgeInsets getDefaultInnerPadding();
+ property public final androidx.ui.layout.EdgeInsets DefaultInnerPadding;
+ field public static final androidx.ui.material.Button! INSTANCE;
+ }
+
public final class ButtonKt {
- method public static void Button(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().primary, androidx.ui.graphics.Color contentColor = contentColorFor(backgroundColor), androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 2.dp, androidx.ui.layout.EdgeInsets paddings = ButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static inline void OutlinedButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = Border(1.dp, MaterialTheme.colors().onSurface.copy(OutlinedStrokeOpacity)), androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.layout.EdgeInsets paddings = ButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static inline void TextButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.layout.EdgeInsets paddings = TextButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 2.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().primary, androidx.ui.graphics.Color contentColor = contentColorFor(backgroundColor), androidx.ui.layout.EdgeInsets innerPadding = Button.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static inline void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = Border(1.dp, MaterialTheme.colors().onSurface.copy(OutlinedStrokeOpacity)), androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.layout.EdgeInsets innerPadding = Button.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static inline void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.layout.EdgeInsets innerPadding = TextButton.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ }
+
+ public final class CardKt {
+ method public static void Card(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = card, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 1.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class CheckboxKt {
@@ -145,25 +155,22 @@
public final class EmphasisKt {
method public static void ProvideEmphasis(androidx.ui.material.Emphasis emphasis, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static androidx.compose.ProvidableAmbient<androidx.ui.material.EmphasisLevels> getEmphasisAmbient();
+ method public static androidx.compose.Ambient<androidx.ui.material.EmphasisLevels> getEmphasisAmbient();
}
- public final class EmphasisLevels {
- ctor public EmphasisLevels(androidx.ui.material.Emphasis high, androidx.ui.material.Emphasis medium, androidx.ui.material.Emphasis disabled);
- ctor public EmphasisLevels();
- method public androidx.ui.material.Emphasis component1();
- method public androidx.ui.material.Emphasis component2();
- method public androidx.ui.material.Emphasis component3();
- method public androidx.ui.material.EmphasisLevels copy(androidx.ui.material.Emphasis high, androidx.ui.material.Emphasis medium, androidx.ui.material.Emphasis disabled);
+ public interface EmphasisLevels {
method public androidx.ui.material.Emphasis getDisabled();
method public androidx.ui.material.Emphasis getHigh();
method public androidx.ui.material.Emphasis getMedium();
+ property public abstract androidx.ui.material.Emphasis disabled;
+ property public abstract androidx.ui.material.Emphasis high;
+ property public abstract androidx.ui.material.Emphasis medium;
}
public final class FloatingActionButtonKt {
- method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.unit.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static void FloatingActionButton(androidx.ui.graphics.ImageAsset icon, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
- method public static void FloatingActionButton(String text, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.ImageAsset? icon = null, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
+ method public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void FloatingActionButton(androidx.ui.graphics.ImageAsset icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
+ method public static void FloatingActionButton(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.ImageAsset? icon = null, androidx.ui.text.TextStyle? textStyle = null, boolean enabled = true, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
}
public final class IconButtonKt {
@@ -263,6 +270,11 @@
method public static androidx.ui.graphics.Color snackbarPrimaryColorFor(androidx.ui.material.ColorPalette colors);
}
+ public final class SurfaceKt {
+ method public static void Surface(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.graphics.Color getPrimarySurface(androidx.ui.material.ColorPalette);
+ }
+
public final class SwitchKt {
method public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, androidx.ui.graphics.Color color = MaterialTheme.colors().secondaryVariant);
}
@@ -291,6 +303,12 @@
property public final androidx.ui.unit.IntPx right;
}
+ public final class TextButton {
+ method public androidx.ui.layout.EdgeInsets getDefaultInnerPadding();
+ property public final androidx.ui.layout.EdgeInsets DefaultInnerPadding;
+ field public static final androidx.ui.material.TextButton! INSTANCE;
+ }
+
public final class Typography {
ctor public Typography(androidx.ui.text.TextStyle h1, androidx.ui.text.TextStyle h2, androidx.ui.text.TextStyle h3, androidx.ui.text.TextStyle h4, androidx.ui.text.TextStyle h5, androidx.ui.text.TextStyle h6, androidx.ui.text.TextStyle subtitle1, androidx.ui.text.TextStyle subtitle2, androidx.ui.text.TextStyle body1, androidx.ui.text.TextStyle body2, androidx.ui.text.TextStyle button, androidx.ui.text.TextStyle caption, androidx.ui.text.TextStyle overline);
ctor public Typography();
@@ -376,16 +394,3 @@
}
-package androidx.ui.material.surface {
-
- public final class CardKt {
- method public static void Card(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = card, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 1.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- }
-
- public final class SurfaceKt {
- method public static void Surface(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static androidx.ui.graphics.Color getPrimarySurface(androidx.ui.material.ColorPalette);
- }
-
-}
-
diff --git a/ui/ui-material/api/public_plus_experimental_current.txt b/ui/ui-material/api/public_plus_experimental_current.txt
index a201912..b3147bb 100644
--- a/ui/ui-material/api/public_plus_experimental_current.txt
+++ b/ui/ui-material/api/public_plus_experimental_current.txt
@@ -36,10 +36,20 @@
method public static void BottomNavigationItem(androidx.ui.layout.RowScope, kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> text = emptyContent(), boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onSelected, androidx.ui.core.Modifier modifier = Modifier.None, boolean alwaysShowLabels = true, androidx.ui.graphics.Color activeColor = contentColor(), androidx.ui.graphics.Color inactiveColor = MaterialTheme.emphasisLevels().medium.emphasize(activeColor));
}
+ public final class Button {
+ method public androidx.ui.layout.EdgeInsets getDefaultInnerPadding();
+ property public final androidx.ui.layout.EdgeInsets DefaultInnerPadding;
+ field public static final androidx.ui.material.Button! INSTANCE;
+ }
+
public final class ButtonKt {
- method public static void Button(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().primary, androidx.ui.graphics.Color contentColor = contentColorFor(backgroundColor), androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 2.dp, androidx.ui.layout.EdgeInsets paddings = ButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static inline void OutlinedButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = Border(1.dp, MaterialTheme.colors().onSurface.copy(OutlinedStrokeOpacity)), androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.layout.EdgeInsets paddings = ButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static inline void TextButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.layout.EdgeInsets paddings = TextButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 2.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().primary, androidx.ui.graphics.Color contentColor = contentColorFor(backgroundColor), androidx.ui.layout.EdgeInsets innerPadding = Button.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static inline void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = Border(1.dp, MaterialTheme.colors().onSurface.copy(OutlinedStrokeOpacity)), androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.layout.EdgeInsets innerPadding = Button.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static inline void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.layout.EdgeInsets innerPadding = TextButton.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ }
+
+ public final class CardKt {
+ method public static void Card(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = card, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 1.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class CheckboxKt {
@@ -145,25 +155,22 @@
public final class EmphasisKt {
method public static void ProvideEmphasis(androidx.ui.material.Emphasis emphasis, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static androidx.compose.ProvidableAmbient<androidx.ui.material.EmphasisLevels> getEmphasisAmbient();
+ method public static androidx.compose.Ambient<androidx.ui.material.EmphasisLevels> getEmphasisAmbient();
}
- public final class EmphasisLevels {
- ctor public EmphasisLevels(androidx.ui.material.Emphasis high, androidx.ui.material.Emphasis medium, androidx.ui.material.Emphasis disabled);
- ctor public EmphasisLevels();
- method public androidx.ui.material.Emphasis component1();
- method public androidx.ui.material.Emphasis component2();
- method public androidx.ui.material.Emphasis component3();
- method public androidx.ui.material.EmphasisLevels copy(androidx.ui.material.Emphasis high, androidx.ui.material.Emphasis medium, androidx.ui.material.Emphasis disabled);
+ public interface EmphasisLevels {
method public androidx.ui.material.Emphasis getDisabled();
method public androidx.ui.material.Emphasis getHigh();
method public androidx.ui.material.Emphasis getMedium();
+ property public abstract androidx.ui.material.Emphasis disabled;
+ property public abstract androidx.ui.material.Emphasis high;
+ property public abstract androidx.ui.material.Emphasis medium;
}
public final class FloatingActionButtonKt {
- method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.unit.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static void FloatingActionButton(androidx.ui.graphics.ImageAsset icon, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
- method public static void FloatingActionButton(String text, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.ImageAsset? icon = null, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
+ method public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void FloatingActionButton(androidx.ui.graphics.ImageAsset icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
+ method public static void FloatingActionButton(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.ImageAsset? icon = null, androidx.ui.text.TextStyle? textStyle = null, boolean enabled = true, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
}
public final class IconButtonKt {
@@ -263,6 +270,11 @@
method public static androidx.ui.graphics.Color snackbarPrimaryColorFor(androidx.ui.material.ColorPalette colors);
}
+ public final class SurfaceKt {
+ method public static void Surface(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.graphics.Color getPrimarySurface(androidx.ui.material.ColorPalette);
+ }
+
public final class SwitchKt {
method public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, androidx.ui.graphics.Color color = MaterialTheme.colors().secondaryVariant);
}
@@ -291,6 +303,12 @@
property public final androidx.ui.unit.IntPx right;
}
+ public final class TextButton {
+ method public androidx.ui.layout.EdgeInsets getDefaultInnerPadding();
+ property public final androidx.ui.layout.EdgeInsets DefaultInnerPadding;
+ field public static final androidx.ui.material.TextButton! INSTANCE;
+ }
+
public final class Typography {
ctor public Typography(androidx.ui.text.TextStyle h1, androidx.ui.text.TextStyle h2, androidx.ui.text.TextStyle h3, androidx.ui.text.TextStyle h4, androidx.ui.text.TextStyle h5, androidx.ui.text.TextStyle h6, androidx.ui.text.TextStyle subtitle1, androidx.ui.text.TextStyle subtitle2, androidx.ui.text.TextStyle body1, androidx.ui.text.TextStyle body2, androidx.ui.text.TextStyle button, androidx.ui.text.TextStyle caption, androidx.ui.text.TextStyle overline);
ctor public Typography();
@@ -376,16 +394,3 @@
}
-package androidx.ui.material.surface {
-
- public final class CardKt {
- method public static void Card(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = card, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 1.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- }
-
- public final class SurfaceKt {
- method public static void Surface(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static androidx.ui.graphics.Color getPrimarySurface(androidx.ui.material.ColorPalette);
- }
-
-}
-
diff --git a/ui/ui-material/api/restricted_0.1.0-dev07.txt b/ui/ui-material/api/restricted_0.1.0-dev07.txt
index a201912..b3147bb 100644
--- a/ui/ui-material/api/restricted_0.1.0-dev07.txt
+++ b/ui/ui-material/api/restricted_0.1.0-dev07.txt
@@ -36,10 +36,20 @@
method public static void BottomNavigationItem(androidx.ui.layout.RowScope, kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> text = emptyContent(), boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onSelected, androidx.ui.core.Modifier modifier = Modifier.None, boolean alwaysShowLabels = true, androidx.ui.graphics.Color activeColor = contentColor(), androidx.ui.graphics.Color inactiveColor = MaterialTheme.emphasisLevels().medium.emphasize(activeColor));
}
+ public final class Button {
+ method public androidx.ui.layout.EdgeInsets getDefaultInnerPadding();
+ property public final androidx.ui.layout.EdgeInsets DefaultInnerPadding;
+ field public static final androidx.ui.material.Button! INSTANCE;
+ }
+
public final class ButtonKt {
- method public static void Button(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().primary, androidx.ui.graphics.Color contentColor = contentColorFor(backgroundColor), androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 2.dp, androidx.ui.layout.EdgeInsets paddings = ButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static inline void OutlinedButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = Border(1.dp, MaterialTheme.colors().onSurface.copy(OutlinedStrokeOpacity)), androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.layout.EdgeInsets paddings = ButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static inline void TextButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.layout.EdgeInsets paddings = TextButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 2.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().primary, androidx.ui.graphics.Color contentColor = contentColorFor(backgroundColor), androidx.ui.layout.EdgeInsets innerPadding = Button.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static inline void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = Border(1.dp, MaterialTheme.colors().onSurface.copy(OutlinedStrokeOpacity)), androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.layout.EdgeInsets innerPadding = Button.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static inline void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.layout.EdgeInsets innerPadding = TextButton.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ }
+
+ public final class CardKt {
+ method public static void Card(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = card, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 1.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class CheckboxKt {
@@ -145,25 +155,22 @@
public final class EmphasisKt {
method public static void ProvideEmphasis(androidx.ui.material.Emphasis emphasis, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static androidx.compose.ProvidableAmbient<androidx.ui.material.EmphasisLevels> getEmphasisAmbient();
+ method public static androidx.compose.Ambient<androidx.ui.material.EmphasisLevels> getEmphasisAmbient();
}
- public final class EmphasisLevels {
- ctor public EmphasisLevels(androidx.ui.material.Emphasis high, androidx.ui.material.Emphasis medium, androidx.ui.material.Emphasis disabled);
- ctor public EmphasisLevels();
- method public androidx.ui.material.Emphasis component1();
- method public androidx.ui.material.Emphasis component2();
- method public androidx.ui.material.Emphasis component3();
- method public androidx.ui.material.EmphasisLevels copy(androidx.ui.material.Emphasis high, androidx.ui.material.Emphasis medium, androidx.ui.material.Emphasis disabled);
+ public interface EmphasisLevels {
method public androidx.ui.material.Emphasis getDisabled();
method public androidx.ui.material.Emphasis getHigh();
method public androidx.ui.material.Emphasis getMedium();
+ property public abstract androidx.ui.material.Emphasis disabled;
+ property public abstract androidx.ui.material.Emphasis high;
+ property public abstract androidx.ui.material.Emphasis medium;
}
public final class FloatingActionButtonKt {
- method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.unit.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static void FloatingActionButton(androidx.ui.graphics.ImageAsset icon, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
- method public static void FloatingActionButton(String text, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.ImageAsset? icon = null, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
+ method public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void FloatingActionButton(androidx.ui.graphics.ImageAsset icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
+ method public static void FloatingActionButton(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.ImageAsset? icon = null, androidx.ui.text.TextStyle? textStyle = null, boolean enabled = true, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
}
public final class IconButtonKt {
@@ -263,6 +270,11 @@
method public static androidx.ui.graphics.Color snackbarPrimaryColorFor(androidx.ui.material.ColorPalette colors);
}
+ public final class SurfaceKt {
+ method public static void Surface(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.graphics.Color getPrimarySurface(androidx.ui.material.ColorPalette);
+ }
+
public final class SwitchKt {
method public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, androidx.ui.graphics.Color color = MaterialTheme.colors().secondaryVariant);
}
@@ -291,6 +303,12 @@
property public final androidx.ui.unit.IntPx right;
}
+ public final class TextButton {
+ method public androidx.ui.layout.EdgeInsets getDefaultInnerPadding();
+ property public final androidx.ui.layout.EdgeInsets DefaultInnerPadding;
+ field public static final androidx.ui.material.TextButton! INSTANCE;
+ }
+
public final class Typography {
ctor public Typography(androidx.ui.text.TextStyle h1, androidx.ui.text.TextStyle h2, androidx.ui.text.TextStyle h3, androidx.ui.text.TextStyle h4, androidx.ui.text.TextStyle h5, androidx.ui.text.TextStyle h6, androidx.ui.text.TextStyle subtitle1, androidx.ui.text.TextStyle subtitle2, androidx.ui.text.TextStyle body1, androidx.ui.text.TextStyle body2, androidx.ui.text.TextStyle button, androidx.ui.text.TextStyle caption, androidx.ui.text.TextStyle overline);
ctor public Typography();
@@ -376,16 +394,3 @@
}
-package androidx.ui.material.surface {
-
- public final class CardKt {
- method public static void Card(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = card, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 1.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- }
-
- public final class SurfaceKt {
- method public static void Surface(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static androidx.ui.graphics.Color getPrimarySurface(androidx.ui.material.ColorPalette);
- }
-
-}
-
diff --git a/ui/ui-material/api/restricted_current.txt b/ui/ui-material/api/restricted_current.txt
index a201912..b3147bb 100644
--- a/ui/ui-material/api/restricted_current.txt
+++ b/ui/ui-material/api/restricted_current.txt
@@ -36,10 +36,20 @@
method public static void BottomNavigationItem(androidx.ui.layout.RowScope, kotlin.jvm.functions.Function0<kotlin.Unit> icon, kotlin.jvm.functions.Function0<kotlin.Unit> text = emptyContent(), boolean selected, kotlin.jvm.functions.Function0<kotlin.Unit> onSelected, androidx.ui.core.Modifier modifier = Modifier.None, boolean alwaysShowLabels = true, androidx.ui.graphics.Color activeColor = contentColor(), androidx.ui.graphics.Color inactiveColor = MaterialTheme.emphasisLevels().medium.emphasize(activeColor));
}
+ public final class Button {
+ method public androidx.ui.layout.EdgeInsets getDefaultInnerPadding();
+ property public final androidx.ui.layout.EdgeInsets DefaultInnerPadding;
+ field public static final androidx.ui.material.Button! INSTANCE;
+ }
+
public final class ButtonKt {
- method public static void Button(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().primary, androidx.ui.graphics.Color contentColor = contentColorFor(backgroundColor), androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 2.dp, androidx.ui.layout.EdgeInsets paddings = ButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static inline void OutlinedButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = Border(1.dp, MaterialTheme.colors().onSurface.copy(OutlinedStrokeOpacity)), androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.layout.EdgeInsets paddings = ButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static inline void TextButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.layout.EdgeInsets paddings = TextButtonPaddings, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void Button(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 2.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().primary, androidx.ui.graphics.Color contentColor = contentColorFor(backgroundColor), androidx.ui.layout.EdgeInsets innerPadding = Button.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static inline void OutlinedButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = Border(1.dp, MaterialTheme.colors().onSurface.copy(OutlinedStrokeOpacity)), androidx.ui.graphics.Color backgroundColor = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.layout.EdgeInsets innerPadding = Button.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static inline void TextButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp elevation = 0.dp, androidx.ui.graphics.Shape shape = button, androidx.ui.foundation.Border? border = null, androidx.ui.graphics.Color backgroundColor = Color.Transparent, androidx.ui.graphics.Color contentColor = MaterialTheme.colors().primary, androidx.ui.layout.EdgeInsets innerPadding = TextButton.DefaultInnerPadding, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ }
+
+ public final class CardKt {
+ method public static void Card(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = card, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 1.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
public final class CheckboxKt {
@@ -145,25 +155,22 @@
public final class EmphasisKt {
method public static void ProvideEmphasis(androidx.ui.material.Emphasis emphasis, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static androidx.compose.ProvidableAmbient<androidx.ui.material.EmphasisLevels> getEmphasisAmbient();
+ method public static androidx.compose.Ambient<androidx.ui.material.EmphasisLevels> getEmphasisAmbient();
}
- public final class EmphasisLevels {
- ctor public EmphasisLevels(androidx.ui.material.Emphasis high, androidx.ui.material.Emphasis medium, androidx.ui.material.Emphasis disabled);
- ctor public EmphasisLevels();
- method public androidx.ui.material.Emphasis component1();
- method public androidx.ui.material.Emphasis component2();
- method public androidx.ui.material.Emphasis component3();
- method public androidx.ui.material.EmphasisLevels copy(androidx.ui.material.Emphasis high, androidx.ui.material.Emphasis medium, androidx.ui.material.Emphasis disabled);
+ public interface EmphasisLevels {
method public androidx.ui.material.Emphasis getDisabled();
method public androidx.ui.material.Emphasis getHigh();
method public androidx.ui.material.Emphasis getMedium();
+ property public abstract androidx.ui.material.Emphasis disabled;
+ property public abstract androidx.ui.material.Emphasis high;
+ property public abstract androidx.ui.material.Emphasis medium;
}
public final class FloatingActionButtonKt {
- method public static void FloatingActionButton(androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.unit.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static void FloatingActionButton(androidx.ui.graphics.ImageAsset icon, androidx.ui.core.Modifier modifier = Modifier.None, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
- method public static void FloatingActionButton(String text, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.ImageAsset? icon = null, androidx.ui.text.TextStyle? textStyle = null, kotlin.jvm.functions.Function0<kotlin.Unit>? onClick = null, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
+ method public static void FloatingActionButton(kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.unit.Dp minSize = androidx.ui.material.FloatingActionButtonKt.FabSize, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static void FloatingActionButton(androidx.ui.graphics.ImageAsset icon, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, boolean enabled = true, androidx.ui.graphics.Shape shape = CircleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
+ method public static void FloatingActionButton(String text, kotlin.jvm.functions.Function0<kotlin.Unit> onClick, androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.ImageAsset? icon = null, androidx.ui.text.TextStyle? textStyle = null, boolean enabled = true, androidx.ui.graphics.Color color = MaterialTheme.colors().primary, androidx.ui.unit.Dp elevation = 6.dp);
}
public final class IconButtonKt {
@@ -263,6 +270,11 @@
method public static androidx.ui.graphics.Color snackbarPrimaryColorFor(androidx.ui.material.ColorPalette colors);
}
+ public final class SurfaceKt {
+ method public static void Surface(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
+ method public static androidx.ui.graphics.Color getPrimarySurface(androidx.ui.material.ColorPalette);
+ }
+
public final class SwitchKt {
method public static void Switch(boolean checked, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit>? onCheckedChange, androidx.ui.graphics.Color color = MaterialTheme.colors().secondaryVariant);
}
@@ -291,6 +303,12 @@
property public final androidx.ui.unit.IntPx right;
}
+ public final class TextButton {
+ method public androidx.ui.layout.EdgeInsets getDefaultInnerPadding();
+ property public final androidx.ui.layout.EdgeInsets DefaultInnerPadding;
+ field public static final androidx.ui.material.TextButton! INSTANCE;
+ }
+
public final class Typography {
ctor public Typography(androidx.ui.text.TextStyle h1, androidx.ui.text.TextStyle h2, androidx.ui.text.TextStyle h3, androidx.ui.text.TextStyle h4, androidx.ui.text.TextStyle h5, androidx.ui.text.TextStyle h6, androidx.ui.text.TextStyle subtitle1, androidx.ui.text.TextStyle subtitle2, androidx.ui.text.TextStyle body1, androidx.ui.text.TextStyle body2, androidx.ui.text.TextStyle button, androidx.ui.text.TextStyle caption, androidx.ui.text.TextStyle overline);
ctor public Typography();
@@ -376,16 +394,3 @@
}
-package androidx.ui.material.surface {
-
- public final class CardKt {
- method public static void Card(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = card, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 1.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- }
-
- public final class SurfaceKt {
- method public static void Surface(androidx.ui.core.Modifier modifier = Modifier.None, androidx.ui.graphics.Shape shape = RectangleShape, androidx.ui.graphics.Color color = MaterialTheme.colors().surface, androidx.ui.graphics.Color contentColor = contentColorFor(color), androidx.ui.foundation.Border? border = null, androidx.ui.unit.Dp elevation = 0.dp, kotlin.jvm.functions.Function0<kotlin.Unit> children);
- method public static androidx.ui.graphics.Color getPrimarySurface(androidx.ui.material.ColorPalette);
- }
-
-}
-
diff --git a/ui/ui-material/icons/extended/build.gradle b/ui/ui-material/icons/extended/build.gradle
index efde2e4..49424e1 100644
--- a/ui/ui-material/icons/extended/build.gradle
+++ b/ui/ui-material/icons/extended/build.gradle
@@ -34,6 +34,7 @@
implementation(KOTLIN_STDLIB)
api project(":ui:ui-material-icons-core")
+ implementation project(":compose:compose-runtime")
androidTestImplementation project(":ui:ui-foundation")
androidTestImplementation project(":ui:ui-layout")
diff --git a/ui/ui-material/icons/extended/src/androidTest/java/androidx/ui/material/icons/test/IconComparisonTest.kt b/ui/ui-material/icons/extended/src/androidTest/java/androidx/ui/material/icons/test/IconComparisonTest.kt
index dfaf609..851e376 100644
--- a/ui/ui-material/icons/extended/src/androidTest/java/androidx/ui/material/icons/test/IconComparisonTest.kt
+++ b/ui/ui-material/icons/extended/src/androidTest/java/androidx/ui/material/icons/test/IconComparisonTest.kt
@@ -19,14 +19,13 @@
import android.app.Activity
import android.graphics.Bitmap
import android.os.Build
-import android.view.ViewGroup
import androidx.compose.Composable
-import androidx.compose.Compose
+import androidx.compose.Composition
import androidx.test.filters.LargeTest
import androidx.test.filters.SdkSuppress
import androidx.test.rule.ActivityTestRule
-import androidx.ui.core.AndroidComposeView
import androidx.ui.core.ContextAmbient
+import androidx.ui.core.DensityAmbient
import androidx.ui.core.TestTag
import androidx.ui.core.setContent
import androidx.ui.foundation.Box
@@ -40,7 +39,7 @@
import androidx.ui.semantics.Semantics
import androidx.ui.test.captureToBitmap
import androidx.ui.test.findByTag
-import androidx.ui.unit.dp
+import androidx.ui.unit.ipx
import com.google.common.truth.Truth
import org.junit.Rule
import org.junit.Test
@@ -74,9 +73,10 @@
AllIcons.forEach { (property, drawableName) ->
var xmlVector: VectorAsset? = null
val programmaticVector = property.get()
+ var composition: Composition? = null
activityTestRule.runOnUiThread {
- activityTestRule.activity.setContent {
+ composition = activityTestRule.activity.setContent {
xmlVector = drawableName.toVectorAsset()
DrawVectors(programmaticVector, xmlVector!!)
}
@@ -94,10 +94,7 @@
// Dispose between composing each pair of icons to ensure correctness
activityTestRule.runOnUiThread {
- val root =
- (activityTestRule.activity.findViewById(android.R.id.content) as ViewGroup)
- val composeView = root.getChildAt(0) as AndroidComposeView
- Compose.disposeComposition(composeView.root, activityTestRule.activity, null)
+ composition?.dispose()
}
}
}
@@ -164,17 +161,24 @@
@Composable
private fun DrawVectors(programmaticVector: VectorAsset, xmlVector: VectorAsset) {
Center {
+ // Ideally these icons would be 24 dp, but due to density changes across devices we test
+ // against in CI, on some devices using DP here causes there to be anti-aliasing issues.
+ // Using ipx directly ensures that we will always have a consistent layout / drawing
+ // story, so anti-aliasing should be identical.
+ val layoutSize = with(DensityAmbient.current) {
+ LayoutSize(72.ipx.toDp())
+ }
Column {
TestTag(ProgrammaticTestTag) {
Semantics(container = true) {
- Box(LayoutSize(24.dp)) {
+ Box(modifier = layoutSize) {
DrawVector(vectorImage = programmaticVector, tintColor = Color.Red)
}
}
}
TestTag(XmlTestTag) {
Semantics(container = true) {
- Box(LayoutSize(24.dp)) {
+ Box(modifier = layoutSize) {
DrawVector(vectorImage = xmlVector, tintColor = Color.Red)
}
}
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/AndroidManifest.xml b/ui/ui-material/integration-tests/material-demos/src/main/AndroidManifest.xml
index e58b228..ed49bd2 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/AndroidManifest.xml
+++ b/ui/ui-material/integration-tests/material-demos/src/main/AndroidManifest.xml
@@ -39,16 +39,6 @@
</activity>
<activity
- android:name=".RippleActivity"
- android:configChanges="orientation|screenSize"
- android:label="Material/Ripples">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="androidx.ui.demos.SAMPLE_CODE" />
- </intent-filter>
- </activity>
-
- <activity
android:name=".SelectionControlsActivity"
android:configChanges="orientation|screenSize"
android:label="Material/Selection Controls">
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ButtonActivity.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ButtonActivity.kt
index 20de3c2..472a726 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ButtonActivity.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ButtonActivity.kt
@@ -90,13 +90,13 @@
Spacer(LayoutHeight(DefaultSpace))
Row(LayoutWidth.Fill, arrangement = Arrangement.SpaceEvenly) {
- Button(backgroundColor = MaterialTheme.colors().secondary, onClick = {}) {
+ Button(onClick = {}, backgroundColor = MaterialTheme.colors().secondary) {
Text("Secondary Color")
}
// TODO(Andrey): Disabled button has wrong bg and text color for now.
// Need to figure out where will we store their styling. Not a part of
// ColorPalette right now and specs are not clear about this.
- Button {
+ Button(onClick = {}, enabled = false) {
Text("DISABLED. TODO")
}
}
@@ -108,19 +108,13 @@
Spacer(LayoutHeight(DefaultSpace))
Row(LayoutWidth.Fill, arrangement = Arrangement.SpaceEvenly) {
+ FloatingActionButton(onClick = {}, icon = icon)
+ FloatingActionButton(onClick = {}, text = "EXTENDED")
FloatingActionButton(
- icon = icon,
- onClick = {}
- )
- FloatingActionButton(
- text = "EXTENDED",
- onClick = {}
- )
- FloatingActionButton(
+ onClick = {},
icon = icon,
text = "ADD TO FAVS",
- color = MaterialTheme.colors().error,
- onClick = {}
+ color = MaterialTheme.colors().error
)
}
}
@@ -141,8 +135,8 @@
Text("Custom shape button")
Spacer(LayoutHeight(DefaultSpace))
OutlinedButton(
- modifier = LayoutSize(100.dp),
onClick = {},
+ modifier = LayoutSize(100.dp),
shape = TriangleShape,
backgroundColor = Color.Yellow,
border = Border(size = 2.dp, color = Color.Black)
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ElevationActivity.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ElevationActivity.kt
index 3a168cd..7a3a727 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ElevationActivity.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/ElevationActivity.kt
@@ -30,7 +30,7 @@
import androidx.ui.layout.LayoutWidth
import androidx.ui.material.MaterialTheme
import androidx.ui.material.ripple.Ripple
-import androidx.ui.material.surface.Card
+import androidx.ui.material.Card
import androidx.ui.unit.Dp
import androidx.ui.unit.dp
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/MaterialDemoActivity.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/MaterialDemoActivity.kt
index 1c245e9..2ac7187 100644
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/MaterialDemoActivity.kt
+++ b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/MaterialDemoActivity.kt
@@ -39,7 +39,7 @@
import androidx.ui.material.darkColorPalette
import androidx.ui.material.demos.MaterialSettingsActivity.SettingsFragment
import androidx.ui.material.lightColorPalette
-import androidx.ui.material.surface.Surface
+import androidx.ui.material.Surface
import kotlin.reflect.full.memberProperties
@Model
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/RippleActivity.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/RippleActivity.kt
deleted file mode 100644
index f64520d8..0000000
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/RippleActivity.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright 2019 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.ui.material.demos
-
-import android.app.Activity
-import android.os.Bundle
-import android.view.Gravity
-import android.view.ViewGroup
-import android.widget.Button
-import android.widget.FrameLayout
-import android.widget.LinearLayout
-import android.widget.TextView
-import androidx.ui.androidview.adapters.dp
-import androidx.ui.androidview.adapters.setPadding
-import androidx.compose.setViewContent
-
-class RippleActivity : Activity() {
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setViewContent {
- val layoutParams = LinearLayout.LayoutParams(
- ViewGroup.LayoutParams.MATCH_PARENT,
- 0,
- 1f
- )
- val gravity = Gravity.CENTER_HORIZONTAL
- LinearLayout(orientation = LinearLayout.VERTICAL) {
- TextView(gravity = gravity, text = "Compose card with ripple:")
- FrameLayout(layoutParams = layoutParams) {
- RippleDemo()
- }
- TextView(gravity = gravity, text = "Platform button with ripple:")
- FrameLayout(layoutParams = layoutParams, padding = 50.dp) {
- Button(background = getDrawable(R.drawable.ripple))
- }
- }
- }
- }
-}
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/RippleDemo.kt b/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/RippleDemo.kt
deleted file mode 100644
index eac0815..0000000
--- a/ui/ui-material/integration-tests/material-demos/src/main/java/androidx/ui/material/demos/RippleDemo.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2019 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.ui.material.demos
-
-import androidx.compose.Composable
-import androidx.ui.core.ComposeView
-import androidx.ui.core.Text
-import androidx.ui.foundation.Border
-import androidx.ui.foundation.shape.corner.RoundedCornerShape
-import androidx.ui.graphics.Color
-import androidx.ui.layout.Container
-import androidx.ui.layout.LayoutPadding
-import androidx.ui.material.MaterialTheme
-import androidx.ui.material.ripple.Ripple
-import androidx.ui.material.surface.Card
-import androidx.ui.unit.dp
-import androidx.ui.unit.px
-
-@Composable
-fun RippleDemo() {
- ComposeView {
- MaterialTheme {
- Card(
- shape = RoundedCornerShape(100.px),
- border = Border(1.dp, Color(0x80000000)),
- modifier = LayoutPadding(50.dp)
- ) {
- Ripple(bounded = true) {
- Container(expanded = true) {
- Ripple(bounded = true) {
- Container(width = 100.dp, height = 50.dp) {
- Text(
- text = "inner",
- style = MaterialTheme.typography().body1
- )
- }
- }
- }
- }
- }
- }
- }
-}
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/res/drawable/ripple.xml b/ui/ui-material/integration-tests/material-demos/src/main/res/drawable/ripple.xml
deleted file mode 100644
index c235e63..0000000
--- a/ui/ui-material/integration-tests/material-demos/src/main/res/drawable/ripple.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2019 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.
- -->
-
-<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- android:color="#20000000">
- <item android:drawable="@drawable/ripple_shape" />
- <item android:id="@android:id/mask"
- android:drawable="@drawable/ripple_shape" />
-</ripple>
\ No newline at end of file
diff --git a/ui/ui-material/integration-tests/material-demos/src/main/res/drawable/ripple_shape.xml b/ui/ui-material/integration-tests/material-demos/src/main/res/drawable/ripple_shape.xml
deleted file mode 100644
index def9261..0000000
--- a/ui/ui-material/integration-tests/material-demos/src/main/res/drawable/ripple_shape.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright 2019 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">
- <corners android:radius="100px"/>
- <solid android:color="@android:color/white"/>
- <stroke android:color="#80000000" android:width="1dp"/>
-</shape>
\ No newline at end of file
diff --git a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/AccountsScreen.kt b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/AccountsScreen.kt
index e9ba36c..9145f66 100644
--- a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/AccountsScreen.kt
+++ b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/AccountsScreen.kt
@@ -28,7 +28,7 @@
import androidx.ui.layout.Spacer
import androidx.ui.layout.Stack
import androidx.ui.material.MaterialTheme
-import androidx.ui.material.surface.Card
+import androidx.ui.material.Card
import androidx.ui.unit.dp
/**
diff --git a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/BillsScreen.kt b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/BillsScreen.kt
index 383f1ea..9888ca4 100644
--- a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/BillsScreen.kt
+++ b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/BillsScreen.kt
@@ -28,7 +28,7 @@
import androidx.ui.layout.Spacer
import androidx.ui.layout.Stack
import androidx.ui.material.MaterialTheme
-import androidx.ui.material.surface.Card
+import androidx.ui.material.Card
import androidx.ui.unit.dp
/**
diff --git a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/OverviewScreen.kt b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/OverviewScreen.kt
index e3cfde5..2976c49 100644
--- a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/OverviewScreen.kt
+++ b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/OverviewScreen.kt
@@ -35,7 +35,7 @@
import androidx.ui.material.TextButton
import androidx.ui.material.icons.Icons
import androidx.ui.material.icons.filled.Sort
-import androidx.ui.material.surface.Card
+import androidx.ui.material.Card
import androidx.ui.unit.dp
import java.util.Locale
@@ -93,7 +93,7 @@
)
TextButton(
onClick = onClickSeeAll,
- paddings = EdgeInsets(0.dp),
+ innerPadding = EdgeInsets(0.dp),
modifier = LayoutGravity.Center
) {
Text("SEE ALL")
diff --git a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/RallyAlertDialog.kt b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/RallyAlertDialog.kt
index d4d7bf1..5e64dff 100644
--- a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/RallyAlertDialog.kt
+++ b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/RallyAlertDialog.kt
@@ -48,7 +48,7 @@
TextButton(
onClick = onDismiss,
shape = RectangleShape,
- paddings = EdgeInsets(16.dp),
+ innerPadding = EdgeInsets(16.dp),
modifier = LayoutWidth.Fill
) {
Text(buttonText)
diff --git a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/TopAppBar.kt b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/TopAppBar.kt
index a88e64a..97c2786 100644
--- a/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/TopAppBar.kt
+++ b/ui/ui-material/integration-tests/material-studies/src/main/java/androidx/ui/material/studies/rally/TopAppBar.kt
@@ -33,7 +33,7 @@
import androidx.ui.layout.Spacer
import androidx.ui.material.MaterialTheme
import androidx.ui.material.ripple.Ripple
-import androidx.ui.material.surface.Surface
+import androidx.ui.material.Surface
import androidx.ui.text.TextStyle
import androidx.ui.unit.dp
import java.util.Locale
@@ -51,7 +51,8 @@
text = screen.name.toUpperCase(Locale.getDefault()),
icon = screen.icon,
onSelected = { onTabSelected(screen) },
- selected = currentScreen.ordinal == index)
+ selected = currentScreen.ordinal == index
+ )
}
}
}
diff --git a/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/CardSamples.kt b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/CardSamples.kt
index 0d330a3..d68d158 100644
--- a/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/CardSamples.kt
+++ b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/CardSamples.kt
@@ -19,7 +19,7 @@
import androidx.annotation.Sampled
import androidx.compose.Composable
import androidx.ui.core.Text
-import androidx.ui.material.surface.Card
+import androidx.ui.material.Card
@Sampled
@Composable
diff --git a/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/FloatingActionButtonSamples.kt b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/FloatingActionButtonSamples.kt
index b6a516b..bb71515 100644
--- a/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/FloatingActionButtonSamples.kt
+++ b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/FloatingActionButtonSamples.kt
@@ -18,7 +18,7 @@
import androidx.annotation.Sampled
import androidx.compose.Composable
-import androidx.ui.foundation.SimpleImage
+import androidx.ui.foundation.Image
import androidx.ui.graphics.ImageAsset
import androidx.ui.material.FloatingActionButton
@@ -32,7 +32,7 @@
@Composable
fun FloatingActionButtonCustomContent(icon: ImageAsset) {
FloatingActionButton(onClick = { /*do something*/ }) {
- SimpleImage(image = icon)
+ Image(image = icon)
}
}
diff --git a/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/ListSamples.kt b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/ListSamples.kt
index ab64774..45c41cc 100644
--- a/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/ListSamples.kt
+++ b/ui/ui-material/integration-tests/samples/src/main/java/androidx/ui/material/samples/ListSamples.kt
@@ -19,7 +19,7 @@
import androidx.annotation.Sampled
import androidx.compose.Composable
import androidx.ui.core.Text
-import androidx.ui.foundation.SimpleImage
+import androidx.ui.foundation.Image
import androidx.ui.graphics.ImageAsset
import androidx.ui.layout.Column
import androidx.ui.material.Divider
@@ -43,13 +43,13 @@
Divider()
ListItem(
text = { Text("One line list item with trailing icon") },
- trailing = { SimpleImage(icon24x24) }
+ trailing = { Image(icon24x24) }
)
Divider()
ListItem(
text = { Text("One line list item") },
- icon = { SimpleImage(icon40x40) },
- trailing = { SimpleImage(icon24x24) }
+ icon = { Image(icon40x40) },
+ trailing = { Image(icon24x24) }
)
Divider()
}
@@ -85,10 +85,10 @@
ListItem(
text = { Text("Two line list item") },
secondaryText = { Text("Secondary text") },
- icon = { SimpleImage(icon40x40) },
+ icon = { Image(icon40x40) },
trailing = {
// TODO(popam): put checkbox here after b/140292836 is fixed
- SimpleImage(icon24x24)
+ Image(icon24x24)
}
)
Divider()
@@ -126,7 +126,7 @@
secondaryText = { Text("This is a long secondary text for the current list" +
" item, displayed on two lines") },
singleLineSecondaryText = false,
- trailing = { SimpleImage(icon40x40) }
+ trailing = { Image(icon40x40) }
)
Divider()
ListItem(
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/ButtonTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/ButtonTest.kt
index 94da01e..fef24de 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/ButtonTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/ButtonTest.kt
@@ -27,7 +27,7 @@
import androidx.ui.core.currentTextStyle
import androidx.ui.layout.Center
import androidx.ui.layout.Column
-import androidx.ui.layout.Wrap
+import androidx.ui.layout.Stack
import androidx.ui.test.assertHasClickAction
import androidx.ui.test.assertHasNoClickAction
import androidx.ui.test.assertSemanticsIsEqualTo
@@ -81,7 +81,9 @@
composeTestRule.setMaterialContent {
Center {
TestTag(tag = "myButton") {
- Button { Text("myButton") }
+ Button(onClick = {}, enabled = false) {
+ Text("myButton")
+ }
}
}
}
@@ -123,15 +125,11 @@
val tag = "myButton"
composeTestRule.setMaterialContent {
- val enabled = state { true }
- val onClick: (() -> Unit)? = if (enabled.value) {
- { enabled.value = false }
- } else {
- null
- }
+ var enabled by state { true }
+ val onClick = { enabled = false }
Center {
TestTag(tag = tag) {
- Button(onClick = onClick) {
+ Button(onClick = onClick, enabled = enabled) {
Text("Hello")
}
}
@@ -293,7 +291,7 @@
var parentCoordinates: LayoutCoordinates? = null
var childCoordinates: LayoutCoordinates? = null
composeTestRule.setMaterialContent {
- Wrap {
+ Stack {
button {
OnPositioned {
parentCoordinates = it
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/ElevationOverlayTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/ElevationOverlayTest.kt
index 3d218d8..320b6a4 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/ElevationOverlayTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/ElevationOverlayTest.kt
@@ -23,7 +23,6 @@
import androidx.ui.core.TestTag
import androidx.ui.graphics.Color
import androidx.ui.layout.Container
-import androidx.ui.material.surface.Surface
import androidx.ui.semantics.Semantics
import androidx.ui.test.assertPixels
import androidx.ui.test.captureToBitmap
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/EmphasisTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/EmphasisTest.kt
index 3b4c3a7..7978266 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/EmphasisTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/EmphasisTest.kt
@@ -19,7 +19,7 @@
import androidx.test.filters.MediumTest
import androidx.ui.core.currentTextStyle
import androidx.ui.foundation.contentColor
-import androidx.ui.material.surface.Surface
+import androidx.ui.graphics.Color
import androidx.ui.test.createComposeRule
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
@@ -31,14 +31,17 @@
@MediumTest
@RunWith(Parameterized::class)
class EmphasisTest(private val colors: ColorPalette, private val debugParameterName: String) {
- private val HighEmphasisAlpha = 0.87f
- private val MediumEmphasisAlpha = 0.60f
- private val DisabledEmphasisAlpha = 0.38f
+ private val SurfaceHighEmphasisAlpha = 0.87f
+ private val SurfaceMediumEmphasisAlpha = 0.60f
+ private val SurfaceDisabledEmphasisAlpha = 0.38f
+
+ private val PrimaryHighEmphasisAlpha = 1.00f
+ private val PrimaryMediumEmphasisAlpha = 0.74f
+ private val PrimaryDisabledEmphasisAlpha = 0.38f
companion object {
@JvmStatic
@Parameterized.Parameters(name = "{1}")
- // Mappings for elevation -> expected overlay color in dark theme
fun initColorPalette() = arrayOf(
arrayOf(lightColorPalette(), "Light theme"),
arrayOf(darkColorPalette(), "Dark theme")
@@ -49,7 +52,7 @@
val composeTestRule = createComposeRule(disableTransitions = true)
@Test
- fun noEmphasisSpecified_contentColorUnmodified() {
+ fun noEmphasisSpecified_contentColorUnmodified_surface() {
composeTestRule.setContent {
MaterialTheme(colors) {
Surface {
@@ -63,13 +66,13 @@
}
@Test
- fun highEmphasis_contentColorSet() {
+ fun highEmphasis_contentColorSet_surface() {
composeTestRule.setContent {
MaterialTheme(colors) {
Surface {
ProvideEmphasis(MaterialTheme.emphasisLevels().high) {
val onSurface = MaterialTheme.colors().onSurface
- val modifiedOnSurface = onSurface.copy(alpha = HighEmphasisAlpha)
+ val modifiedOnSurface = onSurface.copy(alpha = SurfaceHighEmphasisAlpha)
assertThat(contentColor()).isEqualTo(modifiedOnSurface)
assertThat(currentTextStyle().color).isEqualTo(modifiedOnSurface)
@@ -80,13 +83,13 @@
}
@Test
- fun mediumEmphasis_contentColorSet() {
+ fun mediumEmphasis_contentColorSet_surface() {
composeTestRule.setContent {
MaterialTheme(colors) {
Surface {
ProvideEmphasis(MaterialTheme.emphasisLevels().medium) {
val onSurface = MaterialTheme.colors().onSurface
- val modifiedOnSurface = onSurface.copy(alpha = MediumEmphasisAlpha)
+ val modifiedOnSurface = onSurface.copy(alpha = SurfaceMediumEmphasisAlpha)
assertThat(contentColor()).isEqualTo(modifiedOnSurface)
assertThat(currentTextStyle().color).isEqualTo(modifiedOnSurface)
@@ -97,13 +100,13 @@
}
@Test
- fun lowEmphasis_contentColorSet() {
+ fun lowEmphasis_contentColorSet_surface() {
composeTestRule.setContent {
MaterialTheme(colors) {
Surface {
ProvideEmphasis(MaterialTheme.emphasisLevels().disabled) {
val onSurface = MaterialTheme.colors().onSurface
- val modifiedOnSurface = onSurface.copy(alpha = DisabledEmphasisAlpha)
+ val modifiedOnSurface = onSurface.copy(alpha = SurfaceDisabledEmphasisAlpha)
assertThat(contentColor()).isEqualTo(modifiedOnSurface)
assertThat(currentTextStyle().color).isEqualTo(modifiedOnSurface)
@@ -112,4 +115,129 @@
}
}
}
+
+ @Test
+ fun noEmphasisSpecified_contentColorUnmodified_primary() {
+ composeTestRule.setContent {
+ MaterialTheme(colors) {
+ Surface(color = colors.primary) {
+ val onPrimary = MaterialTheme.colors().onPrimary
+
+ assertThat(contentColor()).isEqualTo(onPrimary)
+ assertThat(currentTextStyle().color).isEqualTo(onPrimary)
+ }
+ }
+ }
+ }
+
+ @Test
+ fun highEmphasis_contentColorSet_primary() {
+ composeTestRule.setContent {
+ MaterialTheme(colors) {
+ Surface(color = colors.primary) {
+ ProvideEmphasis(MaterialTheme.emphasisLevels().high) {
+ val onPrimary = MaterialTheme.colors().onPrimary
+ val modifiedOnPrimary = onPrimary.copy(alpha = PrimaryHighEmphasisAlpha)
+
+ assertThat(contentColor()).isEqualTo(modifiedOnPrimary)
+ assertThat(currentTextStyle().color).isEqualTo(modifiedOnPrimary)
+ }
+ }
+ }
+ }
+ }
+
+ @Test
+ fun mediumEmphasis_contentColorSet_primary() {
+ composeTestRule.setContent {
+ MaterialTheme(colors) {
+ Surface(color = colors.primary) {
+ ProvideEmphasis(MaterialTheme.emphasisLevels().medium) {
+ val onPrimary = MaterialTheme.colors().onPrimary
+ val modifiedOnPrimary = onPrimary.copy(alpha = PrimaryMediumEmphasisAlpha)
+
+ assertThat(contentColor()).isEqualTo(modifiedOnPrimary)
+ assertThat(currentTextStyle().color).isEqualTo(modifiedOnPrimary)
+ }
+ }
+ }
+ }
+ }
+
+ @Test
+ fun lowEmphasis_contentColorSet_primary() {
+ composeTestRule.setContent {
+ MaterialTheme(colors) {
+ Surface(color = colors.primary) {
+ ProvideEmphasis(MaterialTheme.emphasisLevels().disabled) {
+ val onPrimary = MaterialTheme.colors().onPrimary
+ val modifiedOnPrimary = onPrimary.copy(alpha = PrimaryDisabledEmphasisAlpha)
+
+ assertThat(contentColor()).isEqualTo(modifiedOnPrimary)
+ assertThat(currentTextStyle().color).isEqualTo(modifiedOnPrimary)
+ }
+ }
+ }
+ }
+ }
+
+ @Test
+ fun noEmphasisSpecified_contentColorUnmodified_colorNotFromTheme() {
+ composeTestRule.setContent {
+ MaterialTheme(colors) {
+ Surface(contentColor = Color.Yellow) {
+ assertThat(contentColor()).isEqualTo(Color.Yellow)
+ assertThat(currentTextStyle().color).isEqualTo(Color.Yellow)
+ }
+ }
+ }
+ }
+
+ @Test
+ fun highEmphasis_contentColorSet_colorNotFromTheme() {
+ composeTestRule.setContent {
+ MaterialTheme(colors) {
+ Surface(contentColor = Color.Yellow) {
+ ProvideEmphasis(MaterialTheme.emphasisLevels().high) {
+ val modifiedYellow = Color.Yellow.copy(alpha = SurfaceHighEmphasisAlpha)
+
+ assertThat(contentColor()).isEqualTo(modifiedYellow)
+ assertThat(currentTextStyle().color).isEqualTo(modifiedYellow)
+ }
+ }
+ }
+ }
+ }
+
+ @Test
+ fun mediumEmphasis_contentColorSet_colorNotFromTheme() {
+ composeTestRule.setContent {
+ MaterialTheme(colors) {
+ Surface(contentColor = Color.Yellow) {
+ ProvideEmphasis(MaterialTheme.emphasisLevels().medium) {
+ val modifiedYellow = Color.Yellow.copy(alpha = SurfaceMediumEmphasisAlpha)
+
+ assertThat(contentColor()).isEqualTo(modifiedYellow)
+ assertThat(currentTextStyle().color).isEqualTo(modifiedYellow)
+ }
+ }
+ }
+ }
+ }
+
+ @Test
+ fun lowEmphasis_contentColorSet_colorNotFromTheme() {
+ composeTestRule.setContent {
+ MaterialTheme(colors) {
+ Surface(contentColor = Color.Yellow) {
+ ProvideEmphasis(MaterialTheme.emphasisLevels().disabled) {
+ val modifiedYellow = Color.Yellow.copy(alpha = SurfaceDisabledEmphasisAlpha)
+
+ assertThat(contentColor()).isEqualTo(modifiedYellow)
+ assertThat(currentTextStyle().color).isEqualTo(modifiedYellow)
+ }
+ }
+ }
+ }
+ }
}
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/FloatingActionButtonUiTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/FloatingActionButtonUiTest.kt
index b37a3c7..8128516 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/FloatingActionButtonUiTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/FloatingActionButtonUiTest.kt
@@ -39,7 +39,7 @@
fun defaultFabHasSizeFromSpec() {
composeTestRule
.setMaterialContentAndCollectSizes {
- FloatingActionButton(icon = createImage())
+ FloatingActionButton(icon = createImage(), onClick = {})
}
.assertIsSquareWithSize(56.dp)
}
@@ -48,7 +48,7 @@
fun extendedFabHasHeightFromSpec() {
val size = composeTestRule
.setMaterialContentAndGetPixelSize {
- FloatingActionButton(icon = createImage(), text = "Extended")
+ FloatingActionButton(icon = createImage(), text = "Extended", onClick = {})
}
with(composeTestRule.density) {
assertThat(size.width.round().value).isAtLeast(48.dp.toIntPx().value)
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/ListItemTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/ListItemTest.kt
index b39ac17..33d760b 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/ListItemTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/ListItemTest.kt
@@ -23,7 +23,7 @@
import androidx.ui.core.OnChildPositioned
import androidx.ui.core.Ref
import androidx.ui.core.Text
-import androidx.ui.foundation.SimpleImage
+import androidx.ui.foundation.Image
import androidx.ui.graphics.ImageAsset
import androidx.ui.layout.Container
import androidx.ui.test.createComposeRule
@@ -199,7 +199,7 @@
ListItem(
text = { SaveLayout(textPosition, textSize) { Text("Primary text") } },
trailing = {
- SaveLayout(trailingPosition, trailingSize) { SimpleImage(icon24x24) }
+ SaveLayout(trailingPosition, trailingSize) { Image(icon24x24) }
}
)
}
@@ -234,7 +234,7 @@
Container(alignment = Alignment.TopStart) {
ListItem(
text = { SaveLayout(textPosition, textSize) { Text("Primary text") } },
- icon = { SaveLayout(iconPosition, iconSize) { SimpleImage(icon24x24) } }
+ icon = { SaveLayout(iconPosition, iconSize) { Image(icon24x24) } }
)
}
}
@@ -349,7 +349,7 @@
}
},
icon = {
- SaveLayout(iconPosition, iconSize) { SimpleImage(icon24x24) }
+ SaveLayout(iconPosition, iconSize) { Image(icon24x24) }
}
)
}
@@ -413,10 +413,10 @@
}
},
icon = {
- SaveLayout(iconPosition, iconSize) { SimpleImage(icon40x40) }
+ SaveLayout(iconPosition, iconSize) { Image(icon40x40) }
},
trailing = {
- SaveLayout(trailingPosition, trailingSize) { SimpleImage(icon24x24) }
+ SaveLayout(trailingPosition, trailingSize) { Image(icon24x24) }
}
)
}
@@ -488,10 +488,10 @@
},
singleLineSecondaryText = false,
icon = {
- SaveLayout(iconPosition, iconSize) { SimpleImage(icon24x24) }
+ SaveLayout(iconPosition, iconSize) { Image(icon24x24) }
},
trailing = {
- SaveLayout(trailingPosition, trailingSize) { SimpleImage(icon24x24) }
+ SaveLayout(trailingPosition, trailingSize) { Image(icon24x24) }
}
)
}
@@ -576,7 +576,7 @@
}
},
icon = {
- SaveLayout(iconPosition, iconSize) { SimpleImage(icon40x40) }
+ SaveLayout(iconPosition, iconSize) { Image(icon40x40) }
},
trailing = {
SaveLayout(
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/MaterialTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/MaterialTest.kt
index 9b6fc4d..07bf5f7 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/MaterialTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/MaterialTest.kt
@@ -18,7 +18,6 @@
import androidx.compose.Composable
import androidx.ui.layout.DpConstraints
-import androidx.ui.material.surface.Surface
import androidx.ui.test.BigTestConstraints
import androidx.ui.test.CollectedSizes
import androidx.ui.test.ComposeTestRule
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/RippleEffectTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/RippleEffectTest.kt
index a111161..5abf5ab 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/RippleEffectTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/RippleEffectTest.kt
@@ -29,13 +29,12 @@
import androidx.ui.layout.Container
import androidx.ui.layout.LayoutPadding
import androidx.ui.layout.Row
-import androidx.ui.layout.Wrap
+import androidx.ui.layout.Stack
import androidx.ui.material.ripple.RippleThemeAmbient
import androidx.ui.material.ripple.Ripple
import androidx.ui.material.ripple.RippleEffect
import androidx.ui.material.ripple.RippleEffectFactory
import androidx.ui.material.ripple.RippleTheme
-import androidx.ui.material.surface.Card
import androidx.ui.test.createComposeRule
import androidx.ui.test.doClick
import androidx.ui.test.findByTag
@@ -115,7 +114,7 @@
latch.countDown()
}) {
Card {
- Wrap {
+ Stack {
Row {
RippleButton(size)
TestTag(tag = "ripple") {
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/ScaffoldTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/ScaffoldTest.kt
index 48945d7..bf001ecfd 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/ScaffoldTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/ScaffoldTest.kt
@@ -227,7 +227,7 @@
composeTestRule.setContent {
Scaffold(
floatingActionButton = {
- FloatingActionButton("text")
+ FloatingActionButton("text", onClick = {})
},
floatingActionButtonPosition = Scaffold.FabPosition.CenterDocked
) {
@@ -241,7 +241,7 @@
composeTestRule.setContent {
Scaffold(
floatingActionButton = {
- FloatingActionButton("text")
+ FloatingActionButton("text", onClick = {})
},
floatingActionButtonPosition = Scaffold.FabPosition.EndDocked
) {
@@ -262,7 +262,7 @@
fabSize = positioned.size
fabPosition = positioned.localToGlobal(positioned.positionInParent)
}) {
- FloatingActionButton("text")
+ FloatingActionButton("text", onClick = {})
}
},
floatingActionButtonPosition = Scaffold.FabPosition.CenterDocked,
@@ -293,7 +293,7 @@
fabSize = positioned.size
fabPosition = positioned.localToGlobal(positioned.positionInParent)
}) {
- FloatingActionButton("text")
+ FloatingActionButton("text", onClick = {})
}
},
floatingActionButtonPosition = Scaffold.FabPosition.EndDocked,
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/SnackbarTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/SnackbarTest.kt
index 9bca6e4..5ade2c0 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/SnackbarTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/SnackbarTest.kt
@@ -24,7 +24,7 @@
import androidx.ui.core.Text
import androidx.ui.core.globalPosition
import androidx.ui.layout.DpConstraints
-import androidx.ui.layout.Wrap
+import androidx.ui.layout.Stack
import androidx.ui.test.createComposeRule
import androidx.ui.test.doClick
import androidx.ui.test.findByText
@@ -54,7 +54,7 @@
fun defaultSnackbar_semantics() {
var clicked = false
composeTestRule.setMaterialContent {
- Wrap {
+ Stack {
Snackbar(text = { Text("Message") }, action = {
TextButton(onClick = { clicked = true }) {
Text("UNDO")
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/SurfaceContentColorTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/SurfaceContentColorTest.kt
index 2fe5eba..5c26f2f 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/SurfaceContentColorTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/SurfaceContentColorTest.kt
@@ -19,7 +19,6 @@
import androidx.test.filters.MediumTest
import androidx.ui.core.currentTextStyle
import androidx.ui.graphics.Color
-import androidx.ui.material.surface.Surface
import androidx.ui.foundation.contentColor
import androidx.ui.test.createComposeRule
import com.google.common.truth.Truth.assertThat
diff --git a/ui/ui-material/src/androidTest/java/androidx/ui/material/TabTest.kt b/ui/ui-material/src/androidTest/java/androidx/ui/material/TabTest.kt
index 3374ac4..d284731 100644
--- a/ui/ui-material/src/androidTest/java/androidx/ui/material/TabTest.kt
+++ b/ui/ui-material/src/androidTest/java/androidx/ui/material/TabTest.kt
@@ -30,7 +30,6 @@
import androidx.ui.material.icons.filled.Favorite
import androidx.ui.material.samples.ScrollingTextTabs
import androidx.ui.material.samples.TextTabs
-import androidx.ui.material.surface.Surface
import androidx.ui.test.assertCountEquals
import androidx.ui.test.assertIsSelected
import androidx.ui.test.assertIsUnselected
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/AlertDialog.kt b/ui/ui-material/src/main/java/androidx/ui/material/AlertDialog.kt
index 45160bb4..cd175e08 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/AlertDialog.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/AlertDialog.kt
@@ -32,7 +32,6 @@
import androidx.ui.layout.Spacer
import androidx.ui.material.AlertDialogButtonLayout.SideBySide
import androidx.ui.material.AlertDialogButtonLayout.Stacked
-import androidx.ui.material.surface.Surface
import androidx.ui.unit.dp
/**
@@ -114,7 +113,10 @@
val currentTypography = MaterialTheme.typography()
Dialog(onCloseRequest = onCloseRequest) {
MaterialTheme(colors = currentColors, typography = currentTypography) {
- Surface(modifier = LayoutWidth(AlertDialogWidth), shape = AlertDialogShape) {
+ Surface(
+ modifier = LayoutWidth(AlertDialogWidth),
+ shape = AlertDialogShape
+ ) {
val emphasisLevels = MaterialTheme.emphasisLevels()
Column {
if (title != null) {
@@ -148,7 +150,8 @@
/**
* An enum which specifies how the buttons are positioned inside the [AlertDialog]:
*
- * [SideBySide] - positions the dismiss button on the left side of the confirm button.
+ * [SideBySide] - positions the dismiss button to the left side of the confirm button in LTR
+ * layout direction contexts, and to the right otherwise.
* [Stacked] - positions the dismiss button below the confirm button.
*/
enum class AlertDialogButtonLayout {
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/AppBar.kt b/ui/ui-material/src/main/java/androidx/ui/material/AppBar.kt
index 72eb6bf..219342d 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/AppBar.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/AppBar.kt
@@ -42,8 +42,6 @@
import androidx.ui.layout.RowScope
import androidx.ui.layout.Spacer
import androidx.ui.material.BottomAppBar.FabConfiguration
-import androidx.ui.material.surface.Surface
-import androidx.ui.material.surface.primarySurface
import androidx.ui.semantics.Semantics
import androidx.ui.unit.Density
import androidx.ui.unit.Dp
@@ -490,7 +488,12 @@
shape: Shape,
children: @Composable() RowScope.() -> Unit
) {
- Surface(color = color, contentColor = contentColor, elevation = elevation, shape = shape) {
+ Surface(
+ color = color,
+ contentColor = contentColor,
+ elevation = elevation,
+ shape = shape
+ ) {
Row(
LayoutWidth.Fill + LayoutPadding(
start = AppBarHorizontalPadding,
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/BottomNavigation.kt b/ui/ui-material/src/main/java/androidx/ui/material/BottomNavigation.kt
index 1d7ec50..8e910f4 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/BottomNavigation.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/BottomNavigation.kt
@@ -29,8 +29,8 @@
import androidx.ui.core.LayoutTag
import androidx.ui.core.MeasureScope
import androidx.ui.core.Modifier
-import androidx.ui.core.Opacity
import androidx.ui.core.Placeable
+import androidx.ui.core.drawOpacity
import androidx.ui.core.tag
import androidx.ui.foundation.Box
import androidx.ui.foundation.ContentGravity
@@ -45,8 +45,6 @@
import androidx.ui.layout.Row
import androidx.ui.layout.RowScope
import androidx.ui.material.ripple.Ripple
-import androidx.ui.material.surface.Surface
-import androidx.ui.material.surface.primarySurface
import androidx.ui.text.style.TextAlign
import androidx.ui.unit.Dp
import androidx.ui.unit.IntPx
@@ -211,14 +209,12 @@
Layout(
{
Box(LayoutTag("icon"), children = icon)
- Opacity(iconPositionAnimationProgress) {
- Box(
- LayoutTag("text"),
- paddingLeft = BottomNavigationItemHorizontalPadding,
- paddingRight = BottomNavigationItemHorizontalPadding,
- children = text
- )
- }
+ Box(
+ LayoutTag("text") + drawOpacity(iconPositionAnimationProgress),
+ paddingStart = BottomNavigationItemHorizontalPadding,
+ paddingEnd = BottomNavigationItemHorizontalPadding,
+ children = text
+ )
}
) { measurables, constraints, _ ->
val iconPlaceable = measurables.first { it.tag == "icon" }.measure(constraints)
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Button.kt b/ui/ui-material/src/main/java/androidx/ui/material/Button.kt
index e4e4c85..0698548 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Button.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Button.kt
@@ -30,7 +30,6 @@
import androidx.ui.layout.DpConstraints
import androidx.ui.layout.EdgeInsets
import androidx.ui.material.ripple.Ripple
-import androidx.ui.material.surface.Surface
import androidx.ui.semantics.Semantics
import androidx.ui.unit.Dp
import androidx.ui.unit.dp
@@ -52,27 +51,29 @@
*
* @sample androidx.ui.material.samples.ButtonSample
*
- * @param modifier Modifier to be applied to the button.
- * @param onClick Will be called when the user clicks the button. The button will be disabled if it
- * is null.
- * @param backgroundColor The background color. Use [Color.Transparent] to have no color
- * @param contentColor The preferred content color. Will be used by text and iconography
+ * @param onClick Will be called when the user clicks the button
+ * @param modifier Modifier to be applied to the button
+ * @param enabled Controls the enabled state of the button. When `false`, this button will not
+ * be clickable
+ * @param elevation The z-coordinate at which to place this button. This controls the size
+ * of the shadow below the button
* @param shape Defines the button's shape as well as its shadow
* @param border Border to draw around the button
- * @param elevation The z-coordinate at which to place this button. This controls the size
- * of the shadow below the button
- * @param paddings The spacing values to apply internally between the container and the content
+ * @param backgroundColor The background color. Use [Color.Transparent] to have no color
+ * @param contentColor The preferred content color. Will be used by text and iconography
+ * @param innerPadding The spacing values to apply internally between the container and the content
*/
@Composable
fun Button(
+ onClick: () -> Unit,
modifier: Modifier = Modifier.None,
- onClick: (() -> Unit)? = null,
- backgroundColor: Color = MaterialTheme.colors().primary,
- contentColor: Color = contentColorFor(backgroundColor),
+ enabled: Boolean = true,
+ elevation: Dp = 2.dp,
shape: Shape = MaterialTheme.shapes().button,
border: Border? = null,
- elevation: Dp = 2.dp,
- paddings: EdgeInsets = ButtonPaddings,
+ backgroundColor: Color = MaterialTheme.colors().primary,
+ contentColor: Color = contentColorFor(backgroundColor),
+ innerPadding: EdgeInsets = Button.DefaultInnerPadding,
children: @Composable() () -> Unit
) {
// Since we're adding layouts in between the clickable layer and the content, we need to
@@ -86,9 +87,9 @@
elevation = elevation,
modifier = modifier
) {
- Ripple(bounded = true, enabled = onClick != null) {
- Clickable(onClick = onClick) {
- Container(constraints = ButtonConstraints, padding = paddings) {
+ Ripple(bounded = true, enabled = enabled) {
+ Clickable(onClick = onClick, enabled = enabled) {
+ Container(constraints = ButtonConstraints, padding = innerPadding) {
CurrentTextStyleProvider(
value = MaterialTheme.typography().button,
children = children
@@ -120,38 +121,42 @@
*
* @sample androidx.ui.material.samples.OutlinedButtonSample
*
- * @param modifier Modifier to be applied to the button.
- * @param onClick Will be called when the user clicks the button. The button will be disabled if it
- * is null.
- * @param backgroundColor The background color. Use [Color.Transparent] to have no color
- * @param contentColor The preferred content color. Will be used by text and iconography
+ * @param onClick Will be called when the user clicks the button
+ * @param modifier Modifier to be applied to the button
+ * @param enabled Controls the enabled state of the button. When `false`, this button will not
+ * be clickable
+ * @param elevation The z-coordinate at which to place this button. This controls the size
+ * of the shadow below the button
* @param shape Defines the button's shape as well as its shadow
* @param border Border to draw around the button
- * @param elevation The z-coordinate at which to place this button. This controls the size
- * of the shadow below the button
- * @param paddings The spacing values to apply internally between the container and the content
+ * @param backgroundColor The background color. Use [Color.Transparent] to have no color
+ * @param contentColor The preferred content color. Will be used by text and iconography
+ * @param innerPadding The spacing values to apply internally between the container and the content
*/
@Composable
inline fun OutlinedButton(
+ noinline onClick: () -> Unit,
modifier: Modifier = Modifier.None,
- noinline onClick: (() -> Unit)? = null,
+ enabled: Boolean = true,
+ elevation: Dp = 0.dp,
+ shape: Shape = MaterialTheme.shapes().button,
+ border: Border? = Border(
+ 1.dp, MaterialTheme.colors().onSurface.copy(alpha = OutlinedStrokeOpacity)
+ ),
backgroundColor: Color = MaterialTheme.colors().surface,
contentColor: Color = MaterialTheme.colors().primary,
- shape: Shape = MaterialTheme.shapes().button,
- border: Border? =
- Border(1.dp, MaterialTheme.colors().onSurface.copy(alpha = OutlinedStrokeOpacity)),
- elevation: Dp = 0.dp,
- paddings: EdgeInsets = ButtonPaddings,
+ innerPadding: EdgeInsets = Button.DefaultInnerPadding,
noinline children: @Composable() () -> Unit
) = Button(
modifier = modifier,
onClick = onClick,
- backgroundColor = backgroundColor,
- contentColor = contentColor,
+ enabled = enabled,
+ elevation = elevation,
shape = shape,
border = border,
- elevation = elevation,
- paddings = paddings,
+ backgroundColor = backgroundColor,
+ contentColor = contentColor,
+ innerPadding = innerPadding,
children = children
)
@@ -172,37 +177,40 @@
*
* @sample androidx.ui.material.samples.TextButtonSample
*
- * @param modifier Modifier to be applied to the button.
- * @param onClick Will be called when the user clicks the button. The button will be disabled if it
- * is null.
- * @param backgroundColor The background color. Use [Color.Transparent] to have no color
- * @param contentColor The preferred content color. Will be used by text and iconography
+ * @param onClick Will be called when the user clicks the button
+ * @param modifier Modifier to be applied to the button
+ * @param enabled Controls the enabled state of the button. When `false`, this button will not
+ * be clickable
+ * @param elevation The z-coordinate at which to place this button. This controls the size
+ * of the shadow below the button
* @param shape Defines the button's shape as well as its shadow
* @param border Border to draw around the button
- * @param elevation The z-coordinate at which to place this button. This controls the size
- * of the shadow below the button
- * @param paddings The spacing values to apply internally between the container and the content
+ * @param backgroundColor The background color. Use [Color.Transparent] to have no color
+ * @param contentColor The preferred content color. Will be used by text and iconography
+ * @param innerPadding The spacing values to apply internally between the container and the content
*/
@Composable
inline fun TextButton(
+ noinline onClick: () -> Unit,
modifier: Modifier = Modifier.None,
- noinline onClick: (() -> Unit)? = null,
- backgroundColor: Color = Color.Transparent,
- contentColor: Color = MaterialTheme.colors().primary,
+ enabled: Boolean = true,
+ elevation: Dp = 0.dp,
shape: Shape = MaterialTheme.shapes().button,
border: Border? = null,
- elevation: Dp = 0.dp,
- paddings: EdgeInsets = TextButtonPaddings,
+ backgroundColor: Color = Color.Transparent,
+ contentColor: Color = MaterialTheme.colors().primary,
+ innerPadding: EdgeInsets = TextButton.DefaultInnerPadding,
noinline children: @Composable() () -> Unit
) = Button(
modifier = modifier,
onClick = onClick,
- backgroundColor = backgroundColor,
- contentColor = contentColor,
+ enabled = enabled,
+ elevation = elevation,
shape = shape,
border = border,
- elevation = elevation,
- paddings = paddings,
+ backgroundColor = backgroundColor,
+ contentColor = contentColor,
+ innerPadding = innerPadding,
children = children
)
@@ -212,23 +220,38 @@
minHeight = 36.dp
)
-private val ButtonHorizontalPadding = 16.dp
-private val ButtonVerticalPadding = 8.dp
-private val TextButtonHorizontalPadding = 8.dp
+/**
+ * Contains the default values used by [Button]
+ */
+object Button {
+ private val ButtonHorizontalPadding = 16.dp
+ private val ButtonVerticalPadding = 8.dp
-@PublishedApi
-internal val ButtonPaddings = EdgeInsets(
- left = ButtonHorizontalPadding,
- top = ButtonVerticalPadding,
- right = ButtonHorizontalPadding,
- bottom = ButtonVerticalPadding
-)
+ /**
+ * The default inner padding used by [Button]
+ */
+ val DefaultInnerPadding = EdgeInsets(
+ left = ButtonHorizontalPadding,
+ top = ButtonVerticalPadding,
+ right = ButtonHorizontalPadding,
+ bottom = ButtonVerticalPadding
+ )
+}
-@PublishedApi
-internal val TextButtonPaddings = ButtonPaddings.copy(
- left = TextButtonHorizontalPadding,
- right = TextButtonHorizontalPadding
-)
+/**
+ * Contains the default values used by [TextButton]
+ */
+object TextButton {
+ private val TextButtonHorizontalPadding = 8.dp
+
+ /**
+ * The default inner padding used by [TextButton]
+ */
+ val DefaultInnerPadding = Button.DefaultInnerPadding.copy(
+ left = TextButtonHorizontalPadding,
+ right = TextButtonHorizontalPadding
+ )
+}
@PublishedApi
internal const val OutlinedStrokeOpacity = 0.12f
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/surface/Card.kt b/ui/ui-material/src/main/java/androidx/ui/material/Card.kt
similarity index 92%
rename from ui/ui-material/src/main/java/androidx/ui/material/surface/Card.kt
rename to ui/ui-material/src/main/java/androidx/ui/material/Card.kt
index 2c1d24d..5196b06 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/surface/Card.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Card.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * 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.
@@ -14,15 +14,13 @@
* limitations under the License.
*/
-package androidx.ui.material.surface
+package androidx.ui.material
import androidx.compose.Composable
import androidx.ui.core.Modifier
import androidx.ui.foundation.Border
import androidx.ui.graphics.Color
import androidx.ui.graphics.Shape
-import androidx.ui.material.MaterialTheme
-import androidx.ui.material.contentColorFor
import androidx.ui.unit.Dp
import androidx.ui.unit.dp
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/DataTable.kt b/ui/ui-material/src/main/java/androidx/ui/material/DataTable.kt
index 1d7335f..a306273 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/DataTable.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/DataTable.kt
@@ -27,7 +27,7 @@
import androidx.ui.foundation.Border
import androidx.ui.foundation.Clickable
import androidx.ui.foundation.ColoredRect
-import androidx.ui.foundation.SimpleImage
+import androidx.ui.foundation.Image
import androidx.ui.foundation.drawBorders
import androidx.ui.foundation.selection.ToggleableState
import androidx.ui.graphics.Color
@@ -212,7 +212,7 @@
Text(text = text(j))
} else {
Row {
- SimpleImage(image = image)
+ Image(image = image)
Spacer(LayoutWidth(2.dp))
Text(text = text(j))
}
@@ -257,7 +257,7 @@
Text(text = text(j))
} else {
Row {
- SimpleImage(image = image)
+ Image(image = image)
Spacer(LayoutWidth(2.dp))
Text(text = text(j))
}
@@ -383,7 +383,8 @@
for (j in 0 until columns) {
Container(height = headerRowHeight, padding = cellSpacing) {
var fontWeight = FontWeight.W500
- var onSort = null as (() -> Unit)?
+ var onSort = {}
+ var enabled = false
var headerDecoration: @Composable() (() -> Unit)? = null
if (sorting != null && sorting.sortableColumns.contains(j)) {
@@ -392,6 +393,7 @@
onSort = {
sorting.onSortChange(j, !sorting.ascending)
}
+ enabled = true
headerDecoration = {
// TODO(calintat): Replace with animated arrow icons.
Text(text = if (sorting.ascending) "↑" else "↓")
@@ -406,7 +408,7 @@
CurrentTextStyleProvider(TextStyle(fontWeight = fontWeight)) {
Ripple(bounded = true) {
- Clickable(onClick = onSort) {
+ Clickable(onClick = onSort, enabled = enabled) {
Row {
headerDecoration?.invoke()
header.children(index = j)
@@ -467,7 +469,7 @@
height = verticalOffsets[i + 2] - verticalOffsets[i + 1]
)
)
- placeable.place(
+ placeable.placeAbsolute(
x = IntPx.Zero,
y = verticalOffsets[i + 1]
)
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Drawer.kt b/ui/ui-material/src/main/java/androidx/ui/material/Drawer.kt
index 4641a91..8392ec7 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Drawer.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Drawer.kt
@@ -37,7 +37,6 @@
import androidx.ui.layout.LayoutSize
import androidx.ui.layout.Stack
import androidx.ui.material.internal.StateDraggable
-import androidx.ui.material.surface.Surface
import androidx.ui.unit.IntPx
import androidx.ui.unit.Px
import androidx.ui.unit.dp
@@ -111,7 +110,7 @@
bodyContent: @Composable() () -> Unit
) {
Container(expanded = true) {
- WithConstraints { pxConstraints ->
+ WithConstraints { pxConstraints, _ ->
// TODO : think about Infinite max bounds case
if (!pxConstraints.hasBoundedWidth) {
throw IllegalStateException("Drawer shouldn't have infinite width")
@@ -178,7 +177,7 @@
bodyContent: @Composable() () -> Unit
) {
Container(expanded = true) {
- WithConstraints { pxConstraints ->
+ WithConstraints { pxConstraints, _ ->
// TODO : think about Infinite max bounds case
if (!pxConstraints.hasBoundedHeight) {
throw IllegalStateException("Drawer shouldn't have infinite height")
@@ -241,7 +240,12 @@
padding = EdgeInsets(right = VerticalDrawerPadding)
) {
// remove Container when we will support multiply children
- Surface { Container(expanded = true, children = children) }
+ Surface {
+ Container(
+ expanded = true,
+ children = children
+ )
+ }
}
}
}
@@ -255,7 +259,12 @@
WithOffset(yOffset = yOffset) {
Container(constraints = constraints) {
// remove Container when we will support multiply children
- Surface { Container(expanded = true, children = children) }
+ Surface {
+ Container(
+ expanded = true,
+ children = children
+ )
+ }
}
}
}
@@ -330,4 +339,4 @@
stiffness = DrawerStiffness
}
-internal val BottomDrawerOpenFraction = 0.5f
\ No newline at end of file
+internal val BottomDrawerOpenFraction = 0.5f
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Emphasis.kt b/ui/ui-material/src/main/java/androidx/ui/material/Emphasis.kt
index 3883708..59cf198 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Emphasis.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Emphasis.kt
@@ -16,6 +16,8 @@
package androidx.ui.material
+import androidx.annotation.FloatRange
+import androidx.compose.Ambient
import androidx.compose.Composable
import androidx.compose.Immutable
import androidx.compose.staticAmbientOf
@@ -53,25 +55,36 @@
}
/**
- * Class holding the different levels of [Emphasis] that will be applied to components in a
- * [MaterialTheme].
+ * EmphasisLevels represents the different levels of [Emphasis] that can be applied to a component.
*
- * @see MaterialTheme.emphasisLevels
+ * By default, the [Emphasis] implementation for each level varies depending on the color being
+ * emphasized (typically [contentColor]). This ensures that the [Emphasis] has the correct
+ * contrast for the background they are on, as [ColorPalette.primary] surfaces typically require
+ * higher contrast for the content color than [ColorPalette.surface] surfaces to ensure they are
+ * accessible.
+ *
+ * This typically should not be customized as the default implementation is optimized for
+ * correct accessibility and contrast on different surfaces.
+ *
+ * See [MaterialTheme.emphasisLevels] to retrieve the current [EmphasisLevels]
*/
-data class EmphasisLevels(
+interface EmphasisLevels {
/**
* Emphasis used to express high emphasis, such as for selected text fields.
*/
- val high: Emphasis = DefaultHighEmphasis,
+ @Composable
+ val high: Emphasis
/**
* Emphasis used to express medium emphasis, such as for placeholder text in a text field.
*/
- val medium: Emphasis = DefaultMediumEmphasis,
+ @Composable
+ val medium: Emphasis
/**
* Emphasis used to express disabled state, such as for a disabled button.
*/
- val disabled: Emphasis = DefaultDisabledEmphasis
-)
+ @Composable
+ val disabled: Emphasis
+}
/**
* Applies [emphasis] to [children], by modifying the value of [contentColor].
@@ -90,29 +103,57 @@
/**
* Ambient containing the current [EmphasisLevels] in this hierarchy.
*/
-val EmphasisAmbient = staticAmbientOf { EmphasisLevels() }
+val EmphasisAmbient: Ambient<EmphasisLevels> = staticAmbientOf { DefaultEmphasisLevels }
-/**
- * Default implementation for expressing high emphasis.
- */
-private val DefaultHighEmphasis: Emphasis = object : Emphasis {
- override fun emphasize(color: Color) = color.copy(alpha = HighEmphasisAlpha)
+private object DefaultEmphasisLevels : EmphasisLevels {
+
+ private class AlphaEmphasis(
+ private val colorPalette: ColorPalette,
+ @FloatRange(from = 0.0, to = 1.0) private val onPrimaryAlpha: Float,
+ @FloatRange(from = 0.0, to = 1.0) private val onSurfaceAlpha: Float
+ ) : Emphasis {
+ override fun emphasize(color: Color): Color {
+ val alpha = when (color) {
+ colorPalette.onPrimary -> onPrimaryAlpha
+ else -> onSurfaceAlpha
+ }
+ return color.copy(alpha = alpha)
+ }
+ }
+
+ @Composable
+ override val high: Emphasis
+ get() = AlphaEmphasis(
+ colorPalette = MaterialTheme.colors(),
+ onPrimaryAlpha = OnPrimaryAlphaLevels.high,
+ onSurfaceAlpha = OnSurfaceAlphaLevels.high
+ )
+
+ @Composable
+ override val medium: Emphasis
+ get() = AlphaEmphasis(
+ colorPalette = MaterialTheme.colors(),
+ onPrimaryAlpha = OnPrimaryAlphaLevels.medium,
+ onSurfaceAlpha = OnSurfaceAlphaLevels.medium
+ )
+
+ @Composable
+ override val disabled: Emphasis
+ get() = AlphaEmphasis(
+ colorPalette = MaterialTheme.colors(),
+ onPrimaryAlpha = OnPrimaryAlphaLevels.disabled,
+ onSurfaceAlpha = OnSurfaceAlphaLevels.disabled
+ )
}
-/**
- * Default implementation for expressing medium emphasis.
- */
-private val DefaultMediumEmphasis: Emphasis = object : Emphasis {
- override fun emphasize(color: Color) = color.copy(alpha = MediumEmphasisAlpha)
+private object OnPrimaryAlphaLevels {
+ const val high: Float = 1.00f
+ const val medium: Float = 0.74f
+ const val disabled: Float = 0.38f
}
-/**
- * Default implementation for expressing disabled emphasis.
- */
-private val DefaultDisabledEmphasis: Emphasis = object : Emphasis {
- override fun emphasize(color: Color) = color.copy(alpha = DisabledEmphasisAlpha)
+private object OnSurfaceAlphaLevels {
+ const val high: Float = 0.87f
+ const val medium: Float = 0.60f
+ const val disabled: Float = 0.38f
}
-
-private const val HighEmphasisAlpha = 0.87f
-private const val MediumEmphasisAlpha = 0.60f
-private const val DisabledEmphasisAlpha = 0.38f
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/FloatingActionButton.kt b/ui/ui-material/src/main/java/androidx/ui/material/FloatingActionButton.kt
index 85715de..ad2b426 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/FloatingActionButton.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/FloatingActionButton.kt
@@ -21,7 +21,7 @@
import androidx.ui.core.Modifier
import androidx.ui.core.Text
import androidx.ui.foundation.Clickable
-import androidx.ui.foundation.SimpleImage
+import androidx.ui.foundation.Image
import androidx.ui.foundation.shape.corner.CircleShape
import androidx.ui.graphics.Color
import androidx.ui.graphics.ImageAsset
@@ -33,7 +33,6 @@
import androidx.ui.layout.Row
import androidx.ui.layout.Spacer
import androidx.ui.material.ripple.Ripple
-import androidx.ui.material.surface.Surface
import androidx.ui.text.TextStyle
import androidx.ui.unit.Dp
import androidx.ui.unit.dp
@@ -47,20 +46,22 @@
*
* @see FloatingActionButton overload for the variants with an icon or an icon and a text.
*
+ * @param onClick will be called when user clicked on the button
* @param modifier Modifier to be applied to the button.
- * @param onClick will be called when user clicked on the button. The button will be disabled
- * when it is null.
- * @param minSize Minimum size of the FAB.
+ * @param enabled Controls the enabled state of the button. When `false`, this button will not
+ * be clickable
+ * @param minSize Minimum size of the FAB
* @param shape Defines the Button's shape as well its shadow. When null is provided it uses
- * the [Shapes.button] from [ShapeAmbient].
+ * the [Shapes.button] from [ShapeAmbient]
* @param color The background color
* @param elevation The z-coordinate at which to place this button. This controls the size
- * of the shadow below the button.
+ * of the shadow below the button
*/
@Composable
fun FloatingActionButton(
+ onClick: () -> Unit,
modifier: Modifier = Modifier.None,
- onClick: (() -> Unit)? = null,
+ enabled: Boolean = true,
minSize: Dp = FabSize,
shape: Shape = CircleShape,
color: Color = MaterialTheme.colors().primary,
@@ -68,8 +69,8 @@
children: @Composable() () -> Unit
) {
Surface(modifier = modifier, shape = shape, color = color, elevation = elevation) {
- Ripple(bounded = true, enabled = onClick != null) {
- Clickable(onClick) {
+ Ripple(bounded = true, enabled = enabled) {
+ Clickable(onClick = onClick, enabled = enabled) {
Container(constraints = DpConstraints(minWidth = minSize, minHeight = minSize)) {
CurrentTextStyleProvider(MaterialTheme.typography().button, children)
}
@@ -87,19 +88,21 @@
*
* @see FloatingActionButton overload for the variants with a custom content or an icon and a text.
*
- * @param icon Image to draw in the center.
+ * @param icon Image to draw in the center
+ * @param onClick will be called when user clicked on the button
* @param modifier Modifier to be applied to the button.
- * @param onClick will be called when user clicked on the button. The button will be disabled
- * when it is null.
+ * @param enabled Controls the enabled state of the button. When `false`, this button will not
+ * be clickable
* @param color The background color
* @param elevation The z-coordinate at which to place this button. This controls the size
- * of the shadow below the button.
+ * of the shadow below the button
*/
@Composable
fun FloatingActionButton(
icon: ImageAsset,
+ onClick: () -> Unit,
modifier: Modifier = Modifier.None,
- onClick: (() -> Unit)? = null,
+ enabled: Boolean = true,
shape: Shape = CircleShape,
color: Color = MaterialTheme.colors().primary,
elevation: Dp = 6.dp
@@ -107,11 +110,12 @@
FloatingActionButton(
modifier = modifier,
onClick = onClick,
+ enabled = enabled,
shape = shape,
color = color,
elevation = elevation
) {
- SimpleImage(image = icon)
+ Image(image = icon)
}
}
@@ -123,28 +127,31 @@
* @see FloatingActionButton overload for the variants with a custom content or an icon.
*
* @param text Text to display.
+ * @param onClick will be called when user clicked on the button
* @param modifier Modifier to be applied to the button.
- * @param icon Image to draw to the left of the text. It is optional.
+ * @param icon Image to draw to the left of the text. It is optional
* @param textStyle Optional [TextStyle] to apply for a [text]
- * @param onClick will be called when user clicked on the button. The button will be disabled
- * when it is null.
+ * @param enabled Controls the enabled state of the button. When `false`, this button will not
+ * be clickable
* @param color The background color
* @param elevation The z-coordinate at which to place this button. This controls the size
- * of the shadow below the button.
+ * if the shadow below the button.
*/
@Composable
fun FloatingActionButton(
text: String,
+ onClick: () -> Unit,
modifier: Modifier = Modifier.None,
icon: ImageAsset? = null,
textStyle: TextStyle? = null,
- onClick: (() -> Unit)? = null,
+ enabled: Boolean = true,
color: Color = MaterialTheme.colors().primary,
elevation: Dp = 6.dp
) {
FloatingActionButton(
modifier = modifier,
onClick = onClick,
+ enabled = enabled,
color = color,
elevation = elevation,
minSize = ExtendedFabHeight) {
@@ -159,7 +166,7 @@
)
} else {
Row(LayoutPadding(start = ExtendedFabIconPadding, end = ExtendedFabTextPadding)) {
- SimpleImage(image = icon)
+ Image(image = icon)
Spacer(LayoutWidth(ExtendedFabIconPadding))
Text(text = text, style = textStyle)
}
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/ListItem.kt b/ui/ui-material/src/main/java/androidx/ui/material/ListItem.kt
index 30d15f4..08bc8a2 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/ListItem.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/ListItem.kt
@@ -25,7 +25,7 @@
import androidx.ui.core.Modifier
import androidx.ui.core.Text
import androidx.ui.foundation.Clickable
-import androidx.ui.foundation.SimpleImage
+import androidx.ui.foundation.Image
import androidx.ui.graphics.ImageAsset
import androidx.ui.layout.Container
import androidx.ui.layout.DpConstraints
@@ -75,7 +75,7 @@
onClick: (() -> Unit)? = null
) {
val iconComposable: @Composable() (() -> Unit)? = icon?.let {
- { SimpleImage(it) }
+ { Image(it) }
}
val textComposable: @Composable() () -> Unit = text.let {
{ Text(it, maxLines = 1, overflow = TextOverflow.Ellipsis) }
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/ProgressIndicator.kt b/ui/ui-material/src/main/java/androidx/ui/material/ProgressIndicator.kt
index 9f8ab28..6a90ebc 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/ProgressIndicator.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/ProgressIndicator.kt
@@ -39,7 +39,7 @@
import androidx.ui.graphics.vectormath.degrees
import androidx.ui.layout.LayoutPadding
import androidx.ui.layout.LayoutSize
-import androidx.ui.layout.Wrap
+import androidx.ui.layout.Stack
import androidx.ui.unit.dp
import kotlin.math.abs
import kotlin.math.max
@@ -57,7 +57,7 @@
color: Color = MaterialTheme.colors().primary
) {
DeterminateProgressIndicator(progress = progress) {
- Wrap {
+ Stack {
val paint = paint(color, StrokeCap.butt)
val backgroundPaint = paint(
color.copy(alpha = BackgroundOpacity),
@@ -79,7 +79,7 @@
*/
@Composable
fun LinearProgressIndicator(color: Color = MaterialTheme.colors().primary) {
- Wrap {
+ Stack {
Transition(
definition = LinearIndeterminateTransition,
initState = 0,
@@ -140,7 +140,7 @@
@FloatRange(from = 0.0, to = 1.0) progress: Float,
color: Color = MaterialTheme.colors().primary
) {
- Wrap {
+ Stack {
DeterminateProgressIndicator(progress = progress) {
val paint = paint(color, StrokeCap.butt)
Canvas(
@@ -164,7 +164,7 @@
*/
@Composable
fun CircularProgressIndicator(color: Color = MaterialTheme.colors().primary) {
- Wrap {
+ Stack {
val paint = paint(color, StrokeCap.square)
Transition(
definition = CircularIndeterminateTransition,
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/RadioButton.kt b/ui/ui-material/src/main/java/androidx/ui/material/RadioButton.kt
index b4e435d..d1645d6 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/RadioButton.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/RadioButton.kt
@@ -37,7 +37,7 @@
import androidx.ui.layout.LayoutSize
import androidx.ui.layout.LayoutWidth
import androidx.ui.layout.Row
-import androidx.ui.layout.Wrap
+import androidx.ui.layout.Stack
import androidx.ui.material.ripple.Ripple
import androidx.ui.semantics.Semantics
import androidx.ui.text.TextStyle
@@ -194,7 +194,7 @@
color: Color = MaterialTheme.colors().secondary
) {
val radioPaint = remember { Paint() }
- Wrap {
+ Stack {
Ripple(bounded = false) {
MutuallyExclusiveSetItem(
selected = selected, onClick = { if (!selected) onSelect?.invoke() }
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Scaffold.kt b/ui/ui-material/src/main/java/androidx/ui/material/Scaffold.kt
index dbb2146..9bfedbd 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Scaffold.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Scaffold.kt
@@ -35,7 +35,6 @@
import androidx.ui.material.BottomAppBar.FabConfiguration
import androidx.ui.material.BottomAppBar.FabDockedPosition
import androidx.ui.material.Scaffold.FabPosition
-import androidx.ui.material.surface.Surface
import androidx.ui.unit.IntPx
import androidx.ui.unit.IntPxSize
import androidx.ui.unit.PxPosition
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Slider.kt b/ui/ui-material/src/main/java/androidx/ui/material/Slider.kt
index 2433f55..5607a30c 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Slider.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Slider.kt
@@ -52,7 +52,6 @@
import androidx.ui.layout.Spacer
import androidx.ui.layout.Stack
import androidx.ui.material.ripple.Ripple
-import androidx.ui.material.surface.Surface
import androidx.ui.semantics.Semantics
import androidx.ui.semantics.accessibilityValue
import androidx.ui.unit.dp
@@ -185,7 +184,7 @@
) {
Semantics(container = true, mergeAllDescendants = true) {
Box(modifier = modifier) {
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
val maxPx = constraints.maxWidth.value.toFloat()
val minPx = 0f
position.setBounds(minPx, maxPx)
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Snackbar.kt b/ui/ui-material/src/main/java/androidx/ui/material/Snackbar.kt
index d758180..bd55a9b7 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Snackbar.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Snackbar.kt
@@ -33,7 +33,6 @@
import androidx.ui.layout.LayoutGravity
import androidx.ui.layout.LayoutPadding
import androidx.ui.layout.LayoutWidth
-import androidx.ui.material.surface.Surface
import androidx.ui.unit.IntPx
import androidx.ui.unit.dp
import androidx.ui.unit.ipx
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/surface/Surface.kt b/ui/ui-material/src/main/java/androidx/ui/material/Surface.kt
similarity index 85%
rename from ui/ui-material/src/main/java/androidx/ui/material/surface/Surface.kt
rename to ui/ui-material/src/main/java/androidx/ui/material/Surface.kt
index a03a041..de0e56a 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/surface/Surface.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Surface.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2019 The Android Open Source Project
+ * 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.
@@ -14,16 +14,15 @@
* limitations under the License.
*/
-package androidx.ui.material.surface
+package androidx.ui.material
import androidx.compose.Composable
-import androidx.ui.core.Clip
import androidx.ui.core.CurrentTextStyleProvider
-import androidx.ui.core.Draw
-import androidx.ui.core.DrawShadow
import androidx.ui.core.Layout
import androidx.ui.core.Modifier
import androidx.ui.core.Text
+import androidx.ui.core.drawClip
+import androidx.ui.core.drawShadow
import androidx.ui.foundation.Border
import androidx.ui.foundation.DrawBackground
import androidx.ui.foundation.DrawBorder
@@ -32,9 +31,6 @@
import androidx.ui.graphics.Color
import androidx.ui.graphics.Shape
import androidx.ui.graphics.compositeOver
-import androidx.ui.material.ColorPalette
-import androidx.ui.material.MaterialTheme
-import androidx.ui.material.contentColorFor
import androidx.ui.text.TextStyle
import androidx.ui.unit.Dp
import androidx.ui.unit.dp
@@ -90,21 +86,13 @@
elevation: Dp = 0.dp,
children: @Composable() () -> Unit
) {
- val borderModifier =
- if (border != null) DrawBorder(border, shape) else Modifier.None
- SurfaceLayout(modifier + borderModifier) {
- if (elevation > 0.dp) {
- DrawShadow(shape = shape, elevation = elevation)
- }
- val backgroundColor = getBackgroundColorForElevation(color, elevation)
- val background = DrawBackground(shape = shape, color = backgroundColor)
- @Suppress("DEPRECATION") // remove when b/147606015 is fixed
- Draw { canvas, size ->
- background.draw(this, {}, canvas, size)
- }
- Clip(shape = shape) {
- ProvideContentColor(contentColor, children)
- }
+ val borderModifier = if (border != null) DrawBorder(border, shape) else Modifier.None
+ val shadowModifier = drawShadow(shape = shape, elevation = elevation, clipToOutline = false)
+ val backgroundColor = getBackgroundColorForElevation(color, elevation)
+ val background = DrawBackground(shape = shape, color = backgroundColor)
+ val clip = drawClip(shape)
+ SurfaceLayout(modifier + shadowModifier + borderModifier + background + clip) {
+ ProvideContentColor(contentColor, children)
}
}
@@ -136,7 +124,7 @@
} else {
val placeable = measurable.measure(constraints)
layout(placeable.width, placeable.height) {
- placeable.place(0.ipx, 0.ipx)
+ placeable.placeAbsolute(0.ipx, 0.ipx)
}
}
}
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Switch.kt b/ui/ui-material/src/main/java/androidx/ui/material/Switch.kt
index 0a756cd..1838cb4 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Switch.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Switch.kt
@@ -31,7 +31,7 @@
import androidx.ui.graphics.StrokeCap
import androidx.ui.layout.LayoutPadding
import androidx.ui.layout.LayoutSize
-import androidx.ui.layout.Wrap
+import androidx.ui.layout.Stack
import androidx.ui.material.internal.StateDraggable
import androidx.ui.material.ripple.Ripple
import androidx.ui.semantics.Semantics
@@ -56,7 +56,7 @@
color: Color = MaterialTheme.colors().secondaryVariant
) {
Semantics(container = true, mergeAllDescendants = true) {
- Wrap {
+ Stack {
Ripple(bounded = false) {
Toggleable(value = checked, onValueChange = onCheckedChange) {
Box(LayoutPadding(DefaultSwitchPadding)) {
diff --git a/ui/ui-material/src/main/java/androidx/ui/material/Tab.kt b/ui/ui-material/src/main/java/androidx/ui/material/Tab.kt
index fc4e129..5db935a 100644
--- a/ui/ui-material/src/main/java/androidx/ui/material/Tab.kt
+++ b/ui/ui-material/src/main/java/androidx/ui/material/Tab.kt
@@ -56,8 +56,6 @@
import androidx.ui.layout.Stack
import androidx.ui.material.TabRow.TabPosition
import androidx.ui.material.ripple.Ripple
-import androidx.ui.material.surface.Surface
-import androidx.ui.material.surface.primarySurface
import androidx.ui.text.style.TextAlign
import androidx.ui.unit.Density
import androidx.ui.unit.IntPx
@@ -150,7 +148,7 @@
tab: @Composable() (Int, T) -> Unit
) {
Surface(color = color, contentColor = contentColor) {
- WithConstraints { constraints ->
+ WithConstraints { constraints, _ ->
val width = constraints.maxWidth
// TODO: force scrollable for tabs that will be too small if they take up equal space?
if (scrollable) {
@@ -576,8 +574,8 @@
{
Box(
LayoutTag("text"),
- paddingLeft = HorizontalTextPadding,
- paddingRight = HorizontalTextPadding,
+ paddingStart = HorizontalTextPadding,
+ paddingEnd = HorizontalTextPadding,
children = text
)
Box(LayoutTag("icon"), children = icon)
diff --git a/ui/ui-platform/api/0.1.0-dev07.txt b/ui/ui-platform/api/0.1.0-dev07.txt
index b35c3899..3d6ea81 100644
--- a/ui/ui-platform/api/0.1.0-dev07.txt
+++ b/ui/ui-platform/api/0.1.0-dev07.txt
@@ -16,6 +16,7 @@
method public void addAndroidView(android.view.View view, androidx.ui.core.LayoutNode layoutNode);
method public androidx.ui.unit.IntPxPosition calculatePosition();
method public void callDraw(androidx.ui.graphics.Canvas canvas, androidx.ui.core.ComponentNode node, androidx.ui.unit.PxSize parentSize);
+ method public androidx.ui.core.OwnedLayer createLayer(androidx.ui.core.DrawLayerModifier drawLayerModifier, kotlin.jvm.functions.Function2<? super androidx.ui.graphics.Canvas,? super androidx.ui.unit.Density,kotlin.Unit> drawBlock);
method public java.util.List<androidx.ui.core.semantics.SemanticsNode> getAllSemanticNodes();
method public androidx.ui.autofill.Autofill? getAutofill();
method public androidx.ui.autofill.AutofillTree getAutofillTree();
@@ -32,6 +33,7 @@
method public androidx.ui.input.TextInputService getTextInputService();
method public void measureAndLayout();
method public void observeDrawModelReads(androidx.ui.core.RepaintBoundaryNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+ method public void observeLayerModelReads(androidx.ui.core.OwnedLayer layer, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void observeLayoutModelReads(androidx.ui.core.LayoutNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void observeMeasureModelReads(androidx.ui.core.LayoutNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void onAttach(androidx.ui.core.ComponentNode node);
@@ -78,12 +80,9 @@
public final class AndroidOwnerKt {
}
- public abstract sealed class ComponentNode implements androidx.compose.Emittable {
+ public abstract sealed class ComponentNode {
method public void attach(androidx.ui.core.Owner owner);
method public void detach();
- method public void emitInsertAt(int index, androidx.compose.Emittable instance);
- method public void emitMove(int from, int to, int count);
- method public void emitRemoveAt(int index, int count);
method public final operator androidx.ui.core.ComponentNode get(int index);
method protected androidx.ui.core.LayoutNode? getContainingLayoutNode();
method public final int getCount();
@@ -93,6 +92,9 @@
method public final androidx.ui.core.ComponentNode? getParent();
method public androidx.ui.core.LayoutNode? getParentLayoutNode();
method public androidx.ui.core.RepaintBoundaryNode? getRepaintBoundary();
+ method public final void insertAt(int index, androidx.ui.core.ComponentNode instance);
+ method public final void move(int from, int to, int count);
+ method public final void removeAt(int index, int count);
method public final void setDepth(int p);
method public final void setOwnerData(Object? p);
method public final inline void visitChildren(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
@@ -268,9 +270,19 @@
method public void pauseObservingReads(kotlin.jvm.functions.Function0<kotlin.Unit> block);
}
+ public interface OwnedLayer {
+ method public void destroy();
+ method public void drawLayer(androidx.ui.graphics.Canvas canvas);
+ method public void invalidate();
+ method public void move(androidx.ui.unit.IntPxPosition position);
+ method public void resize(androidx.ui.unit.IntPxSize size);
+ method public void updateLayerProperties();
+ }
+
public interface Owner {
method public androidx.ui.unit.IntPxPosition calculatePosition();
method public void callDraw(androidx.ui.graphics.Canvas canvas, androidx.ui.core.ComponentNode node, androidx.ui.unit.PxSize parentSize);
+ method public androidx.ui.core.OwnedLayer createLayer(androidx.ui.core.DrawLayerModifier drawLayerModifier, kotlin.jvm.functions.Function2<? super androidx.ui.graphics.Canvas,? super androidx.ui.unit.Density,kotlin.Unit> drawBlock);
method public androidx.ui.unit.Density getDensity();
method public long getMeasureIteration();
method public androidx.ui.core.semantics.SemanticsOwner getSemanticsOwner();
diff --git a/ui/ui-platform/api/current.txt b/ui/ui-platform/api/current.txt
index b35c3899..3d6ea81 100644
--- a/ui/ui-platform/api/current.txt
+++ b/ui/ui-platform/api/current.txt
@@ -16,6 +16,7 @@
method public void addAndroidView(android.view.View view, androidx.ui.core.LayoutNode layoutNode);
method public androidx.ui.unit.IntPxPosition calculatePosition();
method public void callDraw(androidx.ui.graphics.Canvas canvas, androidx.ui.core.ComponentNode node, androidx.ui.unit.PxSize parentSize);
+ method public androidx.ui.core.OwnedLayer createLayer(androidx.ui.core.DrawLayerModifier drawLayerModifier, kotlin.jvm.functions.Function2<? super androidx.ui.graphics.Canvas,? super androidx.ui.unit.Density,kotlin.Unit> drawBlock);
method public java.util.List<androidx.ui.core.semantics.SemanticsNode> getAllSemanticNodes();
method public androidx.ui.autofill.Autofill? getAutofill();
method public androidx.ui.autofill.AutofillTree getAutofillTree();
@@ -32,6 +33,7 @@
method public androidx.ui.input.TextInputService getTextInputService();
method public void measureAndLayout();
method public void observeDrawModelReads(androidx.ui.core.RepaintBoundaryNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+ method public void observeLayerModelReads(androidx.ui.core.OwnedLayer layer, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void observeLayoutModelReads(androidx.ui.core.LayoutNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void observeMeasureModelReads(androidx.ui.core.LayoutNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void onAttach(androidx.ui.core.ComponentNode node);
@@ -78,12 +80,9 @@
public final class AndroidOwnerKt {
}
- public abstract sealed class ComponentNode implements androidx.compose.Emittable {
+ public abstract sealed class ComponentNode {
method public void attach(androidx.ui.core.Owner owner);
method public void detach();
- method public void emitInsertAt(int index, androidx.compose.Emittable instance);
- method public void emitMove(int from, int to, int count);
- method public void emitRemoveAt(int index, int count);
method public final operator androidx.ui.core.ComponentNode get(int index);
method protected androidx.ui.core.LayoutNode? getContainingLayoutNode();
method public final int getCount();
@@ -93,6 +92,9 @@
method public final androidx.ui.core.ComponentNode? getParent();
method public androidx.ui.core.LayoutNode? getParentLayoutNode();
method public androidx.ui.core.RepaintBoundaryNode? getRepaintBoundary();
+ method public final void insertAt(int index, androidx.ui.core.ComponentNode instance);
+ method public final void move(int from, int to, int count);
+ method public final void removeAt(int index, int count);
method public final void setDepth(int p);
method public final void setOwnerData(Object? p);
method public final inline void visitChildren(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
@@ -268,9 +270,19 @@
method public void pauseObservingReads(kotlin.jvm.functions.Function0<kotlin.Unit> block);
}
+ public interface OwnedLayer {
+ method public void destroy();
+ method public void drawLayer(androidx.ui.graphics.Canvas canvas);
+ method public void invalidate();
+ method public void move(androidx.ui.unit.IntPxPosition position);
+ method public void resize(androidx.ui.unit.IntPxSize size);
+ method public void updateLayerProperties();
+ }
+
public interface Owner {
method public androidx.ui.unit.IntPxPosition calculatePosition();
method public void callDraw(androidx.ui.graphics.Canvas canvas, androidx.ui.core.ComponentNode node, androidx.ui.unit.PxSize parentSize);
+ method public androidx.ui.core.OwnedLayer createLayer(androidx.ui.core.DrawLayerModifier drawLayerModifier, kotlin.jvm.functions.Function2<? super androidx.ui.graphics.Canvas,? super androidx.ui.unit.Density,kotlin.Unit> drawBlock);
method public androidx.ui.unit.Density getDensity();
method public long getMeasureIteration();
method public androidx.ui.core.semantics.SemanticsOwner getSemanticsOwner();
diff --git a/ui/ui-platform/api/public_plus_experimental_0.1.0-dev07.txt b/ui/ui-platform/api/public_plus_experimental_0.1.0-dev07.txt
index 61079a5..da1745f 100644
--- a/ui/ui-platform/api/public_plus_experimental_0.1.0-dev07.txt
+++ b/ui/ui-platform/api/public_plus_experimental_0.1.0-dev07.txt
@@ -16,6 +16,7 @@
method public void addAndroidView(android.view.View view, androidx.ui.core.LayoutNode layoutNode);
method public androidx.ui.unit.IntPxPosition calculatePosition();
method public void callDraw(androidx.ui.graphics.Canvas canvas, androidx.ui.core.ComponentNode node, androidx.ui.unit.PxSize parentSize);
+ method public androidx.ui.core.OwnedLayer createLayer(androidx.ui.core.DrawLayerModifier drawLayerModifier, kotlin.jvm.functions.Function2<? super androidx.ui.graphics.Canvas,? super androidx.ui.unit.Density,kotlin.Unit> drawBlock);
method public java.util.List<androidx.ui.core.semantics.SemanticsNode> getAllSemanticNodes();
method public androidx.ui.autofill.Autofill? getAutofill();
method public androidx.ui.autofill.AutofillTree getAutofillTree();
@@ -32,6 +33,7 @@
method public androidx.ui.input.TextInputService getTextInputService();
method public void measureAndLayout();
method public void observeDrawModelReads(androidx.ui.core.RepaintBoundaryNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+ method public void observeLayerModelReads(androidx.ui.core.OwnedLayer layer, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void observeLayoutModelReads(androidx.ui.core.LayoutNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void observeMeasureModelReads(androidx.ui.core.LayoutNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void onAttach(androidx.ui.core.ComponentNode node);
@@ -79,12 +81,9 @@
public final class AndroidOwnerKt {
}
- public abstract sealed class ComponentNode implements androidx.compose.Emittable {
+ public abstract sealed class ComponentNode {
method public void attach(androidx.ui.core.Owner owner);
method public void detach();
- method public void emitInsertAt(int index, androidx.compose.Emittable instance);
- method public void emitMove(int from, int to, int count);
- method public void emitRemoveAt(int index, int count);
method public final operator androidx.ui.core.ComponentNode get(int index);
method protected androidx.ui.core.LayoutNode? getContainingLayoutNode();
method public final int getCount();
@@ -94,6 +93,9 @@
method public final androidx.ui.core.ComponentNode? getParent();
method public androidx.ui.core.LayoutNode? getParentLayoutNode();
method public androidx.ui.core.RepaintBoundaryNode? getRepaintBoundary();
+ method public final void insertAt(int index, androidx.ui.core.ComponentNode instance);
+ method public final void move(int from, int to, int count);
+ method public final void removeAt(int index, int count);
method public final void setDepth(int p);
method public final void setOwnerData(Object? p);
method public final inline void visitChildren(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
@@ -270,9 +272,19 @@
method public void pauseObservingReads(kotlin.jvm.functions.Function0<kotlin.Unit> block);
}
+ public interface OwnedLayer {
+ method public void destroy();
+ method public void drawLayer(androidx.ui.graphics.Canvas canvas);
+ method public void invalidate();
+ method public void move(androidx.ui.unit.IntPxPosition position);
+ method public void resize(androidx.ui.unit.IntPxSize size);
+ method public void updateLayerProperties();
+ }
+
public interface Owner {
method public androidx.ui.unit.IntPxPosition calculatePosition();
method public void callDraw(androidx.ui.graphics.Canvas canvas, androidx.ui.core.ComponentNode node, androidx.ui.unit.PxSize parentSize);
+ method public androidx.ui.core.OwnedLayer createLayer(androidx.ui.core.DrawLayerModifier drawLayerModifier, kotlin.jvm.functions.Function2<? super androidx.ui.graphics.Canvas,? super androidx.ui.unit.Density,kotlin.Unit> drawBlock);
method public androidx.ui.unit.Density getDensity();
method public long getMeasureIteration();
method public androidx.ui.core.semantics.SemanticsOwner getSemanticsOwner();
diff --git a/ui/ui-platform/api/public_plus_experimental_current.txt b/ui/ui-platform/api/public_plus_experimental_current.txt
index 61079a5..da1745f 100644
--- a/ui/ui-platform/api/public_plus_experimental_current.txt
+++ b/ui/ui-platform/api/public_plus_experimental_current.txt
@@ -16,6 +16,7 @@
method public void addAndroidView(android.view.View view, androidx.ui.core.LayoutNode layoutNode);
method public androidx.ui.unit.IntPxPosition calculatePosition();
method public void callDraw(androidx.ui.graphics.Canvas canvas, androidx.ui.core.ComponentNode node, androidx.ui.unit.PxSize parentSize);
+ method public androidx.ui.core.OwnedLayer createLayer(androidx.ui.core.DrawLayerModifier drawLayerModifier, kotlin.jvm.functions.Function2<? super androidx.ui.graphics.Canvas,? super androidx.ui.unit.Density,kotlin.Unit> drawBlock);
method public java.util.List<androidx.ui.core.semantics.SemanticsNode> getAllSemanticNodes();
method public androidx.ui.autofill.Autofill? getAutofill();
method public androidx.ui.autofill.AutofillTree getAutofillTree();
@@ -32,6 +33,7 @@
method public androidx.ui.input.TextInputService getTextInputService();
method public void measureAndLayout();
method public void observeDrawModelReads(androidx.ui.core.RepaintBoundaryNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+ method public void observeLayerModelReads(androidx.ui.core.OwnedLayer layer, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void observeLayoutModelReads(androidx.ui.core.LayoutNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void observeMeasureModelReads(androidx.ui.core.LayoutNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void onAttach(androidx.ui.core.ComponentNode node);
@@ -79,12 +81,9 @@
public final class AndroidOwnerKt {
}
- public abstract sealed class ComponentNode implements androidx.compose.Emittable {
+ public abstract sealed class ComponentNode {
method public void attach(androidx.ui.core.Owner owner);
method public void detach();
- method public void emitInsertAt(int index, androidx.compose.Emittable instance);
- method public void emitMove(int from, int to, int count);
- method public void emitRemoveAt(int index, int count);
method public final operator androidx.ui.core.ComponentNode get(int index);
method protected androidx.ui.core.LayoutNode? getContainingLayoutNode();
method public final int getCount();
@@ -94,6 +93,9 @@
method public final androidx.ui.core.ComponentNode? getParent();
method public androidx.ui.core.LayoutNode? getParentLayoutNode();
method public androidx.ui.core.RepaintBoundaryNode? getRepaintBoundary();
+ method public final void insertAt(int index, androidx.ui.core.ComponentNode instance);
+ method public final void move(int from, int to, int count);
+ method public final void removeAt(int index, int count);
method public final void setDepth(int p);
method public final void setOwnerData(Object? p);
method public final inline void visitChildren(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
@@ -270,9 +272,19 @@
method public void pauseObservingReads(kotlin.jvm.functions.Function0<kotlin.Unit> block);
}
+ public interface OwnedLayer {
+ method public void destroy();
+ method public void drawLayer(androidx.ui.graphics.Canvas canvas);
+ method public void invalidate();
+ method public void move(androidx.ui.unit.IntPxPosition position);
+ method public void resize(androidx.ui.unit.IntPxSize size);
+ method public void updateLayerProperties();
+ }
+
public interface Owner {
method public androidx.ui.unit.IntPxPosition calculatePosition();
method public void callDraw(androidx.ui.graphics.Canvas canvas, androidx.ui.core.ComponentNode node, androidx.ui.unit.PxSize parentSize);
+ method public androidx.ui.core.OwnedLayer createLayer(androidx.ui.core.DrawLayerModifier drawLayerModifier, kotlin.jvm.functions.Function2<? super androidx.ui.graphics.Canvas,? super androidx.ui.unit.Density,kotlin.Unit> drawBlock);
method public androidx.ui.unit.Density getDensity();
method public long getMeasureIteration();
method public androidx.ui.core.semantics.SemanticsOwner getSemanticsOwner();
diff --git a/ui/ui-platform/api/restricted_0.1.0-dev07.txt b/ui/ui-platform/api/restricted_0.1.0-dev07.txt
index 67bf294d..69e5404 100644
--- a/ui/ui-platform/api/restricted_0.1.0-dev07.txt
+++ b/ui/ui-platform/api/restricted_0.1.0-dev07.txt
@@ -16,6 +16,7 @@
method public void addAndroidView(android.view.View view, androidx.ui.core.LayoutNode layoutNode);
method public androidx.ui.unit.IntPxPosition calculatePosition();
method public void callDraw(androidx.ui.graphics.Canvas canvas, androidx.ui.core.ComponentNode node, androidx.ui.unit.PxSize parentSize);
+ method public androidx.ui.core.OwnedLayer createLayer(androidx.ui.core.DrawLayerModifier drawLayerModifier, kotlin.jvm.functions.Function2<? super androidx.ui.graphics.Canvas,? super androidx.ui.unit.Density,kotlin.Unit> drawBlock);
method public java.util.List<androidx.ui.core.semantics.SemanticsNode> getAllSemanticNodes();
method public androidx.ui.autofill.Autofill? getAutofill();
method public androidx.ui.autofill.AutofillTree getAutofillTree();
@@ -32,6 +33,7 @@
method public androidx.ui.input.TextInputService getTextInputService();
method public void measureAndLayout();
method public void observeDrawModelReads(androidx.ui.core.RepaintBoundaryNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+ method public void observeLayerModelReads(androidx.ui.core.OwnedLayer layer, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void observeLayoutModelReads(androidx.ui.core.LayoutNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void observeMeasureModelReads(androidx.ui.core.LayoutNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void onAttach(androidx.ui.core.ComponentNode node);
@@ -79,12 +81,9 @@
public final class AndroidOwnerKt {
}
- public abstract sealed class ComponentNode implements androidx.compose.Emittable {
+ public abstract sealed class ComponentNode {
method public void attach(androidx.ui.core.Owner owner);
method public void detach();
- method public void emitInsertAt(int index, androidx.compose.Emittable instance);
- method public void emitMove(int from, int to, int count);
- method public void emitRemoveAt(int index, int count);
method public final operator androidx.ui.core.ComponentNode get(int index);
method protected androidx.ui.core.LayoutNode? getContainingLayoutNode();
method public final int getCount();
@@ -94,6 +93,9 @@
method public final androidx.ui.core.ComponentNode? getParent();
method public androidx.ui.core.LayoutNode? getParentLayoutNode();
method public androidx.ui.core.RepaintBoundaryNode? getRepaintBoundary();
+ method public final void insertAt(int index, androidx.ui.core.ComponentNode instance);
+ method public final void move(int from, int to, int count);
+ method public final void removeAt(int index, int count);
method public final void setDepth(int p);
method public final void setOwnerData(Object? p);
method public final inline void visitChildren(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
@@ -272,9 +274,19 @@
property @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final kotlin.jvm.functions.Function2<java.util.Set<?>,androidx.compose.frames.Frame,kotlin.Unit> frameCommitObserver;
}
+ public interface OwnedLayer {
+ method public void destroy();
+ method public void drawLayer(androidx.ui.graphics.Canvas canvas);
+ method public void invalidate();
+ method public void move(androidx.ui.unit.IntPxPosition position);
+ method public void resize(androidx.ui.unit.IntPxSize size);
+ method public void updateLayerProperties();
+ }
+
public interface Owner {
method public androidx.ui.unit.IntPxPosition calculatePosition();
method public void callDraw(androidx.ui.graphics.Canvas canvas, androidx.ui.core.ComponentNode node, androidx.ui.unit.PxSize parentSize);
+ method public androidx.ui.core.OwnedLayer createLayer(androidx.ui.core.DrawLayerModifier drawLayerModifier, kotlin.jvm.functions.Function2<? super androidx.ui.graphics.Canvas,? super androidx.ui.unit.Density,kotlin.Unit> drawBlock);
method public androidx.ui.unit.Density getDensity();
method public long getMeasureIteration();
method public androidx.ui.core.semantics.SemanticsOwner getSemanticsOwner();
diff --git a/ui/ui-platform/api/restricted_current.txt b/ui/ui-platform/api/restricted_current.txt
index 67bf294d..69e5404 100644
--- a/ui/ui-platform/api/restricted_current.txt
+++ b/ui/ui-platform/api/restricted_current.txt
@@ -16,6 +16,7 @@
method public void addAndroidView(android.view.View view, androidx.ui.core.LayoutNode layoutNode);
method public androidx.ui.unit.IntPxPosition calculatePosition();
method public void callDraw(androidx.ui.graphics.Canvas canvas, androidx.ui.core.ComponentNode node, androidx.ui.unit.PxSize parentSize);
+ method public androidx.ui.core.OwnedLayer createLayer(androidx.ui.core.DrawLayerModifier drawLayerModifier, kotlin.jvm.functions.Function2<? super androidx.ui.graphics.Canvas,? super androidx.ui.unit.Density,kotlin.Unit> drawBlock);
method public java.util.List<androidx.ui.core.semantics.SemanticsNode> getAllSemanticNodes();
method public androidx.ui.autofill.Autofill? getAutofill();
method public androidx.ui.autofill.AutofillTree getAutofillTree();
@@ -32,6 +33,7 @@
method public androidx.ui.input.TextInputService getTextInputService();
method public void measureAndLayout();
method public void observeDrawModelReads(androidx.ui.core.RepaintBoundaryNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
+ method public void observeLayerModelReads(androidx.ui.core.OwnedLayer layer, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void observeLayoutModelReads(androidx.ui.core.LayoutNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void observeMeasureModelReads(androidx.ui.core.LayoutNode node, kotlin.jvm.functions.Function0<kotlin.Unit> block);
method public void onAttach(androidx.ui.core.ComponentNode node);
@@ -79,12 +81,9 @@
public final class AndroidOwnerKt {
}
- public abstract sealed class ComponentNode implements androidx.compose.Emittable {
+ public abstract sealed class ComponentNode {
method public void attach(androidx.ui.core.Owner owner);
method public void detach();
- method public void emitInsertAt(int index, androidx.compose.Emittable instance);
- method public void emitMove(int from, int to, int count);
- method public void emitRemoveAt(int index, int count);
method public final operator androidx.ui.core.ComponentNode get(int index);
method protected androidx.ui.core.LayoutNode? getContainingLayoutNode();
method public final int getCount();
@@ -94,6 +93,9 @@
method public final androidx.ui.core.ComponentNode? getParent();
method public androidx.ui.core.LayoutNode? getParentLayoutNode();
method public androidx.ui.core.RepaintBoundaryNode? getRepaintBoundary();
+ method public final void insertAt(int index, androidx.ui.core.ComponentNode instance);
+ method public final void move(int from, int to, int count);
+ method public final void removeAt(int index, int count);
method public final void setDepth(int p);
method public final void setOwnerData(Object? p);
method public final inline void visitChildren(kotlin.jvm.functions.Function1<? super androidx.ui.core.ComponentNode,kotlin.Unit> block);
@@ -272,9 +274,19 @@
property @RestrictTo(androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP) public final kotlin.jvm.functions.Function2<java.util.Set<?>,androidx.compose.frames.Frame,kotlin.Unit> frameCommitObserver;
}
+ public interface OwnedLayer {
+ method public void destroy();
+ method public void drawLayer(androidx.ui.graphics.Canvas canvas);
+ method public void invalidate();
+ method public void move(androidx.ui.unit.IntPxPosition position);
+ method public void resize(androidx.ui.unit.IntPxSize size);
+ method public void updateLayerProperties();
+ }
+
public interface Owner {
method public androidx.ui.unit.IntPxPosition calculatePosition();
method public void callDraw(androidx.ui.graphics.Canvas canvas, androidx.ui.core.ComponentNode node, androidx.ui.unit.PxSize parentSize);
+ method public androidx.ui.core.OwnedLayer createLayer(androidx.ui.core.DrawLayerModifier drawLayerModifier, kotlin.jvm.functions.Function2<? super androidx.ui.graphics.Canvas,? super androidx.ui.unit.Density,kotlin.Unit> drawBlock);
method public androidx.ui.unit.Density getDensity();
method public long getMeasureIteration();
method public androidx.ui.core.semantics.SemanticsOwner getSemanticsOwner();
diff --git a/ui/ui-platform/build.gradle b/ui/ui-platform/build.gradle
index e0cf8c2..2f4cafa 100644
--- a/ui/ui-platform/build.gradle
+++ b/ui/ui-platform/build.gradle
@@ -29,6 +29,7 @@
}
dependencies {
+ kotlinPlugin project(path: ":compose:compose-compiler")
implementation(KOTLIN_COROUTINES_ANDROID)
implementation(KOTLIN_STDLIB)
@@ -74,6 +75,12 @@
description = "Contains internal implementation that allows separation of android implementation from host-side tests."
}
+tasks.withType(KotlinCompile).configureEach {
+ kotlinOptions {
+ useIR = true
+ }
+}
+
android {
testOptions {
unitTests {
diff --git a/ui/ui-platform/src/androidTest/java/androidx/ui/core/DepthSortedSetTest.kt b/ui/ui-platform/src/androidTest/java/androidx/ui/core/DepthSortedSetTest.kt
index 88cdab3..ec2c23a 100644
--- a/ui/ui-platform/src/androidTest/java/androidx/ui/core/DepthSortedSetTest.kt
+++ b/ui/ui-platform/src/androidTest/java/androidx/ui/core/DepthSortedSetTest.kt
@@ -142,7 +142,7 @@
set.add(child2)
// change depth of child2
- child1.emitRemoveAt(0, 1)
+ child1.removeAt(0, 1)
root.add(child2)
// now it is on the same level as child1
diff --git a/ui/ui-platform/src/androidTest/java/androidx/ui/core/ModelObserverTest.kt b/ui/ui-platform/src/androidTest/java/androidx/ui/core/ModelObserverTest.kt
index 9719970..92bcdb1 100644
--- a/ui/ui-platform/src/androidTest/java/androidx/ui/core/ModelObserverTest.kt
+++ b/ui/ui-platform/src/androidTest/java/androidx/ui/core/ModelObserverTest.kt
@@ -17,15 +17,10 @@
package androidx.ui.core
import androidx.compose.FrameManager
-import androidx.compose.annotations.Hide
-import androidx.compose.frames.AbstractRecord
-import androidx.compose.frames.Framed
-import androidx.compose.frames.Record
-import androidx.compose.frames._created
+import androidx.compose.MutableState
import androidx.compose.frames.commit
import androidx.compose.frames.open
-import androidx.compose.frames.readable
-import androidx.compose.frames.writable
+import androidx.compose.mutableStateOf
import androidx.test.filters.SmallTest
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
@@ -44,7 +39,7 @@
val node = DrawNode()
val countDownLatch = CountDownLatch(1)
- val model = State(0)
+ val model = mutableStateOf(0)
val modelObserver = ModelObserver { it() }
modelObserver.enableModelUpdatesObserving(true)
@@ -76,9 +71,9 @@
val drawLatch = CountDownLatch(1)
val measureLatch = CountDownLatch(1)
val layoutLatch = CountDownLatch(1)
- val drawModel = State(0)
- val measureModel = State(0)
- val layoutModel = State(0)
+ val drawModel = mutableStateOf(0)
+ val measureModel = mutableStateOf(0)
+ val layoutModel = mutableStateOf(0)
val onCommitDrawListener: (DrawNode) -> Unit = { affectedNode ->
assertEquals(drawNode, affectedNode)
@@ -132,9 +127,9 @@
val layoutLatch1 = CountDownLatch(1)
val layoutLatch2 = CountDownLatch(1)
val measureLatch = CountDownLatch(1)
- val layoutModel1 = State(0)
- val layoutModel2 = State(0)
- val measureModel = State(0)
+ val layoutModel1 = mutableStateOf(0)
+ val layoutModel2 = mutableStateOf(0)
+ val measureModel = mutableStateOf(0)
val onCommitMeasureListener: (LayoutNode) -> Unit = { affectedNode ->
assertEquals(affectedNode, measureNode)
@@ -188,7 +183,7 @@
val node = DrawNode()
val countDownLatch = CountDownLatch(1)
- val model = State(0)
+ val model = mutableStateOf(0)
val onCommitListener: (DrawNode) -> Unit = { _ ->
assertEquals(1, countDownLatch.count)
countDownLatch.countDown()
@@ -282,9 +277,11 @@
assertEquals(1, commits2)
}
- private fun runSimpleTest(block: (modelObserver: ModelObserver, model: State<Int>) -> Unit) {
+ private fun runSimpleTest(
+ block: (modelObserver: ModelObserver, model: MutableState<Int>) -> Unit
+ ) {
val modelObserver = ModelObserver { it() }
- val model = State(0)
+ val model = mutableStateOf(0)
modelObserver.enableModelUpdatesObserving(true)
try {
@@ -297,47 +294,3 @@
}
}
}
-
-// @Model generation is not enabled for this module and androidx.compose.State is internal
-// TODO make State's constructor public and remove the copied code. b/142883125
-private class State<T> constructor(value: T) : Framed {
-
- @Suppress("UNCHECKED_CAST")
- var value: T
- get() = next.readable(this).value
- set(value) {
- next.writable(this).value = value
- }
-
- private var next: StateRecord<T> =
- StateRecord(value)
-
- init {
- _created(this)
- }
-
- // NOTE(lmr): ideally we can compile `State` with our own compiler so that this is not visible
- @Hide
- override val firstFrameRecord: Record
- get() = next
-
- // NOTE(lmr): ideally we can compile `State` with our own compiler so that this is not visible
- @Hide
- override fun prependFrameRecord(value: Record) {
- value.next = next
- @Suppress("UNCHECKED_CAST")
- next = value as StateRecord<T>
- }
-
- private class StateRecord<T>(myValue: T) : AbstractRecord() {
- override fun assign(value: Record) {
- @Suppress("UNCHECKED_CAST")
- this.value = (value as StateRecord<T>).value
- }
-
- override fun create(): Record =
- StateRecord(value)
-
- var value: T = myValue
- }
-}
\ No newline at end of file
diff --git a/ui/ui-platform/src/main/java/androidx/ui/autofill/AndroidAutofillDebugUtils.kt b/ui/ui-platform/src/main/java/androidx/ui/autofill/AndroidAutofillDebugUtils.kt
index 7b835d7..5fd02b2 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/autofill/AndroidAutofillDebugUtils.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/autofill/AndroidAutofillDebugUtils.kt
@@ -28,17 +28,16 @@
* This callback is called when we receive autofill events. It adds some logs that can be useful
* for debug purposes.
*/
-private val autofillCallback =
- @RequiresApi(Build.VERSION_CODES.O)
- object : AutofillManager.AutofillCallback() {
- override fun onAutofillEvent(view: View, virtualId: Int, event: Int) {
- super.onAutofillEvent(view, virtualId, event)
- Log.d(
- "Autofill Status",
- when (event) {
- EVENT_INPUT_SHOWN -> "Autofill popup was shown."
- EVENT_INPUT_HIDDEN -> "Autofill popup was hidden."
- EVENT_INPUT_UNAVAILABLE -> """
+@RequiresApi(Build.VERSION_CODES.O)
+private object AutofillCallback : AutofillManager.AutofillCallback() {
+ override fun onAutofillEvent(view: View, virtualId: Int, event: Int) {
+ super.onAutofillEvent(view, virtualId, event)
+ Log.d(
+ "Autofill Status",
+ when (event) {
+ EVENT_INPUT_SHOWN -> "Autofill popup was shown."
+ EVENT_INPUT_HIDDEN -> "Autofill popup was hidden."
+ EVENT_INPUT_UNAVAILABLE -> """
|Autofill popup isn't shown because autofill is not available.
|
|Did you set up autofill?
@@ -50,18 +49,18 @@
|2. Click on the settings icon next to the Autofill Service
|3. Add your account
""".trimMargin()
- else -> "Unknown status event."
- }
- )
- }
+ else -> "Unknown status event."
+ }
+ )
}
+}
/**
* Registers the autofill debug callback.
*/
@RequiresApi(Build.VERSION_CODES.O)
internal fun AndroidAutofill.registerCallback() {
- autofillManager.registerCallback(autofillCallback)
+ autofillManager.registerCallback(AutofillCallback)
}
/**
@@ -69,5 +68,5 @@
*/
@RequiresApi(Build.VERSION_CODES.O)
internal fun AndroidAutofill.unregisterCallback() {
- autofillManager.unregisterCallback(autofillCallback)
+ autofillManager.unregisterCallback(AutofillCallback)
}
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/AndroidOwner.kt b/ui/ui-platform/src/main/java/androidx/ui/core/AndroidOwner.kt
index 6bec61c..e4c785b 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/AndroidOwner.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/AndroidOwner.kt
@@ -105,6 +105,11 @@
internal val dirtyRepaintBoundaryNodes =
DepthSortedSet<RepaintBoundaryNode>(enableExtraAssertions)
+ // OwnedLayers that are dirty and should be redrawn. This is only
+ // used when RenderNodes are active in Q+. When Views are used, the View
+ // system tracks the dirty RenderNodes.
+ internal val dirtyLayers = mutableListOf<OwnedLayer>()
+
var ref: Ref<AndroidComposeView>? = null
set(value) {
field = value
@@ -173,10 +178,20 @@
repaintBoundaryContainer.dirty = true
}
+ internal val onCommitAffectingLayer: (OwnedLayer) -> Unit = { layer ->
+ layer.invalidate()
+ }
+
private val onCommitAffectingRootDraw: (Unit) -> Unit = { _ ->
invalidate()
}
+ private val onCommitAffectingLayerParams: (OwnedLayer) -> Unit = { layer ->
+ handler.postAtFrontOfQueue {
+ updateLayerProperties(layer)
+ }
+ }
+
private val onPositionedDispatcher = OnPositionedDispatcher()
override var showLayoutBounds = false
@@ -212,10 +227,16 @@
}
override fun onInvalidate(drawNode: DrawNode) {
- // TODO(mount): use ownerScope. This isn't supported by IR compiler yet
- // ownerScope.launch {
+ val repaintBoundary = drawNode.repaintBoundary
+
+ // This is going to be slow temporarily until we remove DrawNode
+ val layerWrapper = findContainingLayer(drawNode)
+ if (layerWrapper != null &&
+ layerWrapper.layoutNode.repaintBoundary === repaintBoundary) {
+ layerWrapper.layer.invalidate()
+ return
+ }
invalidateRepaintBoundary(drawNode)
- // }
}
override fun onInvalidate(layoutNode: LayoutNode) {
@@ -237,16 +258,23 @@
* Make sure the containing RepaintBoundary repaints.
*/
internal fun invalidateRepaintBoundary(node: ComponentNode) {
- node.requireOwner()
val repaintBoundary = node.repaintBoundary
- val repaintBoundaryContainer = repaintBoundary?.container
- if (repaintBoundaryContainer != null) {
- repaintBoundaryContainer.dirty = true
+ if (repaintBoundary != null && repaintBoundary.isAttached()) {
+ repaintBoundary.container.dirty = true
} else {
invalidate()
}
}
+ private fun findContainingLayer(node: ComponentNode): LayerWrapper? {
+ val layoutNode = if (node is LayoutNode) node else node.parentLayoutNode ?: return null
+ var wrapper: LayoutNodeWrapper? = layoutNode.innerLayoutNodeWrapper
+ while (wrapper != null && wrapper !is LayerWrapper) {
+ wrapper = wrapper.wrappedBy
+ }
+ return wrapper as LayerWrapper?
+ }
+
override fun onPositionChange(layoutNode: LayoutNode) {
// TODO(mount): use ownerScope. This isn't supported by IR compiler yet
// ownerScope.launch {
@@ -514,6 +542,10 @@
modelObserver.observeReads(node, onCommitAffectingMeasure, block)
}
+ fun observeLayerModelReads(layer: OwnedLayer, block: () -> Unit) {
+ modelObserver.observeReads(layer, onCommitAffectingLayer, block)
+ }
+
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
onPositionedDispatcher.dispatch()
}
@@ -555,9 +587,7 @@
}
is RepaintBoundaryNode -> {
val boundary = node.container
- canvas.enableZ()
boundary.callDraw(canvas)
- canvas.disableZ()
}
is LayoutNode -> {
if (node.isPlaced) {
@@ -573,6 +603,27 @@
}
}
+ override fun createLayer(
+ drawLayerModifier: DrawLayerModifier,
+ drawBlock: (Canvas, Density) -> Unit
+ ): OwnedLayer {
+ val layer = if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P || isInEditMode()) {
+ ViewLayer(this, drawLayerModifier, drawBlock)
+ } else {
+ RenderNodeLayer(this, drawLayerModifier, drawBlock)
+ }
+
+ updateLayerProperties(layer)
+
+ return layer
+ }
+
+ private fun updateLayerProperties(layer: OwnedLayer) {
+ modelObserver.observeReads(layer, onCommitAffectingLayerParams) {
+ layer.updateLayerProperties()
+ }
+ }
+
internal fun drawChild(canvas: Canvas, view: View, drawingTime: Long) {
super.drawChild(canvas.nativeCanvas, view, drawingTime)
}
@@ -581,12 +632,21 @@
measureAndLayout()
val uiCanvas = Canvas(canvas)
val parentSize = PxSize(root.width, root.height)
+ uiCanvas.enableZ()
modelObserver.observeReads(Unit, onCommitAffectingRootDraw) {
root.visitChildren { callDraw(uiCanvas, it, parentSize) }
}
+ uiCanvas.disableZ()
dirtyRepaintBoundaryNodes.popEach { node ->
node.container.updateDisplayList()
}
+ if (dirtyLayers.isNotEmpty()) {
+ for (i in 0 until dirtyLayers.size) {
+ val layer = dirtyLayers[i]
+ (layer as RenderNodeLayer).updateDisplayList()
+ }
+ dirtyLayers.clear()
+ }
}
/**
@@ -603,11 +663,13 @@
layoutNode.innerLayoutNodeWrapper.height
)
val uiCanvas = Canvas(canvas)
+ uiCanvas.enableZ()
observeDrawModelReads(repaintBoundaryNode) {
repaintBoundaryNode.visitChildren { child ->
callDraw(uiCanvas, child, parentSize)
}
}
+ uiCanvas.disableZ()
}
override fun onAttachedToWindow() {
@@ -903,7 +965,7 @@
}
private val density = Density(context)
- private val outlineResolver = OutlineResolver(density)
+ private val outlineResolver = OutlineResolverWithNode(density)
private val outlineProviderImpl = object : ViewOutlineProvider() {
override fun getOutline(view: View, outline: android.graphics.Outline) {
outlineResolver.applyTo(outline)
@@ -1023,7 +1085,7 @@
}
private val outline = android.graphics.Outline()
private val density = Density(ownerView.context)
- private val outlineResolver = OutlineResolver(density)
+ private val outlineResolver = OutlineResolverWithNode(density)
private var clipPath: android.graphics.Path? = null
private var hasSize = false
@@ -1093,7 +1155,7 @@
/**
* Resolves the Android [Outline] from the [Shape] of [RepaintBoundaryNode].
*/
-private class OutlineResolver(private val density: Density) {
+private class OutlineResolverWithNode(private val density: Density) {
private val cachedOutline = android.graphics.Outline().apply { alpha = 1f }
private var size: PxSize = PxSize.Zero
private var shape: Shape? = null
@@ -1183,4 +1245,4 @@
}
outlinePath = path
}
-}
+}
\ No newline at end of file
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/ComponentNodes.kt b/ui/ui-platform/src/main/java/androidx/ui/core/ComponentNodes.kt
index 32864a4..5fe00fd 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/ComponentNodes.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/ComponentNodes.kt
@@ -15,7 +15,6 @@
*/
package androidx.ui.core
-import androidx.compose.Emittable
import androidx.ui.core.focus.findParentFocusNode
import androidx.ui.core.focus.ownerHasFocus
import androidx.ui.core.focus.requestFocusForOwner
@@ -107,7 +106,7 @@
/**
* Called by [ComponentNode] when it is detached from the view system, such as during
- * [ComponentNode.emitRemoveAt]. This will only be called for [node]s that are already
+ * [ComponentNode.removeAt]. This will only be called for [node]s that are already
* [ComponentNode.attach]ed.
*/
fun onDetach(node: ComponentNode)
@@ -158,6 +157,14 @@
*/
fun measureAndLayout()
+ /**
+ * Creates and returns an [OwnedLayer] for the given [drawLayerModifier].
+ */
+ fun createLayer(
+ drawLayerModifier: DrawLayerModifier,
+ drawBlock: (Canvas, Density) -> Unit
+ ): OwnedLayer
+
val measureIteration: Long
}
@@ -167,7 +174,7 @@
* Specific components are backed by a tree of nodes: Draw, Layout, SemanticsComponentNode, GestureDetector.
* All other components are not represented in the backing hierarchy.
*/
-sealed class ComponentNode : Emittable {
+sealed class ComponentNode {
internal val children = mutableListOf<ComponentNode>()
@@ -243,10 +250,7 @@
* Inserts a child [ComponentNode] at a particular index. If this ComponentNode [isAttached]
* then [instance] will become [attach]ed also. [instance] must have a `null` [parent].
*/
- override fun emitInsertAt(index: Int, instance: Emittable) {
- if (instance !is ComponentNode) {
- ErrorMessages.OnlyComponents.state()
- }
+ fun insertAt(index: Int, instance: ComponentNode) {
ErrorMessages.ComponentNodeHasParent.validateState(instance.parent == null)
ErrorMessages.OwnerAlreadyAttached.validateState(instance.owner == null)
@@ -277,7 +281,7 @@
/**
* Removes one or more children, starting at [index].
*/
- override fun emitRemoveAt(index: Int, count: Int) {
+ fun removeAt(index: Int, count: Int) {
ErrorMessages.CountOutOfRange.validateArg(count >= 0, count)
val attached = owner != null
for (i in index + count - 1 downTo index) {
@@ -293,7 +297,7 @@
}
}
- override fun emitMove(from: Int, to: Int, count: Int) {
+ fun move(from: Int, to: Int, count: Int) {
if (from == to) {
return // nothing to do
}
@@ -355,13 +359,13 @@
* children. After executing, the [owner] will be `null`.
*/
open fun detach() {
- visitChildren { child ->
- child.detach()
- }
val owner = owner ?: ErrorMessages.OwnerAlreadyDetached.state()
owner.onDetach(this)
this.owner = null
depth = 0
+ visitChildren { child ->
+ child.detach()
+ }
}
internal open fun invalidateSemanticsComponentNode() {
@@ -1171,6 +1175,9 @@
if (mod is DrawModifier) {
wrapper = ModifiedDrawNode(wrapper, mod)
}
+ if (mod is DrawLayerModifier) {
+ wrapper = LayerWrapper(wrapper, mod)
+ }
if (mod is LayoutModifier) {
wrapper = ModifiedLayoutNode(wrapper, mod)
}
@@ -1193,6 +1200,7 @@
if (containing != null) {
layoutNodeWrapper.wrappedBy = containing.innerLayoutNodeWrapper
}
+ owner?.onInvalidate(this)
}
/**
@@ -1216,11 +1224,17 @@
var onAttach: ((Owner) -> Unit)? = null
override fun detach() {
- parentLayoutNode?.layoutChildrenDirty = true
- parentLayoutNode?.requestRemeasure()
+ val owner = owner!!
+ val parentLayoutNode = parentLayoutNode
+ if (parentLayoutNode != null) {
+ owner.onInvalidate(parentLayoutNode)
+ parentLayoutNode.layoutChildrenDirty = true
+ parentLayoutNode.requestRemeasure()
+ }
parentDataDirty = true
alignmentLinesQueryOwner = null
- onDetach?.invoke(owner!!)
+ onDetach?.invoke(owner)
+ layoutNodeWrapper.detach()
super.detach()
}
@@ -1331,7 +1345,7 @@
}
positionedDuringMeasurePass = parentLayoutNode?.isMeasuring ?: false ||
parentLayoutNode?.positionedDuringMeasurePass ?: false
- lastLayoutResult.placeChildren(Placeable.PlacementScope)
+ lastLayoutResult.placeChildren(layoutDirection!!)
layoutChildren.forEach { child ->
child.alignmentLinesRead = child.alignmentLinesQueriedSinceLastLayout
}
@@ -1674,7 +1688,7 @@
* then [child] will become [isAttached]ed also. [child] must have a `null` [ComponentNode.parent].
*/
fun ComponentNode.add(child: ComponentNode) {
- emitInsertAt(count, child)
+ insertAt(count, child)
}
class Ref<T> {
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/LayoutNodeWrapper.kt b/ui/ui-platform/src/main/java/androidx/ui/core/LayoutNodeWrapper.kt
index 165af17..f1024e5 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/LayoutNodeWrapper.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/LayoutNodeWrapper.kt
@@ -45,7 +45,7 @@
) : Placeable(), Measurable, LayoutCoordinates {
protected open val wrapped: LayoutNodeWrapper? = null
internal var wrappedBy: LayoutNodeWrapper? = null
- var position = IntPxPosition.Origin
+ open var position = IntPxPosition.Origin
private var dirtySize: Boolean = false
fun hasDirtySize(): Boolean = dirtySize || (wrapped?.hasDirtySize() ?: false)
@@ -490,7 +490,7 @@
layoutNode.layoutDirection!!
)
}
- placeable.place(relativePosition)
+ placeable.placeAbsolute(relativePosition)
}
override operator fun get(line: AlignmentLine): IntPx? = with(layoutModifier) {
@@ -585,3 +585,37 @@
}
}
}
+
+internal class LayerWrapper(
+ wrapped: LayoutNodeWrapper,
+ val drawLayerModifier: DrawLayerModifier
+) : DelegatingLayoutNodeWrapper(wrapped) {
+ private var _layer: OwnedLayer? = null
+ val layer: OwnedLayer
+ get() {
+ return _layer ?: layoutNode.requireOwner().createLayer(
+ drawLayerModifier,
+ wrapped::draw
+ ).also { _layer = it }
+ }
+
+ override fun place(position: IntPxPosition) {
+ super.place(position)
+ layer.move(position)
+ }
+
+ override fun layoutSize(innermostSize: IntPxSize): IntPxSize {
+ val size = super.layoutSize(innermostSize)
+ layer.resize(size)
+ return size
+ }
+
+ override fun draw(canvas: Canvas, density: Density) {
+ layer.drawLayer(canvas)
+ }
+
+ override fun detach() {
+ super.detach()
+ _layer?.destroy()
+ }
+}
\ No newline at end of file
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/ModelObserver.kt b/ui/ui-platform/src/main/java/androidx/ui/core/ModelObserver.kt
index 6dcad32..972f6b6 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/ModelObserver.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/ModelObserver.kt
@@ -22,6 +22,7 @@
import androidx.compose.frames.FrameReadObserver
import androidx.compose.frames.observeAllReads
import androidx.compose.frames.registerCommitObserver
+import androidx.ui.util.synchronized
import org.jetbrains.annotations.TestOnly
/**
@@ -43,18 +44,14 @@
*/
class ModelObserver(private val commitExecutor: (command: () -> Unit) -> Unit) {
private val commitObserver: FrameCommitObserver = { committed, _ ->
- // This array is in the same order as commitMaps
- val targetsArray: Array<List<Any>>
var hasValues = false
- synchronized(commitMaps) {
- targetsArray = Array(commitMaps.size) { index ->
- val commitMap = commitMaps[index]
- val map = commitMap.map
- val targets = map.get(committed)
- if (targets.isNotEmpty()) {
- hasValues = true
+ // This array is in the same order as commitMaps
+ val targetsArray = synchronized(commitMaps) {
+ Array(commitMaps.size) { index ->
+ commitMaps[index].map.get(committed).apply {
+ if (isNotEmpty())
+ hasValues = true
}
- targets
}
}
if (hasValues) {
@@ -140,12 +137,10 @@
val oldMap = currentMap
val oldTarget = currentTarget
val oldPaused = isPaused
- val map: ObserverMap<Any, Any>
- synchronized(commitMaps) {
- map = ensureMap(onCommit)
- map.removeValue(target)
+
+ currentMap = synchronized(commitMaps) {
+ ensureMap(onCommit).apply { removeValue(target) }
}
- currentMap = map
currentTarget = target
isPaused = false
if (!isObserving) {
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/OutlineResolver.kt b/ui/ui-platform/src/main/java/androidx/ui/core/OutlineResolver.kt
new file mode 100644
index 0000000..10cd02f
--- /dev/null
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/OutlineResolver.kt
@@ -0,0 +1,197 @@
+/*
+ * 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.ui.core
+
+import android.os.Build
+import androidx.ui.geometry.RRect
+import androidx.ui.geometry.Rect
+import androidx.ui.geometry.isSimple
+import androidx.ui.graphics.Outline
+import androidx.ui.graphics.Path
+import androidx.ui.graphics.Shape
+import androidx.ui.unit.Density
+import androidx.ui.unit.PxSize
+import androidx.ui.unit.px
+import kotlin.math.roundToInt
+
+/**
+ * Resolves the Android [android.graphics.Outline] from the [Shape] of an [OwnedLayer].
+ */
+internal class OutlineResolver(private val density: Density) {
+ /**
+ * The Android Outline that is used in the layer.
+ */
+ private val cachedOutline = android.graphics.Outline().apply { alpha = 1f }
+
+ /**
+ * The size of the layer. This is used in generating the [Outline] from the [Shape].
+ */
+ private var size: PxSize = PxSize.Zero
+
+ /**
+ * The [Shape] of the Outline of the Layer. `null` indicates that there is no outline.
+ */
+ private var shape: Shape? = null
+
+ /**
+ * Asymmetric rounded rectangles need to use a Path. This caches that Path so that
+ * a new one doesn't have to be generated each time.
+ */
+ // TODO(andreykulikov): Make Outline API reuse the Path when generating.
+ private var cachedRrectPath: Path? = null // for temporary allocation in rounded rects
+
+ /**
+ * The outline Path when a non-conforming (rect or symmetric rounded rect) Outline
+ * is used. This Path is necessary when [usePathForClip] is true to indicate the
+ * Path to clip in [clipPath].
+ */
+ private var outlinePath: Path? = null
+
+ /**
+ * The opacity of the outline, which is the same as the opacity of the layer.
+ */
+ private var alpha = 1f
+
+ /**
+ * True when there's been an update that caused a change in the path and the Outline
+ * has to be reevaluated.
+ */
+ private var cacheIsDirty = false
+
+ /**
+ * True when Outline cannot clip the content and the path should be used instead.
+ * This is when an asymmetric rounded rect or general Path is used in the outline.
+ * This is false when a Rect or a symmetric RRect is used in the outline.
+ */
+ private var usePathForClip = false
+
+ /**
+ * Returns the Android Outline to be used in the layer.
+ */
+ val outline: android.graphics.Outline?
+ get() {
+ updateCache()
+ return if (shape == null) null else cachedOutline
+ }
+
+ /**
+ * When a the layer doesn't support clipping of the outline, this returns the Path
+ * that should be used to manually clip. When the layer does support manual clipping
+ * or there is no outline, this returns null.
+ */
+ val clipPath: Path?
+ get() {
+ updateCache()
+ return if (usePathForClip) outlinePath else null
+ }
+
+ /**
+ * `true` when an Outline can be used. This can be `true` even if the outline
+ * doesn't support clipping because it may be used for shadows. An Outline
+ * is not supported when the shape is `null` or a concave path is used on
+ * pre-Q devices.
+ */
+ val supportsNativeOutline: Boolean
+ get() {
+ if (shape == null) {
+ return false
+ }
+ updateCache()
+ return !cachedOutline.isEmpty
+ }
+
+ /**
+ * Updates the values of the outline.
+ */
+ fun update(shape: Shape?, alpha: Float) {
+ if (this.shape != shape) {
+ this.shape = shape
+ cacheIsDirty = true
+ }
+ if (this.alpha != alpha) {
+ this.alpha = alpha
+ cacheIsDirty = true
+ }
+ }
+
+ /**
+ * Updates the size.
+ */
+ fun update(size: PxSize) {
+ if (this.size != size) {
+ this.size = size
+ cacheIsDirty = true
+ }
+ }
+
+ private fun updateCache() {
+ if (cacheIsDirty) {
+ cacheIsDirty = false
+ usePathForClip = false
+ val shape = this.shape
+ if (shape == null || size.width == 0.px || size.height == 0.px) {
+ cachedOutline.setEmpty()
+ return
+ }
+ cachedOutline.alpha = alpha
+ val outline = shape.createOutline(size, density)
+ when (outline) {
+ is Outline.Rectangle -> updateCacheWithRect(outline.rect)
+ is Outline.Rounded -> updateCacheWithRRect(outline.rrect)
+ is Outline.Generic -> updateCacheWithPath(outline.path)
+ }
+ }
+ }
+
+ private fun updateCacheWithRect(rect: Rect) {
+ cachedOutline.setRect(
+ rect.left.roundToInt(),
+ rect.top.roundToInt(),
+ rect.right.roundToInt(),
+ rect.bottom.roundToInt()
+ )
+ }
+
+ private fun updateCacheWithRRect(rrect: RRect) {
+ val radius = rrect.topLeftRadiusX
+ if (rrect.isSimple) {
+ cachedOutline.setRoundRect(
+ rrect.left.roundToInt(),
+ rrect.top.roundToInt(),
+ rrect.right.roundToInt(),
+ rrect.bottom.roundToInt(),
+ radius
+ )
+ } else {
+ val path = cachedRrectPath ?: Path().also { cachedRrectPath = it }
+ path.reset()
+ path.addRRect(rrect)
+ updateCacheWithPath(path)
+ }
+ }
+
+ private fun updateCacheWithPath(composePath: Path) {
+ if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P || composePath.isConvex) {
+ cachedOutline.setConvexPath(composePath.toFrameworkPath())
+ usePathForClip = !cachedOutline.canClip()
+ } else {
+ cachedOutline.setEmpty()
+ usePathForClip = true
+ }
+ outlinePath = composePath
+ }
+}
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/OwnedLayer.kt b/ui/ui-platform/src/main/java/androidx/ui/core/OwnedLayer.kt
new file mode 100644
index 0000000..94cdc07
--- /dev/null
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/OwnedLayer.kt
@@ -0,0 +1,57 @@
+/*
+ * 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.ui.core
+
+import androidx.ui.graphics.Canvas
+import androidx.ui.unit.IntPxPosition
+import androidx.ui.unit.IntPxSize
+
+/**
+ * A layer returned by [Owner.createLayer] to separate drawn content. An `OwnedLayer` has
+ * the implementation to make [DrawLayerModifier]s work.
+ */
+interface OwnedLayer {
+ /**
+ * Reads the [DrawLayerProperties] and dirties the layer so that it will be redrawn.
+ */
+ fun updateLayerProperties()
+
+ /**
+ * Changes the position of the layer contents.
+ */
+ fun move(position: IntPxPosition)
+
+ /**
+ * Changes the size of the layer's drawn area.
+ */
+ fun resize(size: IntPxSize)
+
+ /**
+ * Causes the layer to be drawn into [canvas]
+ */
+ fun drawLayer(canvas: Canvas)
+
+ /**
+ * Asks to the layer to redraw itself without forcing all of its parents to redraw.
+ */
+ fun invalidate()
+
+ /**
+ * Indicates that the layer is no longer needed.
+ */
+ fun destroy()
+}
\ No newline at end of file
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/RenderNodeLayer.kt b/ui/ui-platform/src/main/java/androidx/ui/core/RenderNodeLayer.kt
new file mode 100644
index 0000000..7f04c06
--- /dev/null
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/RenderNodeLayer.kt
@@ -0,0 +1,133 @@
+/*
+ * 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.ui.core
+
+import android.annotation.TargetApi
+import android.graphics.RenderNode
+import androidx.ui.graphics.Canvas
+import androidx.ui.unit.Density
+import androidx.ui.unit.IntPxPosition
+import androidx.ui.unit.IntPxSize
+import androidx.ui.unit.toPxSize
+
+/**
+ * RenderNode implementation of OwnedLayer.
+ */
+@TargetApi(29)
+internal class RenderNodeLayer(
+ val ownerView: AndroidComposeView,
+ val drawLayerModifier: DrawLayerModifier,
+ val drawBlock: (Canvas, Density) -> Unit
+) : OwnedLayer {
+ /**
+ * True when the RenderNodeLayer has been invalidated and not yet drawn.
+ */
+ private var isDirty = false
+ private val outlineResolver = OutlineResolver(ownerView.density)
+ private var isDestoyed = false
+
+ private val renderNode = RenderNode(null).apply {
+ setHasOverlappingRendering(true)
+ }
+
+ override fun updateLayerProperties() {
+ val wasClippingManually = renderNode.clipToOutline && outlineResolver.clipPath != null
+ val props = drawLayerModifier.properties
+ renderNode.scaleX = props.scaleX
+ renderNode.scaleY = props.scaleY
+ renderNode.alpha = props.alpha
+ renderNode.elevation = props.elevation
+ renderNode.rotationZ = props.rotationZ
+ renderNode.rotationX = props.rotationX
+ renderNode.rotationY = props.rotationY
+ renderNode.clipToOutline = props.clipToOutline
+ renderNode.clipToBounds = props.clipToBounds
+ outlineResolver.update(props.outlineShape, renderNode.alpha)
+ renderNode.setOutline(outlineResolver.outline)
+ val isClippingManually = renderNode.clipToOutline && outlineResolver.clipPath != null
+ if (wasClippingManually != isClippingManually) {
+ invalidate()
+ }
+ }
+
+ override fun resize(size: IntPxSize) {
+ val width = size.width.value
+ val height = size.height.value
+ if (renderNode.setPosition(
+ renderNode.left,
+ renderNode.top,
+ renderNode.left + width,
+ renderNode.top + height
+ )) {
+ outlineResolver.update(size.toPxSize())
+ renderNode.setOutline(outlineResolver.outline)
+ invalidate()
+ }
+ }
+
+ override fun move(position: IntPxPosition) {
+ renderNode.offsetLeftAndRight(position.x.value - renderNode.left)
+ renderNode.offsetTopAndBottom(position.y.value - renderNode.top)
+ }
+
+ override fun invalidate() {
+ if (!isDirty && !isDestoyed) {
+ ownerView.invalidate()
+ ownerView.dirtyLayers += this
+ isDirty = true
+ }
+ }
+
+ override fun drawLayer(canvas: Canvas) {
+ val androidCanvas = canvas.nativeCanvas
+ if (androidCanvas.isHardwareAccelerated) {
+ updateDisplayList()
+ androidCanvas.drawRenderNode(renderNode)
+ } else {
+ drawBlock(canvas, ownerView.density)
+ }
+ isDirty = false
+ }
+
+ fun updateDisplayList() {
+ if (isDirty || !renderNode.hasDisplayList()) {
+ isDirty = false
+ val renderNodeCanvas = renderNode.beginRecording()
+ val uiCanvas = Canvas(renderNodeCanvas)
+
+ uiCanvas.enableZ()
+ val clipPath = outlineResolver.clipPath
+ if (renderNode.clipToOutline && clipPath != null) {
+ uiCanvas.save()
+ uiCanvas.clipPath(clipPath)
+ }
+ ownerView.observeLayerModelReads(this) {
+ drawBlock(uiCanvas, ownerView.density)
+ }
+ if (clipPath != null) {
+ uiCanvas.restore()
+ }
+ uiCanvas.disableZ()
+ renderNode.endRecording()
+ }
+ }
+
+ override fun destroy() {
+ isDestoyed = true
+ ownerView.dirtyLayers -= this
+ }
+}
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/ViewLayer.kt b/ui/ui-platform/src/main/java/androidx/ui/core/ViewLayer.kt
new file mode 100644
index 0000000..9b3f7a8
--- /dev/null
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/ViewLayer.kt
@@ -0,0 +1,149 @@
+/*
+ * 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.ui.core
+
+import android.view.View
+import android.view.ViewOutlineProvider
+import androidx.ui.graphics.Canvas
+import androidx.ui.graphics.Path
+import androidx.ui.unit.Density
+import androidx.ui.unit.IntPxPosition
+import androidx.ui.unit.IntPxSize
+import androidx.ui.unit.toPxSize
+
+/**
+ * View implementation of OwnedLayer.
+ */
+internal class ViewLayer(
+ val ownerView: AndroidComposeView,
+ val drawLayerModifier: DrawLayerModifier,
+ val drawBlock: (Canvas, Density) -> Unit
+) : View(ownerView.context), OwnedLayer {
+ private val outlineResolver = OutlineResolver(ownerView.density)
+ // Value of the layerModifier's clipToBounds property
+ private var clipToBounds = false
+ private var clipBoundsCache: android.graphics.Rect? = null
+ private val manualClipPath: Path? get() =
+ if (!clipToOutline) null else outlineResolver.clipPath
+
+ init {
+ setWillNotDraw(false) // we WILL draw
+ id = generateViewId()
+ ownerView.addView(this)
+ }
+
+ override fun updateLayerProperties() {
+ val props = drawLayerModifier.properties
+ this.scaleX = props.scaleX
+ this.scaleY = props.scaleY
+ this.alpha = props.alpha
+ this.elevation = props.elevation
+ this.rotation = props.rotationZ
+ this.rotationX = props.rotationX
+ this.rotationY = props.rotationY
+ this.clipToBounds = props.clipToBounds
+ resetClipBounds()
+ val wasClippingManually = manualClipPath != null
+ this.clipToOutline = props.clipToOutline
+ outlineResolver.update(props.outlineShape, this.alpha)
+ updateOutlineResolver()
+ if (wasClippingManually || manualClipPath != null) {
+ invalidate() // have to redraw the content
+ }
+ }
+
+ private fun updateOutlineResolver() {
+ this.outlineProvider = if (outlineResolver.supportsNativeOutline) {
+ OutlineProvider
+ } else {
+ null
+ }
+ }
+
+ private fun resetClipBounds() {
+ this.clipBounds = if (clipToBounds) {
+ if (clipBoundsCache == null) {
+ clipBoundsCache = android.graphics.Rect(0, 0, width, height)
+ } else {
+ clipBoundsCache!!.set(0, 0, width, height)
+ }
+ clipBoundsCache
+ } else {
+ null
+ }
+ }
+
+ override fun resize(size: IntPxSize) {
+ val width = size.width.value
+ val height = size.height.value
+ if (width != this.width || height != this.height) {
+ outlineResolver.update(size.toPxSize())
+ updateOutlineResolver()
+ layout(left, top, left + width, top + height)
+ resetClipBounds()
+ }
+ }
+
+ override fun move(position: IntPxPosition) {
+ val left = position.x.value
+
+ if (left != this.left) {
+ offsetLeftAndRight(left - this.left)
+ }
+ val top = position.y.value
+ if (top != this.top) {
+ offsetTopAndBottom(top - this.top)
+ }
+ }
+
+ override fun drawLayer(canvas: Canvas) {
+ ownerView.drawChild(canvas, this, drawingTime)
+ }
+
+ override fun dispatchDraw(canvas: android.graphics.Canvas) {
+ val uiCanvas = Canvas(canvas)
+ val clipPath = manualClipPath
+ if (clipPath != null) {
+ uiCanvas.save()
+ uiCanvas.clipPath(clipPath)
+ }
+ uiCanvas.enableZ()
+ ownerView.observeLayerModelReads(this) {
+ drawBlock(uiCanvas, ownerView.density)
+ }
+ uiCanvas.disableZ()
+ if (clipPath != null) {
+ uiCanvas.restore()
+ }
+ }
+
+ override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
+ }
+
+ override fun destroy() {
+ ownerView.removeView(this)
+ }
+
+ companion object {
+ val OutlineProvider = object : ViewOutlineProvider() {
+ override fun getOutline(view: View, outline: android.graphics.Outline) {
+ view as ViewLayer
+ outline.set(view.outlineResolver.outline!!)
+ }
+ }
+ }
+}
diff --git a/ui/ui-platform/src/test/java/androidx/ui/core/ComponentNodeTest.kt b/ui/ui-platform/src/test/java/androidx/ui/core/ComponentNodeTest.kt
index a49bce0..adb2173 100644
--- a/ui/ui-platform/src/test/java/androidx/ui/core/ComponentNodeTest.kt
+++ b/ui/ui-platform/src/test/java/androidx/ui/core/ComponentNodeTest.kt
@@ -78,25 +78,25 @@
assertEquals(0, child1.count)
assertEquals(0, child2.count)
- node.emitRemoveAt(index = 0, count = 1)
+ node.removeAt(index = 0, count = 1)
assertEquals(1, node.count)
assertEquals(child2, node[0])
- node.emitInsertAt(index = 0, instance = child1)
+ node.insertAt(index = 0, instance = child1)
assertEquals(2, node.count)
assertEquals(child1, node[0])
assertEquals(child2, node[1])
- node.emitRemoveAt(index = 0, count = 2)
+ node.removeAt(index = 0, count = 2)
assertEquals(0, node.count)
val child3 = DrawNode()
val child4 = DrawNode()
- node.emitInsertAt(0, child1)
- node.emitInsertAt(1, child2)
- node.emitInsertAt(2, child3)
- node.emitInsertAt(3, child4)
+ node.insertAt(0, child1)
+ node.insertAt(1, child2)
+ node.insertAt(2, child3)
+ node.insertAt(3, child4)
assertEquals(4, node.count)
assertEquals(child1, node[0])
@@ -104,14 +104,14 @@
assertEquals(child3, node[2])
assertEquals(child4, node[3])
- node.emitMove(from = 3, count = 1, to = 0)
+ node.move(from = 3, count = 1, to = 0)
assertEquals(4, node.count)
assertEquals(child4, node[0])
assertEquals(child1, node[1])
assertEquals(child2, node[2])
assertEquals(child3, node[3])
- node.emitMove(from = 0, count = 2, to = 3)
+ node.move(from = 0, count = 2, to = 3)
assertEquals(4, node.count)
assertEquals(child2, node[0])
assertEquals(child3, node[1])
@@ -162,7 +162,7 @@
val owner = mock(Owner::class.java)
node.attach(owner)
- node.emitRemoveAt(0, 1)
+ node.removeAt(0, 1)
assertEquals(owner, node.owner)
assertNull(child1.owner)
assertEquals(owner, child2.owner)
@@ -179,10 +179,10 @@
val owner = mock(Owner::class.java)
node.attach(owner)
- node.emitRemoveAt(0, 1)
+ node.removeAt(0, 1)
reset(owner)
- node.emitInsertAt(1, child1)
+ node.insertAt(1, child1)
assertEquals(owner, node.owner)
assertEquals(owner, child1.owner)
assertEquals(owner, child2.owner)
@@ -202,7 +202,7 @@
fun drawNodeAdd() {
val node = DrawNode()
val child = DrawNode()
- node.emitInsertAt(0, child)
+ node.insertAt(0, child)
assertEquals(1, node.count)
assertEquals(child, node[0])
}
@@ -215,7 +215,7 @@
verify(owner, times(1)).onAttach(node)
val child = DrawNode()
- node.emitInsertAt(0, child)
+ node.insertAt(0, child)
verify(owner, times(1)).onAttach(child)
assertEquals(1, node.count)
assertEquals(node, child.parent)
@@ -226,7 +226,7 @@
fun childCount() {
val node = PointerInputNode()
assertEquals(0, node.count)
- node.emitInsertAt(0, PointerInputNode())
+ node.insertAt(0, PointerInputNode())
assertEquals(1, node.count)
}
@@ -234,14 +234,14 @@
fun childGet() {
val node = PointerInputNode()
val child = PointerInputNode()
- node.emitInsertAt(0, child)
+ node.insertAt(0, child)
assertEquals(child, node[0])
}
@Test
fun noMove() {
val (layout, child1, child2) = createSimpleLayout()
- layout.emitMove(0, 0, 1)
+ layout.move(0, 0, 1)
assertEquals(child1, layout[0])
assertEquals(child2, layout[1])
}
@@ -252,8 +252,8 @@
val owner = mock(Owner::class.java)
node.attach(owner)
val child = DrawNode()
- node.emitInsertAt(0, child)
- node.emitRemoveAt(index = 0, count = 1)
+ node.insertAt(0, child)
+ node.removeAt(index = 0, count = 1)
verify(owner, times(1)).onDetach(child)
assertEquals(0, node.count)
assertEquals(null, child.parent)
@@ -265,7 +265,7 @@
fun depth() {
val root = LayoutNode()
val (child, grand1, grand2) = createSimpleLayout()
- root.emitInsertAt(0, child)
+ root.insertAt(0, child)
val owner = mock(Owner::class.java)
root.attach(owner)
@@ -281,7 +281,7 @@
fun directLayoutNodeHierarchy() {
val layoutNode = LayoutNode()
val childLayoutNode = LayoutNode()
- layoutNode.emitInsertAt(0, childLayoutNode)
+ layoutNode.insertAt(0, childLayoutNode)
assertNull(layoutNode.parentLayoutNode)
assertEquals(layoutNode, childLayoutNode.parentLayoutNode)
@@ -289,7 +289,7 @@
assertEquals(1, layoutNodeChildren.size)
assertEquals(childLayoutNode, layoutNodeChildren[0])
- layoutNode.emitRemoveAt(index = 0, count = 1)
+ layoutNode.removeAt(index = 0, count = 1)
assertNull(childLayoutNode.parentLayoutNode)
}
@@ -298,7 +298,7 @@
fun directLayoutAndGestureNodesHierarchy() {
val layoutNode = LayoutNode()
val singleChildNode = PointerInputNode()
- layoutNode.emitInsertAt(0, singleChildNode)
+ layoutNode.insertAt(0, singleChildNode)
assertNull(layoutNode.parentLayoutNode)
assertEquals(layoutNode, singleChildNode.parentLayoutNode)
@@ -308,7 +308,7 @@
val childLayoutNodes = findLayoutNodeChildren(singleChildNode)
assertEquals(0, childLayoutNodes.size)
- layoutNode.emitRemoveAt(index = 0, count = 1)
+ layoutNode.removeAt(index = 0, count = 1)
assertNull(singleChildNode.parentLayoutNode)
}
@@ -318,10 +318,10 @@
val layoutNode = LayoutNode()
val intermediate = PointerInputNode()
val childLayoutNode = LayoutNode()
- layoutNode.emitInsertAt(0, intermediate)
+ layoutNode.insertAt(0, intermediate)
assertEquals(layoutNode, intermediate.parentLayoutNode)
- intermediate.emitInsertAt(0, childLayoutNode)
+ intermediate.insertAt(0, childLayoutNode)
assertNull(layoutNode.parentLayoutNode)
assertEquals(layoutNode, childLayoutNode.parentLayoutNode)
@@ -334,7 +334,7 @@
assertEquals(1, intermediateLayoutNodeChildren.size)
assertEquals(childLayoutNode, intermediateLayoutNodeChildren[0])
- intermediate.emitRemoveAt(index = 0, count = 1)
+ intermediate.removeAt(index = 0, count = 1)
assertNull(childLayoutNode.parentLayoutNode)
val intermediateLayoutNodeChildren2 = findLayoutNodeChildren(intermediate)
@@ -346,7 +346,7 @@
fun visitChildren() {
val (node1, node2, node3) = createSimpleLayout()
val node4 = PointerInputNode()
- node3.emitInsertAt(0, node4)
+ node3.insertAt(0, node4)
val nodes = mutableListOf<ComponentNode>()
node1.visitChildren { nodes.add(it) }
assertEquals(2, nodes.size)
@@ -369,7 +369,7 @@
override val width: IntPx = 10.ipx
override val height: IntPx = 10.ipx
override val alignmentLines: Map<AlignmentLine, IntPx> = emptyMap()
- override fun placeChildren(placementScope: Placeable.PlacementScope) {}
+ override fun placeChildren(layoutDirection: LayoutDirection) {}
})
verify(owner, times(1)).onSizeChange(node)
}
@@ -388,7 +388,7 @@
fun testLayoutNodeAdd() {
val (layout, child1, child2) = createSimpleLayout()
val inserted = DrawNode()
- layout.emitInsertAt(0, inserted)
+ layout.insertAt(0, inserted)
val children = mutableListOf<ComponentNode>()
layout.visitChildren { children.add(it) }
assertEquals(3, children.size)
@@ -402,9 +402,9 @@
val (layout, child1, _) = createSimpleLayout()
val child3 = DrawNode()
val child4 = DrawNode()
- layout.emitInsertAt(2, child3)
- layout.emitInsertAt(3, child4)
- layout.emitRemoveAt(index = 1, count = 2)
+ layout.insertAt(2, child3)
+ layout.insertAt(3, child4)
+ layout.removeAt(index = 1, count = 2)
val children = mutableListOf<ComponentNode>()
layout.visitChildren { children.add(it) }
@@ -418,10 +418,10 @@
val (layout, child1, child2) = createSimpleLayout()
val child3 = DrawNode()
val child4 = DrawNode()
- layout.emitInsertAt(2, child3)
- layout.emitInsertAt(3, child4)
+ layout.insertAt(2, child3)
+ layout.insertAt(3, child4)
- layout.emitMove(from = 2, to = 1, count = 2)
+ layout.move(from = 2, to = 1, count = 2)
val children = mutableListOf<ComponentNode>()
layout.visitChildren { children.add(it) }
@@ -431,7 +431,7 @@
assertEquals(child4, children[2])
assertEquals(child2, children[3])
- layout.emitMove(from = 1, to = 3, count = 2)
+ layout.move(from = 1, to = 3, count = 2)
children.clear()
layout.visitChildren { children.add(it) }
@@ -467,7 +467,7 @@
val node0 = LayoutNode()
node0.attach(mockOwner())
val node1 = LayoutNode()
- node0.emitInsertAt(0, node1)
+ node0.insertAt(0, node1)
val x0 = 100.ipx
val y0 = 10.ipx
@@ -492,7 +492,7 @@
val node0 = LayoutNode()
node0.attach(mockOwner())
val node1 = LayoutNode()
- node0.emitInsertAt(0, node1)
+ node0.insertAt(0, node1)
val x0 = 100.ipx
val y0 = 10.ipx
@@ -517,7 +517,7 @@
val node0 = LayoutNode()
node0.attach(mockOwner())
val node1 = LayoutNode()
- node0.emitInsertAt(0, node1)
+ node0.insertAt(0, node1)
val x0 = 100.ipx
val y0 = 10.ipx
@@ -542,7 +542,7 @@
val node0 = LayoutNode()
node0.attach(mockOwner())
val node1 = LayoutNode()
- node0.emitInsertAt(0, node1)
+ node0.insertAt(0, node1)
val x0 = 100.ipx
val y0 = 10.ipx
@@ -589,7 +589,7 @@
val node0 = LayoutNode()
node0.attach(mockOwner())
val node1 = LayoutNode()
- node0.emitInsertAt(0, node1)
+ node0.insertAt(0, node1)
val x1 = 50.ipx
val y1 = 80.ipx
@@ -613,8 +613,8 @@
node0.attach(mockOwner())
val node1 = LayoutNode()
val node2 = LayoutNode()
- node0.emitInsertAt(0, node1)
- node1.emitInsertAt(0, node2)
+ node0.insertAt(0, node1)
+ node1.insertAt(0, node2)
thrown.expect(IllegalStateException::class.java)
@@ -650,7 +650,7 @@
val parent = LayoutNode()
parent.attach(mockOwner())
val child = LayoutNode()
- parent.emitInsertAt(0, child)
+ parent.insertAt(0, child)
parent.place(-100.ipx, 10.ipx)
child.place(50.ipx, 80.ipx)
@@ -664,7 +664,7 @@
val parent = LayoutNode()
parent.attach(mockOwner(IntPxPosition(20.ipx, 20.ipx)))
val child = LayoutNode()
- parent.emitInsertAt(0, child)
+ parent.insertAt(0, child)
child.place(50.ipx, 80.ipx)
val actual = child.coordinates.positionInRoot
@@ -677,7 +677,7 @@
val parent = LayoutNode()
parent.attach(mockOwner())
val child = LayoutNode()
- parent.emitInsertAt(0, child)
+ parent.insertAt(0, child)
parent.place(-100.ipx, 10.ipx)
child.place(50.ipx, 80.ipx)
@@ -692,8 +692,8 @@
grandParent.attach(mockOwner())
val parent = LayoutNode()
val child = LayoutNode()
- grandParent.emitInsertAt(0, parent)
- parent.emitInsertAt(0, child)
+ grandParent.insertAt(0, parent)
+ parent.insertAt(0, child)
grandParent.place(-7.ipx, 17.ipx)
parent.place(23.ipx, -13.ipx)
child.place(-3.ipx, 11.ipx)
@@ -708,7 +708,7 @@
fun testAddBeyondCurrent() {
val pointerInputNode = PointerInputNode()
thrown.expect(IndexOutOfBoundsException::class.java)
- pointerInputNode.emitInsertAt(1, DrawNode())
+ pointerInputNode.insertAt(1, DrawNode())
}
// ComponentNode shouldn't allow adding below 0
@@ -716,43 +716,43 @@
fun testAddBelowZero() {
val pointerInputNode = PointerInputNode()
thrown.expect(IndexOutOfBoundsException::class.java)
- pointerInputNode.emitInsertAt(-1, DrawNode())
+ pointerInputNode.insertAt(-1, DrawNode())
}
// ComponentNode should error when removing at index < 0
@Test
fun testRemoveNegativeIndex() {
val pointerInputNode = PointerInputNode()
- pointerInputNode.emitInsertAt(0, DrawNode())
+ pointerInputNode.insertAt(0, DrawNode())
thrown.expect(IndexOutOfBoundsException::class.java)
- pointerInputNode.emitRemoveAt(-1, 1)
+ pointerInputNode.removeAt(-1, 1)
}
// ComponentNode should error when removing at index > count
@Test
fun testRemoveBeyondIndex() {
val pointerInputNode = PointerInputNode()
- pointerInputNode.emitInsertAt(0, DrawNode())
+ pointerInputNode.insertAt(0, DrawNode())
thrown.expect(IndexOutOfBoundsException::class.java)
- pointerInputNode.emitRemoveAt(1, 1)
+ pointerInputNode.removeAt(1, 1)
}
// ComponentNode should error when removing at count < 0
@Test
fun testRemoveNegativeCount() {
val pointerInputNode = PointerInputNode()
- pointerInputNode.emitInsertAt(0, DrawNode())
+ pointerInputNode.insertAt(0, DrawNode())
thrown.expect(IllegalArgumentException::class.java)
- pointerInputNode.emitRemoveAt(0, -1)
+ pointerInputNode.removeAt(0, -1)
}
// ComponentNode should error when removing at count > entry count
@Test
fun testReplaceoMany() {
val pointerInputNode = PointerInputNode()
- pointerInputNode.emitInsertAt(0, DrawNode())
+ pointerInputNode.insertAt(0, DrawNode())
thrown.expect(IndexOutOfBoundsException::class.java)
- pointerInputNode.emitRemoveAt(0, 2)
+ pointerInputNode.removeAt(0, 2)
}
// ComponentNode should error when there aren't enough items
@@ -760,16 +760,16 @@
fun testReplaceoMany2() {
val pointerInputNode = PointerInputNode()
thrown.expect(IndexOutOfBoundsException::class.java)
- pointerInputNode.emitRemoveAt(0, 1)
+ pointerInputNode.removeAt(0, 1)
}
// ComponentNode should allow removing two items
@Test
fun testRemoveTwoItems() {
val pointerInputNode = PointerInputNode()
- pointerInputNode.emitInsertAt(0, DrawNode())
- pointerInputNode.emitInsertAt(0, DrawNode())
- pointerInputNode.emitRemoveAt(0, 2)
+ pointerInputNode.insertAt(0, DrawNode())
+ pointerInputNode.insertAt(0, DrawNode())
+ pointerInputNode.removeAt(0, 2)
assertEquals(0, pointerInputNode.count)
}
@@ -812,7 +812,7 @@
val layoutNode2 = LayoutNode()
val drawModifier = draw { _, _ -> }
layoutNode.modifier = drawModifier
- layoutNode2.emitInsertAt(0, layoutNode)
+ layoutNode2.insertAt(0, layoutNode)
layoutNode2.attach(mockOwner())
assertEquals(
@@ -905,7 +905,7 @@
middlePointerInputFilter
)
).apply {
- emitInsertAt(0, childLayoutNode)
+ insertAt(0, childLayoutNode)
}
val parentLayoutNode: LayoutNode =
LayoutNode(
@@ -914,7 +914,7 @@
parentPointerInputFilter
)
).apply {
- emitInsertAt(0, middleLayoutNode)
+ insertAt(0, middleLayoutNode)
attach(mockOwner())
}
@@ -1002,8 +1002,8 @@
)
val parentLayoutNode = LayoutNode(0, 0, 100, 100).apply {
- emitInsertAt(0, childLayoutNode1)
- emitInsertAt(1, childLayoutNode2)
+ insertAt(0, childLayoutNode1)
+ insertAt(1, childLayoutNode2)
attach(mockOwner())
}
@@ -1078,9 +1078,9 @@
)
val parentLayoutNode = LayoutNode(0, 0, 200, 200).apply {
- emitInsertAt(0, childLayoutNode1)
- emitInsertAt(1, childLayoutNode2)
- emitInsertAt(2, childLayoutNode3)
+ insertAt(0, childLayoutNode1)
+ insertAt(1, childLayoutNode2)
+ insertAt(2, childLayoutNode3)
attach(mockOwner())
}
@@ -1141,8 +1141,8 @@
)
val parentLayoutNode = LayoutNode(0, 0, 150, 150).apply {
- emitInsertAt(0, childLayoutNode1)
- emitInsertAt(1, childLayoutNode2)
+ insertAt(0, childLayoutNode1)
+ insertAt(1, childLayoutNode2)
attach(mockOwner())
}
@@ -1203,8 +1203,8 @@
)
val parentLayoutNode = LayoutNode(0, 0, 150, 150).apply {
- emitInsertAt(0, childLayoutNode1)
- emitInsertAt(1, childLayoutNode2)
+ insertAt(0, childLayoutNode1)
+ insertAt(1, childLayoutNode2)
attach(mockOwner())
}
@@ -1287,10 +1287,10 @@
)
val parentLayoutNode = LayoutNode(1, 1, 4, 4).apply {
- emitInsertAt(0, layoutNode1)
- emitInsertAt(1, layoutNode2)
- emitInsertAt(2, layoutNode3)
- emitInsertAt(3, layoutNode4)
+ insertAt(0, layoutNode1)
+ insertAt(1, layoutNode2)
+ insertAt(2, layoutNode3)
+ insertAt(3, layoutNode4)
attach(mockOwner())
}
@@ -1467,13 +1467,13 @@
)
)
val layoutNode2: LayoutNode = LayoutNode(2, 6, 500, 500).apply {
- emitInsertAt(0, layoutNode1)
+ insertAt(0, layoutNode1)
}
val layoutNode3: LayoutNode = LayoutNode(3, 7, 500, 500).apply {
- emitInsertAt(0, layoutNode2)
+ insertAt(0, layoutNode2)
}
val layoutNode4: LayoutNode = LayoutNode(4, 8, 500, 500).apply {
- emitInsertAt(0, layoutNode3)
+ insertAt(0, layoutNode3)
}.apply {
attach(mockOwner())
}
@@ -1509,7 +1509,7 @@
)
)
val layoutNode2: LayoutNode = LayoutNode(2, 7, 500, 500).apply {
- emitInsertAt(0, layoutNode1)
+ insertAt(0, layoutNode1)
}
val layoutNode3 =
LayoutNode(
@@ -1520,14 +1520,14 @@
pointerInputFilter4
)
).apply {
- emitInsertAt(0, layoutNode2)
+ insertAt(0, layoutNode2)
}
val layoutNode4: LayoutNode = LayoutNode(4, 9, 500, 500).apply {
- emitInsertAt(0, layoutNode3)
+ insertAt(0, layoutNode3)
}
val layoutNode5: LayoutNode = LayoutNode(5, 10, 500, 500).apply {
- emitInsertAt(0, layoutNode4)
+ insertAt(0, layoutNode4)
}.apply {
attach(mockOwner())
}
@@ -1572,8 +1572,8 @@
)
val parentLayoutNode = LayoutNode(0, 0, 100, 100).apply {
- emitInsertAt(0, layoutNode1)
- emitInsertAt(1, layoutNode2)
+ insertAt(0, layoutNode1)
+ insertAt(1, layoutNode2)
attach(mockOwner())
}
@@ -1617,12 +1617,34 @@
assertThat(hit).isEmpty()
}
+ @Test
+ fun onRequestMeasureIsNotCalledOnDetachedNodes() {
+ val root = LayoutNode()
+
+ val node1 = LayoutNode()
+ root.add(node1)
+ val node2 = LayoutNode()
+ node1.add(node2)
+
+ val owner = mock(Owner::class.java)
+ root.attach(owner)
+ reset(owner)
+
+ // Dispose
+ root.removeAt(0, 1)
+
+ assertFalse(node1.isAttached())
+ assertFalse(node2.isAttached())
+ verify(owner, times(0)).onRequestMeasure(node1)
+ verify(owner, times(0)).onRequestMeasure(node2)
+ }
+
private fun createSimpleLayout(): Triple<LayoutNode, ComponentNode, ComponentNode> {
val layoutNode = LayoutNode()
val child1 = LayoutNode()
val child2 = LayoutNode()
- layoutNode.emitInsertAt(0, child1)
- layoutNode.emitInsertAt(1, child2)
+ layoutNode.insertAt(0, child1)
+ layoutNode.insertAt(1, child2)
return Triple(layoutNode, child1, child2)
}
diff --git a/ui/ui-platform/src/test/java/androidx/ui/core/focus/FindParentFocusNodeTest.kt b/ui/ui-platform/src/test/java/androidx/ui/core/focus/FindParentFocusNodeTest.kt
index d29c95f..33fa5fe 100644
--- a/ui/ui-platform/src/test/java/androidx/ui/core/focus/FindParentFocusNodeTest.kt
+++ b/ui/ui-platform/src/test/java/androidx/ui/core/focus/FindParentFocusNodeTest.kt
@@ -46,7 +46,7 @@
// Arrange.
val focusNode = FocusNode()
val parentFocusNode = FocusNode()
- parentFocusNode.emitInsertAt(0, focusNode)
+ parentFocusNode.insertAt(0, focusNode)
// Act.
val parent = focusNode.findParentFocusNode()
@@ -61,8 +61,8 @@
val focusNode = FocusNode()
val parentFocusNode = FocusNode()
val grandparentFocusNode = FocusNode()
- grandparentFocusNode.emitInsertAt(0, parentFocusNode)
- parentFocusNode.emitInsertAt(0, focusNode)
+ grandparentFocusNode.insertAt(0, parentFocusNode)
+ parentFocusNode.insertAt(0, focusNode)
// Act.
val parent = focusNode.findParentFocusNode()
@@ -78,9 +78,9 @@
val intermediatePointerInputNode = PointerInputNode()
val intermediateLayoutNode = LayoutNode()
val parentFocusNode = FocusNode()
- parentFocusNode.emitInsertAt(0, intermediatePointerInputNode)
- intermediatePointerInputNode.emitInsertAt(0, intermediateLayoutNode)
- intermediateLayoutNode.emitInsertAt(0, focusNode)
+ parentFocusNode.insertAt(0, intermediatePointerInputNode)
+ intermediatePointerInputNode.insertAt(0, intermediateLayoutNode)
+ intermediateLayoutNode.insertAt(0, focusNode)
// Act.
val parent = focusNode.findParentFocusNode()
diff --git a/ui/ui-platform/src/test/java/androidx/ui/core/focus/RequestFocusTest.kt b/ui/ui-platform/src/test/java/androidx/ui/core/focus/RequestFocusTest.kt
index 2c271db..f342318 100644
--- a/ui/ui-platform/src/test/java/androidx/ui/core/focus/RequestFocusTest.kt
+++ b/ui/ui-platform/src/test/java/androidx/ui/core/focus/RequestFocusTest.kt
@@ -112,7 +112,7 @@
val rootNode = FocusNode().apply {
recompose = {}
attach(host)
- emitInsertAt(0, childNode)
+ insertAt(0, childNode)
}
// Act.
@@ -133,9 +133,9 @@
val grandparentNode = FocusNode().apply {
recompose = {}
attach(host)
- emitInsertAt(0, parentNode)
+ insertAt(0, parentNode)
}
- parentNode.emitInsertAt(0, childNode)
+ parentNode.insertAt(0, childNode)
// Act.
parentNode.requestFocus(propagateFocus)
@@ -155,9 +155,9 @@
val grandparentNode = FocusNode().apply {
recompose = {}
attach(host)
- emitInsertAt(0, parentNode)
+ insertAt(0, parentNode)
}
- parentNode.emitInsertAt(0, childNode)
+ parentNode.insertAt(0, childNode)
// Act.
childNode.requestFocus(propagateFocus)
@@ -174,9 +174,9 @@
val grandparentNode = FocusNode().apply {
recompose = {}
attach(host)
- emitInsertAt(0, parentNode)
+ insertAt(0, parentNode)
}
- parentNode.emitInsertAt(0, childNode)
+ parentNode.insertAt(0, childNode)
// Act.
childNode.requestFocus(propagateFocus)
@@ -193,7 +193,7 @@
attach(host)
focusState = Active
recompose = {}
- emitInsertAt(0, focusNode)
+ insertAt(0, focusNode)
}
// Verify Setup.
@@ -215,7 +215,7 @@
val parentNode = FocusNode().apply {
attach(host)
recompose = {}
- emitInsertAt(0, focusNode)
+ insertAt(0, focusNode)
}
focusNode.requestFocus(propagateFocus)
@@ -246,7 +246,7 @@
val parentNode = FocusNode().apply {
attach(host)
recompose = {}
- emitInsertAt(0, focusNode)
+ insertAt(0, focusNode)
}
focusNode.apply {
requestFocus(propagateFocus)
@@ -274,8 +274,8 @@
recompose = {}
focusState = Active
attach(host)
- emitInsertAt(0, focusNode)
- emitInsertAt(1, siblingNode)
+ insertAt(0, focusNode)
+ insertAt(1, siblingNode)
}
// After executing requestFocus, siblingNode will be 'Active'.
siblingNode.requestFocus(propagateFocus)
@@ -303,8 +303,8 @@
recompose = {}
focusState = Active
attach(host)
- emitInsertAt(0, focusNode)
- emitInsertAt(1, siblingNode)
+ insertAt(0, focusNode)
+ insertAt(1, siblingNode)
}
// After executing requestFocus, siblingNode will be 'Active'.
siblingNode.apply {
@@ -355,12 +355,12 @@
grandparentNode.apply {
attach(host)
- emitInsertAt(0, parentNode)
- emitInsertAt(1, auntNode)
+ insertAt(0, parentNode)
+ insertAt(1, auntNode)
}
- parentNode.emitInsertAt(0, focusNode)
- auntNode.emitInsertAt(0, cousinNode)
+ parentNode.insertAt(0, focusNode)
+ auntNode.insertAt(0, cousinNode)
cousinNode.requestFocus(propagateFocus)
// Verify Setup.
@@ -384,10 +384,10 @@
grandparentNode.apply {
attach(host)
- emitInsertAt(0, parentNode)
+ insertAt(0, parentNode)
focusState = Active
}
- parentNode.emitInsertAt(0, focusNode)
+ parentNode.insertAt(0, focusNode)
// Verify Setup.
assertThat(grandparentNode.focusState).isEqualTo(Active)
diff --git a/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/HitPathTracker2Test.kt b/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/HitPathTracker2Test.kt
index fd4e5d6..53074d2 100644
--- a/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/HitPathTracker2Test.kt
+++ b/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/HitPathTracker2Test.kt
@@ -568,22 +568,25 @@
val pif1: PointerInputFilter = PointerInputFilterMock(
pointerInputHandler =
spy(StubPointerInputHandler { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 2f else 64f
- changes.map { it.consumePositionChange(0.px, yConsume.px) }
+ changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 2f else 64f
+ it.consumePositionChange(0.px, yConsume.px) }
})
)
val pif2: PointerInputFilter = PointerInputFilterMock(
pointerInputHandler =
spy(StubPointerInputHandler { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 4f else 32f
- changes.map { it.consumePositionChange(0.px, yConsume.px) }
+ changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 4f else 32f
+ it.consumePositionChange(0.px, yConsume.px) }
})
)
val pif3: PointerInputFilter = PointerInputFilterMock(
pointerInputHandler =
spy(StubPointerInputHandler { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 8f else 16f
- changes.map { it.consumePositionChange(0.px, yConsume.px) }
+ changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 8f else 16f
+ it.consumePositionChange(0.px, yConsume.px) }
})
)
hitPathTracker.addHitPath(PointerId(13), listOf(pif1, pif2, pif3))
@@ -639,29 +642,33 @@
val pif1: PointerInputFilter = PointerInputFilterMock(
pointerInputHandler =
spy(StubPointerInputHandler { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 2f else 12f
- changes.map { it.consumePositionChange(0.px, yConsume.px) }
+ changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 2f else 12f
+ it.consumePositionChange(0.px, yConsume.px) }
})
)
val pif2: PointerInputFilter = PointerInputFilterMock(
pointerInputHandler =
spy(StubPointerInputHandler { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 3f else 6f
- changes.map { it.consumePositionChange(0.px, yConsume.px) }
+ changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 3f else 6f
+ it.consumePositionChange(0.px, yConsume.px) }
})
)
val pif3: PointerInputFilter = PointerInputFilterMock(
pointerInputHandler =
spy(StubPointerInputHandler { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) -2f else -12f
- changes.map { it.consumePositionChange(0.px, yConsume.px) }
+ changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) -2f else -12f
+ it.consumePositionChange(0.px, yConsume.px) }
})
)
val pif4: PointerInputFilter = PointerInputFilterMock(
pointerInputHandler =
spy(StubPointerInputHandler { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) -3f else -6f
- changes.map { it.consumePositionChange(0.px, yConsume.px) }
+ changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) -3f else -6f
+ it.consumePositionChange(0.px, yConsume.px) }
})
)
hitPathTracker.addHitPath(PointerId(3), listOf(pif1, pif2))
@@ -727,8 +734,8 @@
val parent = PointerInputFilterMock(
pointerInputHandler =
spy(StubPointerInputHandler { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 2 else 3
changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 2 else 3
it.consumePositionChange(
0.px,
(it.positionChange().y.value.toInt() / yConsume).px
@@ -739,8 +746,8 @@
val child1: PointerInputFilter = PointerInputFilterMock(
pointerInputHandler =
spy(StubPointerInputHandler { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 5 else 7
changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 5 else 7
it.consumePositionChange(
0.px,
(it.positionChange().y.value.toInt() / yConsume).px
@@ -751,8 +758,8 @@
val child2: PointerInputFilter = PointerInputFilterMock(
pointerInputHandler =
spy(StubPointerInputHandler { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 11 else 13
changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 11 else 13
it.consumePositionChange(
0.px,
(it.positionChange().y.value.toInt() / yConsume).px
@@ -817,8 +824,8 @@
val child1: PointerInputFilter = PointerInputFilterMock(
pointerInputHandler =
spy(StubPointerInputHandler { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 2 else 3
changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 2 else 3
it.consumePositionChange(
0.px,
(it.positionChange().y.value.toInt() / yConsume).px
@@ -829,8 +836,8 @@
val child2: PointerInputFilter = PointerInputFilterMock(
pointerInputHandler =
spy(StubPointerInputHandler { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 5 else 7
changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 5 else 7
it.consumePositionChange(
0.px,
(it.positionChange().y.value.toInt() / yConsume).px
diff --git a/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/HitPathTrackerTest.kt b/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/HitPathTrackerTest.kt
index db6c057..07e7523 100644
--- a/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/HitPathTrackerTest.kt
+++ b/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/HitPathTrackerTest.kt
@@ -604,20 +604,23 @@
val pin3 = PointerInputNode()
pin1.pointerInputHandler = spy(StubPointerInputHandler().apply {
modifyBlock = { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 2f else 64f
- changes.map { it.consumePositionChange(0.px, yConsume.px) }
+ changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 2f else 64f
+ it.consumePositionChange(0.px, yConsume.px) }
}
})
pin2.pointerInputHandler = spy(StubPointerInputHandler().apply {
modifyBlock = { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 4f else 32f
- changes.map { it.consumePositionChange(0.px, yConsume.px) }
+ changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 4f else 32f
+ it.consumePositionChange(0.px, yConsume.px) }
}
})
pin3.pointerInputHandler = spy(StubPointerInputHandler().apply {
modifyBlock = { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 8f else 16f
- changes.map { it.consumePositionChange(0.px, yConsume.px) }
+ changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 8f else 16f
+ it.consumePositionChange(0.px, yConsume.px) }
}
})
hitResult.addHitPath(PointerId(13), listOf(pin1, pin2, pin3))
@@ -676,26 +679,30 @@
val pin4 = PointerInputNode()
pin1.pointerInputHandler = spy(StubPointerInputHandler().apply {
modifyBlock = { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 2f else 12f
- changes.map { it.consumePositionChange(0.px, yConsume.px) }
+ changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 2f else 12f
+ it.consumePositionChange(0.px, yConsume.px) }
}
})
pin2.pointerInputHandler = spy(StubPointerInputHandler().apply {
modifyBlock = { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 3f else 6f
- changes.map { it.consumePositionChange(0.px, yConsume.px) }
+ changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 3f else 6f
+ it.consumePositionChange(0.px, yConsume.px) }
}
})
pin3.pointerInputHandler = spy(StubPointerInputHandler().apply {
modifyBlock = { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) -2f else -12f
- changes.map { it.consumePositionChange(0.px, yConsume.px) }
+ changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) -2f else -12f
+ it.consumePositionChange(0.px, yConsume.px) }
}
})
pin4.pointerInputHandler = spy(StubPointerInputHandler().apply {
modifyBlock = { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) -3f else -6f
- changes.map { it.consumePositionChange(0.px, yConsume.px) }
+ changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) -3f else -6f
+ it.consumePositionChange(0.px, yConsume.px) }
}
})
hitResult.addHitPath(PointerId(3), listOf(pin1, pin2))
@@ -763,8 +770,8 @@
val child2 = PointerInputNode()
parent.pointerInputHandler = spy(StubPointerInputHandler().apply {
modifyBlock = { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 2 else 3
changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 2 else 3
it.consumePositionChange(
0.px,
(it.positionChange().y.value.toInt() / yConsume).px
@@ -776,8 +783,8 @@
child1.pointerInputHandler = spy(StubPointerInputHandler().apply
{
modifyBlock = { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 5 else 7
changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 5 else 7
it.consumePositionChange(
0.px,
(it.positionChange().y.value.toInt() / yConsume).px
@@ -788,8 +795,8 @@
child2.pointerInputHandler = spy(StubPointerInputHandler().apply
{
modifyBlock = { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 11 else 13
changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 11 else 13
it.consumePositionChange(
0.px,
(it.positionChange().y.value.toInt() / yConsume).px
@@ -855,8 +862,8 @@
val child2 = PointerInputNode()
child1.pointerInputHandler = spy(StubPointerInputHandler().apply {
modifyBlock = { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 2 else 3
changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 2 else 3
it.consumePositionChange(
0.px,
(it.positionChange().y.value.toInt() / yConsume).px
@@ -866,8 +873,8 @@
})
child2.pointerInputHandler = spy(StubPointerInputHandler().apply {
modifyBlock = { changes, pass, _ ->
- val yConsume = if (pass == PointerEventPass.InitialDown) 5 else 7
changes.map {
+ val yConsume = if (pass == PointerEventPass.InitialDown) 5 else 7
it.consumePositionChange(
0.px,
(it.positionChange().y.value.toInt() / yConsume).px
@@ -953,7 +960,7 @@
this.cancelHandler = neverCalled
}
val pin3 = PointerInputNode().apply {
- emitInsertAt(0, pin2)
+ insertAt(0, pin2)
this.cancelHandler = neverCalled
}
@@ -961,11 +968,11 @@
this.cancelHandler = neverCalled
}
val pin5 = PointerInputNode().apply {
- emitInsertAt(0, pin4)
+ insertAt(0, pin4)
this.cancelHandler = neverCalled
}
val pin6 = PointerInputNode().apply {
- emitInsertAt(0, pin5)
+ insertAt(0, pin5)
this.cancelHandler = neverCalled
}
@@ -976,18 +983,18 @@
this.cancelHandler = neverCalled
}
val layoutNode = LayoutNode().apply {
- emitInsertAt(0, pin7)
- emitInsertAt(1, pin8)
+ insertAt(0, pin7)
+ insertAt(1, pin8)
}
val pin9 = PointerInputNode().apply {
- emitInsertAt(0, layoutNode)
+ insertAt(0, layoutNode)
this.cancelHandler = neverCalled
}
- compositionRoot.emitInsertAt(0, pin1)
- compositionRoot.emitInsertAt(1, pin3)
- compositionRoot.emitInsertAt(2, pin6)
- compositionRoot.emitInsertAt(3, pin9)
+ compositionRoot.insertAt(0, pin1)
+ compositionRoot.insertAt(1, pin3)
+ compositionRoot.insertAt(2, pin6)
+ compositionRoot.insertAt(3, pin9)
val pointerId1 = PointerId(1)
val pointerId2 = PointerId(2)
@@ -1048,11 +1055,11 @@
cancelHandler = spy {}
}
val middle = PointerInputNode().apply {
- emitInsertAt(0, leaf)
+ insertAt(0, leaf)
cancelHandler = spy {}
}
val root = PointerInputNode().apply {
- emitInsertAt(0, middle)
+ insertAt(0, middle)
cancelHandler = spy {}
}
hitResult.addHitPath(PointerId(0), listOf(root, middle, leaf))
@@ -1074,7 +1081,7 @@
cancelHandler = spy {}
}
val middle = PointerInputNode().apply {
- emitInsertAt(0, child)
+ insertAt(0, child)
cancelHandler = spy {}
}
val root = PointerInputNode().apply {
@@ -1110,7 +1117,7 @@
cancelHandler = spy {}
}
val root = PointerInputNode().apply {
- emitInsertAt(0, middle)
+ insertAt(0, middle)
cancelHandler = spy {}
}
compositionRoot.add(root)
@@ -1145,11 +1152,11 @@
cancelHandler = neverCalled
}
val middle1 = PointerInputNode().apply {
- emitInsertAt(0, leaf1)
+ insertAt(0, leaf1)
cancelHandler = neverCalled
}
val root1 = PointerInputNode().apply {
- emitInsertAt(0, middle1)
+ insertAt(0, middle1)
cancelHandler = neverCalled
}
@@ -1157,11 +1164,11 @@
cancelHandler = neverCalled
}
val middle2 = PointerInputNode().apply {
- emitInsertAt(0, leaf2)
+ insertAt(0, leaf2)
cancelHandler = neverCalled
}
val root2 = PointerInputNode().apply {
- emitInsertAt(0, middle2)
+ insertAt(0, middle2)
cancelHandler = neverCalled
}
@@ -1169,16 +1176,16 @@
cancelHandler = spy {}
}
val middle3 = PointerInputNode().apply {
- emitInsertAt(0, leaf3)
+ insertAt(0, leaf3)
cancelHandler = spy {}
}
val root3 = PointerInputNode().apply {
- emitInsertAt(0, middle3)
+ insertAt(0, middle3)
cancelHandler = spy {}
}
- compositionRoot.emitInsertAt(0, root1)
- compositionRoot.emitInsertAt(1, root2)
+ compositionRoot.insertAt(0, root1)
+ compositionRoot.insertAt(1, root2)
val pointerId1 = PointerId(3)
val pointerId2 = PointerId(5)
@@ -1232,7 +1239,7 @@
cancelHandler = spy {}
}
val middle1 = PointerInputNode().apply {
- emitInsertAt(0, leaf1)
+ insertAt(0, leaf1)
cancelHandler = spy {}
}
val root1 = PointerInputNode().apply {
@@ -1243,11 +1250,11 @@
cancelHandler = neverCalled
}
val middle2 = PointerInputNode().apply {
- emitInsertAt(0, leaf2)
+ insertAt(0, leaf2)
cancelHandler = neverCalled
}
val root2 = PointerInputNode().apply {
- emitInsertAt(0, middle2)
+ insertAt(0, middle2)
cancelHandler = neverCalled
}
@@ -1255,17 +1262,17 @@
cancelHandler = neverCalled
}
val middle3 = PointerInputNode().apply {
- emitInsertAt(0, leaf3)
+ insertAt(0, leaf3)
cancelHandler = neverCalled
}
val root3 = PointerInputNode().apply {
- emitInsertAt(0, middle3)
+ insertAt(0, middle3)
cancelHandler = neverCalled
}
- compositionRoot.emitInsertAt(0, root1)
- compositionRoot.emitInsertAt(1, root2)
- compositionRoot.emitInsertAt(2, root3)
+ compositionRoot.insertAt(0, root1)
+ compositionRoot.insertAt(1, root2)
+ compositionRoot.insertAt(2, root3)
val pointerId1 = PointerId(3)
val pointerId2 = PointerId(5)
@@ -1321,11 +1328,11 @@
cancelHandler = neverCalled
}
val middle1 = PointerInputNode().apply {
- emitInsertAt(0, leaf1)
+ insertAt(0, leaf1)
cancelHandler = neverCalled
}
val root1 = PointerInputNode().apply {
- emitInsertAt(0, middle1)
+ insertAt(0, middle1)
cancelHandler = neverCalled
}
@@ -1336,7 +1343,7 @@
cancelHandler = neverCalled
}
val root2 = PointerInputNode().apply {
- emitInsertAt(0, middle2)
+ insertAt(0, middle2)
cancelHandler = neverCalled
}
@@ -1344,17 +1351,17 @@
cancelHandler = neverCalled
}
val middle3 = PointerInputNode().apply {
- emitInsertAt(0, leaf3)
+ insertAt(0, leaf3)
cancelHandler = neverCalled
}
val root3 = PointerInputNode().apply {
- emitInsertAt(0, middle3)
+ insertAt(0, middle3)
cancelHandler = neverCalled
}
- compositionRoot.emitInsertAt(0, root1)
- compositionRoot.emitInsertAt(1, root2)
- compositionRoot.emitInsertAt(2, root3)
+ compositionRoot.insertAt(0, root1)
+ compositionRoot.insertAt(1, root2)
+ compositionRoot.insertAt(2, root3)
val pointerId1 = PointerId(3)
val pointerId2 = PointerId(5)
@@ -1410,11 +1417,11 @@
cancelHandler = spy {}
}
val middle1 = PointerInputNode().apply {
- emitInsertAt(0, leaf1)
+ insertAt(0, leaf1)
cancelHandler = spy {}
}
val root1 = PointerInputNode().apply {
- emitInsertAt(0, middle1)
+ insertAt(0, middle1)
cancelHandler = spy {}
}
@@ -1422,11 +1429,11 @@
cancelHandler = neverCalled
}
val middle2 = PointerInputNode().apply {
- emitInsertAt(0, leaf2)
+ insertAt(0, leaf2)
cancelHandler = neverCalled
}
val root2 = PointerInputNode().apply {
- emitInsertAt(0, middle2)
+ insertAt(0, middle2)
cancelHandler = neverCalled
}
@@ -1434,15 +1441,15 @@
cancelHandler = spy {}
}
val middle3 = PointerInputNode().apply {
- emitInsertAt(0, leaf3)
+ insertAt(0, leaf3)
cancelHandler = spy {}
}
val root3 = PointerInputNode().apply {
- emitInsertAt(0, middle3)
+ insertAt(0, middle3)
cancelHandler = spy {}
}
- compositionRoot.emitInsertAt(0, root2)
+ compositionRoot.insertAt(0, root2)
val pointerId1 = PointerId(3)
val pointerId2 = PointerId(5)
@@ -1493,7 +1500,7 @@
cancelHandler = spy {}
}
val middle1 = PointerInputNode().apply {
- emitInsertAt(0, leaf1)
+ insertAt(0, leaf1)
cancelHandler = spy {}
}
val root1 = PointerInputNode().apply {
@@ -1504,7 +1511,7 @@
cancelHandler = spy {}
}
val middle2 = PointerInputNode().apply {
- emitInsertAt(0, leaf2)
+ insertAt(0, leaf2)
cancelHandler = spy {}
}
val root2 = PointerInputNode().apply {
@@ -1515,17 +1522,17 @@
cancelHandler = neverCalled
}
val middle3 = PointerInputNode().apply {
- emitInsertAt(0, leaf3)
+ insertAt(0, leaf3)
cancelHandler = neverCalled
}
val root3 = PointerInputNode().apply {
- emitInsertAt(0, middle3)
+ insertAt(0, middle3)
cancelHandler = neverCalled
}
- compositionRoot.emitInsertAt(0, root1)
- compositionRoot.emitInsertAt(1, root2)
- compositionRoot.emitInsertAt(2, root3)
+ compositionRoot.insertAt(0, root1)
+ compositionRoot.insertAt(1, root2)
+ compositionRoot.insertAt(2, root3)
val pointerId1 = PointerId(3)
val pointerId2 = PointerId(5)
@@ -1580,11 +1587,11 @@
cancelHandler = neverCalled
}
val middle1 = PointerInputNode().apply {
- emitInsertAt(0, leaf1)
+ insertAt(0, leaf1)
cancelHandler = neverCalled
}
val root1 = PointerInputNode().apply {
- emitInsertAt(0, middle1)
+ insertAt(0, middle1)
cancelHandler = neverCalled
}
@@ -1595,7 +1602,7 @@
cancelHandler = neverCalled
}
val root2 = PointerInputNode().apply {
- emitInsertAt(0, middle2)
+ insertAt(0, middle2)
cancelHandler = neverCalled
}
@@ -1606,13 +1613,13 @@
cancelHandler = neverCalled
}
val root3 = PointerInputNode().apply {
- emitInsertAt(0, middle3)
+ insertAt(0, middle3)
cancelHandler = neverCalled
}
- compositionRoot.emitInsertAt(0, root1)
- compositionRoot.emitInsertAt(1, root2)
- compositionRoot.emitInsertAt(2, root3)
+ compositionRoot.insertAt(0, root1)
+ compositionRoot.insertAt(1, root2)
+ compositionRoot.insertAt(2, root3)
val pointerId1 = PointerId(3)
val pointerId2 = PointerId(5)
@@ -1663,11 +1670,11 @@
cancelHandler = spy {}
}
val middle1 = PointerInputNode().apply {
- emitInsertAt(0, leaf1)
+ insertAt(0, leaf1)
cancelHandler = spy {}
}
val root1 = PointerInputNode().apply {
- emitInsertAt(0, middle1)
+ insertAt(0, middle1)
cancelHandler = spy {}
}
@@ -1675,11 +1682,11 @@
cancelHandler = spy {}
}
val middle2 = PointerInputNode().apply {
- emitInsertAt(0, leaf2)
+ insertAt(0, leaf2)
cancelHandler = spy {}
}
val root2 = PointerInputNode().apply {
- emitInsertAt(0, middle2)
+ insertAt(0, middle2)
cancelHandler = spy {}
}
@@ -1687,11 +1694,11 @@
cancelHandler = spy {}
}
val middle3 = PointerInputNode().apply {
- emitInsertAt(0, leaf3)
+ insertAt(0, leaf3)
cancelHandler = spy {}
}
val root3 = PointerInputNode().apply {
- emitInsertAt(0, middle3)
+ insertAt(0, middle3)
cancelHandler = spy {}
}
@@ -1733,7 +1740,7 @@
cancelHandler = spy {}
}
val middle1 = PointerInputNode().apply {
- emitInsertAt(0, leaf1)
+ insertAt(0, leaf1)
cancelHandler = spy {}
}
val root1 = PointerInputNode().apply {
@@ -1744,7 +1751,7 @@
cancelHandler = spy {}
}
val middle2 = PointerInputNode().apply {
- emitInsertAt(0, leaf2)
+ insertAt(0, leaf2)
cancelHandler = spy {}
}
val root2 = PointerInputNode().apply {
@@ -1755,16 +1762,16 @@
cancelHandler = spy {}
}
val middle3 = PointerInputNode().apply {
- emitInsertAt(0, leaf3)
+ insertAt(0, leaf3)
cancelHandler = spy {}
}
val root3 = PointerInputNode().apply {
cancelHandler = neverCalled
}
- compositionRoot.emitInsertAt(0, root1)
- compositionRoot.emitInsertAt(1, root2)
- compositionRoot.emitInsertAt(2, root3)
+ compositionRoot.insertAt(0, root1)
+ compositionRoot.insertAt(1, root2)
+ compositionRoot.insertAt(2, root3)
val pointerId1 = PointerId(3)
val pointerId2 = PointerId(5)
@@ -1819,7 +1826,7 @@
cancelHandler = neverCalled
}
val root1 = PointerInputNode().apply {
- emitInsertAt(0, middle1)
+ insertAt(0, middle1)
cancelHandler = neverCalled
}
@@ -1830,7 +1837,7 @@
cancelHandler = neverCalled
}
val root2 = PointerInputNode().apply {
- emitInsertAt(0, middle2)
+ insertAt(0, middle2)
cancelHandler = neverCalled
}
@@ -1841,13 +1848,13 @@
cancelHandler = neverCalled
}
val root3 = PointerInputNode().apply {
- emitInsertAt(0, middle3)
+ insertAt(0, middle3)
cancelHandler = neverCalled
}
- compositionRoot.emitInsertAt(0, root1)
- compositionRoot.emitInsertAt(1, root2)
- compositionRoot.emitInsertAt(2, root3)
+ compositionRoot.insertAt(0, root1)
+ compositionRoot.insertAt(1, root2)
+ compositionRoot.insertAt(2, root3)
val pointerId1 = PointerId(3)
val pointerId2 = PointerId(5)
@@ -1899,11 +1906,11 @@
cancelHandler = spy {}
}
val middle1 = PointerInputNode().apply {
- emitInsertAt(0, leaf1)
+ insertAt(0, leaf1)
cancelHandler = spy {}
}
val root1 = PointerInputNode().apply {
- emitInsertAt(0, middle1)
+ insertAt(0, middle1)
cancelHandler = spy {}
}
@@ -1911,7 +1918,7 @@
cancelHandler = spy {}
}
val middle2 = PointerInputNode().apply {
- emitInsertAt(0, leaf2)
+ insertAt(0, leaf2)
cancelHandler = spy {}
}
val root2 = PointerInputNode().apply {
@@ -1925,12 +1932,12 @@
cancelHandler = neverCalled
}
val root3 = PointerInputNode().apply {
- emitInsertAt(0, middle3)
+ insertAt(0, middle3)
cancelHandler = neverCalled
}
- compositionRoot.emitInsertAt(0, root2)
- compositionRoot.emitInsertAt(1, root3)
+ compositionRoot.insertAt(0, root2)
+ compositionRoot.insertAt(1, root3)
val pointerId1 = PointerId(3)
val pointerId2 = PointerId(5)
@@ -1978,7 +1985,7 @@
cancelHandler = spy {}
}
val middle1 = PointerInputNode().apply {
- emitInsertAt(0, leaf1)
+ insertAt(0, leaf1)
cancelHandler = spy {}
}
@@ -1986,7 +1993,7 @@
cancelHandler = spy {}
}
val middle2 = PointerInputNode().apply {
- emitInsertAt(0, leaf2)
+ insertAt(0, leaf2)
cancelHandler = spy {}
}
@@ -1994,18 +2001,18 @@
cancelHandler = spy {}
}
val middle3 = PointerInputNode().apply {
- emitInsertAt(0, leaf3)
+ insertAt(0, leaf3)
cancelHandler = spy {}
}
val layoutNode = LayoutNode().apply {
- emitInsertAt(0, middle1)
- emitInsertAt(1, middle2)
- emitInsertAt(2, middle3)
+ insertAt(0, middle1)
+ insertAt(1, middle2)
+ insertAt(2, middle3)
}
val root = PointerInputNode().apply {
- emitInsertAt(0, layoutNode)
+ insertAt(0, layoutNode)
cancelHandler = spy {}
}
@@ -2048,7 +2055,7 @@
cancelHandler = neverCalled
}
val middle1 = PointerInputNode().apply {
- emitInsertAt(0, leaf1)
+ insertAt(0, leaf1)
cancelHandler = neverCalled
}
@@ -2056,7 +2063,7 @@
cancelHandler = neverCalled
}
val middle2 = PointerInputNode().apply {
- emitInsertAt(0, leaf2)
+ insertAt(0, leaf2)
cancelHandler = neverCalled
}
@@ -2064,21 +2071,21 @@
cancelHandler = spy {}
}
val middle3 = PointerInputNode().apply {
- emitInsertAt(0, leaf3)
+ insertAt(0, leaf3)
cancelHandler = spy {}
}
val layoutNode = LayoutNode().apply {
- emitInsertAt(0, middle1)
- emitInsertAt(1, middle2)
+ insertAt(0, middle1)
+ insertAt(1, middle2)
}
val root = PointerInputNode().apply {
- emitInsertAt(0, layoutNode)
+ insertAt(0, layoutNode)
cancelHandler = neverCalled
}
- compositionRoot.emitInsertAt(0, root)
+ compositionRoot.insertAt(0, root)
val pointerId1 = PointerId(3)
val pointerId2 = PointerId(5)
@@ -2131,7 +2138,7 @@
cancelHandler = spy {}
}
val middle1 = PointerInputNode().apply {
- emitInsertAt(0, leaf1)
+ insertAt(0, leaf1)
cancelHandler = spy {}
}
@@ -2139,7 +2146,7 @@
cancelHandler = spy {}
}
val middle2 = PointerInputNode().apply {
- emitInsertAt(0, leaf2)
+ insertAt(0, leaf2)
cancelHandler = spy {}
}
@@ -2147,20 +2154,20 @@
cancelHandler = neverCalled
}
val middle3 = PointerInputNode().apply {
- emitInsertAt(0, leaf3)
+ insertAt(0, leaf3)
cancelHandler = neverCalled
}
val layoutNode = LayoutNode().apply {
- emitInsertAt(0, middle3)
+ insertAt(0, middle3)
}
val root = PointerInputNode().apply {
- emitInsertAt(0, layoutNode)
+ insertAt(0, layoutNode)
cancelHandler = neverCalled
}
- compositionRoot.emitInsertAt(0, root)
+ compositionRoot.insertAt(0, root)
val pointerId1 = PointerId(3)
val pointerId2 = PointerId(5)
@@ -2211,7 +2218,7 @@
cancelHandler = spy {}
}
val middle1 = PointerInputNode().apply {
- emitInsertAt(0, leaf1)
+ insertAt(0, leaf1)
cancelHandler = spy {}
}
@@ -2219,7 +2226,7 @@
cancelHandler = spy {}
}
val middle2 = PointerInputNode().apply {
- emitInsertAt(0, leaf2)
+ insertAt(0, leaf2)
cancelHandler = spy {}
}
@@ -2227,18 +2234,18 @@
cancelHandler = spy {}
}
val middle3 = PointerInputNode().apply {
- emitInsertAt(0, leaf3)
+ insertAt(0, leaf3)
cancelHandler = spy {}
}
val layoutNode = LayoutNode()
val root = PointerInputNode().apply {
- emitInsertAt(0, layoutNode)
+ insertAt(0, layoutNode)
cancelHandler = neverCalled
}
- compositionRoot.emitInsertAt(0, root)
+ compositionRoot.insertAt(0, root)
val pointerId1 = PointerId(3)
val pointerId2 = PointerId(5)
@@ -2294,21 +2301,21 @@
}
val layoutNode = LayoutNode().apply {
- emitInsertAt(0, leaf1)
- emitInsertAt(1, leaf3)
+ insertAt(0, leaf1)
+ insertAt(1, leaf3)
}
val middle = PointerInputNode().apply {
- emitInsertAt(0, layoutNode)
+ insertAt(0, layoutNode)
cancelHandler = neverCalled
}
val root = PointerInputNode().apply {
- emitInsertAt(0, middle)
+ insertAt(0, middle)
cancelHandler = neverCalled
}
- compositionRoot.emitInsertAt(0, root)
+ compositionRoot.insertAt(0, root)
val pointerId1 = PointerId(3)
val pointerId2 = PointerId(5)
@@ -2364,20 +2371,20 @@
}
val layoutNode = LayoutNode().apply {
- emitInsertAt(0, leaf2)
+ insertAt(0, leaf2)
}
val middle = PointerInputNode().apply {
- emitInsertAt(0, layoutNode)
+ insertAt(0, layoutNode)
cancelHandler = neverCalled
}
val root = PointerInputNode().apply {
- emitInsertAt(0, middle)
+ insertAt(0, middle)
cancelHandler = neverCalled
}
- compositionRoot.emitInsertAt(0, root)
+ compositionRoot.insertAt(0, root)
val pointerId1 = PointerId(3)
val pointerId2 = PointerId(5)
@@ -2433,16 +2440,16 @@
val layoutNode = LayoutNode()
val middle = PointerInputNode().apply {
- emitInsertAt(0, layoutNode)
+ insertAt(0, layoutNode)
cancelHandler = neverCalled
}
val root = PointerInputNode().apply {
- emitInsertAt(0, middle)
+ insertAt(0, middle)
cancelHandler = neverCalled
}
- compositionRoot.emitInsertAt(0, root)
+ compositionRoot.insertAt(0, root)
val pointerId1 = PointerId(3)
val pointerId2 = PointerId(5)
@@ -2503,7 +2510,7 @@
fun removePointerInputNodesWithNoLayoutNodeDescendants_dnInPin_pinRemovedCancelCalledOnce() {
val drawNode = DrawNode()
val pointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, drawNode)
+ insertAt(0, drawNode)
cancelHandler = spy {}
}
hitResult.addHitPath(PointerId(0), listOf(pointerInputNode))
@@ -2519,7 +2526,7 @@
fun removePointerInputNodesWithNoLayoutNodeDescendants_snInPin_pinRemoved() {
val semanticsNode = SemanticsComponentNode(1, SemanticsConfiguration())
val pointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, semanticsNode)
+ insertAt(0, semanticsNode)
cancelHandler = spy {}
}
hitResult.addHitPath(PointerId(0), listOf(pointerInputNode))
@@ -2535,11 +2542,11 @@
fun removePointerInputNodesWithNoLayoutNodeDescendants_smInPinInPin_removesAndCancelsCorrect() {
val semanticsNode = SemanticsComponentNode(1, SemanticsConfiguration())
val pointerInputNodeB = PointerInputNode().apply {
- emitInsertAt(0, semanticsNode)
+ insertAt(0, semanticsNode)
cancelHandler = spy {}
}
val pointerInputNodeA = PointerInputNode().apply {
- emitInsertAt(0, pointerInputNodeB)
+ insertAt(0, pointerInputNodeB)
cancelHandler = spy {}
}
hitResult.addHitPath(
@@ -2561,11 +2568,11 @@
fun removePointerInputNodesWithNoLayoutNodeDescendants_dnInPinInPin_removesAndCancelsCorrect() {
val drawnode = DrawNode()
val pointerInputNodeB = PointerInputNode().apply {
- emitInsertAt(0, drawnode)
+ insertAt(0, drawnode)
cancelHandler = spy {}
}
val pointerInputNodeA = PointerInputNode().apply {
- emitInsertAt(0, pointerInputNodeB)
+ insertAt(0, pointerInputNodeB)
cancelHandler = spy {}
}
hitResult.addHitPath(
@@ -2587,7 +2594,7 @@
fun removePointerInputNodesWithNoLayoutNodeDescendants_pinWithLn_noRemovesOrCancels() {
val layoutNode = LayoutNode(0, 0, 100, 100)
val pointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, layoutNode)
+ insertAt(0, layoutNode)
cancelHandler = spy {}
}
val pointerId = PointerId(0)
@@ -2610,11 +2617,11 @@
val layoutNode = LayoutNode(0, 0, 100, 100)
val pointerInputNodeB = PointerInputNode().apply {
- emitInsertAt(0, layoutNode)
+ insertAt(0, layoutNode)
cancelHandler = neverCalled
}
val pointerInputNodeA = PointerInputNode().apply {
- emitInsertAt(0, pointerInputNodeB)
+ insertAt(0, pointerInputNodeB)
cancelHandler = neverCalled
}
val pointerId = PointerId(0)
@@ -2642,10 +2649,10 @@
cancelHandler = spy {}
}
val layoutNode = LayoutNode(0, 0, 100, 100).apply {
- emitInsertAt(0, pointerInputNodeB)
+ insertAt(0, pointerInputNodeB)
}
val pointerInputNodeA = PointerInputNode().apply {
- emitInsertAt(0, layoutNode)
+ insertAt(0, layoutNode)
cancelHandler = spy {}
}
val pointerId = PointerId(0)
@@ -2673,15 +2680,15 @@
val layoutNode = LayoutNode(0, 0, 100, 100)
val pointerInputNodeB = PointerInputNode().apply {
- emitInsertAt(0, layoutNode)
+ insertAt(0, layoutNode)
cancelHandler = neverCalled
}
val pointerInputNodeC = PointerInputNode().apply {
cancelHandler = spy {}
}
val pointerInputNodeA = PointerInputNode().apply {
- emitInsertAt(0, pointerInputNodeB)
- emitInsertAt(0, pointerInputNodeC)
+ insertAt(0, pointerInputNodeB)
+ insertAt(0, pointerInputNodeC)
cancelHandler = neverCalled
}
val pointerId1 = PointerId(0)
@@ -3042,25 +3049,25 @@
val childOffset = PxPosition(cX1.px, cY1.px)
val childLayoutNode = LayoutNode(cX1, cY1, cX2, cY2)
val childPointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, childLayoutNode)
+ insertAt(0, childLayoutNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
val middleOffset = PxPosition(mX1.px, mY1.px)
val middleLayoutNode = LayoutNode(mX1, mY1, mX2, mY2).apply {
- emitInsertAt(0, childPointerInputNode)
+ insertAt(0, childPointerInputNode)
}
val middlePointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, middleLayoutNode)
+ insertAt(0, middleLayoutNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
val parentLayoutNode = LayoutNode(pX1, pY1, pX2, pY2).apply {
- emitInsertAt(0, middlePointerInputNode)
+ insertAt(0, middlePointerInputNode)
}
val parentPointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, parentLayoutNode)
+ insertAt(0, parentLayoutNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
- compositionRoot.emitInsertAt(0, parentPointerInputNode)
+ compositionRoot.insertAt(0, parentPointerInputNode)
hitResult.addHitPath(
PointerId(3),
@@ -3255,18 +3262,18 @@
val childLayoutNode = LayoutNode(c1.left, c1.top, c1.right, c1.bottom)
val childPointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, childLayoutNode)
+ insertAt(0, childLayoutNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
val parentLayoutNode = LayoutNode(p1.left, p1.top, p1.right, p1.bottom).apply {
- emitInsertAt(0, childPointerInputNode)
+ insertAt(0, childPointerInputNode)
}
val parentPointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, parentLayoutNode)
+ insertAt(0, parentLayoutNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
- compositionRoot.emitInsertAt(0, parentPointerInputNode)
+ compositionRoot.insertAt(0, parentPointerInputNode)
hitResult.addHitPath(
PointerId(3),
@@ -3363,32 +3370,32 @@
val childLayoutNode1 = LayoutNode(child1Offset, child1Size)
val childPointerInputNode1 = PointerInputNode().apply {
- emitInsertAt(0, childLayoutNode1)
+ insertAt(0, childLayoutNode1)
pointerInputHandler = spy(StubPointerInputHandler())
}
val parentLayoutNode1 = LayoutNode(parent1Offset, parent1Size).apply {
- emitInsertAt(0, childPointerInputNode1)
+ insertAt(0, childPointerInputNode1)
}
val parentPointerInputNode1 = PointerInputNode().apply {
- emitInsertAt(0, parentLayoutNode1)
+ insertAt(0, parentLayoutNode1)
pointerInputHandler = spy(StubPointerInputHandler())
}
val childLayoutNode2 = LayoutNode(child2Offset, child2Size)
val childPointerInputNode2 = PointerInputNode().apply {
- emitInsertAt(0, childLayoutNode2)
+ insertAt(0, childLayoutNode2)
pointerInputHandler = spy(StubPointerInputHandler())
}
val parentLayoutNode2 = LayoutNode(parent2Offset, parent2Size).apply {
- emitInsertAt(0, childPointerInputNode2)
+ insertAt(0, childPointerInputNode2)
}
val parentPointerInputNode2 = PointerInputNode().apply {
- emitInsertAt(0, parentLayoutNode2)
+ insertAt(0, parentLayoutNode2)
pointerInputHandler = spy(StubPointerInputHandler())
}
- compositionRoot.emitInsertAt(0, parentPointerInputNode1)
- compositionRoot.emitInsertAt(1, parentPointerInputNode2)
+ compositionRoot.insertAt(0, parentPointerInputNode1)
+ compositionRoot.insertAt(1, parentPointerInputNode2)
hitResult.addHitPath(
PointerId(3),
@@ -3526,26 +3533,26 @@
val childLayoutNode1 = LayoutNode(child1Offset, child1Size)
val childPointerInputNode1: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, childLayoutNode1)
+ insertAt(0, childLayoutNode1)
pointerInputHandler = spy(StubPointerInputHandler())
}
val childLayoutNode2 = LayoutNode(child2Offset, child2Size)
val childPointerInputNode2: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, childLayoutNode2)
+ insertAt(0, childLayoutNode2)
pointerInputHandler = spy(StubPointerInputHandler())
}
val parentLayoutNode: LayoutNode = LayoutNode(parentOffset, parentSize).apply {
- emitInsertAt(0, childPointerInputNode1)
- emitInsertAt(1, childPointerInputNode2)
+ insertAt(0, childPointerInputNode1)
+ insertAt(1, childPointerInputNode2)
}
val parentPointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, parentLayoutNode)
+ insertAt(0, parentLayoutNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
- compositionRoot.emitInsertAt(0, parentPointerInputNode)
+ compositionRoot.insertAt(0, parentPointerInputNode)
hitResult.addHitPath(
PointerId(3),
@@ -3670,18 +3677,18 @@
val childLayoutNode = LayoutNode(childOffset, childSize)
val pointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, childLayoutNode)
+ insertAt(0, childLayoutNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
val parentLayoutNode2 = LayoutNode(parentOffset2, parentSize2).apply {
- emitInsertAt(0, pointerInputNode)
+ insertAt(0, pointerInputNode)
}
@Suppress("UNUSED_VARIABLE")
val parentLayoutNode1 = LayoutNode(parentOffset1, parentSize1).apply {
- emitInsertAt(0, parentLayoutNode2)
+ insertAt(0, parentLayoutNode2)
}
- compositionRoot.emitInsertAt(0, parentLayoutNode1)
+ compositionRoot.insertAt(0, parentLayoutNode1)
hitResult.addHitPath(PointerId(3), listOf(pointerInputNode))
@@ -3746,28 +3753,28 @@
val childLayoutNode2 = LayoutNode(childOffset2, childSize2)
val childPointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, childLayoutNode2)
+ insertAt(0, childLayoutNode2)
pointerInputHandler = spy(StubPointerInputHandler())
}
val childLayoutNode1 = LayoutNode(childOffset1, childSize1).apply {
- emitInsertAt(0, childPointerInputNode)
+ insertAt(0, childPointerInputNode)
}
val parentLayoutNode3 = LayoutNode(parentOffset3, parentSize3).apply {
- emitInsertAt(0, childLayoutNode1)
+ insertAt(0, childLayoutNode1)
}
val parentPointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, parentLayoutNode3)
+ insertAt(0, parentLayoutNode3)
pointerInputHandler = spy(StubPointerInputHandler())
}
val parentLayoutNode2 = LayoutNode(parentOffset2, parentSize2).apply {
- emitInsertAt(0, parentPointerInputNode)
+ insertAt(0, parentPointerInputNode)
}
@Suppress("UNUSED_VARIABLE")
val parentLayoutNode1 = LayoutNode(parentOffset1, parentSize1).apply {
- emitInsertAt(0, parentLayoutNode2)
+ insertAt(0, parentLayoutNode2)
}
- compositionRoot.emitInsertAt(0, parentLayoutNode1)
+ compositionRoot.insertAt(0, parentLayoutNode1)
hitResult.addHitPath(
PointerId(3),
@@ -3887,12 +3894,12 @@
// Arrange
val pointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(layoutNodeAX1, layoutNodeAY1, layoutNodeAX2, layoutNodeAY2))
- emitInsertAt(1, LayoutNode(layoutNodeBX1, layoutNodeBY1, layoutNodeBX2, layoutNodeBY2))
+ insertAt(0, LayoutNode(layoutNodeAX1, layoutNodeAY1, layoutNodeAX2, layoutNodeAY2))
+ insertAt(1, LayoutNode(layoutNodeBX1, layoutNodeBY1, layoutNodeBX2, layoutNodeBY2))
pointerInputHandler = spy(StubPointerInputHandler())
}
- compositionRoot.emitInsertAt(0, pointerInputNode)
+ compositionRoot.insertAt(0, pointerInputNode)
hitResult.addHitPath(PointerId(3), listOf(pointerInputNode))
@@ -3940,13 +3947,13 @@
// Arrange
val pointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(100, 200, 200, 300).apply {
- emitInsertAt(0, LayoutNode(-20, -40, -60, -80))
+ insertAt(0, LayoutNode(100, 200, 200, 300).apply {
+ insertAt(0, LayoutNode(-20, -40, -60, -80))
})
pointerInputHandler = spy(StubPointerInputHandler())
}
- compositionRoot.emitInsertAt(0, pointerInputNode)
+ compositionRoot.insertAt(0, pointerInputNode)
hitResult.addHitPath(PointerId(3), listOf(pointerInputNode))
diff --git a/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/PointerInputEventProcessor2Test.kt b/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/PointerInputEventProcessor2Test.kt
index f2b6a26..fdae0d7 100644
--- a/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/PointerInputEventProcessor2Test.kt
+++ b/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/PointerInputEventProcessor2Test.kt
@@ -103,7 +103,7 @@
)
)
- root.emitInsertAt(0, layoutNode)
+ root.insertAt(0, layoutNode)
val offset = PxPosition(100.px, 200.px)
val offset2 = PxPosition(300.px, 400.px)
@@ -168,7 +168,7 @@
)
)
- root.emitInsertAt(0, layoutNode)
+ root.insertAt(0, layoutNode)
val offsets = arrayOf(
PxPosition(100.px, 200.px),
@@ -229,7 +229,7 @@
)
)
- root.emitInsertAt(0, layoutNode)
+ root.insertAt(0, layoutNode)
val offsets = arrayOf(
PxPosition(99.px, 200.px),
@@ -293,7 +293,7 @@
TestPointerInputFilter(pointerInputHandler = middlePointerInputHandler)
)
).apply {
- emitInsertAt(0, childLayoutNode)
+ insertAt(0, childLayoutNode)
}
val parentLayoutNode: LayoutNode =
LayoutNode(
@@ -302,9 +302,9 @@
TestPointerInputFilter(pointerInputHandler = parentPointerInputHandler)
)
).apply {
- emitInsertAt(0, middleLayoutNode)
+ insertAt(0, middleLayoutNode)
}
- root.emitInsertAt(0, parentLayoutNode)
+ root.insertAt(0, parentLayoutNode)
val offset = when (numberOfChildrenHit) {
3 -> PxPosition(250.px, 250.px)
@@ -420,7 +420,7 @@
)
)
- root.emitInsertAt(0, layoutNode)
+ root.insertAt(0, layoutNode)
val down = PointerInputEvent(
0,
@@ -522,7 +522,7 @@
TestPointerInputFilter(pointerInputHandler = middlePointerInputHandler)
)
).apply {
- emitInsertAt(0, childLayoutNode)
+ insertAt(0, childLayoutNode)
}
val parentLayoutNode: LayoutNode = LayoutNode(
pX1, pY1, pX2, pY2,
@@ -530,12 +530,12 @@
TestPointerInputFilter(pointerInputHandler = parentPointerInputHandler)
)
).apply {
- emitInsertAt(0, middleLayoutNode)
+ insertAt(0, middleLayoutNode)
}
testOwner.position = IntPxPosition(aOX.ipx, aOY.ipx)
- root.emitInsertAt(0, parentLayoutNode)
+ root.insertAt(0, parentLayoutNode)
val additionalOffset = IntPxPosition(aOX.ipx, aOY.ipx)
@@ -646,8 +646,8 @@
)
)
root.apply {
- emitInsertAt(0, childLayoutNode1)
- emitInsertAt(0, childLayoutNode2)
+ insertAt(0, childLayoutNode1)
+ insertAt(0, childLayoutNode2)
}
val offset1 = PxPosition(25.px, 25.px)
@@ -753,9 +753,9 @@
)
root.apply {
- emitInsertAt(0, childLayoutNode1)
- emitInsertAt(1, childLayoutNode2)
- emitInsertAt(2, childLayoutNode3)
+ insertAt(0, childLayoutNode1)
+ insertAt(1, childLayoutNode2)
+ insertAt(2, childLayoutNode3)
}
val offset1 = PxPosition(25.px, 25.px)
@@ -860,8 +860,8 @@
)
root.apply {
- emitInsertAt(0, childLayoutNode1)
- emitInsertAt(1, childLayoutNode2)
+ insertAt(0, childLayoutNode1)
+ insertAt(1, childLayoutNode2)
}
val offset1 = PxPosition(50.px, 25.px)
@@ -962,8 +962,8 @@
)
root.apply {
- emitInsertAt(0, childLayoutNode1)
- emitInsertAt(1, childLayoutNode2)
+ insertAt(0, childLayoutNode1)
+ insertAt(1, childLayoutNode2)
}
val offset1 = PxPosition(25.px, 50.px)
@@ -1083,13 +1083,13 @@
)
val parentLayoutNode = LayoutNode(1, 1, 4, 4).apply {
- emitInsertAt(0, layoutNode1)
- emitInsertAt(1, layoutNode2)
- emitInsertAt(2, layoutNode3)
- emitInsertAt(3, layoutNode4)
+ insertAt(0, layoutNode1)
+ insertAt(1, layoutNode2)
+ insertAt(2, layoutNode3)
+ insertAt(3, layoutNode4)
}
root.apply {
- emitInsertAt(0, parentLayoutNode)
+ insertAt(0, parentLayoutNode)
}
val offsetsThatHit =
listOf(
@@ -1186,7 +1186,7 @@
)
)
root.apply {
- emitInsertAt(0, layoutNode)
+ insertAt(0, layoutNode)
}
val offsetsThatHit =
listOf(
@@ -1265,7 +1265,7 @@
)
root.apply {
- emitInsertAt(0, layoutNode)
+ insertAt(0, layoutNode)
}
val offset1 = PxPosition(50.px, 75.px)
@@ -1330,16 +1330,16 @@
)
)
val layoutNode2: LayoutNode = LayoutNode(2, 6, 500, 500).apply {
- emitInsertAt(0, layoutNode1)
+ insertAt(0, layoutNode1)
}
val layoutNode3: LayoutNode = LayoutNode(3, 7, 500, 500).apply {
- emitInsertAt(0, layoutNode2)
+ insertAt(0, layoutNode2)
}
val layoutNode4: LayoutNode = LayoutNode(4, 8, 500, 500).apply {
- emitInsertAt(0, layoutNode3)
+ insertAt(0, layoutNode3)
}
root.apply {
- emitInsertAt(0, layoutNode4)
+ insertAt(0, layoutNode4)
}
val offset1 = PxPosition(499.px, 499.px)
@@ -1396,7 +1396,7 @@
)
)
val layoutNode2: LayoutNode = LayoutNode(2, 7, 500, 500).apply {
- emitInsertAt(0, layoutNode1)
+ insertAt(0, layoutNode1)
}
val layoutNode3 =
LayoutNode(
@@ -1407,17 +1407,17 @@
TestPointerInputFilter(pointerInputHandler = pointerInputHandler4)
)
).apply {
- emitInsertAt(0, layoutNode2)
+ insertAt(0, layoutNode2)
}
val layoutNode4: LayoutNode = LayoutNode(4, 9, 500, 500).apply {
- emitInsertAt(0, layoutNode3)
+ insertAt(0, layoutNode3)
}
val layoutNode5: LayoutNode = LayoutNode(5, 10, 500, 500).apply {
- emitInsertAt(0, layoutNode4)
+ insertAt(0, layoutNode4)
}
root.apply {
- emitInsertAt(0, layoutNode5)
+ insertAt(0, layoutNode5)
}
val offset1 = PxPosition(499.px, 499.px)
@@ -1514,8 +1514,8 @@
)
root.apply {
- emitInsertAt(0, layoutNode1)
- emitInsertAt(1, layoutNode2)
+ insertAt(0, layoutNode1)
+ insertAt(1, layoutNode2)
}
val down = PointerInputEvent(
@@ -1544,7 +1544,7 @@
)
root.apply {
- emitInsertAt(0, layoutNode1)
+ insertAt(0, layoutNode1)
}
val down = PointerInputEvent(
@@ -1583,7 +1583,7 @@
)
)
- root.emitInsertAt(0, layoutNode)
+ root.insertAt(0, layoutNode)
val pointerInputEvent =
PointerInputEvent(
@@ -1646,7 +1646,7 @@
)
)
- root.emitInsertAt(0, layoutNode)
+ root.insertAt(0, layoutNode)
val pointerInputEvent1 =
PointerInputEvent(
@@ -1777,8 +1777,8 @@
)
)
- root.emitInsertAt(0, layoutNode1)
- root.emitInsertAt(1, layoutNode2)
+ root.insertAt(0, layoutNode1)
+ root.insertAt(1, layoutNode2)
val pointerInputEventData1 =
PointerInputEventData(
@@ -1877,7 +1877,7 @@
)
)
- root.emitInsertAt(0, layoutNode)
+ root.insertAt(0, layoutNode)
val down =
PointerInputEvent(
@@ -1971,7 +1971,7 @@
)
)
- root.emitInsertAt(0, layoutNode)
+ root.insertAt(0, layoutNode)
val down =
PointerInputEvent(
@@ -2033,7 +2033,7 @@
)
)
- root.emitInsertAt(0, layoutNode)
+ root.insertAt(0, layoutNode)
val down1 =
PointerInputEvent(
@@ -2130,10 +2130,10 @@
)
)
).apply {
- emitInsertAt(0, childLayoutNode)
+ insertAt(0, childLayoutNode)
}
- root.emitInsertAt(0, parentLayoutNode)
+ root.insertAt(0, parentLayoutNode)
val offset = PxPosition(50.px, 50.px)
@@ -2157,7 +2157,7 @@
// Act
pointerInputEventProcessor.process(down)
- parentLayoutNode.emitRemoveAt(0, 1)
+ parentLayoutNode.removeAt(0, 1)
pointerInputEventProcessor.process(up)
// Assert
@@ -2198,10 +2198,10 @@
)
)
).apply {
- emitInsertAt(0, childLayoutNode)
+ insertAt(0, childLayoutNode)
}
- root.emitInsertAt(0, parentLayoutNode)
+ root.insertAt(0, parentLayoutNode)
val down =
PointerInputEvent(0, Uptime.Boot + 7.milliseconds, PxPosition(50.px, 50.px), true)
@@ -2211,7 +2211,7 @@
// Act
pointerInputEventProcessor.process(down)
- parentLayoutNode.emitRemoveAt(0, 1)
+ parentLayoutNode.removeAt(0, 1)
pointerInputEventProcessor.process(up)
// Assert
@@ -2243,10 +2243,10 @@
)
)
).apply {
- emitInsertAt(0, childLayoutNode)
+ insertAt(0, childLayoutNode)
}
- root.emitInsertAt(0, parentLayoutNode)
+ root.insertAt(0, parentLayoutNode)
val offset = PxPosition(50.px, 50.px)
@@ -2311,10 +2311,10 @@
)
)
).apply {
- emitInsertAt(0, childLayoutNode)
+ insertAt(0, childLayoutNode)
}
- root.emitInsertAt(0, parentLayoutNode)
+ root.insertAt(0, parentLayoutNode)
val down =
PointerInputEvent(0, Uptime.Boot + 7.milliseconds, PxPosition(50.px, 50.px), true)
diff --git a/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/PointerInputEventProcessorTest.kt b/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/PointerInputEventProcessorTest.kt
index 706ff84..5291c35 100644
--- a/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/PointerInputEventProcessorTest.kt
+++ b/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/PointerInputEventProcessorTest.kt
@@ -99,10 +99,10 @@
// Arrange
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(0, 0, 500, 500))
+ insertAt(0, LayoutNode(0, 0, 500, 500))
pointerInputHandler = spy(StubPointerInputHandler())
}
- root.emitInsertAt(0, pointerInputNode)
+ root.insertAt(0, pointerInputNode)
val offset = PxPosition(100.px, 200.px)
val offset2 = PxPosition(300.px, 400.px)
@@ -160,10 +160,10 @@
val childOffset = PxPosition(100.px, 200.px)
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(100, 200, 301, 401))
+ insertAt(0, LayoutNode(100, 200, 301, 401))
pointerInputHandler = spy(StubPointerInputHandler())
}
- root.emitInsertAt(0, pointerInputNode)
+ root.insertAt(0, pointerInputNode)
val offsets = arrayOf(
PxPosition(100.px, 200.px),
@@ -217,10 +217,10 @@
// Arrange
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(100, 200, 301, 401))
+ insertAt(0, LayoutNode(100, 200, 301, 401))
pointerInputHandler = spy(StubPointerInputHandler())
}
- root.emitInsertAt(0, pointerInputNode)
+ root.insertAt(0, pointerInputNode)
val offsets = arrayOf(
PxPosition(99.px, 200.px),
@@ -268,24 +268,24 @@
val childLayoutNode = LayoutNode(100, 100, 200, 200)
val childPointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, childLayoutNode)
+ insertAt(0, childLayoutNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
val middleLayoutNode: LayoutNode = LayoutNode(100, 100, 400, 400).apply {
- emitInsertAt(0, childPointerInputNode)
+ insertAt(0, childPointerInputNode)
}
val middlePointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, middleLayoutNode)
+ insertAt(0, middleLayoutNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
val parentLayoutNode: LayoutNode = LayoutNode(0, 0, 500, 500).apply {
- emitInsertAt(0, middlePointerInputNode)
+ insertAt(0, middlePointerInputNode)
}
val parentPointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, parentLayoutNode)
+ insertAt(0, parentLayoutNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
- root.emitInsertAt(0, parentPointerInputNode)
+ root.insertAt(0, parentPointerInputNode)
val offset = when (numberOfChildrenHit) {
3 -> PxPosition(250.px, 250.px)
@@ -385,7 +385,7 @@
)
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(0, 0, 500, 500))
+ insertAt(0, LayoutNode(0, 0, 500, 500))
pointerInputHandler = spy(StubPointerInputHandler())
whenever(
pointerInputHandler.invoke(
@@ -400,7 +400,7 @@
)
)
}
- root.emitInsertAt(0, pointerInputNode)
+ root.insertAt(0, pointerInputNode)
val down = PointerInputEvent(
0,
@@ -486,25 +486,25 @@
val childOffset = PxPosition(cX1.px, cY1.px)
val childLayoutNode = LayoutNode(cX1, cY1, cX2, cY2)
val childPointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, childLayoutNode)
+ insertAt(0, childLayoutNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
val middleOffset = PxPosition(mX1.px, mY1.px)
val middleLayoutNode: LayoutNode = LayoutNode(mX1, mY1, mX2, mY2).apply {
- emitInsertAt(0, childPointerInputNode)
+ insertAt(0, childPointerInputNode)
}
val middlePointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, middleLayoutNode)
+ insertAt(0, middleLayoutNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
val parentLayoutNode: LayoutNode = LayoutNode(pX1, pY1, pX2, pY2).apply {
- emitInsertAt(0, middlePointerInputNode)
+ insertAt(0, middlePointerInputNode)
}
val parentPointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, parentLayoutNode)
+ insertAt(0, parentLayoutNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
- root.emitInsertAt(0, parentPointerInputNode)
+ root.insertAt(0, parentPointerInputNode)
val additionalOffset = IntPxPosition(aOX.ipx, aOY.ipx)
@@ -598,16 +598,16 @@
// Arrange
val childPointerInputNode1: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(0, 0, 50, 50))
+ insertAt(0, LayoutNode(0, 0, 50, 50))
pointerInputHandler = spy(StubPointerInputHandler())
}
val childPointerInputNode2: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(50, 50, 100, 100))
+ insertAt(0, LayoutNode(50, 50, 100, 100))
pointerInputHandler = spy(StubPointerInputHandler())
}
root.apply {
- emitInsertAt(0, childPointerInputNode1)
- emitInsertAt(0, childPointerInputNode2)
+ insertAt(0, childPointerInputNode1)
+ insertAt(0, childPointerInputNode2)
}
val offset1 = PxPosition(25.px, 25.px)
@@ -689,21 +689,21 @@
@Test
fun process_3DownOnOverlappingPointerNodes_hitAndDispatchInfoAreCorrect() {
val childPointerInputNode1: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(0, 0, 100, 100))
+ insertAt(0, LayoutNode(0, 0, 100, 100))
pointerInputHandler = spy(StubPointerInputHandler())
}
val childPointerInputNode2: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(50, 50, 150, 150))
+ insertAt(0, LayoutNode(50, 50, 150, 150))
pointerInputHandler = spy(StubPointerInputHandler())
}
val childPointerInputNode3: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(100, 100, 200, 200))
+ insertAt(0, LayoutNode(100, 100, 200, 200))
pointerInputHandler = spy(StubPointerInputHandler())
}
root.apply {
- emitInsertAt(0, childPointerInputNode1)
- emitInsertAt(1, childPointerInputNode2)
- emitInsertAt(2, childPointerInputNode3)
+ insertAt(0, childPointerInputNode1)
+ insertAt(1, childPointerInputNode2)
+ insertAt(2, childPointerInputNode3)
}
val offset1 = PxPosition(25.px, 25.px)
@@ -791,16 +791,16 @@
@Test
fun process_3DownOnFloatingPointerNodeV_hitAndDispatchInfoAreCorrect() {
val childPointerInputNode1: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(0, 0, 100, 150))
+ insertAt(0, LayoutNode(0, 0, 100, 150))
pointerInputHandler = spy(StubPointerInputHandler())
}
val childPointerInputNode2: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(25, 50, 75, 100))
+ insertAt(0, LayoutNode(25, 50, 75, 100))
pointerInputHandler = spy(StubPointerInputHandler())
}
root.apply {
- emitInsertAt(0, childPointerInputNode1)
- emitInsertAt(1, childPointerInputNode2)
+ insertAt(0, childPointerInputNode1)
+ insertAt(1, childPointerInputNode2)
}
val offset1 = PxPosition(50.px, 25.px)
@@ -885,16 +885,16 @@
@Test
fun process_3DownOnFloatingPointerNodeH_hitAndDispatchInfoAreCorrect() {
val childPointerInputNode1: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(0, 0, 150, 100))
+ insertAt(0, LayoutNode(0, 0, 150, 100))
pointerInputHandler = spy(StubPointerInputHandler())
}
val childPointerInputNode2: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(50, 25, 100, 75))
+ insertAt(0, LayoutNode(50, 25, 100, 75))
pointerInputHandler = spy(StubPointerInputHandler())
}
root.apply {
- emitInsertAt(0, childPointerInputNode1)
- emitInsertAt(1, childPointerInputNode2)
+ insertAt(0, childPointerInputNode1)
+ insertAt(1, childPointerInputNode2)
}
val offset1 = PxPosition(25.px, 50.px)
@@ -986,12 +986,12 @@
// Arrange
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(100, 100, 200, 200))
- emitInsertAt(1, LayoutNode(300, 300, 400, 400))
+ insertAt(0, LayoutNode(100, 100, 200, 200))
+ insertAt(1, LayoutNode(300, 300, 400, 400))
pointerInputHandler = spy(StubPointerInputHandler())
}
root.apply {
- emitInsertAt(0, pointerInputNode)
+ insertAt(0, pointerInputNode)
}
val offsetsThatHit =
listOf(
@@ -1083,12 +1083,12 @@
// Arrange
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(300, 100, 400, 200))
- emitInsertAt(1, LayoutNode(100, 300, 200, 400))
+ insertAt(0, LayoutNode(300, 100, 400, 200))
+ insertAt(1, LayoutNode(100, 300, 200, 400))
pointerInputHandler = spy(StubPointerInputHandler())
}
root.apply {
- emitInsertAt(0, pointerInputNode)
+ insertAt(0, pointerInputNode)
}
val offsetsThatHit =
listOf(
@@ -1182,29 +1182,29 @@
val singlePointerInputHandler = spy(StubPointerInputHandler())
val pointerInputNode1 = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(-1, -1, 1, 1))
+ insertAt(0, LayoutNode(-1, -1, 1, 1))
pointerInputHandler = singlePointerInputHandler
}
val pointerInputNode2 = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(2, -1, 4, 1))
+ insertAt(0, LayoutNode(2, -1, 4, 1))
pointerInputHandler = singlePointerInputHandler
}
val pointerInputNode3 = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(-1, 2, 1, 4))
+ insertAt(0, LayoutNode(-1, 2, 1, 4))
pointerInputHandler = singlePointerInputHandler
}
val pointerInputNode4 = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(2, 2, 4, 4))
+ insertAt(0, LayoutNode(2, 2, 4, 4))
pointerInputHandler = singlePointerInputHandler
}
val parentLayoutNode = LayoutNode(1, 1, 4, 4).apply {
- emitInsertAt(0, pointerInputNode1)
- emitInsertAt(1, pointerInputNode2)
- emitInsertAt(2, pointerInputNode3)
- emitInsertAt(3, pointerInputNode4)
+ insertAt(0, pointerInputNode1)
+ insertAt(1, pointerInputNode2)
+ insertAt(2, pointerInputNode3)
+ insertAt(3, pointerInputNode4)
}
root.apply {
- emitInsertAt(0, parentLayoutNode)
+ insertAt(0, parentLayoutNode)
}
val offsetsThatHit =
listOf(
@@ -1299,15 +1299,15 @@
// Arrange
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(350, -50, 400, 0))
- emitInsertAt(1, LayoutNode(-50, 350, 0, 400))
+ insertAt(0, LayoutNode(350, -50, 400, 0))
+ insertAt(1, LayoutNode(-50, 350, 0, 400))
pointerInputHandler = spy(StubPointerInputHandler())
}
val layoutNode: LayoutNode = LayoutNode(100, 100, 400, 400).apply {
- emitInsertAt(0, pointerInputNode)
+ insertAt(0, pointerInputNode)
}
root.apply {
- emitInsertAt(0, layoutNode)
+ insertAt(0, layoutNode)
}
val offsetsThatHit =
listOf(
@@ -1394,12 +1394,12 @@
// Arrange
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(400, 100, 400, 100))
- emitInsertAt(1, LayoutNode(100, 400, 100, 400))
+ insertAt(0, LayoutNode(400, 100, 400, 100))
+ insertAt(1, LayoutNode(100, 400, 100, 400))
pointerInputHandler = spy(StubPointerInputHandler())
}
root.apply {
- emitInsertAt(0, pointerInputNode)
+ insertAt(0, pointerInputNode)
}
val offsetsThatHit =
listOf(
@@ -1490,11 +1490,11 @@
// Arrange
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(0, 0, 2, 2))
+ insertAt(0, LayoutNode(0, 0, 2, 2))
pointerInputHandler = spy(StubPointerInputHandler())
}
root.apply {
- emitInsertAt(0, pointerInputNode)
+ insertAt(0, pointerInputNode)
}
val offsetsThatHit =
listOf(
@@ -1551,19 +1551,19 @@
@Test
fun process_downOn3NestedPointerInputNodes_hitAndDispatchInfoAreCorrect() {
val childPointerInputNode1: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(25, 50, 75, 100))
+ insertAt(0, LayoutNode(25, 50, 75, 100))
pointerInputHandler = spy(StubPointerInputHandler())
}
val childPointerInputNode2: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, childPointerInputNode1)
+ insertAt(0, childPointerInputNode1)
pointerInputHandler = spy(StubPointerInputHandler())
}
val childPointerInputNode3: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, childPointerInputNode2)
+ insertAt(0, childPointerInputNode2)
pointerInputHandler = spy(StubPointerInputHandler())
}
root.apply {
- emitInsertAt(0, childPointerInputNode3)
+ insertAt(0, childPointerInputNode3)
}
val offset1 = PxPosition(50.px, 75.px)
@@ -1621,20 +1621,20 @@
fun process_downOnDeeplyNestedPointerInputNode_hitAndDispatchInfoAreCorrect() {
val layoutNode1 = LayoutNode(1, 5, 500, 500)
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, layoutNode1)
+ insertAt(0, layoutNode1)
pointerInputHandler = spy(StubPointerInputHandler())
}
val layoutNode2: LayoutNode = LayoutNode(2, 6, 500, 500).apply {
- emitInsertAt(0, pointerInputNode)
+ insertAt(0, pointerInputNode)
}
val layoutNode3: LayoutNode = LayoutNode(3, 7, 500, 500).apply {
- emitInsertAt(0, layoutNode2)
+ insertAt(0, layoutNode2)
}
val layoutNode4: LayoutNode = LayoutNode(4, 8, 500, 500).apply {
- emitInsertAt(0, layoutNode3)
+ insertAt(0, layoutNode3)
}
root.apply {
- emitInsertAt(0, layoutNode4)
+ insertAt(0, layoutNode4)
}
val offset1 = PxPosition(499.px, 499.px)
@@ -1678,35 +1678,35 @@
fun process_downOnComplexPointerAndLayoutNodePath_hitAndDispatchInfoAreCorrect() {
val layoutNode1 = LayoutNode(1, 6, 500, 500)
val pointerInputNode1: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, layoutNode1)
+ insertAt(0, layoutNode1)
pointerInputHandler = spy(StubPointerInputHandler())
}
val pointerInputNode2: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, pointerInputNode1)
+ insertAt(0, pointerInputNode1)
pointerInputHandler = spy(StubPointerInputHandler())
}
val layoutNode2: LayoutNode = LayoutNode(2, 7, 500, 500).apply {
- emitInsertAt(0, pointerInputNode2)
+ insertAt(0, pointerInputNode2)
}
val layoutNode3: LayoutNode = LayoutNode(3, 8, 500, 500).apply {
- emitInsertAt(0, layoutNode2)
+ insertAt(0, layoutNode2)
}
val pointerInputNode3: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, layoutNode3)
+ insertAt(0, layoutNode3)
pointerInputHandler = spy(StubPointerInputHandler())
}
val pointerInputNode4: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, pointerInputNode3)
+ insertAt(0, pointerInputNode3)
pointerInputHandler = spy(StubPointerInputHandler())
}
val layoutNode4: LayoutNode = LayoutNode(4, 9, 500, 500).apply {
- emitInsertAt(0, pointerInputNode4)
+ insertAt(0, pointerInputNode4)
}
val layoutNode5: LayoutNode = LayoutNode(5, 10, 500, 500).apply {
- emitInsertAt(0, layoutNode4)
+ insertAt(0, layoutNode4)
}
root.apply {
- emitInsertAt(0, layoutNode5)
+ insertAt(0, layoutNode5)
}
val offset1 = PxPosition(499.px, 499.px)
@@ -1784,16 +1784,16 @@
@Test
fun process_downOnCompletelyOverlappingPointerInputNodes_onlyTopPointerInputNodeReceives() {
val childPointerInputNode1: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(0, 0, 100, 100))
+ insertAt(0, LayoutNode(0, 0, 100, 100))
pointerInputHandler = spy(StubPointerInputHandler())
}
val childPointerInputNode2: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(0, 0, 100, 100))
+ insertAt(0, LayoutNode(0, 0, 100, 100))
pointerInputHandler = spy(StubPointerInputHandler())
}
root.apply {
- emitInsertAt(0, childPointerInputNode1)
- emitInsertAt(1, childPointerInputNode2)
+ insertAt(0, childPointerInputNode1)
+ insertAt(1, childPointerInputNode2)
}
val down = PointerInputEvent(
@@ -1816,14 +1816,14 @@
1,
SemanticsConfiguration()
).apply {
- emitInsertAt(0, LayoutNode(0, 0, 100, 100))
+ insertAt(0, LayoutNode(0, 0, 100, 100))
}
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, semanticsComponentNode)
+ insertAt(0, semanticsComponentNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
root.apply {
- emitInsertAt(0, pointerInputNode)
+ insertAt(0, pointerInputNode)
}
val down = PointerInputEvent(
@@ -1841,11 +1841,11 @@
@Test
fun process_downOnPointerInputNodeWrappingDrawNode_downNotReceived() {
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, DrawNode())
+ insertAt(0, DrawNode())
pointerInputHandler = spy(StubPointerInputHandler())
}
root.apply {
- emitInsertAt(0, pointerInputNode)
+ insertAt(0, pointerInputNode)
}
val down = PointerInputEvent(
@@ -1863,14 +1863,14 @@
@Test
fun process_downOnPointerInputNodeWrappingSemanticsNode_downNotReceived() {
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(
+ insertAt(
0,
SemanticsComponentNode(1, SemanticsConfiguration())
)
pointerInputHandler = spy(StubPointerInputHandler())
}
root.apply {
- emitInsertAt(0, pointerInputNode)
+ insertAt(0, pointerInputNode)
}
val down = PointerInputEvent(
@@ -1888,11 +1888,11 @@
@Test
fun process_downOnPointerInputNodeWrappingPointerInputNodeNode_downNotReceived() {
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, PointerInputNode())
+ insertAt(0, PointerInputNode())
pointerInputHandler = spy(StubPointerInputHandler())
}
root.apply {
- emitInsertAt(0, pointerInputNode)
+ insertAt(0, pointerInputNode)
}
val down = PointerInputEvent(
@@ -1918,11 +1918,11 @@
// Arrange
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(0, 0, 500, 500))
+ insertAt(0, LayoutNode(0, 0, 500, 500))
pointerInputHandler = spy(StubPointerInputHandler())
cancelHandler = spy(StubCancelHandler())
}
- root.emitInsertAt(0, pointerInputNode)
+ root.insertAt(0, pointerInputNode)
val pointerInputEvent =
PointerInputEvent(
@@ -1973,11 +1973,11 @@
// Arrange
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(0, 0, 500, 500))
+ insertAt(0, LayoutNode(0, 0, 500, 500))
pointerInputHandler = spy(StubPointerInputHandler())
cancelHandler = spy(StubCancelHandler())
}
- root.emitInsertAt(0, pointerInputNode)
+ root.insertAt(0, pointerInputNode)
val pointerInputEvent1 =
PointerInputEvent(
@@ -2085,17 +2085,17 @@
// Arrange
val pointerInputNode1: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(0, 0, 199, 199))
+ insertAt(0, LayoutNode(0, 0, 199, 199))
pointerInputHandler = spy(StubPointerInputHandler())
cancelHandler = spy(StubCancelHandler())
}
val pointerInputNode2: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(200, 200, 399, 399))
+ insertAt(0, LayoutNode(200, 200, 399, 399))
pointerInputHandler = spy(StubPointerInputHandler())
cancelHandler = spy(StubCancelHandler())
}
- root.emitInsertAt(0, pointerInputNode1)
- root.emitInsertAt(1, pointerInputNode2)
+ root.insertAt(0, pointerInputNode1)
+ root.insertAt(1, pointerInputNode2)
val pointerInputEventData1 =
PointerInputEventData(
@@ -2183,11 +2183,11 @@
// Arrange
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(0, 0, 500, 500))
+ insertAt(0, LayoutNode(0, 0, 500, 500))
pointerInputHandler = spy(StubPointerInputHandler())
cancelHandler = spy(StubCancelHandler())
}
- root.emitInsertAt(0, pointerInputNode)
+ root.insertAt(0, pointerInputNode)
val down =
PointerInputEvent(
@@ -2270,11 +2270,11 @@
// Arrange
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(0, 0, 500, 500))
+ insertAt(0, LayoutNode(0, 0, 500, 500))
pointerInputHandler = spy(StubPointerInputHandler())
cancelHandler = spy(StubCancelHandler())
}
- root.emitInsertAt(0, pointerInputNode)
+ root.insertAt(0, pointerInputNode)
val down =
PointerInputEvent(
@@ -2325,11 +2325,11 @@
// Arrange
val pointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, LayoutNode(0, 0, 500, 500))
+ insertAt(0, LayoutNode(0, 0, 500, 500))
pointerInputHandler = spy(StubPointerInputHandler())
cancelHandler = spy(StubCancelHandler())
}
- root.emitInsertAt(0, pointerInputNode)
+ root.insertAt(0, pointerInputNode)
val down1 =
PointerInputEvent(
@@ -2409,17 +2409,17 @@
val childLayoutNode = LayoutNode(0, 0, 100, 100)
val childPointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, childLayoutNode)
+ insertAt(0, childLayoutNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
val parentLayoutNode: LayoutNode = LayoutNode(0, 0, 100, 100).apply {
- emitInsertAt(0, childPointerInputNode)
+ insertAt(0, childPointerInputNode)
}
val parentPointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, parentLayoutNode)
+ insertAt(0, parentLayoutNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
- root.emitInsertAt(0, parentPointerInputNode)
+ root.insertAt(0, parentPointerInputNode)
val offset = PxPosition(50.px, 50.px)
@@ -2443,7 +2443,7 @@
// Act
pointerInputEventProcessor.process(down, IntPxPosition.Origin)
- parentLayoutNode.emitRemoveAt(0, 1)
+ parentLayoutNode.removeAt(0, 1)
pointerInputEventProcessor.process(up, IntPxPosition.Origin)
// Assert
@@ -2467,17 +2467,17 @@
val childLayoutNode = LayoutNode(0, 0, 100, 100)
val childPointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, childLayoutNode)
+ insertAt(0, childLayoutNode)
cancelHandler = spy(StubCancelHandler())
}
val parentLayoutNode: LayoutNode = LayoutNode(0, 0, 100, 100).apply {
- emitInsertAt(0, childPointerInputNode)
+ insertAt(0, childPointerInputNode)
}
val parentPointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, parentLayoutNode)
+ insertAt(0, parentLayoutNode)
cancelHandler = spy(StubCancelHandler())
}
- root.emitInsertAt(0, parentPointerInputNode)
+ root.insertAt(0, parentPointerInputNode)
val down =
PointerInputEvent(0, Uptime.Boot + 7.milliseconds, PxPosition(50.px, 50.px), true)
@@ -2487,7 +2487,7 @@
// Act
pointerInputEventProcessor.process(down, IntPxPosition.Origin)
- parentLayoutNode.emitRemoveAt(0, 1)
+ parentLayoutNode.removeAt(0, 1)
pointerInputEventProcessor.process(up, IntPxPosition.Origin)
// Assert
@@ -2502,17 +2502,17 @@
val childLayoutNode = LayoutNode(0, 0, 100, 100)
val childPointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, childLayoutNode)
+ insertAt(0, childLayoutNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
val parentLayoutNode: LayoutNode = LayoutNode(0, 0, 100, 100).apply {
- emitInsertAt(0, childPointerInputNode)
+ insertAt(0, childPointerInputNode)
}
val parentPointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, parentLayoutNode)
+ insertAt(0, parentLayoutNode)
pointerInputHandler = spy(StubPointerInputHandler())
}
- root.emitInsertAt(0, parentPointerInputNode)
+ root.insertAt(0, parentPointerInputNode)
val offset = PxPosition(50.px, 50.px)
@@ -2536,7 +2536,7 @@
// Act
pointerInputEventProcessor.process(down, IntPxPosition.Origin)
- childPointerInputNode.emitRemoveAt(0, 1)
+ childPointerInputNode.removeAt(0, 1)
pointerInputEventProcessor.process(up, IntPxPosition.Origin)
// Assert
@@ -2560,17 +2560,17 @@
val childLayoutNode = LayoutNode(0, 0, 100, 100)
val childPointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, childLayoutNode)
+ insertAt(0, childLayoutNode)
cancelHandler = spy(StubCancelHandler())
}
val parentLayoutNode: LayoutNode = LayoutNode(0, 0, 100, 100).apply {
- emitInsertAt(0, childPointerInputNode)
+ insertAt(0, childPointerInputNode)
}
val parentPointerInputNode: PointerInputNode = PointerInputNode().apply {
- emitInsertAt(0, parentLayoutNode)
+ insertAt(0, parentLayoutNode)
cancelHandler = spy(StubCancelHandler())
}
- root.emitInsertAt(0, parentPointerInputNode)
+ root.insertAt(0, parentPointerInputNode)
val down =
PointerInputEvent(0, Uptime.Boot + 7.milliseconds, PxPosition(50.px, 50.px), true)
@@ -2580,7 +2580,7 @@
// Act
pointerInputEventProcessor.process(down, IntPxPosition.Origin)
- childPointerInputNode.emitRemoveAt(0, 1)
+ childPointerInputNode.removeAt(0, 1)
pointerInputEventProcessor.process(up, IntPxPosition.Origin)
// Assert
diff --git a/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/TestUtils.kt b/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/TestUtils.kt
index da05de8..7b40f7c 100644
--- a/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/TestUtils.kt
+++ b/ui/ui-platform/src/test/java/androidx/ui/core/pointerinput/TestUtils.kt
@@ -17,10 +17,10 @@
package androidx.ui.core.pointerinput
import androidx.ui.core.AlignmentLine
+import androidx.ui.core.LayoutDirection
import androidx.ui.core.LayoutNode
import androidx.ui.core.MeasureScope
import androidx.ui.core.Modifier
-import androidx.ui.core.Placeable
import androidx.ui.core.PointerEventPass
import androidx.ui.core.PointerId
import androidx.ui.core.PointerInputChange
@@ -74,7 +74,7 @@
override val width: IntPx = width
override val height: IntPx = height
override val alignmentLines: Map<AlignmentLine, IntPx> = emptyMap()
- override fun placeChildren(placementScope: Placeable.PlacementScope) {}
+ override fun placeChildren(layoutDirection: LayoutDirection) {}
}
)
}
diff --git a/ui/ui-test/api/0.1.0-dev07.txt b/ui/ui-test/api/0.1.0-dev07.txt
index 74bc0ae..481e266 100644
--- a/ui/ui-test/api/0.1.0-dev07.txt
+++ b/ui/ui-test/api/0.1.0-dev07.txt
@@ -9,6 +9,18 @@
method public static androidx.ui.test.SemanticsNodeInteraction doScrollTo(androidx.ui.test.SemanticsNodeInteraction);
}
+ public final class AnimationClockTestRule implements org.junit.rules.TestRule {
+ ctor public AnimationClockTestRule();
+ method public void advanceClock(long milliseconds);
+ method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
+ method public androidx.ui.test.TestAnimationClock getClock();
+ method public boolean isPaused();
+ method public void pauseClock();
+ method public void resumeClock();
+ property public final androidx.ui.test.TestAnimationClock clock;
+ property public final boolean isPaused;
+ }
+
public final class AssertionsKt {
method public static androidx.ui.test.SemanticsNodeInteraction assert(androidx.ui.test.SemanticsNodeInteraction, androidx.ui.test.SemanticsPredicate predicate);
method public static <T extends java.util.Collection<? extends androidx.ui.test.SemanticsNodeInteraction>> T assertCountEquals(T, int expectedSize);
@@ -104,11 +116,13 @@
method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
+ method public androidx.ui.test.AnimationClockTestRule getClockTestRule();
method public androidx.ui.unit.Density getDensity();
method public android.util.DisplayMetrics getDisplayMetrics();
method public <T> T! runOnIdleCompose(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);
+ property public abstract androidx.ui.test.AnimationClockTestRule clockTestRule;
property public abstract androidx.ui.unit.Density density;
property public abstract android.util.DisplayMetrics displayMetrics;
}
@@ -238,6 +252,16 @@
method public static androidx.ui.unit.PxSize setContentAndGetPixelSize(androidx.ui.test.ComposeTestRule, androidx.ui.layout.DpConstraints parentConstraints = BigTestConstraints, kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> performSetContent = { setContent(it) }, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
+ public interface TestAnimationClock extends androidx.animation.AnimationClockObservable {
+ method public void advanceClock(long milliseconds);
+ method public boolean isIdle();
+ method public boolean isPaused();
+ method public void pauseClock();
+ method public void resumeClock();
+ property public abstract boolean isIdle;
+ property public abstract boolean isPaused;
+ }
+
}
package androidx.ui.test.android {
@@ -258,12 +282,14 @@
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.test.rule.ActivityTestRule<T> getActivityTestRule();
+ method public androidx.ui.test.AnimationClockTestRule getClockTestRule();
method public androidx.ui.unit.Density getDensity();
method public android.util.DisplayMetrics getDisplayMetrics();
method public <T> T! runOnIdleCompose(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);
property public final androidx.test.rule.ActivityTestRule<T> activityTestRule;
+ property public androidx.ui.test.AnimationClockTestRule clockTestRule;
property public androidx.ui.unit.Density density;
property public android.util.DisplayMetrics displayMetrics;
}
@@ -282,6 +308,9 @@
method public static void unregisterComposeFromEspresso();
}
+ public final class InternalUtilsKt {
+ }
+
public final class WindowCaptureKt {
}
diff --git a/ui/ui-test/api/api_lint.ignore b/ui/ui-test/api/api_lint.ignore
index b747788..df3feb1 100644
--- a/ui/ui-test/api/api_lint.ignore
+++ b/ui/ui-test/api/api_lint.ignore
@@ -1,5 +1,3 @@
// Baseline format: 1.0
-DocumentExceptions: androidx.ui.test.AssertionsKt#assertCountEquals(java.util.List<androidx.ui.test.SemanticsNodeInteraction>, int):
- Method AssertionsKt.assertCountEquals appears to be throwing java.lang.AssertionError; this should be listed in the documentation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
DocumentExceptions: androidx.ui.test.GoldenSemanticsKt#assertEquals(androidx.ui.core.semantics.SemanticsConfiguration, androidx.ui.core.semantics.SemanticsConfiguration):
Method GoldenSemanticsKt.assertEquals appears to be throwing java.lang.AssertionError; this should be listed in the documentation; see https://android.github.io/kotlin-guides/interop.html#document-exceptions
diff --git a/ui/ui-test/api/current.txt b/ui/ui-test/api/current.txt
index 74bc0ae..481e266 100644
--- a/ui/ui-test/api/current.txt
+++ b/ui/ui-test/api/current.txt
@@ -9,6 +9,18 @@
method public static androidx.ui.test.SemanticsNodeInteraction doScrollTo(androidx.ui.test.SemanticsNodeInteraction);
}
+ public final class AnimationClockTestRule implements org.junit.rules.TestRule {
+ ctor public AnimationClockTestRule();
+ method public void advanceClock(long milliseconds);
+ method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
+ method public androidx.ui.test.TestAnimationClock getClock();
+ method public boolean isPaused();
+ method public void pauseClock();
+ method public void resumeClock();
+ property public final androidx.ui.test.TestAnimationClock clock;
+ property public final boolean isPaused;
+ }
+
public final class AssertionsKt {
method public static androidx.ui.test.SemanticsNodeInteraction assert(androidx.ui.test.SemanticsNodeInteraction, androidx.ui.test.SemanticsPredicate predicate);
method public static <T extends java.util.Collection<? extends androidx.ui.test.SemanticsNodeInteraction>> T assertCountEquals(T, int expectedSize);
@@ -104,11 +116,13 @@
method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
+ method public androidx.ui.test.AnimationClockTestRule getClockTestRule();
method public androidx.ui.unit.Density getDensity();
method public android.util.DisplayMetrics getDisplayMetrics();
method public <T> T! runOnIdleCompose(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);
+ property public abstract androidx.ui.test.AnimationClockTestRule clockTestRule;
property public abstract androidx.ui.unit.Density density;
property public abstract android.util.DisplayMetrics displayMetrics;
}
@@ -238,6 +252,16 @@
method public static androidx.ui.unit.PxSize setContentAndGetPixelSize(androidx.ui.test.ComposeTestRule, androidx.ui.layout.DpConstraints parentConstraints = BigTestConstraints, kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> performSetContent = { setContent(it) }, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
+ public interface TestAnimationClock extends androidx.animation.AnimationClockObservable {
+ method public void advanceClock(long milliseconds);
+ method public boolean isIdle();
+ method public boolean isPaused();
+ method public void pauseClock();
+ method public void resumeClock();
+ property public abstract boolean isIdle;
+ property public abstract boolean isPaused;
+ }
+
}
package androidx.ui.test.android {
@@ -258,12 +282,14 @@
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.test.rule.ActivityTestRule<T> getActivityTestRule();
+ method public androidx.ui.test.AnimationClockTestRule getClockTestRule();
method public androidx.ui.unit.Density getDensity();
method public android.util.DisplayMetrics getDisplayMetrics();
method public <T> T! runOnIdleCompose(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);
property public final androidx.test.rule.ActivityTestRule<T> activityTestRule;
+ property public androidx.ui.test.AnimationClockTestRule clockTestRule;
property public androidx.ui.unit.Density density;
property public android.util.DisplayMetrics displayMetrics;
}
@@ -282,6 +308,9 @@
method public static void unregisterComposeFromEspresso();
}
+ public final class InternalUtilsKt {
+ }
+
public final class WindowCaptureKt {
}
diff --git a/ui/ui-test/api/public_plus_experimental_0.1.0-dev07.txt b/ui/ui-test/api/public_plus_experimental_0.1.0-dev07.txt
index 74bc0ae..481e266 100644
--- a/ui/ui-test/api/public_plus_experimental_0.1.0-dev07.txt
+++ b/ui/ui-test/api/public_plus_experimental_0.1.0-dev07.txt
@@ -9,6 +9,18 @@
method public static androidx.ui.test.SemanticsNodeInteraction doScrollTo(androidx.ui.test.SemanticsNodeInteraction);
}
+ public final class AnimationClockTestRule implements org.junit.rules.TestRule {
+ ctor public AnimationClockTestRule();
+ method public void advanceClock(long milliseconds);
+ method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
+ method public androidx.ui.test.TestAnimationClock getClock();
+ method public boolean isPaused();
+ method public void pauseClock();
+ method public void resumeClock();
+ property public final androidx.ui.test.TestAnimationClock clock;
+ property public final boolean isPaused;
+ }
+
public final class AssertionsKt {
method public static androidx.ui.test.SemanticsNodeInteraction assert(androidx.ui.test.SemanticsNodeInteraction, androidx.ui.test.SemanticsPredicate predicate);
method public static <T extends java.util.Collection<? extends androidx.ui.test.SemanticsNodeInteraction>> T assertCountEquals(T, int expectedSize);
@@ -104,11 +116,13 @@
method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
+ method public androidx.ui.test.AnimationClockTestRule getClockTestRule();
method public androidx.ui.unit.Density getDensity();
method public android.util.DisplayMetrics getDisplayMetrics();
method public <T> T! runOnIdleCompose(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);
+ property public abstract androidx.ui.test.AnimationClockTestRule clockTestRule;
property public abstract androidx.ui.unit.Density density;
property public abstract android.util.DisplayMetrics displayMetrics;
}
@@ -238,6 +252,16 @@
method public static androidx.ui.unit.PxSize setContentAndGetPixelSize(androidx.ui.test.ComposeTestRule, androidx.ui.layout.DpConstraints parentConstraints = BigTestConstraints, kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> performSetContent = { setContent(it) }, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
+ public interface TestAnimationClock extends androidx.animation.AnimationClockObservable {
+ method public void advanceClock(long milliseconds);
+ method public boolean isIdle();
+ method public boolean isPaused();
+ method public void pauseClock();
+ method public void resumeClock();
+ property public abstract boolean isIdle;
+ property public abstract boolean isPaused;
+ }
+
}
package androidx.ui.test.android {
@@ -258,12 +282,14 @@
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.test.rule.ActivityTestRule<T> getActivityTestRule();
+ method public androidx.ui.test.AnimationClockTestRule getClockTestRule();
method public androidx.ui.unit.Density getDensity();
method public android.util.DisplayMetrics getDisplayMetrics();
method public <T> T! runOnIdleCompose(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);
property public final androidx.test.rule.ActivityTestRule<T> activityTestRule;
+ property public androidx.ui.test.AnimationClockTestRule clockTestRule;
property public androidx.ui.unit.Density density;
property public android.util.DisplayMetrics displayMetrics;
}
@@ -282,6 +308,9 @@
method public static void unregisterComposeFromEspresso();
}
+ public final class InternalUtilsKt {
+ }
+
public final class WindowCaptureKt {
}
diff --git a/ui/ui-test/api/public_plus_experimental_current.txt b/ui/ui-test/api/public_plus_experimental_current.txt
index 74bc0ae..481e266 100644
--- a/ui/ui-test/api/public_plus_experimental_current.txt
+++ b/ui/ui-test/api/public_plus_experimental_current.txt
@@ -9,6 +9,18 @@
method public static androidx.ui.test.SemanticsNodeInteraction doScrollTo(androidx.ui.test.SemanticsNodeInteraction);
}
+ public final class AnimationClockTestRule implements org.junit.rules.TestRule {
+ ctor public AnimationClockTestRule();
+ method public void advanceClock(long milliseconds);
+ method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
+ method public androidx.ui.test.TestAnimationClock getClock();
+ method public boolean isPaused();
+ method public void pauseClock();
+ method public void resumeClock();
+ property public final androidx.ui.test.TestAnimationClock clock;
+ property public final boolean isPaused;
+ }
+
public final class AssertionsKt {
method public static androidx.ui.test.SemanticsNodeInteraction assert(androidx.ui.test.SemanticsNodeInteraction, androidx.ui.test.SemanticsPredicate predicate);
method public static <T extends java.util.Collection<? extends androidx.ui.test.SemanticsNodeInteraction>> T assertCountEquals(T, int expectedSize);
@@ -104,11 +116,13 @@
method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
+ method public androidx.ui.test.AnimationClockTestRule getClockTestRule();
method public androidx.ui.unit.Density getDensity();
method public android.util.DisplayMetrics getDisplayMetrics();
method public <T> T! runOnIdleCompose(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);
+ property public abstract androidx.ui.test.AnimationClockTestRule clockTestRule;
property public abstract androidx.ui.unit.Density density;
property public abstract android.util.DisplayMetrics displayMetrics;
}
@@ -238,6 +252,16 @@
method public static androidx.ui.unit.PxSize setContentAndGetPixelSize(androidx.ui.test.ComposeTestRule, androidx.ui.layout.DpConstraints parentConstraints = BigTestConstraints, kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> performSetContent = { setContent(it) }, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
+ public interface TestAnimationClock extends androidx.animation.AnimationClockObservable {
+ method public void advanceClock(long milliseconds);
+ method public boolean isIdle();
+ method public boolean isPaused();
+ method public void pauseClock();
+ method public void resumeClock();
+ property public abstract boolean isIdle;
+ property public abstract boolean isPaused;
+ }
+
}
package androidx.ui.test.android {
@@ -258,12 +282,14 @@
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.test.rule.ActivityTestRule<T> getActivityTestRule();
+ method public androidx.ui.test.AnimationClockTestRule getClockTestRule();
method public androidx.ui.unit.Density getDensity();
method public android.util.DisplayMetrics getDisplayMetrics();
method public <T> T! runOnIdleCompose(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);
property public final androidx.test.rule.ActivityTestRule<T> activityTestRule;
+ property public androidx.ui.test.AnimationClockTestRule clockTestRule;
property public androidx.ui.unit.Density density;
property public android.util.DisplayMetrics displayMetrics;
}
@@ -282,6 +308,9 @@
method public static void unregisterComposeFromEspresso();
}
+ public final class InternalUtilsKt {
+ }
+
public final class WindowCaptureKt {
}
diff --git a/ui/ui-test/api/restricted_0.1.0-dev07.txt b/ui/ui-test/api/restricted_0.1.0-dev07.txt
index 74bc0ae..481e266 100644
--- a/ui/ui-test/api/restricted_0.1.0-dev07.txt
+++ b/ui/ui-test/api/restricted_0.1.0-dev07.txt
@@ -9,6 +9,18 @@
method public static androidx.ui.test.SemanticsNodeInteraction doScrollTo(androidx.ui.test.SemanticsNodeInteraction);
}
+ public final class AnimationClockTestRule implements org.junit.rules.TestRule {
+ ctor public AnimationClockTestRule();
+ method public void advanceClock(long milliseconds);
+ method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
+ method public androidx.ui.test.TestAnimationClock getClock();
+ method public boolean isPaused();
+ method public void pauseClock();
+ method public void resumeClock();
+ property public final androidx.ui.test.TestAnimationClock clock;
+ property public final boolean isPaused;
+ }
+
public final class AssertionsKt {
method public static androidx.ui.test.SemanticsNodeInteraction assert(androidx.ui.test.SemanticsNodeInteraction, androidx.ui.test.SemanticsPredicate predicate);
method public static <T extends java.util.Collection<? extends androidx.ui.test.SemanticsNodeInteraction>> T assertCountEquals(T, int expectedSize);
@@ -104,11 +116,13 @@
method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
+ method public androidx.ui.test.AnimationClockTestRule getClockTestRule();
method public androidx.ui.unit.Density getDensity();
method public android.util.DisplayMetrics getDisplayMetrics();
method public <T> T! runOnIdleCompose(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);
+ property public abstract androidx.ui.test.AnimationClockTestRule clockTestRule;
property public abstract androidx.ui.unit.Density density;
property public abstract android.util.DisplayMetrics displayMetrics;
}
@@ -238,6 +252,16 @@
method public static androidx.ui.unit.PxSize setContentAndGetPixelSize(androidx.ui.test.ComposeTestRule, androidx.ui.layout.DpConstraints parentConstraints = BigTestConstraints, kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> performSetContent = { setContent(it) }, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
+ public interface TestAnimationClock extends androidx.animation.AnimationClockObservable {
+ method public void advanceClock(long milliseconds);
+ method public boolean isIdle();
+ method public boolean isPaused();
+ method public void pauseClock();
+ method public void resumeClock();
+ property public abstract boolean isIdle;
+ property public abstract boolean isPaused;
+ }
+
}
package androidx.ui.test.android {
@@ -258,12 +282,14 @@
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.test.rule.ActivityTestRule<T> getActivityTestRule();
+ method public androidx.ui.test.AnimationClockTestRule getClockTestRule();
method public androidx.ui.unit.Density getDensity();
method public android.util.DisplayMetrics getDisplayMetrics();
method public <T> T! runOnIdleCompose(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);
property public final androidx.test.rule.ActivityTestRule<T> activityTestRule;
+ property public androidx.ui.test.AnimationClockTestRule clockTestRule;
property public androidx.ui.unit.Density density;
property public android.util.DisplayMetrics displayMetrics;
}
@@ -282,6 +308,9 @@
method public static void unregisterComposeFromEspresso();
}
+ public final class InternalUtilsKt {
+ }
+
public final class WindowCaptureKt {
}
diff --git a/ui/ui-test/api/restricted_current.txt b/ui/ui-test/api/restricted_current.txt
index 74bc0ae..481e266 100644
--- a/ui/ui-test/api/restricted_current.txt
+++ b/ui/ui-test/api/restricted_current.txt
@@ -9,6 +9,18 @@
method public static androidx.ui.test.SemanticsNodeInteraction doScrollTo(androidx.ui.test.SemanticsNodeInteraction);
}
+ public final class AnimationClockTestRule implements org.junit.rules.TestRule {
+ ctor public AnimationClockTestRule();
+ method public void advanceClock(long milliseconds);
+ method public org.junit.runners.model.Statement apply(org.junit.runners.model.Statement base, org.junit.runner.Description? description);
+ method public androidx.ui.test.TestAnimationClock getClock();
+ method public boolean isPaused();
+ method public void pauseClock();
+ method public void resumeClock();
+ property public final androidx.ui.test.TestAnimationClock clock;
+ property public final boolean isPaused;
+ }
+
public final class AssertionsKt {
method public static androidx.ui.test.SemanticsNodeInteraction assert(androidx.ui.test.SemanticsNodeInteraction, androidx.ui.test.SemanticsPredicate predicate);
method public static <T extends java.util.Collection<? extends androidx.ui.test.SemanticsNodeInteraction>> T assertCountEquals(T, int expectedSize);
@@ -104,11 +116,13 @@
method @RequiresApi(android.os.Build.VERSION_CODES.O) public android.graphics.Bitmap captureScreenOnIdle();
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
+ method public androidx.ui.test.AnimationClockTestRule getClockTestRule();
method public androidx.ui.unit.Density getDensity();
method public android.util.DisplayMetrics getDisplayMetrics();
method public <T> T! runOnIdleCompose(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);
+ property public abstract androidx.ui.test.AnimationClockTestRule clockTestRule;
property public abstract androidx.ui.unit.Density density;
property public abstract android.util.DisplayMetrics displayMetrics;
}
@@ -238,6 +252,16 @@
method public static androidx.ui.unit.PxSize setContentAndGetPixelSize(androidx.ui.test.ComposeTestRule, androidx.ui.layout.DpConstraints parentConstraints = BigTestConstraints, kotlin.jvm.functions.Function1<? super kotlin.jvm.functions.Function0<kotlin.Unit>,kotlin.Unit> performSetContent = { setContent(it) }, kotlin.jvm.functions.Function0<kotlin.Unit> children);
}
+ public interface TestAnimationClock extends androidx.animation.AnimationClockObservable {
+ method public void advanceClock(long milliseconds);
+ method public boolean isIdle();
+ method public boolean isPaused();
+ method public void pauseClock();
+ method public void resumeClock();
+ property public abstract boolean isIdle;
+ property public abstract boolean isPaused;
+ }
+
}
package androidx.ui.test.android {
@@ -258,12 +282,14 @@
method public androidx.ui.test.ComposeTestCaseSetup forGivenContent(kotlin.jvm.functions.Function0<kotlin.Unit> composable);
method public androidx.ui.test.ComposeTestCaseSetup forGivenTestCase(androidx.ui.test.ComposeTestCase testCase);
method public androidx.test.rule.ActivityTestRule<T> getActivityTestRule();
+ method public androidx.ui.test.AnimationClockTestRule getClockTestRule();
method public androidx.ui.unit.Density getDensity();
method public android.util.DisplayMetrics getDisplayMetrics();
method public <T> T! runOnIdleCompose(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);
property public final androidx.test.rule.ActivityTestRule<T> activityTestRule;
+ property public androidx.ui.test.AnimationClockTestRule clockTestRule;
property public androidx.ui.unit.Density density;
property public android.util.DisplayMetrics displayMetrics;
}
@@ -282,6 +308,9 @@
method public static void unregisterComposeFromEspresso();
}
+ public final class InternalUtilsKt {
+ }
+
public final class WindowCaptureKt {
}
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/AnimationSynchronizationTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/AnimationSynchronizationTest.kt
new file mode 100644
index 0000000..23f3be7
--- /dev/null
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/AnimationSynchronizationTest.kt
@@ -0,0 +1,304 @@
+/*
+ * 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.ui.test
+
+import android.os.Handler
+import android.os.Looper
+import androidx.animation.FloatPropKey
+import androidx.animation.LinearEasing
+import androidx.animation.transitionDefinition
+import androidx.compose.Composable
+import androidx.compose.State
+import androidx.compose.mutableStateOf
+import androidx.compose.remember
+import androidx.test.espresso.Espresso.onIdle
+import androidx.test.filters.LargeTest
+import androidx.test.filters.MediumTest
+import androidx.ui.animation.Transition
+import androidx.ui.foundation.Canvas
+import androidx.ui.foundation.DrawBackground
+import androidx.ui.geometry.Rect
+import androidx.ui.graphics.Color
+import androidx.ui.graphics.Paint
+import androidx.ui.layout.Container
+import androidx.ui.layout.LayoutSize
+import androidx.ui.test.android.ComposeIdlingResource
+import com.google.common.truth.Truth.assertThat
+import org.junit.Ignore
+import org.junit.Rule
+import org.junit.Test
+
+private const val nonIdleDuration = 1000L
+
+private const val animateFromX = 0f
+private const val animateToX = 50f
+private val animatedRect = Rect.fromLTWH(0f, 0f, 50f, 50f)
+
+@LargeTest
+class AnimationSynchronizationTest {
+
+ private val handler = Handler(Looper.getMainLooper())
+
+ private var animationRunning = false
+ private val recordedAnimatedValues = mutableListOf<Float>()
+ private var hasRecomposed = false
+
+ @get:Rule
+ val composeTestRule = createComposeRule()
+ private val clockTestRule = composeTestRule.clockTestRule
+
+ /**
+ * High level test to only verify that [ComposeTestRule.runOnIdleCompose] awaits animations.
+ */
+ @Test
+ fun testRunOnIdleCompose() {
+ val animationState = mutableStateOf(AnimationStates.From)
+ composeTestRule.setContent { Ui(animationState) }
+
+ composeTestRule.runOnIdleCompose {
+ // Kick off the animation
+ animationRunning = true
+ animationState.value = AnimationStates.To
+ }
+
+ // Verify that animation is kicked off
+ assertThat(animationRunning).isTrue()
+ // Wait until it is finished
+ composeTestRule.runOnIdleCompose {
+ // Verify it was finished
+ assertThat(animationRunning).isFalse()
+ }
+ }
+
+ /**
+ * High level test to only verify that [onIdle] awaits animations.
+ */
+ @Test
+ fun testAnimationIdle_simple() {
+ val animationState = mutableStateOf(AnimationStates.From)
+ composeTestRule.setContent { Ui(animationState) }
+
+ composeTestRule.runOnIdleCompose {
+ // Kick off the animation
+ animationRunning = true
+ animationState.value = AnimationStates.To
+ }
+
+ // Verify that animation is kicked off
+ assertThat(animationRunning).isTrue()
+ // Wait until it is finished
+ onIdle()
+ // Verify it was finished
+ assertThat(animationRunning).isFalse()
+ }
+
+ /**
+ * Detailed test to verify if [ComposeIdlingResource.isIdle] reports idleness correctly at
+ * key moments during the animation kick-off process.
+ */
+ @Test
+ fun testAnimationIdle_detailed() {
+ var wasIdleAfterCommit = false
+ var wasIdleAfterRecompose = false
+ var wasIdleBeforeKickOff = false
+ var wasIdleBeforeCommit = false
+
+ val animationState = mutableStateOf(AnimationStates.From)
+ composeTestRule.setContent { Ui(animationState) }
+
+ composeTestRule.runOnIdleCompose {
+ // Record idleness after this frame is committed. The mutation we're about to make
+ // will trigger a commit of the frame, which is posted at the front of the handler's
+ // queue. By posting a message at the front of the queue here, it will be executed
+ // right after the frame commit.
+ handler.postAtFrontOfQueue {
+ wasIdleAfterCommit = ComposeIdlingResource.isIdle()
+ }
+
+ // Record idleness after the next recomposition. Since we can't get a signal from the
+ // recomposer, keep polling until we detect we have been recomposed.
+ hasRecomposed = false
+ handler.pollUntil({ hasRecomposed }) {
+ wasIdleAfterRecompose = ComposeIdlingResource.isIdle()
+ }
+
+ // Record idleness before kickoff of animation
+ wasIdleBeforeKickOff = ComposeIdlingResource.isIdle()
+
+ // Kick off the animation
+ animationRunning = true
+ animationState.value = AnimationStates.To
+
+ // Record idleness after kickoff of animation, but before the frame is committed
+ wasIdleBeforeCommit = ComposeIdlingResource.isIdle()
+ }
+
+ // Verify that animation is kicked off
+ assertThat(animationRunning).isTrue()
+ // Wait until it is finished
+ onIdle()
+ // Verify it was finished
+ assertThat(animationRunning).isFalse()
+
+ // Before the animation is kicked off, it is still idle
+ assertThat(wasIdleBeforeKickOff).isTrue()
+ // After animation is kicked off, but before the frame is committed, it must be busy
+ assertThat(wasIdleBeforeCommit).isFalse()
+ // After the frame is committed, it must still be busy
+ assertThat(wasIdleAfterCommit).isFalse()
+ // After recomposition, it must still be busy
+ assertThat(wasIdleAfterRecompose).isFalse()
+ }
+
+ /**
+ * Tests if advancing the clock manually works when the clock is paused, and that idleness is
+ * reported correctly when doing that.
+ */
+ @Test
+ @MediumTest
+ fun testAnimation_manuallyAdvanceClock_paused() {
+ clockTestRule.pauseClock()
+
+ val animationState = mutableStateOf(AnimationStates.From)
+ composeTestRule.setContent { Ui(animationState) }
+
+ composeTestRule.runOnIdleCompose {
+ recordedAnimatedValues.clear()
+
+ // Kick off the animation
+ animationRunning = true
+ animationState.value = AnimationStates.To
+
+ // Changes need to trickle down the animation system, so compose should be non-idle
+ assertThat(ComposeIdlingResource.isIdle()).isFalse()
+ }
+
+ // Await recomposition
+ onIdle()
+
+ // Did one recomposition, but no animation frames
+ // TODO(b/149754986): Canvas draws twice in our use case. Fix expected values when fixed
+ assertThat(recordedAnimatedValues).isEqualTo(listOf(0f, 0f))
+
+ // Animation doesn't actually start until the next frame.
+ // Advance by 0ms to force dispatching of a frame time.
+ composeTestRule.runOnIdleCompose {
+ // Advance clock on main thread so we can assert Compose is not idle afterwards
+ clockTestRule.advanceClock(0)
+ assertThat(ComposeIdlingResource.isIdle()).isFalse()
+ }
+
+ // Await start animation frame
+ onIdle()
+
+ // Did start animation frame
+ assertThat(recordedAnimatedValues).isEqualTo(listOf(0f, 0f, 0f))
+
+ // Advance first half of the animation (.5 sec)
+ composeTestRule.runOnIdleCompose {
+ clockTestRule.advanceClock(500)
+ assertThat(ComposeIdlingResource.isIdle()).isFalse()
+ }
+
+ // Await next animation frame
+ onIdle()
+
+ // Did one animation frame
+ assertThat(recordedAnimatedValues).isEqualTo(listOf(0f, 0f, 0f, 25f))
+
+ // Advance second half of the animation (.5 sec)
+ composeTestRule.runOnIdleCompose {
+ clockTestRule.advanceClock(500)
+ assertThat(ComposeIdlingResource.isIdle()).isFalse()
+ }
+
+ // Await next animation frame
+ onIdle()
+
+ // Did last animation frame
+ assertThat(recordedAnimatedValues).isEqualTo(listOf(0f, 0f, 0f, 25f, 50f))
+ }
+
+ /**
+ * Tests if advancing the clock manually works when the clock is resumed, and that idleness
+ * is reported correctly when doing that.
+ */
+ @Test
+ @MediumTest
+ @Ignore("b/150357516: not yet implemented")
+ fun testAnimation_manuallyAdvanceClock_resumed() {
+ // TODO(b/150357516): Test advancing the clock while it is resumed
+ }
+
+ private fun Handler.pollUntil(condition: () -> Boolean, onDone: () -> Unit) {
+ object : Runnable {
+ override fun run() {
+ if (condition()) {
+ onDone()
+ } else {
+ [email protected](this)
+ }
+ }
+ }.run()
+ }
+
+ @Composable
+ private fun Ui(animationState: State<AnimationStates>) {
+ val paint = remember { Paint().also { it.color = Color.Cyan } }
+
+ hasRecomposed = true
+ Container(modifier = DrawBackground(color = Color.Yellow) + LayoutSize.Fill) {
+ hasRecomposed = true
+ Transition(
+ definition = animationDefinition,
+ toState = animationState.value,
+ onStateChangeFinished = { animationRunning = false }
+ ) { state ->
+ hasRecomposed = true
+ Canvas(modifier = LayoutSize.Fill) {
+ recordedAnimatedValues.add(state[x])
+ drawRect(animatedRect.translate(state[x], 0f), paint)
+ }
+ }
+ }
+ }
+
+ private val x = FloatPropKey()
+
+ private enum class AnimationStates {
+ From,
+ To
+ }
+
+ private val animationDefinition = transitionDefinition {
+ state(AnimationStates.From) {
+ this[x] = animateFromX
+ }
+ state(AnimationStates.To) {
+ this[x] = animateToX
+ }
+ transition(AnimationStates.From to AnimationStates.To) {
+ x using tween {
+ easing = LinearEasing
+ duration = nonIdleDuration.toInt()
+ }
+ }
+ transition(AnimationStates.To to AnimationStates.From) {
+ x using snap()
+ }
+ }
+}
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/AssertExistsTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/AssertExistsTest.kt
index 5d5c383..90465c9 100644
--- a/ui/ui-test/src/androidTest/java/androidx/ui/test/AssertExistsTest.kt
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/AssertExistsTest.kt
@@ -23,7 +23,7 @@
import androidx.ui.layout.Column
import androidx.ui.material.Button
import androidx.ui.material.MaterialTheme
-import androidx.ui.material.surface.Surface
+import androidx.ui.material.Surface
import androidx.ui.semantics.Semantics
import androidx.ui.test.util.expectAssertionError
import org.junit.Rule
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/CustomActivityTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/CustomActivityTest.kt
index d35421a..8bda174 100644
--- a/ui/ui-test/src/androidTest/java/androidx/ui/test/CustomActivityTest.kt
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/CustomActivityTest.kt
@@ -38,7 +38,7 @@
setContent {
MaterialTheme {
Stack {
- Button {
+ Button(onClick = {}) {
Text("Hello")
}
}
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/ErrorMessagesTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/ErrorMessagesTest.kt
index 6ae56e6..4d6ddec 100644
--- a/ui/ui-test/src/androidTest/java/androidx/ui/test/ErrorMessagesTest.kt
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/ErrorMessagesTest.kt
@@ -25,7 +25,7 @@
import androidx.ui.layout.Column
import androidx.ui.layout.Container
import androidx.ui.material.MaterialTheme
-import androidx.ui.material.surface.Surface
+import androidx.ui.material.Surface
import androidx.ui.semantics.Semantics
import androidx.ui.semantics.SemanticsActions
import androidx.ui.test.util.obfuscateNodesInfo
@@ -334,7 +334,7 @@
// merge all descendants, or we'll get multiple nodes
Semantics(container = true, mergeAllDescendants = true) {
Surface() {
- Clickable(onClick = onClick) {
+ Clickable(onClick = onClick ?: {}, enabled = onClick != null) {
Container(children = children)
}
}
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/FindAllTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/FindAllTest.kt
index 1ac2e98..0f61e4d 100644
--- a/ui/ui-test/src/androidTest/java/androidx/ui/test/FindAllTest.kt
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/FindAllTest.kt
@@ -21,7 +21,7 @@
import androidx.ui.layout.Column
import androidx.ui.material.Checkbox
import androidx.ui.material.MaterialTheme
-import androidx.ui.material.surface.Surface
+import androidx.ui.material.Surface
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/MultipleComposeRootsTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/MultipleComposeRootsTest.kt
index af76918..d9f079f 100644
--- a/ui/ui-test/src/androidTest/java/androidx/ui/test/MultipleComposeRootsTest.kt
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/MultipleComposeRootsTest.kt
@@ -32,7 +32,7 @@
import androidx.ui.foundation.selection.ToggleableState
import androidx.ui.material.MaterialTheme
import androidx.ui.material.TriStateCheckbox
-import androidx.ui.material.surface.Surface
+import androidx.ui.material.Surface
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/SendClickTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/SendClickTest.kt
index 3ac265a..3081970 100644
--- a/ui/ui-test/src/androidTest/java/androidx/ui/test/SendClickTest.kt
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/SendClickTest.kt
@@ -21,9 +21,8 @@
import android.view.Gravity
import android.widget.FrameLayout
import androidx.compose.Composable
-import androidx.compose.Compose
+import androidx.compose.Composition
import androidx.test.filters.MediumTest
-import androidx.ui.core.AndroidComposeView
import androidx.ui.core.DensityAmbient
import androidx.ui.core.PointerEventPass
import androidx.ui.core.PointerInput
@@ -60,6 +59,7 @@
// The presence of an ActionBar follows from the theme set in AndroidManifest.xml
class ActivityWithActionBar : Activity() {
private lateinit var composeHolder: FrameLayout
+ private var composition: Composition? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -76,15 +76,12 @@
}
override fun onDestroy() {
- val composeView = composeHolder.getChildAt(0) as? AndroidComposeView
- if (composeView != null) {
- Compose.disposeComposition(composeView.root, this, null)
- }
+ composition?.dispose()
super.onDestroy()
}
fun setContent(composable: @Composable() () -> Unit) {
- composeHolder.setContent(composable)
+ composition = composeHolder.setContent(composable)
}
}
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/ComposeTestRule.kt b/ui/ui-test/src/main/java/androidx/ui/test/ComposeTestRule.kt
index 3102233..986e02b 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/ComposeTestRule.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/ComposeTestRule.kt
@@ -41,6 +41,11 @@
val density: Density
/**
+ * A test rule that allows you to control the animation clock
+ */
+ val clockTestRule: AnimationClockTestRule
+
+ /**
* Sets the given composable as a content of the current screen.
*
* Use this in your tests to setup the UI content to be tested. This should be called exactly
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/SizesTesting.kt b/ui/ui-test/src/main/java/androidx/ui/test/SizesTesting.kt
index 197af1e..f9600d6 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/SizesTesting.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/SizesTesting.kt
@@ -26,7 +26,7 @@
import androidx.ui.layout.DpConstraints
import androidx.ui.layout.LayoutSize
import androidx.ui.layout.Stack
-import androidx.ui.layout.Wrap
+import androidx.ui.layout.Stack
import androidx.ui.unit.round
import androidx.ui.unit.toPxSize
import kotlin.math.abs
@@ -52,7 +52,7 @@
): PxSize {
var realSize: PxSize? = null
performSetContent {
- Wrap {
+ Stack {
Stack(
LayoutSize.Min(parentConstraints.minWidth, parentConstraints.minHeight) +
LayoutSize.Max(parentConstraints.maxWidth, parentConstraints.maxHeight)
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/TestAnimationClock.kt b/ui/ui-test/src/main/java/androidx/ui/test/TestAnimationClock.kt
new file mode 100644
index 0000000..914c3eb
--- /dev/null
+++ b/ui/ui-test/src/main/java/androidx/ui/test/TestAnimationClock.kt
@@ -0,0 +1,140 @@
+/*
+ * 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.ui.test
+
+import androidx.animation.AnimationClockObservable
+import androidx.animation.rootAnimationClockFactory
+import androidx.ui.test.android.AndroidTestAnimationClock
+import androidx.ui.test.android.ComposeIdlingResource
+import androidx.test.espresso.IdlingResource
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+
+/**
+ * Interface for animation clocks that can report their idleness and can switch between ticking
+ * automatically (e.g., if it's driven by the main loop of the host) and ticking manually.
+ *
+ * An idle clock is one that is currently not driving any animations. Typically, that means a
+ * clock where no observers are registered. The idleness can be retrieved by [isIdle].
+ *
+ * Use [pauseClock] to switch from automatic ticking to manual ticking, [resumeClock] to switch
+ * from manual to automatic with; and manually tick the clock with [advanceClock].
+ */
+interface TestAnimationClock : AnimationClockObservable {
+ /**
+ * Whether the clock is idle or not. An idle clock is one that is not driving animations,
+ * which happens (1) when no observers are observing this clock, or (2) when the clock is
+ * paused.
+ */
+ val isIdle: Boolean
+
+ /**
+ * Pauses the automatic ticking of the clock. The clock shall only tick in response to
+ * [advanceClock], and shall continue ticking automatically when [resumeClock] is called.
+ * It's safe to call this method when the clock is already paused.
+ */
+ fun pauseClock()
+
+ /**
+ * Resumes the automatic ticking of the clock. It's safe to call this method when the clock
+ * is already resumed.
+ */
+ fun resumeClock()
+
+ /**
+ * Whether the clock is [paused][pauseClock] or [not][resumeClock].
+ */
+ val isPaused: Boolean
+
+ /**
+ * Advances the clock by the given number of [milliseconds]. It is safe to call this method
+ * both when the clock is paused and resumed.
+ */
+ fun advanceClock(milliseconds: Long)
+}
+
+/**
+ * A [TestRule] to monitor and take over the animation clock in the composition. It substitutes
+ * the ambient animation clock provided at the root of the composition tree with a
+ * [TestAnimationClock] and registers it with [ComposeIdlingResource].
+ *
+ * Usually you don't need to create this rule by yourself, it is done for you in
+ * [ComposeTestRule]. If you don't use [ComposeTestRule], use this rule in your test and make
+ * sure it is run _before_ your activity is created.
+ *
+ * If your app provides a custom animation clock somewhere in your composition, make sure to have
+ * it implement [TestAnimationClock] and register it with [ComposeIdlingResource]. Alternatively,
+ * if you use Espresso you can create your own [IdlingResource] to let Espresso await your
+ * animations. Otherwise, built in steps that make sure the UI is stable when performing actions
+ * or assertions will fail to work.
+ */
+class AnimationClockTestRule : TestRule {
+
+ /** Backing property for [clock] */
+ private val _clock = AndroidTestAnimationClock()
+
+ /**
+ * The ambient animation clock that is provided at the root of the composition tree.
+ * Typically, apps will only use this clock. If your app provides another clock in the tree,
+ * make sure to let it implement [TestAnimationClock] and register it with
+ * [ComposeIdlingResource].
+ */
+ val clock: TestAnimationClock get() = _clock
+
+ /**
+ * Convenience property for calling [`clock.isPaused`][TestAnimationClock.isPaused]
+ */
+ val isPaused: Boolean get() = clock.isPaused
+
+ /**
+ * Convenience method for calling [`clock.pauseClock()`][TestAnimationClock.pauseClock]
+ */
+ fun pauseClock() = clock.pauseClock()
+
+ /**
+ * Convenience method for calling [`clock.resumeClock()`][TestAnimationClock.resumeClock]
+ */
+ fun resumeClock() = clock.resumeClock()
+
+ /**
+ * Convenience method for calling [`clock.advanceClock()`][TestAnimationClock.advanceClock]
+ */
+ fun advanceClock(milliseconds: Long) = clock.advanceClock(milliseconds)
+
+ override fun apply(base: Statement, description: Description?): Statement {
+ return AnimationClockStatement(base)
+ }
+
+ private inner class AnimationClockStatement(private val base: Statement) : Statement() {
+ override fun evaluate() {
+ val oldFactory = rootAnimationClockFactory
+ ComposeIdlingResource.registerTestClock(clock)
+ rootAnimationClockFactory = { clock }
+ try {
+ base.evaluate()
+ } finally {
+ try {
+ _clock.dispose()
+ } finally {
+ rootAnimationClockFactory = oldFactory
+ ComposeIdlingResource.unregisterTestClock(clock)
+ }
+ }
+ }
+ }
+}
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidComposeTestCaseRunner.kt b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidComposeTestCaseRunner.kt
index a115e8d..df1b0e4 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidComposeTestCaseRunner.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidComposeTestCaseRunner.kt
@@ -28,7 +28,6 @@
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
-import androidx.compose.Compose
import androidx.compose.Composition
import androidx.compose.FrameManager
import androidx.compose.Recomposer
@@ -218,8 +217,7 @@
return
}
- // TODO(pavlis): replace with activity.disposeComposition() after it gets fixed.
- Compose.disposeComposition((view as AndroidComposeView).root, activity, null)
+ composition?.dispose()
// Clear the view
val rootView = activity.findViewById(R.id.content) as ViewGroup
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidComposeTestRule.kt b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidComposeTestRule.kt
index 7aacee1..a7e8dfe 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidComposeTestRule.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidComposeTestRule.kt
@@ -22,17 +22,15 @@
import android.os.Handler
import android.os.Looper
import android.util.DisplayMetrics
-import android.view.View
import android.view.ViewGroup
import android.view.ViewTreeObserver
import androidx.annotation.RequiresApi
import androidx.compose.Composable
-import androidx.compose.Compose
import androidx.test.rule.ActivityTestRule
import androidx.ui.animation.transitionsEnabled
-import androidx.ui.core.AndroidComposeView
import androidx.ui.core.setContent
import androidx.ui.geometry.Rect
+import androidx.ui.test.AnimationClockTestRule
import androidx.ui.test.ComposeTestCase
import androidx.ui.test.ComposeTestCaseSetup
import androidx.ui.test.ComposeTestRule
@@ -71,6 +69,7 @@
) : ComposeTestRule {
val activityTestRule = ActivityTestRule<T>(activityClass)
+ override val clockTestRule = AnimationClockTestRule()
private val handler: Handler = Handler(Looper.getMainLooper())
private var disposeContentHook: (() -> Unit)? = null
@@ -81,7 +80,10 @@
activityTestRule.activity.resources.displayMetrics
override fun apply(base: Statement, description: Description?): Statement {
- return activityTestRule.apply(AndroidComposeStatement(base), description)
+ return clockTestRule.apply(
+ activityTestRule.apply(AndroidComposeStatement(base), description),
+ description
+ )
}
override fun <T> runOnUiThread(action: () -> T): T {
@@ -122,14 +124,12 @@
}
val runnable: Runnable = object : Runnable {
override fun run() {
- activityTestRule.activity.setContent(composable)
+ val composition = activityTestRule.activity.setContent(composable)
val contentViewGroup =
activityTestRule.activity.findViewById<ViewGroup>(android.R.id.content)
contentViewGroup.viewTreeObserver.addOnGlobalLayoutListener(listener)
- val view = findComposeView(activityTestRule.activity)
disposeContentHook = {
- Compose.disposeComposition((view as AndroidComposeView).root,
- activityTestRule.activity, null)
+ composition.dispose()
}
}
}
@@ -203,26 +203,4 @@
}
}
}
-
- // TODO(pavlis): These methods are only needed because we don't have an API to purge all
- // compositions from the app. Remove them once we have the option.
- private fun findComposeView(activity: Activity): AndroidComposeView? {
- return findComposeView(activity.findViewById(android.R.id.content) as ViewGroup)
- }
-
- private fun findComposeView(view: View): AndroidComposeView? {
- if (view is AndroidComposeView) {
- return view
- }
-
- if (view is ViewGroup) {
- for (i in 0 until view.childCount) {
- val composeView = findComposeView(view.getChildAt(i))
- if (composeView != null) {
- return composeView
- }
- }
- }
- return null
- }
}
\ No newline at end of file
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidTestAnimationClock.kt b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidTestAnimationClock.kt
new file mode 100644
index 0000000..2bc2e2b
--- /dev/null
+++ b/ui/ui-test/src/main/java/androidx/ui/test/android/AndroidTestAnimationClock.kt
@@ -0,0 +1,173 @@
+/*
+ * 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.ui.test.android
+
+import android.os.Handler
+import android.os.Looper
+import android.view.Choreographer
+import androidx.animation.AnimationClockObserver
+import androidx.animation.ManualAnimationClock
+import androidx.ui.test.AnimationClockTestRule
+import androidx.ui.test.TestAnimationClock
+
+/**
+ * An animation clock driven by an external time source, that can be queried for idleness and has
+ * the ability to seamlessly detach the clock from that time source and pump it manually.
+ * Normally there is no need to instantiate this class by yourself, it will be done for you by
+ * [AnimationClockTestRule].
+ *
+ * This [TestAnimationClock] is resumed by default.
+ *
+ * @see isIdle
+ * @see pauseClock
+ * @see advanceClock
+ * @see resumeClock
+ */
+internal class AndroidTestAnimationClock : TestAnimationClock {
+
+ private val mainHandler = Handler(Looper.getMainLooper())
+ private val mainChoreographer: Choreographer
+
+ init {
+ /**
+ * If not initializing on the main thread, a message will be posted on the main thread to
+ * fetch the Choreographer, and initialization blocks until that fetch is completed.
+ */
+ mainChoreographer = mainHandler.runAndAwait { Choreographer.getInstance() }
+ }
+
+ private val lock = Any()
+ private val clock = ManualAnimationClock(0, false)
+ private var advancedTime = 0L
+ private var needsToDispatch = false
+ private var isDispatching = false
+ private var choreographerPaused = false
+ private var isDisposed = false
+
+ override val isPaused: Boolean
+ get() = choreographerPaused
+
+ override val isIdle: Boolean
+ get() = synchronized(lock) {
+ return choreographerPaused || !needsToDispatch
+ }
+
+ // FrameCallback with which we receive timestamps from the choreographer
+ private val frameCallback = Choreographer.FrameCallback { frameTimeNanos ->
+ synchronized(lock) {
+ // The choreographer can be paused before we entered
+ // our synchronized block. Ignore this frame
+ if (!choreographerPaused) {
+ handleFrameTimeLocked(frameTimeNanos / 1_000_000 + advancedTime)
+ }
+ }
+ }
+
+ override fun subscribe(observer: AnimationClockObserver) {
+ synchronized(lock) {
+ check(!isDisposed) { "Can't subscribe to a disposed clock" }
+ clock.subscribe(observer)
+ if (!needsToDispatch) {
+ // Didn't need to dispatch before, but now we do
+ postFrameCallbackLocked()
+ needsToDispatch = true
+ }
+ }
+ }
+
+ override fun unsubscribe(observer: AnimationClockObserver) {
+ clock.unsubscribe(observer)
+ }
+
+ override fun advanceClock(milliseconds: Long) {
+ mainHandler.runAndAwait {
+ advanceClockOnMainThread(milliseconds)
+ }
+ }
+
+ private fun advanceClockOnMainThread(milliseconds: Long) {
+ synchronized(lock) {
+ check(!isDispatching) { "Can't advance clock while dispatching a frame time" }
+ require(milliseconds >= 0) { "Can only advance the clock forward" }
+ advancedTime += milliseconds
+ handleFrameTimeLocked(clock.clockTimeMillis + milliseconds)
+ }
+ }
+
+ private fun handleFrameTimeLocked(frameTimeMillis: Long) {
+ synchronized(lock) {
+ // Start dispatching
+ isDispatching = true
+
+ // Dispatch to the backing clock
+ clock.clockTimeMillis = frameTimeMillis
+
+ // If we still have observers, we want another frame
+ needsToDispatch = clock.hasObservers
+ if (needsToDispatch) {
+ postFrameCallbackLocked()
+ }
+
+ // Finish dispatching
+ isDispatching = false
+ }
+ }
+
+ private fun postFrameCallbackLocked() {
+ if (!choreographerPaused) {
+ mainChoreographer.postFrameCallback(frameCallback)
+ }
+ }
+
+ override fun pauseClock() {
+ synchronized(lock) {
+ /**
+ * Simply remove the link between the choreographer and us. Our observers are still
+ * there and will be notified on the next call to [advanceClock] or [resumeClock].
+ */
+ mainChoreographer.removeFrameCallback(frameCallback)
+ choreographerPaused = true
+ }
+ }
+
+ override fun resumeClock() {
+ synchronized(lock) {
+ if (choreographerPaused) {
+ choreographerPaused = false
+ if (needsToDispatch) {
+ postFrameCallbackLocked()
+ }
+ }
+ }
+ }
+
+ /**
+ * Cancels pending frames and prevents future subscription to this clock. This clock can not
+ * be reused after this method.
+ */
+ fun dispose() {
+ synchronized(lock) {
+ mainChoreographer.removeFrameCallback(frameCallback)
+ needsToDispatch = false
+ isDisposed = true
+ if (clock.hasObservers) {
+ throw AssertionError("Animation clock still has observer(s) after it is disposed." +
+ " Are there still animations running?")
+ }
+ }
+ }
+}
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/android/ComposeIdlingResource.kt b/ui/ui-test/src/main/java/androidx/ui/test/android/ComposeIdlingResource.kt
index f2d540c..9f49ba1 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/android/ComposeIdlingResource.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/android/ComposeIdlingResource.kt
@@ -19,8 +19,10 @@
import android.os.Handler
import android.os.Looper
import androidx.compose.Recomposer
+import androidx.compose.frames.currentFrame
import androidx.test.espresso.IdlingRegistry
import androidx.test.espresso.IdlingResource
+import androidx.ui.test.TestAnimationClock
/**
* Register compose's idling check to Espresso.
@@ -57,16 +59,52 @@
private var isRegistered = false
+ private var isIdleCheckScheduled = false
+
+ private val clocks = mutableSetOf<TestAnimationClock>()
+
private val handler = Handler(Looper.getMainLooper())
+ /**
+ * Returns whether or not Compose is idle, without starting to poll if it is not.
+ */
+ fun isIdle(): Boolean {
+ return handler.runAndAwait {
+ !currentFrame().hasPendingChanges() &&
+ !Recomposer.hasPendingChanges() &&
+ areAllClocksIdle()
+ }
+ }
+
+ /**
+ * Returns whether or not Compose is idle, and starts polling if it is not. Will always be
+ * called from the main thread by Espresso, and should _only_ be called from Espresso. Use
+ * [isIdle] if you need to query the idleness of Compose manually.
+ */
override fun isIdleNow(): Boolean {
- val isIdle = !Recomposer.hasPendingChanges()
+ val isIdle = isIdle()
if (!isIdle) {
scheduleIdleCheck()
}
return isIdle
}
+ private fun scheduleIdleCheck() {
+ if (!isIdleCheckScheduled) {
+ isIdleCheckScheduled = true
+ handler.post {
+ isIdleCheckScheduled = false
+ if (isIdle()) {
+ if (callback != null) {
+ callback!!.onTransitionToIdle()
+ }
+ } else {
+ scheduleIdleCheck()
+ }
+ }
+ }
+ }
+
override fun registerIdleTransitionCallback(callback: IdlingResource.ResourceCallback?) {
this.callback = callback
}
@@ -97,17 +135,21 @@
isRegistered = false
}
- private fun scheduleIdleCheck() {
- handler.post(object : Runnable {
- override fun run() {
- if (Recomposer.hasPendingChanges()) {
- scheduleIdleCheck()
- return
- }
- if (callback != null) {
- callback!!.onTransitionToIdle()
- }
- }
- })
+ fun registerTestClock(clock: TestAnimationClock) {
+ synchronized(clocks) {
+ clocks.add(clock)
+ }
+ }
+
+ fun unregisterTestClock(clock: TestAnimationClock) {
+ synchronized(clocks) {
+ clocks.remove(clock)
+ }
+ }
+
+ private fun areAllClocksIdle(): Boolean {
+ return synchronized(clocks) {
+ clocks.all { it.isIdle }
+ }
}
}
\ No newline at end of file
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/android/InternalUtils.kt b/ui/ui-test/src/main/java/androidx/ui/test/android/InternalUtils.kt
new file mode 100644
index 0000000..9e3e3a3
--- /dev/null
+++ b/ui/ui-test/src/main/java/androidx/ui/test/android/InternalUtils.kt
@@ -0,0 +1,42 @@
+/*
+ * 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.ui.test.android
+
+import android.os.Handler
+import android.os.Looper
+import java.util.concurrent.CountDownLatch
+
+internal fun <R> Handler.runAndAwait(command: () -> R): R {
+ if (looper === Looper.myLooper()) {
+ return command()
+ } else {
+ val latch = CountDownLatch(1)
+ var result = Result.failure<R>(Throwable("runAndAwait got neither a result nor a crash"))
+ post {
+ // Don't lift assignment out of 'try': count down must happen *after* assignment
+ try {
+ result = Result.success(command())
+ } catch (t: Throwable) {
+ result = Result.failure(t)
+ } finally {
+ latch.countDown()
+ }
+ }
+ latch.await()
+ return result.getOrThrow()
+ }
+}
diff --git a/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/PreviewActivityTest.kt b/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/PreviewActivityTest.kt
index 178ff14c..c8dee5a 100644
--- a/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/PreviewActivityTest.kt
+++ b/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/PreviewActivityTest.kt
@@ -41,6 +41,7 @@
@After
fun tearDown() {
activityTestRule.runOnUiThread {
+ @Suppress("DEPRECATION")
Compose.disposeComposition(activityTestRule.activity.findViewById(android.R.id.content))
}
}
diff --git a/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/SimpleComposablePreview.kt b/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/SimpleComposablePreview.kt
index 171212ae..425ed56 100644
--- a/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/SimpleComposablePreview.kt
+++ b/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/SimpleComposablePreview.kt
@@ -19,7 +19,7 @@
import androidx.compose.Composable
import androidx.ui.core.Text
import androidx.ui.graphics.Color
-import androidx.ui.material.surface.Surface
+import androidx.ui.material.Surface
import androidx.ui.tooling.preview.Preview
@Preview
diff --git a/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/preview/ParameterProviderComposable.kt b/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/preview/ParameterProviderComposable.kt
index 67cb5dd..d140fc2 100644
--- a/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/preview/ParameterProviderComposable.kt
+++ b/ui/ui-tooling/src/androidTest/java/androidx/ui/tooling/preview/ParameterProviderComposable.kt
@@ -19,7 +19,7 @@
import androidx.compose.Composable
import androidx.ui.core.Text
import androidx.ui.graphics.Color
-import androidx.ui.material.surface.Surface
+import androidx.ui.material.Surface
@Preview
@Composable
diff --git a/ui/ui-tooling/src/main/java/androidx/ui/tooling/preview/ComposeViewAdapter.kt b/ui/ui-tooling/src/main/java/androidx/ui/tooling/preview/ComposeViewAdapter.kt
index 1c7e8b1..24361f0 100644
--- a/ui/ui-tooling/src/main/java/androidx/ui/tooling/preview/ComposeViewAdapter.kt
+++ b/ui/ui-tooling/src/main/java/androidx/ui/tooling/preview/ComposeViewAdapter.kt
@@ -28,7 +28,6 @@
import androidx.compose.Composition
import androidx.compose.Providers
import androidx.compose.currentComposer
-import androidx.compose.disposeComposition
import androidx.ui.core.FontLoaderAmbient
import androidx.ui.core.setContent
import androidx.ui.core.toFrameworkRect
@@ -279,7 +278,6 @@
* Disposes the Compose elements allocated during [init]
*/
internal fun dispose() {
- disposeComposition()
composition?.dispose()
composition = null
}
diff --git a/ui/ui-util/api/0.1.0-dev07.txt b/ui/ui-util/api/0.1.0-dev07.txt
index 2baff75..2452352 100644
--- a/ui/ui-util/api/0.1.0-dev07.txt
+++ b/ui/ui-util/api/0.1.0-dev07.txt
@@ -83,6 +83,10 @@
method public static String toStringAsFixed(float, int digits);
}
+ public final class SynchronizationHelperKt {
+ method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
+ }
+
public final class TraceKt {
method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
}
diff --git a/ui/ui-util/api/current.txt b/ui/ui-util/api/current.txt
index 2baff75..2452352 100644
--- a/ui/ui-util/api/current.txt
+++ b/ui/ui-util/api/current.txt
@@ -83,6 +83,10 @@
method public static String toStringAsFixed(float, int digits);
}
+ public final class SynchronizationHelperKt {
+ method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
+ }
+
public final class TraceKt {
method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
}
diff --git a/ui/ui-util/api/public_plus_experimental_0.1.0-dev07.txt b/ui/ui-util/api/public_plus_experimental_0.1.0-dev07.txt
index 2baff75..2452352 100644
--- a/ui/ui-util/api/public_plus_experimental_0.1.0-dev07.txt
+++ b/ui/ui-util/api/public_plus_experimental_0.1.0-dev07.txt
@@ -83,6 +83,10 @@
method public static String toStringAsFixed(float, int digits);
}
+ public final class SynchronizationHelperKt {
+ method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
+ }
+
public final class TraceKt {
method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
}
diff --git a/ui/ui-util/api/public_plus_experimental_current.txt b/ui/ui-util/api/public_plus_experimental_current.txt
index 2baff75..2452352 100644
--- a/ui/ui-util/api/public_plus_experimental_current.txt
+++ b/ui/ui-util/api/public_plus_experimental_current.txt
@@ -83,6 +83,10 @@
method public static String toStringAsFixed(float, int digits);
}
+ public final class SynchronizationHelperKt {
+ method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
+ }
+
public final class TraceKt {
method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
}
diff --git a/ui/ui-util/api/restricted_0.1.0-dev07.txt b/ui/ui-util/api/restricted_0.1.0-dev07.txt
index 2baff75..2452352 100644
--- a/ui/ui-util/api/restricted_0.1.0-dev07.txt
+++ b/ui/ui-util/api/restricted_0.1.0-dev07.txt
@@ -83,6 +83,10 @@
method public static String toStringAsFixed(float, int digits);
}
+ public final class SynchronizationHelperKt {
+ method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
+ }
+
public final class TraceKt {
method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
}
diff --git a/ui/ui-util/api/restricted_current.txt b/ui/ui-util/api/restricted_current.txt
index 2baff75..2452352 100644
--- a/ui/ui-util/api/restricted_current.txt
+++ b/ui/ui-util/api/restricted_current.txt
@@ -83,6 +83,10 @@
method public static String toStringAsFixed(float, int digits);
}
+ public final class SynchronizationHelperKt {
+ method public static <T> T! synchronized(Object lock, kotlin.jvm.functions.Function0<? extends T> block);
+ }
+
public final class TraceKt {
method public static inline <T> T! trace(String sectionName, kotlin.jvm.functions.Function0<? extends T> block);
}
diff --git a/ui/ui-util/src/main/java/androidx/ui/util/SynchronizationHelper.kt b/ui/ui-util/src/main/java/androidx/ui/util/SynchronizationHelper.kt
new file mode 100644
index 0000000..cb6a142
--- /dev/null
+++ b/ui/ui-util/src/main/java/androidx/ui/util/SynchronizationHelper.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.ui.util
+
+import kotlin.contracts.ExperimentalContracts
+import kotlin.contracts.InvocationKind
+import kotlin.contracts.contract
+
+/**
+ * [kotlin.synchronized][synchronized] is deprecated, and the build fails if we use
+ * [kotlin.synchronized][synchronized] along with the IR compiler. As a workaround, we have this
+ * function here, which is in a module that doesn't use the IR COmpiler.
+ */
+@UseExperimental(ExperimentalContracts::class)
+fun <T> synchronized(lock: Any, block: () -> T): T {
+ contract {
+ callsInPlace(block, InvocationKind.EXACTLY_ONCE)
+ }
+ return kotlin.synchronized(lock, block)
+}
\ No newline at end of file
diff --git a/window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarDisplayFeature.java b/window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarDisplayFeature.java
index 015bc15..39dcca4 100644
--- a/window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarDisplayFeature.java
+++ b/window/window-sidecar/src/main/java/androidx/window/sidecar/SidecarDisplayFeature.java
@@ -35,7 +35,7 @@
* coordinate space.
*/
@NonNull
- private Rect mRect;
+ private Rect mRect = new Rect();
/**
* The physical type of the feature.
diff --git a/window/window/build.gradle b/window/window/build.gradle
index 0350c25..296c1e5 100644
--- a/window/window/build.gradle
+++ b/window/window/build.gradle
@@ -21,6 +21,8 @@
import static androidx.build.dependencies.DependenciesKt.ANDROIDX_TEST_EXT_JUNIT
import static androidx.build.dependencies.DependenciesKt.ANDROIDX_TEST_RULES
import static androidx.build.dependencies.DependenciesKt.ANDROIDX_TEST_RUNNER
+import static androidx.build.dependencies.DependenciesKt.DEXMAKER_MOCKITO
+import static androidx.build.dependencies.DependenciesKt.MOCKITO_CORE
import static androidx.build.dependencies.DependenciesKt.TRUTH
plugins {
@@ -46,8 +48,11 @@
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
androidTestImplementation(ANDROIDX_TEST_RULES)
+ androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy)
+ androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy)
androidTestImplementation(TRUTH)
androidTestImplementation(compileOnly(project(":window:window-extensions")))
+ androidTestImplementation(compileOnly(project(":window:window-sidecar")))
}
androidx {
diff --git a/window/window/src/androidTest/java/androidx/window/CompatDeviceTestInterface.java b/window/window/src/androidTest/java/androidx/window/CompatDeviceTestInterface.java
new file mode 100644
index 0000000..a02324f
--- /dev/null
+++ b/window/window/src/androidTest/java/androidx/window/CompatDeviceTestInterface.java
@@ -0,0 +1,32 @@
+/*
+ * 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.window;
+
+/**
+ * Base interface for tests of {@link ExtensionInterfaceCompat} implementations, contains methods
+ * that each test of the device extension should include.
+ * <p>Most tests of the extension compatibility wrappers require mocked extension, they are
+ * listed in {@link CompatTestInterface}. This interface defines only the tests that can be
+ * implemented to use the extension provided on the device.
+ *
+ * @see CompatTestInterface the definition of all tests that every implementation of
+ * {@link ExtensionInterfaceCompat} should pass.
+ */
+interface CompatDeviceTestInterface {
+ void testGetDeviceState();
+ void testGetWindowLayout();
+}
diff --git a/window/window/src/androidTest/java/androidx/window/CompatTestInterface.java b/window/window/src/androidTest/java/androidx/window/CompatTestInterface.java
new file mode 100644
index 0000000..8906533
--- /dev/null
+++ b/window/window/src/androidTest/java/androidx/window/CompatTestInterface.java
@@ -0,0 +1,30 @@
+/*
+ * 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.window;
+
+/**
+ * The list of tests that every implementation of {@link ExtensionInterfaceCompat} should pass.
+ */
+interface CompatTestInterface {
+ void testGetDeviceState();
+ void testGetWindowLayout();
+ void testGetWindowLayout_featureWithEmptyBounds();
+ void testSetExtensionCallback();
+ void testOnWindowLayoutChangeListenerAdded();
+ void testOnWindowLayoutChangeListenerRemoved();
+ void testOnDeviceStateListenersChanged();
+}
diff --git a/window/window/src/androidTest/java/androidx/window/DeviceStateTest.java b/window/window/src/androidTest/java/androidx/window/DeviceStateTest.java
new file mode 100644
index 0000000..e5bd7ed
--- /dev/null
+++ b/window/window/src/androidTest/java/androidx/window/DeviceStateTest.java
@@ -0,0 +1,48 @@
+/*
+ * 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.window;
+
+import static org.junit.Assert.assertEquals;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Tests for {@link DeviceState} class. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class DeviceStateTest {
+
+ @Test
+ public void testBuilder_empty() {
+ DeviceState.Builder builder = new DeviceState.Builder();
+ DeviceState state = builder.build();
+
+ assertEquals(DeviceState.POSTURE_UNKNOWN, state.getPosture());
+ }
+
+ @Test
+ public void testBuilder_setPosture() {
+ DeviceState.Builder builder = new DeviceState.Builder();
+ builder.setPosture(DeviceState.POSTURE_OPENED);
+ DeviceState state = builder.build();
+
+ assertEquals(DeviceState.POSTURE_OPENED, state.getPosture());
+ }
+}
diff --git a/window/window/src/androidTest/java/androidx/window/DisplayFeatureTest.java b/window/window/src/androidTest/java/androidx/window/DisplayFeatureTest.java
new file mode 100644
index 0000000..900886d
--- /dev/null
+++ b/window/window/src/androidTest/java/androidx/window/DisplayFeatureTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.window;
+
+import static org.junit.Assert.assertEquals;
+
+import android.graphics.Rect;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Tests for {@link DisplayFeature} class. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class DisplayFeatureTest {
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBuilder_empty() {
+ new DisplayFeature.Builder().build();
+ }
+
+ @Test
+ public void testBuilder_setBoundsAndType() {
+ DisplayFeature.Builder builder = new DisplayFeature.Builder();
+ Rect bounds = new Rect(1, 2, 3, 4);
+ builder.setBounds(bounds);
+ builder.setType(DisplayFeature.TYPE_HINGE);
+ DisplayFeature feature = builder.build();
+
+ assertEquals(bounds, feature.getBounds());
+ assertEquals(DisplayFeature.TYPE_HINGE, feature.getType());
+ }
+}
diff --git a/window/window/src/androidTest/java/androidx/window/ExtensionCompatDeviceTest.java b/window/window/src/androidTest/java/androidx/window/ExtensionCompatDeviceTest.java
new file mode 100644
index 0000000..b3bdf9a
--- /dev/null
+++ b/window/window/src/androidTest/java/androidx/window/ExtensionCompatDeviceTest.java
@@ -0,0 +1,90 @@
+/*
+ * 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.window;
+
+import static androidx.window.Version.VERSION_1_0;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.LargeTest;
+import androidx.window.extensions.ExtensionDeviceState;
+import androidx.window.extensions.ExtensionDisplayFeature;
+import androidx.window.extensions.ExtensionWindowLayoutInfo;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for {@link ExtensionCompat} implementation of {@link ExtensionInterfaceCompat} that are
+ * executed with Extension implementation provided on the device (and only if one is available).
+ */
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class ExtensionCompatDeviceTest extends WindowTestBase implements CompatDeviceTestInterface {
+ ExtensionCompat mExtensionCompat;
+
+ @Before
+ public void setUp() {
+ assumeExtensionV1_0();
+ mExtensionCompat =
+ new ExtensionCompat((Context) ApplicationProvider.getApplicationContext());
+ }
+
+ @Test
+ @Override
+ public void testGetDeviceState() {
+ ExtensionDeviceState extensionDeviceState =
+ mExtensionCompat.mWindowExtension.getDeviceState();
+ DeviceState deviceState = mExtensionCompat.getDeviceState();
+ assertEquals(extensionDeviceState.getPosture(), deviceState.getPosture());
+ }
+
+ @Test
+ @Override
+ public void testGetWindowLayout() {
+ TestActivity activity = mActivityTestRule.launchActivity(new Intent());
+ IBinder windowToken = getActivityWindowToken(activity);
+ assertNotNull(windowToken);
+
+ ExtensionWindowLayoutInfo extensionWindowLayoutInfo =
+ mExtensionCompat.mWindowExtension.getWindowLayoutInfo(windowToken);
+ WindowLayoutInfo windowLayoutInfo = mExtensionCompat.getWindowLayoutInfo(windowToken);
+
+ for (int i = 0; i < windowLayoutInfo.getDisplayFeatures().size(); i++) {
+ DisplayFeature feature = windowLayoutInfo.getDisplayFeatures().get(i);
+ ExtensionDisplayFeature sidecarDisplayFeature =
+ extensionWindowLayoutInfo.getDisplayFeatures().get(i);
+
+ assertEquals(feature.getType(), sidecarDisplayFeature.getType());
+ assertEquals(feature.getBounds(), sidecarDisplayFeature.getBounds());
+ }
+ }
+
+ private void assumeExtensionV1_0() {
+ Version extensionVersion = ExtensionCompat.getExtensionVersion();
+ assumeTrue(extensionVersion != null && VERSION_1_0.compareTo(extensionVersion) <= 0);
+ }
+}
diff --git a/window/window/src/androidTest/java/androidx/window/ExtensionCompatTest.java b/window/window/src/androidTest/java/androidx/window/ExtensionCompatTest.java
new file mode 100644
index 0000000..b7eb109
--- /dev/null
+++ b/window/window/src/androidTest/java/androidx/window/ExtensionCompatTest.java
@@ -0,0 +1,163 @@
+/*
+ * 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.window;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.graphics.Rect;
+import android.os.IBinder;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.LargeTest;
+import androidx.window.extensions.ExtensionDeviceState;
+import androidx.window.extensions.ExtensionDisplayFeature;
+import androidx.window.extensions.ExtensionInterface;
+import androidx.window.extensions.ExtensionWindowLayoutInfo;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link ExtensionCompat} implementation of {@link ExtensionInterfaceCompat}. This
+ * class uses a mocked Extension to verify the behavior of the implementation on any hardware.
+ * <p>Because this class extends {@link ExtensionCompatDeviceTest}, it will also run the mocked
+ * versions of methods defined in {@link CompatDeviceTestInterface}.
+ */
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public final class ExtensionCompatTest extends ExtensionCompatDeviceTest
+ implements CompatTestInterface {
+
+ @Before
+ public void setUp() {
+ mExtensionCompat = new ExtensionCompat(mock(ExtensionInterface.class));
+
+ // Setup mocked extension responses
+ ExtensionDeviceState defaultDeviceState =
+ new ExtensionDeviceState(ExtensionDeviceState.POSTURE_HALF_OPENED);
+ when(mExtensionCompat.mWindowExtension.getDeviceState()).thenReturn(defaultDeviceState);
+
+ Rect bounds = new Rect(1, 2, 3, 4);
+ ExtensionDisplayFeature extensionDisplayFeatureDisplayFeature =
+ new ExtensionDisplayFeature(bounds, ExtensionDisplayFeature.TYPE_HINGE);
+ List<ExtensionDisplayFeature> displayFeatures = new ArrayList<>();
+ displayFeatures.add(extensionDisplayFeatureDisplayFeature);
+ ExtensionWindowLayoutInfo extensionWindowLayoutInfo =
+ new ExtensionWindowLayoutInfo(displayFeatures);
+ when(mExtensionCompat.mWindowExtension.getWindowLayoutInfo(any()))
+ .thenReturn(extensionWindowLayoutInfo);
+ }
+
+ @Test
+ public void testGetWindowLayout_featureWithEmptyBounds() {
+ // Add a feature with an empty bounds to the reported list
+ ExtensionWindowLayoutInfo originalWindowLayoutInfo =
+ mExtensionCompat.mWindowExtension.getWindowLayoutInfo(mock(IBinder.class));
+ List<ExtensionDisplayFeature> extensionDisplayFeatures =
+ originalWindowLayoutInfo.getDisplayFeatures();
+ extensionDisplayFeatures.add(
+ new ExtensionDisplayFeature(new Rect(), ExtensionDisplayFeature.TYPE_HINGE));
+
+ // Verify that this feature is skipped.
+ WindowLayoutInfo windowLayoutInfo =
+ mExtensionCompat.getWindowLayoutInfo(mock(IBinder.class));
+
+ assertEquals(extensionDisplayFeatures.size() - 1,
+ windowLayoutInfo.getDisplayFeatures().size());
+ }
+
+ @Test
+ @Override
+ public void testSetExtensionCallback() {
+ ArgumentCaptor<ExtensionInterface.ExtensionCallback> extensionCallbackCaptor =
+ ArgumentCaptor.forClass(ExtensionInterface.ExtensionCallback.class);
+
+ // Verify that the extension got the callback set
+ ExtensionInterfaceCompat.ExtensionCallbackInterface callback =
+ mock(ExtensionInterfaceCompat.ExtensionCallbackInterface.class);
+ mExtensionCompat.setExtensionCallback(callback);
+
+ verify(mExtensionCompat.mWindowExtension).setExtensionCallback(
+ extensionCallbackCaptor.capture());
+
+ // Verify that the callback set for extension propagates the device state callback
+ ExtensionDeviceState extensionDeviceState = new ExtensionDeviceState(
+ ExtensionDeviceState.POSTURE_HALF_OPENED);
+
+ extensionCallbackCaptor.getValue().onDeviceStateChanged(extensionDeviceState);
+ ArgumentCaptor<DeviceState> deviceStateCaptor = ArgumentCaptor.forClass(DeviceState.class);
+ verify(callback).onDeviceStateChanged(deviceStateCaptor.capture());
+ assertEquals(DeviceState.POSTURE_HALF_OPENED, deviceStateCaptor.getValue().getPosture());
+
+ // Verify that the callback set for extension propagates the window layout callback
+ Rect bounds = new Rect(1, 2, 3, 4);
+ ExtensionDisplayFeature extensionDisplayFeature =
+ new ExtensionDisplayFeature(bounds, ExtensionDisplayFeature.TYPE_HINGE);
+ List<ExtensionDisplayFeature> displayFeatures = new ArrayList<>();
+ displayFeatures.add(extensionDisplayFeature);
+ ExtensionWindowLayoutInfo extensionWindowLayoutInfo =
+ new ExtensionWindowLayoutInfo(displayFeatures);
+ IBinder windowToken = mock(IBinder.class);
+
+ extensionCallbackCaptor.getValue().onWindowLayoutChanged(windowToken,
+ extensionWindowLayoutInfo);
+ ArgumentCaptor<WindowLayoutInfo> windowLayoutInfoCaptor =
+ ArgumentCaptor.forClass(WindowLayoutInfo.class);
+ verify(callback).onWindowLayoutChanged(eq(windowToken), windowLayoutInfoCaptor.capture());
+
+ WindowLayoutInfo capturedLayout = windowLayoutInfoCaptor.getValue();
+ assertEquals(1, capturedLayout.getDisplayFeatures().size());
+ DisplayFeature capturedDisplayFeature = capturedLayout.getDisplayFeatures().get(0);
+ assertEquals(DisplayFeature.TYPE_HINGE, capturedDisplayFeature.getType());
+ assertEquals(bounds, capturedDisplayFeature.getBounds());
+ }
+
+ @Test
+ @Override
+ public void testOnWindowLayoutChangeListenerAdded() {
+ IBinder windowToken = mock(IBinder.class);
+ mExtensionCompat.onWindowLayoutChangeListenerAdded(windowToken);
+ verify(mExtensionCompat.mWindowExtension)
+ .onWindowLayoutChangeListenerAdded(eq(windowToken));
+ }
+
+ @Test
+ @Override
+ public void testOnWindowLayoutChangeListenerRemoved() {
+ IBinder windowToken = mock(IBinder.class);
+ mExtensionCompat.onWindowLayoutChangeListenerRemoved(windowToken);
+ verify(mExtensionCompat.mWindowExtension)
+ .onWindowLayoutChangeListenerRemoved(eq(windowToken));
+ }
+
+ @Test
+ @Override
+ public void testOnDeviceStateListenersChanged() {
+ mExtensionCompat.onDeviceStateListenersChanged(true);
+ verify(mExtensionCompat.mWindowExtension).onDeviceStateListenersChanged(eq(true));
+ }
+}
diff --git a/window/window/src/androidTest/java/androidx/window/ExtensionTest.java b/window/window/src/androidTest/java/androidx/window/ExtensionTest.java
index bafdd82..4c08da3 100644
--- a/window/window/src/androidTest/java/androidx/window/ExtensionTest.java
+++ b/window/window/src/androidTest/java/androidx/window/ExtensionTest.java
@@ -16,6 +16,7 @@
package androidx.window;
+import static androidx.window.ExtensionWindowBackend.initAndVerifyExtension;
import static androidx.window.Version.VERSION_0_1;
import static androidx.window.Version.VERSION_1_0;
@@ -28,7 +29,6 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;
-import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
@@ -42,13 +42,17 @@
import androidx.window.extensions.ExtensionDeviceState;
import androidx.window.extensions.ExtensionDisplayFeature;
+import com.google.common.collect.BoundType;
+import com.google.common.collect.Range;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+/** Tests for the extension implementation on the device. */
@LargeTest
@RunWith(AndroidJUnit4.class)
-public class ExtensionTest {
+public final class ExtensionTest extends WindowTestBase {
private Context mContext;
private ActivityTestRule<TestActivity> mActivityTestRule =
@@ -57,38 +61,39 @@
new ActivityTestRule<>(TestConfigChangeHandlingActivity.class, false, true);
@Before
- public void setUp() throws Exception {
+ public void setUp() {
mContext = ApplicationProvider.getApplicationContext();
}
@Test
- public void testExtensionInterface() throws Exception {
+ public void testExtensionInterface() {
assumeExtensionV10_V01();
- ExtensionInterfaceCompat extension = ExtensionHelper.getExtensionImpl(mContext);
+ ExtensionInterfaceCompat extension = initAndVerifyExtension(mContext);
assertTrue(extension.validateExtensionInterface());
}
@Test
- public void testGetDeviceState() throws Exception {
+ public void testGetDeviceState() {
assumeExtensionV10_V01();
- ExtensionInterfaceCompat extension = ExtensionHelper.getExtensionImpl(mContext);
+ ExtensionInterfaceCompat extension = initAndVerifyExtension(mContext);
DeviceState deviceState = extension.getDeviceState();
- assertThat(deviceState.getPosture()).isAtLeast(ExtensionDeviceState.POSTURE_UNKNOWN);
- assertThat(deviceState.getPosture()).isAtMost(ExtensionDeviceState.POSTURE_FLIPPED);
+ assertThat(deviceState.getPosture()).isIn(Range.range(
+ ExtensionDeviceState.POSTURE_UNKNOWN, BoundType.CLOSED,
+ ExtensionDeviceState.POSTURE_FLIPPED, BoundType.CLOSED));
}
@Test
- public void testRegisterDeviceStateChangeListener() throws Exception {
+ public void testRegisterDeviceStateChangeListener() {
assumeExtensionV10_V01();
- ExtensionInterfaceCompat extension = ExtensionHelper.getExtensionImpl(mContext);
+ ExtensionInterfaceCompat extension = initAndVerifyExtension(mContext);
extension.onDeviceStateListenersChanged(false);
extension.onDeviceStateListenersChanged(true);
}
@Test
- public void testDisplayFeatureDataClass() throws Exception {
+ public void testDisplayFeatureDataClass() {
assumeExtensionV10_V01();
Rect rect = new Rect(1, 2, 3, 4);
@@ -99,9 +104,9 @@
}
@Test
- public void testGetWindowLayoutInfo() throws Exception {
+ public void testGetWindowLayoutInfo() {
assumeExtensionV10_V01();
- ExtensionInterfaceCompat extension = ExtensionHelper.getExtensionImpl(mContext);
+ ExtensionInterfaceCompat extension = initAndVerifyExtension(mContext);
TestActivity activity = mActivityTestRule.launchActivity(new Intent());
IBinder windowToken = getActivityWindowToken(activity);
@@ -130,9 +135,9 @@
}
@Test
- public void testRegisterWindowLayoutChangeListener() throws Exception {
+ public void testRegisterWindowLayoutChangeListener() {
assumeExtensionV10_V01();
- ExtensionInterfaceCompat extension = ExtensionHelper.getExtensionImpl(mContext);
+ ExtensionInterfaceCompat extension = initAndVerifyExtension(mContext);
TestActivity activity = mActivityTestRule.launchActivity(new Intent());
IBinder windowToken = getActivityWindowToken(activity);
@@ -143,9 +148,9 @@
}
@Test
- public void testWindowLayoutUpdatesOnConfigChange() throws Exception {
+ public void testWindowLayoutUpdatesOnConfigChange() {
assumeExtensionV10_V01();
- ExtensionInterfaceCompat extension = ExtensionHelper.getExtensionImpl(mContext);
+ ExtensionInterfaceCompat extension = initAndVerifyExtension(mContext);
TestConfigChangeHandlingActivity activity =
mConfigHandlingActivityTestRule.launchActivity(new Intent());
@@ -173,9 +178,9 @@
}
@Test
- public void testWindowLayoutUpdatesOnRecreate() throws Exception {
+ public void testWindowLayoutUpdatesOnRecreate() {
assumeExtensionV10_V01();
- ExtensionInterfaceCompat extension = ExtensionHelper.getExtensionImpl(mContext);
+ ExtensionInterfaceCompat extension = initAndVerifyExtension(mContext);
TestActivity activity = mActivityTestRule.launchActivity(new Intent());
@@ -208,7 +213,7 @@
}
@Test
- public void testVersionSupport() throws Exception {
+ public void testVersionSupport() {
// Only versions 1.0 and 0.1 are supported for now
Version version = SidecarCompat.getSidecarVersion();
if (version != null) {
@@ -224,8 +229,4 @@
assumeTrue(VERSION_1_0.equals(ExtensionCompat.getExtensionVersion())
|| VERSION_0_1.equals(SidecarCompat.getSidecarVersion()));
}
-
- private IBinder getActivityWindowToken(Activity activity) {
- return activity.getWindow().getAttributes().token;
- }
}
diff --git a/window/window/src/androidTest/java/androidx/window/ExtensionWindowBackendTest.java b/window/window/src/androidTest/java/androidx/window/ExtensionWindowBackendTest.java
new file mode 100644
index 0000000..bb795c6
--- /dev/null
+++ b/window/window/src/androidTest/java/androidx/window/ExtensionWindowBackendTest.java
@@ -0,0 +1,323 @@
+/*
+ * 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.window;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeNotNull;
+import static org.junit.Assume.assumeTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.verify;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.IBinder;
+
+import androidx.core.util.Consumer;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.LargeTest;
+
+import com.google.common.collect.BoundType;
+import com.google.common.collect.Range;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/** Tests for {@link ExtensionWindowBackend} class. */
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public final class ExtensionWindowBackendTest extends WindowTestBase {
+ private Context mContext;
+
+ @Before
+ public void setUp() {
+ mContext = ApplicationProvider.getApplicationContext();
+ ExtensionWindowBackend.resetInstance();
+ }
+
+ @Test
+ public void testGetInstance() {
+ ExtensionWindowBackend backend = ExtensionWindowBackend.getInstance(mContext);
+ assertNotNull(backend);
+
+ // Verify that getInstance always returns the same value
+ ExtensionWindowBackend newBackend = ExtensionWindowBackend.getInstance(mContext);
+ assertEquals(backend, newBackend);
+ }
+
+ @Test
+ public void testInitAndVerifyExtension() {
+ Version extensionVersion = ExtensionCompat.getExtensionVersion();
+ assumeTrue(extensionVersion != null);
+ assertTrue(ExtensionWindowBackend.isExtensionVersionSupported(extensionVersion));
+
+ ExtensionInterfaceCompat extension =
+ ExtensionWindowBackend.initAndVerifyExtension(mContext);
+ assertNotNull(extension);
+ assertTrue(extension instanceof ExtensionCompat);
+ assertTrue(extension.validateExtensionInterface());
+ }
+
+ @Test
+ public void testInitAndVerifySidecar() {
+ Version sidecarVersion = SidecarCompat.getSidecarVersion();
+ assumeTrue(sidecarVersion != null);
+ assertTrue(ExtensionWindowBackend.isExtensionVersionSupported(sidecarVersion));
+
+ ExtensionInterfaceCompat sidecar =
+ ExtensionWindowBackend.initAndVerifyExtension(mContext);
+ assertNotNull(sidecar);
+ assertTrue(sidecar instanceof SidecarCompat);
+ assertTrue(sidecar.validateExtensionInterface());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testGetWindowLayoutInfo_applicationContext() {
+ ExtensionWindowBackend backend = ExtensionWindowBackend.getInstance(mContext);
+ backend.mWindowExtension = mock(ExtensionInterfaceCompat.class);
+
+ backend.getWindowLayoutInfo(mContext);
+ }
+
+ @Test
+ public void testGetWindowLayoutInfo_activityContext_deviceExtension() {
+ ExtensionWindowBackend backend = ExtensionWindowBackend.getInstance(mContext);
+ assumeNotNull(backend.mWindowExtension);
+
+ TestActivity activity = mActivityTestRule.launchActivity(new Intent());
+ WindowLayoutInfo layoutInfo = backend.getWindowLayoutInfo(activity);
+ assertNotNull(layoutInfo);
+ assertNotNull(layoutInfo.getDisplayFeatures());
+ IBinder windowToken = getActivityWindowToken(activity);
+ }
+
+ @Test
+ public void testGetWindowLayoutInfo_activityContext_noExtension() {
+ // Verify method with extension
+ ExtensionWindowBackend backend = ExtensionWindowBackend.getInstance(mContext);
+ assumeTrue(backend.mWindowExtension == null);
+ backend.mWindowExtension = mock(ExtensionInterfaceCompat.class);
+
+ TestActivity activity = mActivityTestRule.launchActivity(new Intent());
+ WindowLayoutInfo layoutInfo = backend.getWindowLayoutInfo(activity);
+ assertNotNull(layoutInfo);
+ assertNotNull(layoutInfo.getDisplayFeatures());
+ IBinder windowToken = getActivityWindowToken(activity);
+ verify(backend.mWindowExtension).getWindowLayoutInfo(eq(windowToken));
+ WindowLayoutInfo initialLastReportedState =
+ backend.mLastReportedWindowLayouts.get(windowToken);
+
+ // Verify method without extension
+ backend.mWindowExtension = null;
+ layoutInfo = backend.getWindowLayoutInfo(activity);
+ assertNotNull(layoutInfo);
+ assertNotNull(layoutInfo.getDisplayFeatures());
+ assertTrue(layoutInfo.getDisplayFeatures().isEmpty());
+
+ // Verify that last reported state does not change when using the getter
+ assertEquals(initialLastReportedState, backend.mLastReportedWindowLayouts.get(windowToken));
+ }
+
+ @Test
+ public void testGetDeviceState_deviceExtension() {
+ ExtensionWindowBackend backend = ExtensionWindowBackend.getInstance(mContext);
+ assumeNotNull(backend.mWindowExtension);
+
+ DeviceState deviceState = backend.getDeviceState();
+ assertNotNull(deviceState);
+ assertThat(deviceState.getPosture()).isIn(Range.range(
+ DeviceState.POSTURE_UNKNOWN, BoundType.CLOSED,
+ DeviceState.POSTURE_MAX_KNOWN, BoundType.CLOSED));
+ }
+
+ @Test
+ public void testGetDeviceState_noExtension() {
+ // Verify method with extension
+ ExtensionWindowBackend backend = ExtensionWindowBackend.getInstance(mContext);
+ assumeTrue(backend.mWindowExtension == null);
+ backend.mWindowExtension = mock(ExtensionInterfaceCompat.class);
+
+ DeviceState deviceState = backend.getDeviceState();
+ assertNotNull(deviceState);
+ assertThat(deviceState.getPosture()).isIn(Range.range(
+ DeviceState.POSTURE_UNKNOWN, BoundType.CLOSED,
+ DeviceState.POSTURE_MAX_KNOWN, BoundType.CLOSED));
+ verify(backend.mWindowExtension).getDeviceState();
+ DeviceState initialLastReportedState = backend.mLastReportedDeviceState;
+
+ // Verify method without extension
+ backend.mWindowExtension = null;
+ deviceState = backend.getDeviceState();
+ assertNotNull(deviceState);
+ assertEquals(DeviceState.POSTURE_UNKNOWN, deviceState.getPosture());
+ // Verify that last reported state does not change when using the getter
+ assertEquals(initialLastReportedState, backend.mLastReportedDeviceState);
+ }
+
+ @Test
+ public void testRegisterLayoutChangeCallback() {
+ ExtensionWindowBackend backend = ExtensionWindowBackend.getInstance(mContext);
+ backend.mWindowExtension = mock(ExtensionInterfaceCompat.class);
+
+ // Check registering the layout change callback
+ Consumer<WindowLayoutInfo> consumer = mock(Consumer.class);
+ TestActivity activity = mActivityTestRule.launchActivity(new Intent());
+ backend.registerLayoutChangeCallback(activity, Runnable::run, consumer);
+
+ assertEquals(1, backend.mWindowLayoutChangeCallbacks.size());
+ verify(backend.mWindowExtension).onWindowLayoutChangeListenerAdded(
+ eq(getActivityWindowToken(activity)));
+
+ // Check unregistering the layout change callback
+ backend.unregisterLayoutChangeCallback(consumer);
+
+ assertTrue(backend.mWindowLayoutChangeCallbacks.isEmpty());
+ verify(backend.mWindowExtension).onWindowLayoutChangeListenerRemoved(
+ eq(getActivityWindowToken(activity)));
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testRegisterLayoutChangeCallback_activityNoWindow() {
+ ExtensionWindowBackend backend = ExtensionWindowBackend.getInstance(mContext);
+ backend.mWindowExtension = mock(ExtensionInterfaceCompat.class);
+
+ backend.registerLayoutChangeCallback(mock(Activity.class), mock(Executor.class),
+ mock(Consumer.class));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testRegisterLayoutChangeCallback_applicationContext() {
+ ExtensionWindowBackend backend = ExtensionWindowBackend.getInstance(mContext);
+ backend.mWindowExtension = mock(ExtensionInterfaceCompat.class);
+
+ backend.registerLayoutChangeCallback(mContext, mock(Executor.class),
+ mock(Consumer.class));
+ }
+
+ @Test
+ public void testLayoutChangeCallback() {
+ ExtensionWindowBackend backend = ExtensionWindowBackend.getInstance(mContext);
+ backend.mWindowExtension = mock(ExtensionInterfaceCompat.class);
+
+ // Check that callbacks from the extension are propagated correctly
+ Consumer<WindowLayoutInfo> consumer = mock(Consumer.class);
+ TestActivity activity = mActivityTestRule.launchActivity(new Intent());
+ IBinder windowToken = getActivityWindowToken(activity);
+
+ backend.registerLayoutChangeCallback(activity, Runnable::run, consumer);
+ WindowLayoutInfo windowLayoutInfo = newTestWindowLayoutInfo();
+
+ ExtensionWindowBackend.ExtensionListenerImpl backendListener =
+ backend.new ExtensionListenerImpl();
+ backendListener.onWindowLayoutChanged(windowToken, windowLayoutInfo);
+
+ verify(consumer).accept(eq(windowLayoutInfo));
+ assertEquals(windowLayoutInfo, backend.mLastReportedWindowLayouts.get(windowToken));
+
+ // Test that the same value wouldn't be reported again
+ reset(consumer);
+ backendListener.onWindowLayoutChanged(windowToken, windowLayoutInfo);
+ verify(consumer, never()).accept(any());
+ }
+
+ @Test
+ public void testRegisterDeviceChangeCallback() {
+ ExtensionWindowBackend backend = ExtensionWindowBackend.getInstance(mContext);
+ backend.mWindowExtension = mock(ExtensionInterfaceCompat.class);
+
+ // Check registering the device state change callback
+ Consumer<DeviceState> consumer = mock(Consumer.class);
+ backend.registerDeviceStateChangeCallback(Runnable::run, consumer);
+
+ assertEquals(1, backend.mDeviceStateChangeCallbacks.size());
+ verify(backend.mWindowExtension).onDeviceStateListenersChanged(eq(false));
+
+ // Check unregistering the device state change callback
+ backend.unregisterDeviceStateChangeCallback(consumer);
+
+ assertTrue(backend.mDeviceStateChangeCallbacks.isEmpty());
+ verify(backend.mWindowExtension).onDeviceStateListenersChanged(eq(true));
+ }
+
+ @Test
+ public void testDeviceChangeCallback() {
+ ExtensionWindowBackend backend = ExtensionWindowBackend.getInstance(mContext);
+ backend.mWindowExtension = mock(ExtensionInterfaceCompat.class);
+
+ // Check that callbacks from the extension are propagated correctly
+ Consumer<DeviceState> consumer = mock(Consumer.class);
+
+ backend.registerDeviceStateChangeCallback(Runnable::run, consumer);
+ DeviceState deviceState = newTestDeviceState();
+ ExtensionWindowBackend.ExtensionListenerImpl backendListener =
+ backend.new ExtensionListenerImpl();
+ backendListener.onDeviceStateChanged(deviceState);
+
+ verify(consumer).accept(eq(deviceState));
+ assertEquals(deviceState, backend.mLastReportedDeviceState);
+
+ // Test that the same value wouldn't be reported again
+ reset(consumer);
+ backendListener.onDeviceStateChanged(deviceState);
+ verify(consumer, never()).accept(any());
+ }
+
+ private static WindowLayoutInfo newTestWindowLayoutInfo() {
+ WindowLayoutInfo.Builder builder = new WindowLayoutInfo.Builder();
+ WindowLayoutInfo windowLayoutInfo = builder.build();
+
+ assertTrue(windowLayoutInfo.getDisplayFeatures().isEmpty());
+
+ DisplayFeature.Builder featureBuilder = new DisplayFeature.Builder();
+ featureBuilder.setType(DisplayFeature.TYPE_HINGE);
+ featureBuilder.setBounds(new Rect(1, 2, 3, 4));
+ DisplayFeature feature1 = featureBuilder.build();
+
+ featureBuilder = new DisplayFeature.Builder();
+ featureBuilder.setBounds(new Rect(5, 6, 7, 8));
+ DisplayFeature feature2 = featureBuilder.build();
+
+ List<DisplayFeature> displayFeatures = new ArrayList<>();
+ displayFeatures.add(feature1);
+ displayFeatures.add(feature2);
+
+ builder = new WindowLayoutInfo.Builder();
+ builder.setDisplayFeatures(displayFeatures);
+ return builder.build();
+ }
+
+ private static DeviceState newTestDeviceState() {
+ DeviceState.Builder builder = new DeviceState.Builder();
+ builder.setPosture(DeviceState.POSTURE_OPENED);
+ return builder.build();
+ }
+}
diff --git a/window/window/src/androidTest/java/androidx/window/SidecarCompatDeviceTest.java b/window/window/src/androidTest/java/androidx/window/SidecarCompatDeviceTest.java
new file mode 100644
index 0000000..73980ba
--- /dev/null
+++ b/window/window/src/androidTest/java/androidx/window/SidecarCompatDeviceTest.java
@@ -0,0 +1,88 @@
+/*
+ * 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.window;
+
+import static androidx.window.Version.VERSION_0_1;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assume.assumeTrue;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.LargeTest;
+import androidx.window.sidecar.SidecarDeviceState;
+import androidx.window.sidecar.SidecarDisplayFeature;
+import androidx.window.sidecar.SidecarWindowLayoutInfo;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for {@link SidecarCompat} implementation of {@link ExtensionInterfaceCompat} that are
+ * executed with Sidecar implementation provided on the device (and only if one is available).
+ */
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public class SidecarCompatDeviceTest extends WindowTestBase implements CompatDeviceTestInterface {
+ SidecarCompat mSidecarCompat;
+
+ @Before
+ public void setUp() {
+ assumeExtensionV01();
+ mSidecarCompat = new SidecarCompat((Context) ApplicationProvider.getApplicationContext());
+ }
+
+ @Test
+ @Override
+ public void testGetDeviceState() {
+ SidecarDeviceState sidecarDeviceState = mSidecarCompat.mSidecar.getDeviceState();
+ DeviceState deviceState = mSidecarCompat.getDeviceState();
+ assertEquals(sidecarDeviceState.posture, deviceState.getPosture());
+ }
+
+ @Test
+ @Override
+ public void testGetWindowLayout() {
+ TestActivity activity = mActivityTestRule.launchActivity(new Intent());
+ IBinder windowToken = getActivityWindowToken(activity);
+ assertNotNull(windowToken);
+
+ SidecarWindowLayoutInfo sidecarWindowLayoutInfo =
+ mSidecarCompat.mSidecar.getWindowLayoutInfo(windowToken);
+ WindowLayoutInfo windowLayoutInfo = mSidecarCompat.getWindowLayoutInfo(windowToken);
+
+ for (int i = 0; i < windowLayoutInfo.getDisplayFeatures().size(); i++) {
+ DisplayFeature feature = windowLayoutInfo.getDisplayFeatures().get(i);
+ SidecarDisplayFeature sidecarDisplayFeature =
+ sidecarWindowLayoutInfo.displayFeatures.get(i);
+
+ assertEquals(feature.getType(), sidecarDisplayFeature.getType());
+ assertEquals(feature.getBounds(), sidecarDisplayFeature.getRect());
+ }
+ }
+
+ private void assumeExtensionV01() {
+ Version sidecarVersion = SidecarCompat.getSidecarVersion();
+ assumeTrue(VERSION_0_1.equals(sidecarVersion));
+ }
+}
diff --git a/window/window/src/androidTest/java/androidx/window/SidecarCompatTest.java b/window/window/src/androidTest/java/androidx/window/SidecarCompatTest.java
new file mode 100644
index 0000000..6d1e898
--- /dev/null
+++ b/window/window/src/androidTest/java/androidx/window/SidecarCompatTest.java
@@ -0,0 +1,160 @@
+/*
+ * 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.window;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.graphics.Rect;
+import android.os.IBinder;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.LargeTest;
+import androidx.window.sidecar.SidecarDeviceState;
+import androidx.window.sidecar.SidecarDisplayFeature;
+import androidx.window.sidecar.SidecarInterface;
+import androidx.window.sidecar.SidecarWindowLayoutInfo;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests for {@link SidecarCompat} implementation of {@link ExtensionInterfaceCompat}. This class
+ * uses a mocked Sidecar to verify the behavior of the implementation on any hardware.
+ * <p>Because this class extends {@link SidecarCompatDeviceTest}, it will also run the mocked
+ * versions of methods defined in {@link CompatDeviceTestInterface}.
+ */
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public final class SidecarCompatTest extends SidecarCompatDeviceTest
+ implements CompatTestInterface {
+
+ @Before
+ public void setUp() {
+ mSidecarCompat = new SidecarCompat(mock(SidecarInterface.class));
+
+ // Setup mocked sidecar responses
+ SidecarDeviceState defaultDeviceState = new SidecarDeviceState();
+ defaultDeviceState.posture = SidecarDeviceState.POSTURE_HALF_OPENED;
+ when(mSidecarCompat.mSidecar.getDeviceState()).thenReturn(defaultDeviceState);
+
+ SidecarDisplayFeature sidecarDisplayFeature = new SidecarDisplayFeature();
+ sidecarDisplayFeature.setType(SidecarDisplayFeature.TYPE_HINGE);
+ Rect bounds = new Rect(1, 2, 3, 4);
+ sidecarDisplayFeature.setRect(bounds);
+ SidecarWindowLayoutInfo sidecarWindowLayoutInfo = new SidecarWindowLayoutInfo();
+ sidecarWindowLayoutInfo.displayFeatures = new ArrayList<>();
+ sidecarWindowLayoutInfo.displayFeatures.add(sidecarDisplayFeature);
+ when(mSidecarCompat.mSidecar.getWindowLayoutInfo(any()))
+ .thenReturn(sidecarWindowLayoutInfo);
+ }
+
+ @Test
+ public void testGetWindowLayout_featureWithEmptyBounds() {
+ // Add a feature with an empty bounds to the reported list
+ SidecarWindowLayoutInfo originalWindowLayoutInfo =
+ mSidecarCompat.mSidecar.getWindowLayoutInfo(mock(IBinder.class));
+ List<SidecarDisplayFeature> sidecarDisplayFeatures =
+ originalWindowLayoutInfo.displayFeatures;
+ SidecarDisplayFeature newFeature = new SidecarDisplayFeature();
+ newFeature.setRect(new Rect());
+ sidecarDisplayFeatures.add(newFeature);
+
+ // Verify that this feature is skipped.
+ WindowLayoutInfo windowLayoutInfo = mSidecarCompat.getWindowLayoutInfo(mock(IBinder.class));
+
+ assertEquals(sidecarDisplayFeatures.size() - 1,
+ windowLayoutInfo.getDisplayFeatures().size());
+ }
+
+ @Test
+ @Override
+ public void testSetExtensionCallback() {
+ ArgumentCaptor<SidecarInterface.SidecarCallback> sidecarCallbackCaptor =
+ ArgumentCaptor.forClass(SidecarInterface.SidecarCallback.class);
+
+ // Verify that the sidecar got the callback set
+ ExtensionInterfaceCompat.ExtensionCallbackInterface callback =
+ mock(ExtensionInterfaceCompat.ExtensionCallbackInterface.class);
+ mSidecarCompat.setExtensionCallback(callback);
+
+ verify(mSidecarCompat.mSidecar).setSidecarCallback(sidecarCallbackCaptor.capture());
+
+ // Verify that the callback set for sidecar propagates the device state callback
+ SidecarDeviceState sidecarDeviceState = new SidecarDeviceState();
+ sidecarDeviceState.posture = SidecarDeviceState.POSTURE_HALF_OPENED;
+
+ sidecarCallbackCaptor.getValue().onDeviceStateChanged(sidecarDeviceState);
+ ArgumentCaptor<DeviceState> deviceStateCaptor = ArgumentCaptor.forClass(DeviceState.class);
+ verify(callback).onDeviceStateChanged(deviceStateCaptor.capture());
+ assertEquals(DeviceState.POSTURE_HALF_OPENED, deviceStateCaptor.getValue().getPosture());
+
+ // Verify that the callback set for sidecar propagates the window layout callback
+ SidecarDisplayFeature sidecarDisplayFeature = new SidecarDisplayFeature();
+ sidecarDisplayFeature.setType(SidecarDisplayFeature.TYPE_HINGE);
+ Rect bounds = new Rect(1, 2, 3, 4);
+ sidecarDisplayFeature.setRect(bounds);
+ SidecarWindowLayoutInfo sidecarWindowLayoutInfo = new SidecarWindowLayoutInfo();
+ sidecarWindowLayoutInfo.displayFeatures = new ArrayList<>();
+ sidecarWindowLayoutInfo.displayFeatures.add(sidecarDisplayFeature);
+ IBinder windowToken = mock(IBinder.class);
+
+ sidecarCallbackCaptor.getValue().onWindowLayoutChanged(windowToken,
+ sidecarWindowLayoutInfo);
+ ArgumentCaptor<WindowLayoutInfo> windowLayoutInfoCaptor =
+ ArgumentCaptor.forClass(WindowLayoutInfo.class);
+ verify(callback).onWindowLayoutChanged(eq(windowToken), windowLayoutInfoCaptor.capture());
+
+ WindowLayoutInfo capturedLayout = windowLayoutInfoCaptor.getValue();
+ assertEquals(1, capturedLayout.getDisplayFeatures().size());
+ DisplayFeature capturedDisplayFeature = capturedLayout.getDisplayFeatures().get(0);
+ assertEquals(DisplayFeature.TYPE_HINGE, capturedDisplayFeature.getType());
+ assertEquals(bounds, capturedDisplayFeature.getBounds());
+ }
+
+ @Test
+ @Override
+ public void testOnWindowLayoutChangeListenerAdded() {
+ IBinder windowToken = mock(IBinder.class);
+ mSidecarCompat.onWindowLayoutChangeListenerAdded(windowToken);
+ verify(mSidecarCompat.mSidecar).onWindowLayoutChangeListenerAdded(eq(windowToken));
+ }
+
+ @Test
+ @Override
+ public void testOnWindowLayoutChangeListenerRemoved() {
+ IBinder windowToken = mock(IBinder.class);
+ mSidecarCompat.onWindowLayoutChangeListenerRemoved(windowToken);
+ verify(mSidecarCompat.mSidecar).onWindowLayoutChangeListenerRemoved(eq(windowToken));
+ }
+
+ @Test
+ @Override
+ public void testOnDeviceStateListenersChanged() {
+ mSidecarCompat.onDeviceStateListenersChanged(true);
+ verify(mSidecarCompat.mSidecar).onDeviceStateListenersChanged(eq(true));
+ }
+}
diff --git a/window/window/src/androidTest/java/androidx/window/TestConfigChangeHandlingActivity.java b/window/window/src/androidTest/java/androidx/window/TestConfigChangeHandlingActivity.java
index 55a59a0..2f42d07 100644
--- a/window/window/src/androidTest/java/androidx/window/TestConfigChangeHandlingActivity.java
+++ b/window/window/src/androidTest/java/androidx/window/TestConfigChangeHandlingActivity.java
@@ -17,5 +17,5 @@
package androidx.window;
/** Activity that handles orientation configuration change. */
-public class TestConfigChangeHandlingActivity extends TestActivity {
+public final class TestConfigChangeHandlingActivity extends TestActivity {
}
diff --git a/window/window/src/androidTest/java/androidx/window/VersionTest.java b/window/window/src/androidTest/java/androidx/window/VersionTest.java
new file mode 100644
index 0000000..ce83b7f
--- /dev/null
+++ b/window/window/src/androidTest/java/androidx/window/VersionTest.java
@@ -0,0 +1,84 @@
+/*
+ * 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.window;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class VersionTest {
+
+ @Test
+ public void testParse() {
+ // Test valid version string
+ Version v = Version.parse("1.2.3-test");
+ assertNotNull(v);
+ assertEquals(1, v.getMajor());
+ assertEquals(2, v.getMinor());
+ assertEquals(3, v.getPatch());
+ assertEquals("test", v.getDescription());
+
+ // Test invalid version string
+ v = Version.parse("invalid");
+ assertNull(v);
+ }
+
+ @Test
+ public void testCompareTo() {
+ // Test diff in major
+ Version v1 = Version.parse("2.2.3-test");
+ Version v2 = Version.parse("1.2.3-test");
+ assertThat(v1.compareTo(v2)).isGreaterThan(0);
+ assertThat(v2.compareTo(v1)).isLessThan(0);
+
+ // Test diff in minor
+ v1 = Version.parse("1.2.3-test");
+ v2 = Version.parse("1.1.3-test");
+ assertThat(v1.compareTo(v2)).isGreaterThan(0);
+ assertThat(v2.compareTo(v1)).isLessThan(0);
+
+ // Test diff in patch
+ v1 = Version.parse("1.2.3-test");
+ v2 = Version.parse("1.2.0-test");
+ assertThat(v1.compareTo(v2)).isGreaterThan(0);
+ assertThat(v2.compareTo(v1)).isLessThan(0);
+
+ // Test equals. Description is not included in the check.
+ v1 = Version.parse("1.2.3-t1");
+ v2 = Version.parse("1.2.3-t2");
+ assertEquals(v1, v2);
+ assertEquals(v1.hashCode(), v2.hashCode());
+ }
+
+ @Test
+ public void testStatics() {
+ assertEquals(Version.parse("0.1.0-1"), Version.VERSION_0_1);
+ assertEquals(Version.parse("1.0.0-2"), Version.VERSION_1_0);
+ assertEquals(Version.parse("0.0.0-3"), Version.UNKNOWN);
+ assertEquals(Version.CURRENT, Version.VERSION_1_0);
+ }
+}
diff --git a/window/window/src/androidTest/java/androidx/window/WindowBackendTest.java b/window/window/src/androidTest/java/androidx/window/WindowBackendTest.java
index abc59e7..60f2226 100644
--- a/window/window/src/androidTest/java/androidx/window/WindowBackendTest.java
+++ b/window/window/src/androidTest/java/androidx/window/WindowBackendTest.java
@@ -26,7 +26,6 @@
import androidx.core.util.Consumer;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
-import androidx.test.rule.ActivityTestRule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -35,11 +34,10 @@
import java.util.List;
import java.util.concurrent.Executor;
+/** Tests for {@link WindowBackend} class. */
@LargeTest
@RunWith(AndroidJUnit4.class)
-public class WindowBackendTest {
- private ActivityTestRule<TestActivity> mActivityTestRule =
- new ActivityTestRule<>(TestActivity.class, false, true);
+public final class WindowBackendTest extends WindowTestBase {
/**
* Verify that {@link WindowManager} instance would use the assigned
@@ -47,8 +45,8 @@
*/
@Test
public void testFakeWindowBackend() {
- WindowLayoutInfo windowLayoutInfo = testWindowLayout();
- DeviceState deviceState = testDeviceState();
+ WindowLayoutInfo windowLayoutInfo = newTestWindowLayout();
+ DeviceState deviceState = newTestDeviceState();
WindowBackend windowBackend = new FakeWindowBackend(windowLayoutInfo, deviceState);
TestActivity activity = mActivityTestRule.launchActivity(new Intent());
WindowManager wm = new WindowManager(activity, windowBackend);
@@ -57,7 +55,7 @@
assertEquals(deviceState, wm.getDeviceState());
}
- private WindowLayoutInfo testWindowLayout() {
+ private WindowLayoutInfo newTestWindowLayout() {
List<DisplayFeature> displayFeatureList = new ArrayList<>();
DisplayFeature displayFeature = new DisplayFeature(
new Rect(10, 10, 100, 100), DisplayFeature.TYPE_HINGE);
@@ -65,7 +63,7 @@
return new WindowLayoutInfo(displayFeatureList);
}
- private DeviceState testDeviceState() {
+ private DeviceState newTestDeviceState() {
return new DeviceState(DeviceState.POSTURE_OPENED);
}
diff --git a/window/window/src/androidTest/java/androidx/window/WindowLayoutInfoTest.java b/window/window/src/androidTest/java/androidx/window/WindowLayoutInfoTest.java
new file mode 100644
index 0000000..e9f86ae
--- /dev/null
+++ b/window/window/src/androidTest/java/androidx/window/WindowLayoutInfoTest.java
@@ -0,0 +1,68 @@
+/*
+ * 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.window;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertEquals;
+
+import android.graphics.Rect;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Tests for {@link WindowLayoutInfo} class. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class WindowLayoutInfoTest {
+
+ @Test
+ public void testBuilder_empty() {
+ WindowLayoutInfo.Builder builder = new WindowLayoutInfo.Builder();
+ WindowLayoutInfo windowLayoutInfo = builder.build();
+
+ assertThat(windowLayoutInfo.getDisplayFeatures()).isEmpty();
+ }
+
+ @Test
+ public void testBuilder_setDisplayFeatures() {
+ DisplayFeature.Builder featureBuilder = new DisplayFeature.Builder();
+ featureBuilder.setType(DisplayFeature.TYPE_HINGE);
+ featureBuilder.setBounds(new Rect(1, 2, 3, 4));
+ DisplayFeature feature1 = featureBuilder.build();
+
+ featureBuilder = new DisplayFeature.Builder();
+ featureBuilder.setBounds(new Rect(5, 6, 7, 8));
+ DisplayFeature feature2 = featureBuilder.build();
+
+ List<DisplayFeature> displayFeatures = new ArrayList<>();
+ displayFeatures.add(feature1);
+ displayFeatures.add(feature2);
+
+ WindowLayoutInfo.Builder builder = new WindowLayoutInfo.Builder();
+ builder.setDisplayFeatures(displayFeatures);
+ WindowLayoutInfo windowLayoutInfo = builder.build();
+
+ assertEquals(displayFeatures, windowLayoutInfo.getDisplayFeatures());
+ }
+}
diff --git a/window/window/src/androidTest/java/androidx/window/WindowManagerTest.java b/window/window/src/androidTest/java/androidx/window/WindowManagerTest.java
new file mode 100644
index 0000000..5546366
--- /dev/null
+++ b/window/window/src/androidTest/java/androidx/window/WindowManagerTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.window;
+
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import android.app.Activity;
+import android.content.ContextWrapper;
+
+import androidx.core.util.Consumer;
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.LargeTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.concurrent.Executor;
+
+/** Tests for {@link WindowManager} class. */
+@LargeTest
+@RunWith(AndroidJUnit4.class)
+public final class WindowManagerTest extends WindowTestBase {
+
+ @Test
+ public void testConstructor_activity() {
+ new WindowManager(mock(Activity.class), mock(WindowBackend.class));
+ }
+
+ @Test
+ public void testConstructor_wrappedActivity() {
+ new WindowManager(new ContextWrapper(mock(Activity.class)), mock(WindowBackend.class));
+ }
+
+ @Test
+ public void testConstructor_nullWindowBackend() {
+ new WindowManager(mock(Activity.class), null);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConstructor_applicationContext() {
+ new WindowManager(ApplicationProvider.getApplicationContext(), mock(WindowBackend.class));
+ }
+
+ @Test
+ public void testGetWindowLayoutInfo() {
+ WindowBackend backend = mock(WindowBackend.class);
+ Activity activity = mock(Activity.class);
+ WindowManager wm = new WindowManager(activity, backend);
+
+ wm.getWindowLayoutInfo();
+ verify(backend).getWindowLayoutInfo(eq(activity));
+ }
+
+ @Test
+ public void testGetDeviceState() {
+ WindowBackend backend = mock(WindowBackend.class);
+ WindowManager wm = new WindowManager(mock(Activity.class), backend);
+
+ wm.getDeviceState();
+ verify(backend).getDeviceState();
+ }
+
+ @Test
+ public void testRegisterLayoutChangeCallback() {
+ WindowBackend backend = mock(WindowBackend.class);
+ Activity activity = mock(Activity.class);
+ WindowManager wm = new WindowManager(activity, backend);
+
+ Executor executor = mock(Executor.class);
+ Consumer<WindowLayoutInfo> consumer = mock(Consumer.class);
+ wm.registerLayoutChangeCallback(executor, consumer);
+ verify(backend).registerLayoutChangeCallback(eq(activity), eq(executor), eq(consumer));
+
+ wm.unregisterLayoutChangeCallback(consumer);
+ verify(backend).unregisterLayoutChangeCallback(eq(consumer));
+ }
+
+ @Test
+ public void testRegisterDeviceStateChangeCallback() {
+ WindowBackend backend = mock(WindowBackend.class);
+ Activity activity = mock(Activity.class);
+ WindowManager wm = new WindowManager(activity, backend);
+
+ Executor executor = mock(Executor.class);
+ Consumer<DeviceState> consumer = mock(Consumer.class);
+ wm.registerDeviceStateChangeCallback(executor, consumer);
+ verify(backend).registerDeviceStateChangeCallback(eq(executor), eq(consumer));
+
+ wm.unregisterDeviceStateChangeCallback(consumer);
+ verify(backend).unregisterDeviceStateChangeCallback(eq(consumer));
+ }
+}
diff --git a/window/window/src/androidTest/java/androidx/window/WindowTestBase.java b/window/window/src/androidTest/java/androidx/window/WindowTestBase.java
new file mode 100644
index 0000000..afa2bee
--- /dev/null
+++ b/window/window/src/androidTest/java/androidx/window/WindowTestBase.java
@@ -0,0 +1,34 @@
+/*
+ * 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.window;
+
+import android.app.Activity;
+import android.os.IBinder;
+
+import androidx.test.rule.ActivityTestRule;
+
+/**
+ * Base class for all tests in the module.
+ */
+class WindowTestBase {
+ ActivityTestRule<TestActivity> mActivityTestRule =
+ new ActivityTestRule<>(TestActivity.class, false, true);
+
+ static IBinder getActivityWindowToken(Activity activity) {
+ return activity.getWindow().getAttributes().token;
+ }
+}
diff --git a/window/window/src/main/java/androidx/window/DisplayFeature.java b/window/window/src/main/java/androidx/window/DisplayFeature.java
index 46e1309..a7eb874 100644
--- a/window/window/src/main/java/androidx/window/DisplayFeature.java
+++ b/window/window/src/main/java/androidx/window/DisplayFeature.java
@@ -41,6 +41,9 @@
private int mType;
DisplayFeature(@NonNull Rect bounds, @Type int type) {
+ if (bounds.height() == 0 && bounds.width() == 0) {
+ throw new IllegalArgumentException("Bounding rectangle must not be empty: " + bounds);
+ }
mBounds = new Rect(bounds);
mType = type;
}
diff --git a/window/window/src/main/java/androidx/window/ExtensionCompat.java b/window/window/src/main/java/androidx/window/ExtensionCompat.java
index 4edf49b..35d428c 100644
--- a/window/window/src/main/java/androidx/window/ExtensionCompat.java
+++ b/window/window/src/main/java/androidx/window/ExtensionCompat.java
@@ -18,7 +18,6 @@
import static androidx.window.DeviceState.POSTURE_MAX_KNOWN;
import static androidx.window.DeviceState.POSTURE_UNKNOWN;
-import static androidx.window.ExtensionHelper.DEBUG;
import android.annotation.SuppressLint;
import android.content.Context;
@@ -29,6 +28,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import androidx.window.extensions.ExtensionDeviceState;
import androidx.window.extensions.ExtensionDisplayFeature;
import androidx.window.extensions.ExtensionInterface;
@@ -41,17 +41,24 @@
/** Compatibility wrapper for extension versions v1.0+. */
final class ExtensionCompat implements ExtensionInterfaceCompat {
+ static final boolean DEBUG = false;
private static final String TAG = "ExtensionVersionCompat";
- private ExtensionInterface mWindowExtension;
+ @VisibleForTesting
+ final ExtensionInterface mWindowExtension;
ExtensionCompat(Context context) {
- mWindowExtension = ExtensionProvider.getExtensionImpl(context);
+ this(ExtensionProvider.getExtensionImpl(context));
if (mWindowExtension == null) {
throw new IllegalArgumentException("Extension provider returned null");
}
}
+ @VisibleForTesting
+ ExtensionCompat(ExtensionInterface extension) {
+ mWindowExtension = extension;
+ }
+
@Override
public void setExtensionCallback(@NonNull ExtensionCallbackInterface extensionCallback) {
mWindowExtension.setExtensionCallback(new ExtensionInterface.ExtensionCallback() {
@@ -119,7 +126,18 @@
}
}
+ /**
+ * Convert the display feature from extension. Can return {@code null} if there is an issue with
+ * the value passed from extension.
+ */
+ @Nullable
private static DisplayFeature displayFeatureFromExtension(ExtensionDisplayFeature feature) {
+ if (feature.getBounds().width() == 0 && feature.getBounds().height() == 0) {
+ if (DEBUG) {
+ Log.d(TAG, "Passed a display feature with empty rect, skipping: " + feature);
+ }
+ return null;
+ }
return new DisplayFeature(feature.getBounds(), feature.getType());
}
@@ -134,7 +152,10 @@
}
for (ExtensionDisplayFeature extensionFeature : extensionFeatures) {
- displayFeatures.add(displayFeatureFromExtension(extensionFeature));
+ final DisplayFeature displayFeature = displayFeatureFromExtension(extensionFeature);
+ if (displayFeature != null) {
+ displayFeatures.add(displayFeature);
+ }
}
return displayFeatures;
}
diff --git a/window/window/src/main/java/androidx/window/ExtensionHelper.java b/window/window/src/main/java/androidx/window/ExtensionHelper.java
deleted file mode 100644
index f414254..0000000
--- a/window/window/src/main/java/androidx/window/ExtensionHelper.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * 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.window;
-
-import android.content.Context;
-import android.util.Log;
-
-import androidx.annotation.Nullable;
-import androidx.window.extensions.ExtensionInterface;
-
-/**
- * Helper class that loads the correct {@link ExtensionInterfaceCompat}.
- */
-final class ExtensionHelper {
- static final boolean DEBUG = false;
- private static final String TAG = "WindowExtensionHelper";
-
- private ExtensionHelper() {}
-
- /**
- * Get an instance of {@link ExtensionInterface} implemented by OEM if available on this device.
- */
- static ExtensionInterfaceCompat getExtensionImpl(Context context) {
- ExtensionInterfaceCompat impl = null;
- try {
- if (isExtensionVersionSupported(ExtensionCompat.getExtensionVersion())) {
- impl = new ExtensionCompat(context);
- } else if (isExtensionVersionSupported(SidecarCompat.getSidecarVersion())) {
- impl = new SidecarCompat(context);
- }
- } catch (Throwable t) {
- if (DEBUG) {
- Log.d(TAG, "Failed to load extension: " + t);
- }
- return null;
- }
-
- if (impl == null) {
- if (DEBUG) {
- Log.d(TAG, "No supported extension found");
- }
- return null;
- }
-
- if (!impl.validateExtensionInterface()) {
- if (DEBUG) {
- Log.d(TAG, "Loaded extension doesn't match the interface version");
- }
- return null;
- }
-
- return impl;
- }
-
- /**
- * Check if the Extension version provided on this device is supported by the current version
- * of the library.
- */
- private static boolean isExtensionVersionSupported(@Nullable Version extensionVersion) {
- return extensionVersion != null
- && Version.CURRENT.getMajor() >= extensionVersion.getMajor();
- }
-}
-
diff --git a/window/window/src/main/java/androidx/window/ExtensionWindowBackend.java b/window/window/src/main/java/androidx/window/ExtensionWindowBackend.java
index e83f3a0..da9e589 100644
--- a/window/window/src/main/java/androidx/window/ExtensionWindowBackend.java
+++ b/window/window/src/main/java/androidx/window/ExtensionWindowBackend.java
@@ -16,7 +16,7 @@
package androidx.window;
-import static androidx.window.ExtensionHelper.DEBUG;
+import static androidx.window.ExtensionCompat.DEBUG;
import static androidx.window.WindowManager.getActivityFromContext;
import android.annotation.SuppressLint;
@@ -27,7 +27,10 @@
import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import androidx.core.util.Consumer;
+import androidx.window.extensions.ExtensionInterface;
import java.util.ArrayList;
import java.util.HashMap;
@@ -44,26 +47,34 @@
private static final Object sLock = new Object();
@GuardedBy("sLock")
- private ExtensionInterfaceCompat mWindowExtension;
+ @VisibleForTesting
+ ExtensionInterfaceCompat mWindowExtension;
+
/**
* List of all registered callbacks for window layout info. Not protected by {@link #sLock} to
* allow iterating and callback execution without holding the global lock.
*/
- private final List<WindowLayoutChangeCallbackWrapper> mWindowLayoutChangeCallbacks =
+ @VisibleForTesting
+ final List<WindowLayoutChangeCallbackWrapper> mWindowLayoutChangeCallbacks =
new CopyOnWriteArrayList<>();
+
/**
* List of all registered callbacks for window layout info. Not protected by {@link #sLock} to
* allow iterating and callback execution without holding the global lock.
*/
- private final List<DeviceStateChangeCallbackWrapper> mDeviceStateChangeCallbacks =
+ @VisibleForTesting
+ final List<DeviceStateChangeCallbackWrapper> mDeviceStateChangeCallbacks =
new CopyOnWriteArrayList<>();
+
/** Device state that was last reported through callbacks, used to filter out duplicates. */
@GuardedBy("sLock")
- private DeviceState mLastReportedDeviceState;
+ @VisibleForTesting
+ DeviceState mLastReportedDeviceState;
+
/** Window layouts that were last reported through callbacks, used to filter out duplicates. */
@GuardedBy("sLock")
- private final HashMap<IBinder, WindowLayoutInfo> mLastReportedWindowLayouts =
- new HashMap<>();
+ @VisibleForTesting
+ final HashMap<IBinder, WindowLayoutInfo> mLastReportedWindowLayouts = new HashMap<>();
private static final String TAG = "WindowServer";
@@ -91,7 +102,7 @@
@SuppressLint("SyntheticAccessor")
@GuardedBy("sLock")
private void initExtension(Context context) {
- mWindowExtension = ExtensionHelper.getExtensionImpl(context);
+ mWindowExtension = initAndVerifyExtension(context);
if (mWindowExtension == null) {
return;
}
@@ -108,11 +119,10 @@
}
synchronized (sLock) {
- WindowLayoutInfo extensionWindowLayoutInfo = mWindowExtension != null
- ? mWindowExtension.getWindowLayoutInfo(windowToken)
- : new WindowLayoutInfo(new ArrayList<>());
- mLastReportedWindowLayouts.put(windowToken, extensionWindowLayoutInfo);
- return extensionWindowLayoutInfo;
+ WindowLayoutInfo windowLayoutInfo = mWindowExtension != null
+ ? mWindowExtension.getWindowLayoutInfo(windowToken) : null;
+ return windowLayoutInfo != null
+ ? windowLayoutInfo : new WindowLayoutInfo(new ArrayList<>());
}
}
@@ -120,8 +130,9 @@
@Override
public DeviceState getDeviceState() {
synchronized (sLock) {
- return mWindowExtension != null ? mWindowExtension.getDeviceState() :
- new DeviceState(DeviceState.POSTURE_UNKNOWN);
+ DeviceState deviceState = mWindowExtension != null
+ ? mWindowExtension.getDeviceState() : null;
+ return deviceState != null ? deviceState : new DeviceState(DeviceState.POSTURE_UNKNOWN);
}
}
@@ -248,8 +259,8 @@
}
}
- private class ExtensionListenerImpl implements
- ExtensionInterfaceCompat.ExtensionCallbackInterface {
+ @VisibleForTesting
+ class ExtensionListenerImpl implements ExtensionInterfaceCompat.ExtensionCallbackInterface {
@Override
@SuppressLint("SyntheticAccessor")
public void onDeviceStateChanged(@NonNull DeviceState newDeviceState) {
@@ -314,8 +325,9 @@
return activity;
}
+ @Nullable
private IBinder getActivityWindowToken(Activity activity) {
- return activity.getWindow().getAttributes().token;
+ return activity.getWindow() != null ? activity.getWindow().getAttributes().token : null;
}
/**
@@ -349,4 +361,59 @@
mCallback = callback;
}
}
+
+ /**
+ * Load an instance of {@link ExtensionInterface} implemented by OEM if available on this
+ * device. This also verifies if the loaded implementation conforms to the declared API version.
+ */
+ @Nullable
+ static ExtensionInterfaceCompat initAndVerifyExtension(Context context) {
+ ExtensionInterfaceCompat impl = null;
+ try {
+ if (isExtensionVersionSupported(ExtensionCompat.getExtensionVersion())) {
+ impl = new ExtensionCompat(context);
+ } else if (isExtensionVersionSupported(SidecarCompat.getSidecarVersion())) {
+ impl = new SidecarCompat(context);
+ }
+ } catch (Throwable t) {
+ if (DEBUG) {
+ Log.d(TAG, "Failed to load extension: " + t);
+ }
+ return null;
+ }
+
+ if (impl == null) {
+ if (DEBUG) {
+ Log.d(TAG, "No supported extension found");
+ }
+ return null;
+ }
+
+ if (!impl.validateExtensionInterface()) {
+ if (DEBUG) {
+ Log.d(TAG, "Loaded extension doesn't match the interface version");
+ }
+ return null;
+ }
+
+ return impl;
+ }
+
+ /**
+ * Check if the Extension version provided on this device is supported by the current version
+ * of the library.
+ */
+ @VisibleForTesting
+ static boolean isExtensionVersionSupported(@Nullable Version extensionVersion) {
+ return extensionVersion != null
+ && Version.CURRENT.getMajor() >= extensionVersion.getMajor();
+ }
+
+ /**
+ * Test-only affordance to forget the existing instance.
+ */
+ @VisibleForTesting
+ static void resetInstance() {
+ sInstance = null;
+ }
}
diff --git a/window/window/src/main/java/androidx/window/SidecarCompat.java b/window/window/src/main/java/androidx/window/SidecarCompat.java
index f4e26f4..1f5f554 100644
--- a/window/window/src/main/java/androidx/window/SidecarCompat.java
+++ b/window/window/src/main/java/androidx/window/SidecarCompat.java
@@ -18,7 +18,7 @@
import static androidx.window.DeviceState.POSTURE_MAX_KNOWN;
import static androidx.window.DeviceState.POSTURE_UNKNOWN;
-import static androidx.window.ExtensionHelper.DEBUG;
+import static androidx.window.ExtensionCompat.DEBUG;
import static androidx.window.Version.VERSION_0_1;
import android.annotation.SuppressLint;
@@ -30,6 +30,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import androidx.window.sidecar.SidecarDeviceState;
import androidx.window.sidecar.SidecarDisplayFeature;
import androidx.window.sidecar.SidecarInterface;
@@ -45,15 +46,21 @@
final class SidecarCompat implements ExtensionInterfaceCompat {
private static final String TAG = "SidecarCompat";
- private SidecarInterface mSidecar;
+ @VisibleForTesting
+ final SidecarInterface mSidecar;
SidecarCompat(Context context) {
- mSidecar = SidecarProvider.getSidecarImpl(context);
+ this(SidecarProvider.getSidecarImpl(context));
if (mSidecar == null) {
throw new IllegalArgumentException("Sidecar provider returned null");
}
}
+ @VisibleForTesting
+ SidecarCompat(@NonNull SidecarInterface sidecar) {
+ mSidecar = sidecar;
+ }
+
@Override
public void setExtensionCallback(@NonNull ExtensionCallbackInterface extensionCallback) {
mSidecar.setSidecarCallback(new SidecarInterface.SidecarCallback() {
@@ -204,7 +211,18 @@
}
}
+ /**
+ * Convert the display feature from extension. Can return {@code null} if there is an issue with
+ * the value passed from extension.
+ */
+ @Nullable
private static DisplayFeature displayFeatureFromExtension(SidecarDisplayFeature feature) {
+ if (feature.getRect().width() == 0 && feature.getRect().height() == 0) {
+ if (DEBUG) {
+ Log.d(TAG, "Passed a display feature with empty rect, skipping: " + feature);
+ }
+ return null;
+ }
return new DisplayFeature(feature.getRect(), feature.getType());
}
@@ -217,7 +235,10 @@
}
for (SidecarDisplayFeature sidecarFeature : sidecarWindowLayoutInfo.displayFeatures) {
- displayFeatures.add(displayFeatureFromExtension(sidecarFeature));
+ final DisplayFeature displayFeature = displayFeatureFromExtension(sidecarFeature);
+ if (displayFeature != null) {
+ displayFeatures.add(displayFeature);
+ }
}
return displayFeatures;
}
diff --git a/window/window/src/main/java/androidx/window/WindowLayoutInfo.java b/window/window/src/main/java/androidx/window/WindowLayoutInfo.java
index 6724345..7a812df 100644
--- a/window/window/src/main/java/androidx/window/WindowLayoutInfo.java
+++ b/window/window/src/main/java/androidx/window/WindowLayoutInfo.java
@@ -68,7 +68,7 @@
* Builder for {@link WindowLayoutInfo} objects.
*/
public static class Builder {
- private List<DisplayFeature> mDisplayFeatures;
+ private List<DisplayFeature> mDisplayFeatures = new ArrayList<>();
/**
* Creates an initially empty builder.
@@ -81,7 +81,8 @@
*/
@NonNull
public Builder setDisplayFeatures(@NonNull List<DisplayFeature> displayFeatures) {
- mDisplayFeatures = displayFeatures;
+ mDisplayFeatures.clear();
+ mDisplayFeatures.addAll(displayFeatures);
return this;
}
diff --git a/work/integration-tests/testapp/build.gradle b/work/integration-tests/testapp/build.gradle
index a13b574..91f60e3 100644
--- a/work/integration-tests/testapp/build.gradle
+++ b/work/integration-tests/testapp/build.gradle
@@ -59,8 +59,8 @@
annotationProcessor(project(":room:room-compiler"))
implementation(project(":room:room-runtime"))
} else {
- annotationProcessor("androidx.room:room-compiler:2.2.2")
- implementation("androidx.room:room-runtime:2.2.2")
+ annotationProcessor("androidx.room:room-compiler:2.2.5")
+ implementation("androidx.room:room-runtime:2.2.5")
}
implementation(CONSTRAINT_LAYOUT, { transitive = true })
diff --git a/work/workmanager-benchmark/build.gradle b/work/workmanager-benchmark/build.gradle
index 2824d59..23a2265 100644
--- a/work/workmanager-benchmark/build.gradle
+++ b/work/workmanager-benchmark/build.gradle
@@ -32,7 +32,7 @@
dependencies {
androidTestImplementation(project(':work:work-runtime-ktx'))
androidTestImplementation(project(":benchmark:benchmark-junit4"))
- androidTestImplementation("androidx.room:room-runtime:2.2.3")
+ androidTestImplementation("androidx.room:room-runtime:2.2.5")
androidTestImplementation(JUNIT)
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
androidTestImplementation(ANDROIDX_TEST_CORE)
diff --git a/work/workmanager-gcm/api/2.4.0-alpha02.txt b/work/workmanager-gcm/api/2.4.0-alpha02.txt
new file mode 100644
index 0000000..da4f6cc
--- /dev/null
+++ b/work/workmanager-gcm/api/2.4.0-alpha02.txt
@@ -0,0 +1 @@
+// Signature format: 3.0
diff --git a/work/workmanager-gcm/api/public_plus_experimental_2.4.0-alpha02.txt b/work/workmanager-gcm/api/public_plus_experimental_2.4.0-alpha02.txt
new file mode 100644
index 0000000..da4f6cc
--- /dev/null
+++ b/work/workmanager-gcm/api/public_plus_experimental_2.4.0-alpha02.txt
@@ -0,0 +1 @@
+// Signature format: 3.0
diff --git a/lifecycle/lifecycle-extensions/api/res-2.3.0-alpha02.txt b/work/workmanager-gcm/api/res-2.4.0-alpha02.txt
similarity index 100%
copy from lifecycle/lifecycle-extensions/api/res-2.3.0-alpha02.txt
copy to work/workmanager-gcm/api/res-2.4.0-alpha02.txt
diff --git a/work/workmanager-gcm/api/restricted_2.4.0-alpha02.txt b/work/workmanager-gcm/api/restricted_2.4.0-alpha02.txt
new file mode 100644
index 0000000..da4f6cc
--- /dev/null
+++ b/work/workmanager-gcm/api/restricted_2.4.0-alpha02.txt
@@ -0,0 +1 @@
+// Signature format: 3.0
diff --git a/work/workmanager-gcm/build.gradle b/work/workmanager-gcm/build.gradle
index c4f46f9..80b16b4 100644
--- a/work/workmanager-gcm/build.gradle
+++ b/work/workmanager-gcm/build.gradle
@@ -51,9 +51,9 @@
implementation(project(":room:room-runtime"))
androidTestImplementation(project(":room:room-testing"))
} else {
- annotationProcessor("androidx.room:room-compiler:2.2.3")
- implementation("androidx.room:room-runtime:2.2.3")
- androidTestImplementation("androidx.room:room-testing:2.2.3")
+ annotationProcessor("androidx.room:room-compiler:2.2.5")
+ implementation("androidx.room:room-runtime:2.2.5")
+ androidTestImplementation("androidx.room:room-testing:2.2.5")
}
androidTestImplementation(project(":work:work-runtime-ktx"))
diff --git a/work/workmanager-ktx/api/2.4.0-alpha02.txt b/work/workmanager-ktx/api/2.4.0-alpha02.txt
new file mode 100644
index 0000000..dee5846
--- /dev/null
+++ b/work/workmanager-ktx/api/2.4.0-alpha02.txt
@@ -0,0 +1,40 @@
+// Signature format: 3.0
+package androidx.work {
+
+ public abstract class CoroutineWorker extends androidx.work.ListenableWorker {
+ ctor public CoroutineWorker(android.content.Context appContext, androidx.work.WorkerParameters params);
+ method public abstract suspend Object doWork(kotlin.coroutines.Continuation<? super androidx.work.ListenableWorker.Result> p);
+ method @Deprecated public kotlinx.coroutines.CoroutineDispatcher getCoroutineContext();
+ method public final void onStopped();
+ method public final suspend Object! setForeground(androidx.work.ForegroundInfo foregroundInfo, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+ method public final suspend Object! setProgress(androidx.work.Data data, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+ method public final com.google.common.util.concurrent.ListenableFuture<androidx.work.ListenableWorker.Result> startWork();
+ property @Deprecated public kotlinx.coroutines.CoroutineDispatcher coroutineContext;
+ }
+
+ public final class DataKt {
+ method public static inline <reified T> boolean hasKeyWithValueOfType(androidx.work.Data, String key);
+ method public static inline androidx.work.Data workDataOf(kotlin.Pair<java.lang.String,?>... pairs);
+ }
+
+ public final class ListenableFutureKt {
+ }
+
+ public final class OneTimeWorkRequestKt {
+ method public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.OneTimeWorkRequest.Builder OneTimeWorkRequestBuilder();
+ method public static inline androidx.work.OneTimeWorkRequest.Builder setInputMerger(androidx.work.OneTimeWorkRequest.Builder, kotlin.reflect.KClass<? extends androidx.work.InputMerger> inputMerger);
+ }
+
+ public final class OperationKt {
+ method public static suspend inline Object! await(androidx.work.Operation, kotlin.coroutines.Continuation<? super androidx.work.Operation.State.SUCCESS> p);
+ }
+
+ public final class PeriodicWorkRequestKt {
+ method public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.PeriodicWorkRequest.Builder PeriodicWorkRequestBuilder(long repeatInterval, java.util.concurrent.TimeUnit repeatIntervalTimeUnit);
+ method @RequiresApi(26) public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.PeriodicWorkRequest.Builder PeriodicWorkRequestBuilder(java.time.Duration repeatInterval);
+ method public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.PeriodicWorkRequest.Builder PeriodicWorkRequestBuilder(long repeatInterval, java.util.concurrent.TimeUnit repeatIntervalTimeUnit, long flexTimeInterval, java.util.concurrent.TimeUnit flexTimeIntervalUnit);
+ method @RequiresApi(26) public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.PeriodicWorkRequest.Builder PeriodicWorkRequestBuilder(java.time.Duration repeatInterval, java.time.Duration flexTimeInterval);
+ }
+
+}
+
diff --git a/work/workmanager-ktx/api/public_plus_experimental_2.4.0-alpha02.txt b/work/workmanager-ktx/api/public_plus_experimental_2.4.0-alpha02.txt
new file mode 100644
index 0000000..dee5846
--- /dev/null
+++ b/work/workmanager-ktx/api/public_plus_experimental_2.4.0-alpha02.txt
@@ -0,0 +1,40 @@
+// Signature format: 3.0
+package androidx.work {
+
+ public abstract class CoroutineWorker extends androidx.work.ListenableWorker {
+ ctor public CoroutineWorker(android.content.Context appContext, androidx.work.WorkerParameters params);
+ method public abstract suspend Object doWork(kotlin.coroutines.Continuation<? super androidx.work.ListenableWorker.Result> p);
+ method @Deprecated public kotlinx.coroutines.CoroutineDispatcher getCoroutineContext();
+ method public final void onStopped();
+ method public final suspend Object! setForeground(androidx.work.ForegroundInfo foregroundInfo, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+ method public final suspend Object! setProgress(androidx.work.Data data, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+ method public final com.google.common.util.concurrent.ListenableFuture<androidx.work.ListenableWorker.Result> startWork();
+ property @Deprecated public kotlinx.coroutines.CoroutineDispatcher coroutineContext;
+ }
+
+ public final class DataKt {
+ method public static inline <reified T> boolean hasKeyWithValueOfType(androidx.work.Data, String key);
+ method public static inline androidx.work.Data workDataOf(kotlin.Pair<java.lang.String,?>... pairs);
+ }
+
+ public final class ListenableFutureKt {
+ }
+
+ public final class OneTimeWorkRequestKt {
+ method public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.OneTimeWorkRequest.Builder OneTimeWorkRequestBuilder();
+ method public static inline androidx.work.OneTimeWorkRequest.Builder setInputMerger(androidx.work.OneTimeWorkRequest.Builder, kotlin.reflect.KClass<? extends androidx.work.InputMerger> inputMerger);
+ }
+
+ public final class OperationKt {
+ method public static suspend inline Object! await(androidx.work.Operation, kotlin.coroutines.Continuation<? super androidx.work.Operation.State.SUCCESS> p);
+ }
+
+ public final class PeriodicWorkRequestKt {
+ method public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.PeriodicWorkRequest.Builder PeriodicWorkRequestBuilder(long repeatInterval, java.util.concurrent.TimeUnit repeatIntervalTimeUnit);
+ method @RequiresApi(26) public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.PeriodicWorkRequest.Builder PeriodicWorkRequestBuilder(java.time.Duration repeatInterval);
+ method public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.PeriodicWorkRequest.Builder PeriodicWorkRequestBuilder(long repeatInterval, java.util.concurrent.TimeUnit repeatIntervalTimeUnit, long flexTimeInterval, java.util.concurrent.TimeUnit flexTimeIntervalUnit);
+ method @RequiresApi(26) public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.PeriodicWorkRequest.Builder PeriodicWorkRequestBuilder(java.time.Duration repeatInterval, java.time.Duration flexTimeInterval);
+ }
+
+}
+
diff --git a/lifecycle/lifecycle-extensions/api/res-2.3.0-alpha02.txt b/work/workmanager-ktx/api/res-2.4.0-alpha02.txt
similarity index 100%
copy from lifecycle/lifecycle-extensions/api/res-2.3.0-alpha02.txt
copy to work/workmanager-ktx/api/res-2.4.0-alpha02.txt
diff --git a/work/workmanager-ktx/api/restricted_2.4.0-alpha02.txt b/work/workmanager-ktx/api/restricted_2.4.0-alpha02.txt
new file mode 100644
index 0000000..dee5846
--- /dev/null
+++ b/work/workmanager-ktx/api/restricted_2.4.0-alpha02.txt
@@ -0,0 +1,40 @@
+// Signature format: 3.0
+package androidx.work {
+
+ public abstract class CoroutineWorker extends androidx.work.ListenableWorker {
+ ctor public CoroutineWorker(android.content.Context appContext, androidx.work.WorkerParameters params);
+ method public abstract suspend Object doWork(kotlin.coroutines.Continuation<? super androidx.work.ListenableWorker.Result> p);
+ method @Deprecated public kotlinx.coroutines.CoroutineDispatcher getCoroutineContext();
+ method public final void onStopped();
+ method public final suspend Object! setForeground(androidx.work.ForegroundInfo foregroundInfo, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+ method public final suspend Object! setProgress(androidx.work.Data data, kotlin.coroutines.Continuation<? super kotlin.Unit> p);
+ method public final com.google.common.util.concurrent.ListenableFuture<androidx.work.ListenableWorker.Result> startWork();
+ property @Deprecated public kotlinx.coroutines.CoroutineDispatcher coroutineContext;
+ }
+
+ public final class DataKt {
+ method public static inline <reified T> boolean hasKeyWithValueOfType(androidx.work.Data, String key);
+ method public static inline androidx.work.Data workDataOf(kotlin.Pair<java.lang.String,?>... pairs);
+ }
+
+ public final class ListenableFutureKt {
+ }
+
+ public final class OneTimeWorkRequestKt {
+ method public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.OneTimeWorkRequest.Builder OneTimeWorkRequestBuilder();
+ method public static inline androidx.work.OneTimeWorkRequest.Builder setInputMerger(androidx.work.OneTimeWorkRequest.Builder, kotlin.reflect.KClass<? extends androidx.work.InputMerger> inputMerger);
+ }
+
+ public final class OperationKt {
+ method public static suspend inline Object! await(androidx.work.Operation, kotlin.coroutines.Continuation<? super androidx.work.Operation.State.SUCCESS> p);
+ }
+
+ public final class PeriodicWorkRequestKt {
+ method public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.PeriodicWorkRequest.Builder PeriodicWorkRequestBuilder(long repeatInterval, java.util.concurrent.TimeUnit repeatIntervalTimeUnit);
+ method @RequiresApi(26) public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.PeriodicWorkRequest.Builder PeriodicWorkRequestBuilder(java.time.Duration repeatInterval);
+ method public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.PeriodicWorkRequest.Builder PeriodicWorkRequestBuilder(long repeatInterval, java.util.concurrent.TimeUnit repeatIntervalTimeUnit, long flexTimeInterval, java.util.concurrent.TimeUnit flexTimeIntervalUnit);
+ method @RequiresApi(26) public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.PeriodicWorkRequest.Builder PeriodicWorkRequestBuilder(java.time.Duration repeatInterval, java.time.Duration flexTimeInterval);
+ }
+
+}
+
diff --git a/work/workmanager-ktx/build.gradle b/work/workmanager-ktx/build.gradle
index 2c47aea..c1a1a67 100644
--- a/work/workmanager-ktx/build.gradle
+++ b/work/workmanager-ktx/build.gradle
@@ -53,7 +53,7 @@
androidTestImplementation(ESPRESSO_CORE)
androidTestImplementation(MOCKITO_CORE, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has its own MockMaker
- androidTestImplementation("androidx.room:room-testing:2.2.3")
+ androidTestImplementation("androidx.room:room-testing:2.2.5")
testImplementation(JUNIT)
}
diff --git a/work/workmanager-rxjava2/api/2.4.0-alpha02.txt b/work/workmanager-rxjava2/api/2.4.0-alpha02.txt
new file mode 100644
index 0000000..8764610
--- /dev/null
+++ b/work/workmanager-rxjava2/api/2.4.0-alpha02.txt
@@ -0,0 +1,14 @@
+// Signature format: 3.0
+package androidx.work {
+
+ public abstract class RxWorker extends androidx.work.ListenableWorker {
+ ctor public RxWorker(android.content.Context, androidx.work.WorkerParameters);
+ method @MainThread public abstract io.reactivex.Single<androidx.work.ListenableWorker.Result!> createWork();
+ method protected io.reactivex.Scheduler getBackgroundScheduler();
+ method public final io.reactivex.Completable setCompletableProgress(androidx.work.Data);
+ method @Deprecated public final io.reactivex.Single<java.lang.Void!> setProgress(androidx.work.Data);
+ method public com.google.common.util.concurrent.ListenableFuture<androidx.work.ListenableWorker.Result!> startWork();
+ }
+
+}
+
diff --git a/work/workmanager-rxjava2/api/public_plus_experimental_2.4.0-alpha02.txt b/work/workmanager-rxjava2/api/public_plus_experimental_2.4.0-alpha02.txt
new file mode 100644
index 0000000..8764610
--- /dev/null
+++ b/work/workmanager-rxjava2/api/public_plus_experimental_2.4.0-alpha02.txt
@@ -0,0 +1,14 @@
+// Signature format: 3.0
+package androidx.work {
+
+ public abstract class RxWorker extends androidx.work.ListenableWorker {
+ ctor public RxWorker(android.content.Context, androidx.work.WorkerParameters);
+ method @MainThread public abstract io.reactivex.Single<androidx.work.ListenableWorker.Result!> createWork();
+ method protected io.reactivex.Scheduler getBackgroundScheduler();
+ method public final io.reactivex.Completable setCompletableProgress(androidx.work.Data);
+ method @Deprecated public final io.reactivex.Single<java.lang.Void!> setProgress(androidx.work.Data);
+ method public com.google.common.util.concurrent.ListenableFuture<androidx.work.ListenableWorker.Result!> startWork();
+ }
+
+}
+
diff --git a/lifecycle/lifecycle-extensions/api/res-2.3.0-alpha02.txt b/work/workmanager-rxjava2/api/res-2.4.0-alpha02.txt
similarity index 100%
copy from lifecycle/lifecycle-extensions/api/res-2.3.0-alpha02.txt
copy to work/workmanager-rxjava2/api/res-2.4.0-alpha02.txt
diff --git a/work/workmanager-rxjava2/api/restricted_2.4.0-alpha02.txt b/work/workmanager-rxjava2/api/restricted_2.4.0-alpha02.txt
new file mode 100644
index 0000000..8764610
--- /dev/null
+++ b/work/workmanager-rxjava2/api/restricted_2.4.0-alpha02.txt
@@ -0,0 +1,14 @@
+// Signature format: 3.0
+package androidx.work {
+
+ public abstract class RxWorker extends androidx.work.ListenableWorker {
+ ctor public RxWorker(android.content.Context, androidx.work.WorkerParameters);
+ method @MainThread public abstract io.reactivex.Single<androidx.work.ListenableWorker.Result!> createWork();
+ method protected io.reactivex.Scheduler getBackgroundScheduler();
+ method public final io.reactivex.Completable setCompletableProgress(androidx.work.Data);
+ method @Deprecated public final io.reactivex.Single<java.lang.Void!> setProgress(androidx.work.Data);
+ method public com.google.common.util.concurrent.ListenableFuture<androidx.work.ListenableWorker.Result!> startWork();
+ }
+
+}
+
diff --git a/work/workmanager-testing/api/2.4.0-alpha02.txt b/work/workmanager-testing/api/2.4.0-alpha02.txt
new file mode 100644
index 0000000..b64dd6c3
--- /dev/null
+++ b/work/workmanager-testing/api/2.4.0-alpha02.txt
@@ -0,0 +1,52 @@
+// Signature format: 3.0
+package androidx.work.testing {
+
+ public class SynchronousExecutor implements java.util.concurrent.Executor {
+ ctor public SynchronousExecutor();
+ method public void execute(Runnable);
+ }
+
+ public interface TestDriver {
+ method public void setAllConstraintsMet(java.util.UUID);
+ method public void setInitialDelayMet(java.util.UUID);
+ method public void setPeriodDelayMet(java.util.UUID);
+ }
+
+ public class TestListenableWorkerBuilder<W extends androidx.work.ListenableWorker> {
+ method public W build();
+ method public static androidx.work.testing.TestListenableWorkerBuilder from(android.content.Context, androidx.work.WorkRequest);
+ method public static <W extends androidx.work.ListenableWorker> androidx.work.testing.TestListenableWorkerBuilder<W!> from(android.content.Context, Class<W!>);
+ method public androidx.work.testing.TestListenableWorkerBuilder setForegroundUpdater(androidx.work.ForegroundUpdater);
+ method public androidx.work.testing.TestListenableWorkerBuilder setId(java.util.UUID);
+ method public androidx.work.testing.TestListenableWorkerBuilder setInputData(androidx.work.Data);
+ method @RequiresApi(28) public androidx.work.testing.TestListenableWorkerBuilder setNetwork(android.net.Network);
+ method public androidx.work.testing.TestListenableWorkerBuilder setProgressUpdater(androidx.work.ProgressUpdater);
+ method public androidx.work.testing.TestListenableWorkerBuilder setRunAttemptCount(int);
+ method public androidx.work.testing.TestListenableWorkerBuilder setTags(java.util.List<java.lang.String!>);
+ method @RequiresApi(24) public androidx.work.testing.TestListenableWorkerBuilder setTriggeredContentAuthorities(java.util.List<java.lang.String!>);
+ method @RequiresApi(24) public androidx.work.testing.TestListenableWorkerBuilder setTriggeredContentUris(java.util.List<android.net.Uri!>);
+ method public androidx.work.testing.TestListenableWorkerBuilder setWorkerFactory(androidx.work.WorkerFactory);
+ }
+
+ public final class TestListenableWorkerBuilderKt {
+ method public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.testing.TestListenableWorkerBuilder<W> TestListenableWorkerBuilder(android.content.Context context, androidx.work.Data inputData = androidx.work.Data.EMPTY, java.util.List<java.lang.String> tags = emptyList(), int runAttemptCount = 1, java.util.List<? extends android.net.Uri> triggeredContentUris = emptyList(), java.util.List<java.lang.String> triggeredContentAuthorities = emptyList());
+ }
+
+ public class TestWorkerBuilder<W extends androidx.work.Worker> extends androidx.work.testing.TestListenableWorkerBuilder<W> {
+ method public static androidx.work.testing.TestWorkerBuilder<? extends androidx.work.Worker> from(android.content.Context, androidx.work.WorkRequest, java.util.concurrent.Executor);
+ method public static <W extends androidx.work.Worker> androidx.work.testing.TestWorkerBuilder<W!> from(android.content.Context, Class<W!>, java.util.concurrent.Executor);
+ }
+
+ public final class TestWorkerBuilderKt {
+ method public static inline <reified W extends androidx.work.Worker> androidx.work.testing.TestWorkerBuilder<W> TestWorkerBuilder(android.content.Context context, java.util.concurrent.Executor executor, androidx.work.Data inputData = androidx.work.Data.EMPTY, java.util.List<java.lang.String> tags = emptyList(), int runAttemptCount = 1, java.util.List<? extends android.net.Uri> triggeredContentUris = emptyList(), java.util.List<java.lang.String> triggeredContentAuthorities = emptyList());
+ }
+
+ public final class WorkManagerTestInitHelper {
+ method @Deprecated public static androidx.work.testing.TestDriver? getTestDriver();
+ method public static androidx.work.testing.TestDriver? getTestDriver(android.content.Context);
+ method public static void initializeTestWorkManager(android.content.Context);
+ method public static void initializeTestWorkManager(android.content.Context, androidx.work.Configuration);
+ }
+
+}
+
diff --git a/work/workmanager-testing/api/public_plus_experimental_2.4.0-alpha02.txt b/work/workmanager-testing/api/public_plus_experimental_2.4.0-alpha02.txt
new file mode 100644
index 0000000..b64dd6c3
--- /dev/null
+++ b/work/workmanager-testing/api/public_plus_experimental_2.4.0-alpha02.txt
@@ -0,0 +1,52 @@
+// Signature format: 3.0
+package androidx.work.testing {
+
+ public class SynchronousExecutor implements java.util.concurrent.Executor {
+ ctor public SynchronousExecutor();
+ method public void execute(Runnable);
+ }
+
+ public interface TestDriver {
+ method public void setAllConstraintsMet(java.util.UUID);
+ method public void setInitialDelayMet(java.util.UUID);
+ method public void setPeriodDelayMet(java.util.UUID);
+ }
+
+ public class TestListenableWorkerBuilder<W extends androidx.work.ListenableWorker> {
+ method public W build();
+ method public static androidx.work.testing.TestListenableWorkerBuilder from(android.content.Context, androidx.work.WorkRequest);
+ method public static <W extends androidx.work.ListenableWorker> androidx.work.testing.TestListenableWorkerBuilder<W!> from(android.content.Context, Class<W!>);
+ method public androidx.work.testing.TestListenableWorkerBuilder setForegroundUpdater(androidx.work.ForegroundUpdater);
+ method public androidx.work.testing.TestListenableWorkerBuilder setId(java.util.UUID);
+ method public androidx.work.testing.TestListenableWorkerBuilder setInputData(androidx.work.Data);
+ method @RequiresApi(28) public androidx.work.testing.TestListenableWorkerBuilder setNetwork(android.net.Network);
+ method public androidx.work.testing.TestListenableWorkerBuilder setProgressUpdater(androidx.work.ProgressUpdater);
+ method public androidx.work.testing.TestListenableWorkerBuilder setRunAttemptCount(int);
+ method public androidx.work.testing.TestListenableWorkerBuilder setTags(java.util.List<java.lang.String!>);
+ method @RequiresApi(24) public androidx.work.testing.TestListenableWorkerBuilder setTriggeredContentAuthorities(java.util.List<java.lang.String!>);
+ method @RequiresApi(24) public androidx.work.testing.TestListenableWorkerBuilder setTriggeredContentUris(java.util.List<android.net.Uri!>);
+ method public androidx.work.testing.TestListenableWorkerBuilder setWorkerFactory(androidx.work.WorkerFactory);
+ }
+
+ public final class TestListenableWorkerBuilderKt {
+ method public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.testing.TestListenableWorkerBuilder<W> TestListenableWorkerBuilder(android.content.Context context, androidx.work.Data inputData = androidx.work.Data.EMPTY, java.util.List<java.lang.String> tags = emptyList(), int runAttemptCount = 1, java.util.List<? extends android.net.Uri> triggeredContentUris = emptyList(), java.util.List<java.lang.String> triggeredContentAuthorities = emptyList());
+ }
+
+ public class TestWorkerBuilder<W extends androidx.work.Worker> extends androidx.work.testing.TestListenableWorkerBuilder<W> {
+ method public static androidx.work.testing.TestWorkerBuilder<? extends androidx.work.Worker> from(android.content.Context, androidx.work.WorkRequest, java.util.concurrent.Executor);
+ method public static <W extends androidx.work.Worker> androidx.work.testing.TestWorkerBuilder<W!> from(android.content.Context, Class<W!>, java.util.concurrent.Executor);
+ }
+
+ public final class TestWorkerBuilderKt {
+ method public static inline <reified W extends androidx.work.Worker> androidx.work.testing.TestWorkerBuilder<W> TestWorkerBuilder(android.content.Context context, java.util.concurrent.Executor executor, androidx.work.Data inputData = androidx.work.Data.EMPTY, java.util.List<java.lang.String> tags = emptyList(), int runAttemptCount = 1, java.util.List<? extends android.net.Uri> triggeredContentUris = emptyList(), java.util.List<java.lang.String> triggeredContentAuthorities = emptyList());
+ }
+
+ public final class WorkManagerTestInitHelper {
+ method @Deprecated public static androidx.work.testing.TestDriver? getTestDriver();
+ method public static androidx.work.testing.TestDriver? getTestDriver(android.content.Context);
+ method public static void initializeTestWorkManager(android.content.Context);
+ method public static void initializeTestWorkManager(android.content.Context, androidx.work.Configuration);
+ }
+
+}
+
diff --git a/lifecycle/lifecycle-extensions/api/res-2.3.0-alpha02.txt b/work/workmanager-testing/api/res-2.4.0-alpha02.txt
similarity index 100%
copy from lifecycle/lifecycle-extensions/api/res-2.3.0-alpha02.txt
copy to work/workmanager-testing/api/res-2.4.0-alpha02.txt
diff --git a/work/workmanager-testing/api/restricted_2.4.0-alpha02.txt b/work/workmanager-testing/api/restricted_2.4.0-alpha02.txt
new file mode 100644
index 0000000..b64dd6c3
--- /dev/null
+++ b/work/workmanager-testing/api/restricted_2.4.0-alpha02.txt
@@ -0,0 +1,52 @@
+// Signature format: 3.0
+package androidx.work.testing {
+
+ public class SynchronousExecutor implements java.util.concurrent.Executor {
+ ctor public SynchronousExecutor();
+ method public void execute(Runnable);
+ }
+
+ public interface TestDriver {
+ method public void setAllConstraintsMet(java.util.UUID);
+ method public void setInitialDelayMet(java.util.UUID);
+ method public void setPeriodDelayMet(java.util.UUID);
+ }
+
+ public class TestListenableWorkerBuilder<W extends androidx.work.ListenableWorker> {
+ method public W build();
+ method public static androidx.work.testing.TestListenableWorkerBuilder from(android.content.Context, androidx.work.WorkRequest);
+ method public static <W extends androidx.work.ListenableWorker> androidx.work.testing.TestListenableWorkerBuilder<W!> from(android.content.Context, Class<W!>);
+ method public androidx.work.testing.TestListenableWorkerBuilder setForegroundUpdater(androidx.work.ForegroundUpdater);
+ method public androidx.work.testing.TestListenableWorkerBuilder setId(java.util.UUID);
+ method public androidx.work.testing.TestListenableWorkerBuilder setInputData(androidx.work.Data);
+ method @RequiresApi(28) public androidx.work.testing.TestListenableWorkerBuilder setNetwork(android.net.Network);
+ method public androidx.work.testing.TestListenableWorkerBuilder setProgressUpdater(androidx.work.ProgressUpdater);
+ method public androidx.work.testing.TestListenableWorkerBuilder setRunAttemptCount(int);
+ method public androidx.work.testing.TestListenableWorkerBuilder setTags(java.util.List<java.lang.String!>);
+ method @RequiresApi(24) public androidx.work.testing.TestListenableWorkerBuilder setTriggeredContentAuthorities(java.util.List<java.lang.String!>);
+ method @RequiresApi(24) public androidx.work.testing.TestListenableWorkerBuilder setTriggeredContentUris(java.util.List<android.net.Uri!>);
+ method public androidx.work.testing.TestListenableWorkerBuilder setWorkerFactory(androidx.work.WorkerFactory);
+ }
+
+ public final class TestListenableWorkerBuilderKt {
+ method public static inline <reified W extends androidx.work.ListenableWorker> androidx.work.testing.TestListenableWorkerBuilder<W> TestListenableWorkerBuilder(android.content.Context context, androidx.work.Data inputData = androidx.work.Data.EMPTY, java.util.List<java.lang.String> tags = emptyList(), int runAttemptCount = 1, java.util.List<? extends android.net.Uri> triggeredContentUris = emptyList(), java.util.List<java.lang.String> triggeredContentAuthorities = emptyList());
+ }
+
+ public class TestWorkerBuilder<W extends androidx.work.Worker> extends androidx.work.testing.TestListenableWorkerBuilder<W> {
+ method public static androidx.work.testing.TestWorkerBuilder<? extends androidx.work.Worker> from(android.content.Context, androidx.work.WorkRequest, java.util.concurrent.Executor);
+ method public static <W extends androidx.work.Worker> androidx.work.testing.TestWorkerBuilder<W!> from(android.content.Context, Class<W!>, java.util.concurrent.Executor);
+ }
+
+ public final class TestWorkerBuilderKt {
+ method public static inline <reified W extends androidx.work.Worker> androidx.work.testing.TestWorkerBuilder<W> TestWorkerBuilder(android.content.Context context, java.util.concurrent.Executor executor, androidx.work.Data inputData = androidx.work.Data.EMPTY, java.util.List<java.lang.String> tags = emptyList(), int runAttemptCount = 1, java.util.List<? extends android.net.Uri> triggeredContentUris = emptyList(), java.util.List<java.lang.String> triggeredContentAuthorities = emptyList());
+ }
+
+ public final class WorkManagerTestInitHelper {
+ method @Deprecated public static androidx.work.testing.TestDriver? getTestDriver();
+ method public static androidx.work.testing.TestDriver? getTestDriver(android.content.Context);
+ method public static void initializeTestWorkManager(android.content.Context);
+ method public static void initializeTestWorkManager(android.content.Context, androidx.work.Configuration);
+ }
+
+}
+
diff --git a/work/workmanager-testing/build.gradle b/work/workmanager-testing/build.gradle
index 0cf3b2b..c21d7f6 100644
--- a/work/workmanager-testing/build.gradle
+++ b/work/workmanager-testing/build.gradle
@@ -38,7 +38,7 @@
dependencies {
api(project(':work:work-runtime-ktx'))
implementation("androidx.lifecycle:lifecycle-livedata-core:2.1.0")
- implementation("androidx.room:room-runtime:2.2.3")
+ implementation("androidx.room:room-runtime:2.2.5")
androidTestImplementation("androidx.arch.core:core-testing:2.1.0")
androidTestImplementation(ANDROIDX_TEST_EXT_JUNIT)
diff --git a/work/workmanager/api/2.4.0-alpha02.txt b/work/workmanager/api/2.4.0-alpha02.txt
new file mode 100644
index 0000000..c9948b2
--- /dev/null
+++ b/work/workmanager/api/2.4.0-alpha02.txt
@@ -0,0 +1,340 @@
+// Signature format: 3.0
+package androidx.work {
+
+ public final class ArrayCreatingInputMerger extends androidx.work.InputMerger {
+ ctor public ArrayCreatingInputMerger();
+ method public androidx.work.Data merge(java.util.List<androidx.work.Data!>);
+ }
+
+ public enum BackoffPolicy {
+ enum_constant public static final androidx.work.BackoffPolicy EXPONENTIAL;
+ enum_constant public static final androidx.work.BackoffPolicy LINEAR;
+ }
+
+ public final class Configuration {
+ method public java.util.concurrent.Executor getExecutor();
+ method public androidx.work.InputMergerFactory getInputMergerFactory();
+ method public int getMaxJobSchedulerId();
+ method public int getMinJobSchedulerId();
+ method public androidx.work.RunnableScheduler getRunnableScheduler();
+ method public java.util.concurrent.Executor getTaskExecutor();
+ method public androidx.work.WorkerFactory getWorkerFactory();
+ field public static final int MIN_SCHEDULER_LIMIT = 20; // 0x14
+ }
+
+ public static final class Configuration.Builder {
+ ctor public Configuration.Builder();
+ method public androidx.work.Configuration build();
+ method public androidx.work.Configuration.Builder setExecutor(java.util.concurrent.Executor);
+ method public androidx.work.Configuration.Builder setInputMergerFactory(androidx.work.InputMergerFactory);
+ method public androidx.work.Configuration.Builder setJobSchedulerJobIdRange(int, int);
+ method public androidx.work.Configuration.Builder setMaxSchedulerLimit(int);
+ method public androidx.work.Configuration.Builder setMinimumLoggingLevel(int);
+ method public androidx.work.Configuration.Builder setRunnableScheduler(androidx.work.RunnableScheduler);
+ method public androidx.work.Configuration.Builder setTaskExecutor(java.util.concurrent.Executor);
+ method public androidx.work.Configuration.Builder setWorkerFactory(androidx.work.WorkerFactory);
+ }
+
+ public static interface Configuration.Provider {
+ method public androidx.work.Configuration getWorkManagerConfiguration();
+ }
+
+ public final class Constraints {
+ ctor public Constraints(androidx.work.Constraints);
+ method public androidx.work.NetworkType getRequiredNetworkType();
+ method public boolean requiresBatteryNotLow();
+ method public boolean requiresCharging();
+ method @RequiresApi(23) public boolean requiresDeviceIdle();
+ method public boolean requiresStorageNotLow();
+ field public static final androidx.work.Constraints! NONE;
+ }
+
+ public static final class Constraints.Builder {
+ ctor public Constraints.Builder();
+ method @RequiresApi(24) public androidx.work.Constraints.Builder addContentUriTrigger(android.net.Uri, boolean);
+ method public androidx.work.Constraints build();
+ method public androidx.work.Constraints.Builder setRequiredNetworkType(androidx.work.NetworkType);
+ method public androidx.work.Constraints.Builder setRequiresBatteryNotLow(boolean);
+ method public androidx.work.Constraints.Builder setRequiresCharging(boolean);
+ method @RequiresApi(23) public androidx.work.Constraints.Builder setRequiresDeviceIdle(boolean);
+ method public androidx.work.Constraints.Builder setRequiresStorageNotLow(boolean);
+ method @RequiresApi(24) public androidx.work.Constraints.Builder setTriggerContentMaxDelay(long, java.util.concurrent.TimeUnit);
+ method @RequiresApi(26) public androidx.work.Constraints.Builder setTriggerContentMaxDelay(java.time.Duration!);
+ method @RequiresApi(24) public androidx.work.Constraints.Builder setTriggerContentUpdateDelay(long, java.util.concurrent.TimeUnit);
+ method @RequiresApi(26) public androidx.work.Constraints.Builder setTriggerContentUpdateDelay(java.time.Duration!);
+ }
+
+ public final class Data {
+ ctor public Data(androidx.work.Data);
+ method public static androidx.work.Data fromByteArray(byte[]);
+ method public boolean getBoolean(String, boolean);
+ method public boolean[]? getBooleanArray(String);
+ method public byte getByte(String, byte);
+ method public byte[]? getByteArray(String);
+ method public double getDouble(String, double);
+ method public double[]? getDoubleArray(String);
+ method public float getFloat(String, float);
+ method public float[]? getFloatArray(String);
+ method public int getInt(String, int);
+ method public int[]? getIntArray(String);
+ method public java.util.Map<java.lang.String!,java.lang.Object!> getKeyValueMap();
+ method public long getLong(String, long);
+ method public long[]? getLongArray(String);
+ method public String? getString(String);
+ method public String![]? getStringArray(String);
+ method public <T> boolean hasKeyWithValueOfType(String, Class<T!>);
+ method public byte[] toByteArray();
+ field public static final androidx.work.Data! EMPTY;
+ field public static final int MAX_DATA_BYTES = 10240; // 0x2800
+ }
+
+ public static final class Data.Builder {
+ ctor public Data.Builder();
+ method public androidx.work.Data build();
+ method public androidx.work.Data.Builder putAll(androidx.work.Data);
+ method public androidx.work.Data.Builder putAll(java.util.Map<java.lang.String!,java.lang.Object!>);
+ method public androidx.work.Data.Builder putBoolean(String, boolean);
+ method public androidx.work.Data.Builder putBooleanArray(String, boolean[]);
+ method public androidx.work.Data.Builder putByte(String, byte);
+ method public androidx.work.Data.Builder putByteArray(String, byte[]);
+ method public androidx.work.Data.Builder putDouble(String, double);
+ method public androidx.work.Data.Builder putDoubleArray(String, double[]);
+ method public androidx.work.Data.Builder putFloat(String, float);
+ method public androidx.work.Data.Builder putFloatArray(String, float[]);
+ method public androidx.work.Data.Builder putInt(String, int);
+ method public androidx.work.Data.Builder putIntArray(String, int[]);
+ method public androidx.work.Data.Builder putLong(String, long);
+ method public androidx.work.Data.Builder putLongArray(String, long[]);
+ method public androidx.work.Data.Builder putString(String, String?);
+ method public androidx.work.Data.Builder putStringArray(String, String![]);
+ }
+
+ public class DelegatingWorkerFactory extends androidx.work.WorkerFactory {
+ ctor public DelegatingWorkerFactory();
+ method public final void addFactory(androidx.work.WorkerFactory);
+ method public final androidx.work.ListenableWorker? createWorker(android.content.Context, String, androidx.work.WorkerParameters);
+ }
+
+ public enum ExistingPeriodicWorkPolicy {
+ enum_constant public static final androidx.work.ExistingPeriodicWorkPolicy KEEP;
+ enum_constant public static final androidx.work.ExistingPeriodicWorkPolicy REPLACE;
+ }
+
+ public enum ExistingWorkPolicy {
+ enum_constant public static final androidx.work.ExistingWorkPolicy APPEND;
+ enum_constant public static final androidx.work.ExistingWorkPolicy APPEND_OR_REPLACE;
+ enum_constant public static final androidx.work.ExistingWorkPolicy KEEP;
+ enum_constant public static final androidx.work.ExistingWorkPolicy REPLACE;
+ }
+
+ public final class ForegroundInfo {
+ ctor public ForegroundInfo(int, android.app.Notification);
+ ctor public ForegroundInfo(int, android.app.Notification, int);
+ method public int getForegroundServiceType();
+ method public android.app.Notification getNotification();
+ method public int getNotificationId();
+ }
+
+ public interface ForegroundUpdater {
+ method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setForegroundAsync(android.content.Context, java.util.UUID, androidx.work.ForegroundInfo);
+ }
+
+ public abstract class InputMerger {
+ ctor public InputMerger();
+ method public abstract androidx.work.Data merge(java.util.List<androidx.work.Data!>);
+ }
+
+ public abstract class InputMergerFactory {
+ ctor public InputMergerFactory();
+ method public abstract androidx.work.InputMerger? createInputMerger(String);
+ }
+
+ public abstract class ListenableWorker {
+ ctor @Keep public ListenableWorker(android.content.Context, androidx.work.WorkerParameters);
+ method public final android.content.Context getApplicationContext();
+ method public final java.util.UUID getId();
+ method public final androidx.work.Data getInputData();
+ method @RequiresApi(28) public final android.net.Network? getNetwork();
+ method @IntRange(from=0) public final int getRunAttemptCount();
+ method public final java.util.Set<java.lang.String!> getTags();
+ method @RequiresApi(24) public final java.util.List<java.lang.String!> getTriggeredContentAuthorities();
+ method @RequiresApi(24) public final java.util.List<android.net.Uri!> getTriggeredContentUris();
+ method public final boolean isStopped();
+ method public void onStopped();
+ method public final com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setForegroundAsync(androidx.work.ForegroundInfo);
+ method public final com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setProgressAsync(androidx.work.Data);
+ method @MainThread public abstract com.google.common.util.concurrent.ListenableFuture<androidx.work.ListenableWorker.Result!> startWork();
+ }
+
+ public abstract static class ListenableWorker.Result {
+ method public static androidx.work.ListenableWorker.Result failure();
+ method public static androidx.work.ListenableWorker.Result failure(androidx.work.Data);
+ method public static androidx.work.ListenableWorker.Result retry();
+ method public static androidx.work.ListenableWorker.Result success();
+ method public static androidx.work.ListenableWorker.Result success(androidx.work.Data);
+ }
+
+ public enum NetworkType {
+ enum_constant public static final androidx.work.NetworkType CONNECTED;
+ enum_constant public static final androidx.work.NetworkType METERED;
+ enum_constant public static final androidx.work.NetworkType NOT_REQUIRED;
+ enum_constant public static final androidx.work.NetworkType NOT_ROAMING;
+ enum_constant public static final androidx.work.NetworkType UNMETERED;
+ }
+
+ public final class OneTimeWorkRequest extends androidx.work.WorkRequest {
+ method public static androidx.work.OneTimeWorkRequest from(Class<? extends androidx.work.ListenableWorker>);
+ method public static java.util.List<androidx.work.OneTimeWorkRequest!> from(java.util.List<java.lang.Class<? extends androidx.work.ListenableWorker>!>);
+ }
+
+ public static final class OneTimeWorkRequest.Builder extends androidx.work.WorkRequest.Builder<androidx.work.OneTimeWorkRequest.Builder,androidx.work.OneTimeWorkRequest> {
+ ctor public OneTimeWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker>);
+ method public androidx.work.OneTimeWorkRequest.Builder setInputMerger(Class<? extends androidx.work.InputMerger>);
+ }
+
+ public interface Operation {
+ method public com.google.common.util.concurrent.ListenableFuture<androidx.work.Operation.State.SUCCESS!> getResult();
+ method public androidx.lifecycle.LiveData<androidx.work.Operation.State!> getState();
+ }
+
+ public abstract static class Operation.State {
+ }
+
+ public static final class Operation.State.FAILURE extends androidx.work.Operation.State {
+ ctor public Operation.State.FAILURE(Throwable);
+ method public Throwable getThrowable();
+ }
+
+ public static final class Operation.State.IN_PROGRESS extends androidx.work.Operation.State {
+ }
+
+ public static final class Operation.State.SUCCESS extends androidx.work.Operation.State {
+ }
+
+ public final class OverwritingInputMerger extends androidx.work.InputMerger {
+ ctor public OverwritingInputMerger();
+ method public androidx.work.Data merge(java.util.List<androidx.work.Data!>);
+ }
+
+ public final class PeriodicWorkRequest extends androidx.work.WorkRequest {
+ field public static final long MIN_PERIODIC_FLEX_MILLIS = 300000L; // 0x493e0L
+ field public static final long MIN_PERIODIC_INTERVAL_MILLIS = 900000L; // 0xdbba0L
+ }
+
+ public static final class PeriodicWorkRequest.Builder extends androidx.work.WorkRequest.Builder<androidx.work.PeriodicWorkRequest.Builder,androidx.work.PeriodicWorkRequest> {
+ ctor public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker>, long, java.util.concurrent.TimeUnit);
+ ctor @RequiresApi(26) public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker>, java.time.Duration);
+ ctor public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker>, long, java.util.concurrent.TimeUnit, long, java.util.concurrent.TimeUnit);
+ ctor @RequiresApi(26) public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker>, java.time.Duration, java.time.Duration);
+ }
+
+ public interface ProgressUpdater {
+ method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> updateProgress(android.content.Context, java.util.UUID, androidx.work.Data);
+ }
+
+ public interface RunnableScheduler {
+ method public void cancel(Runnable);
+ method public void scheduleWithDelay(long, Runnable);
+ }
+
+ public abstract class WorkContinuation {
+ ctor public WorkContinuation();
+ method public static androidx.work.WorkContinuation combine(java.util.List<androidx.work.WorkContinuation!>);
+ method public abstract androidx.work.Operation enqueue();
+ method public abstract com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.work.WorkInfo!>!> getWorkInfos();
+ method public abstract androidx.lifecycle.LiveData<java.util.List<androidx.work.WorkInfo!>!> getWorkInfosLiveData();
+ method public final androidx.work.WorkContinuation then(androidx.work.OneTimeWorkRequest);
+ method public abstract androidx.work.WorkContinuation then(java.util.List<androidx.work.OneTimeWorkRequest!>);
+ }
+
+ public final class WorkInfo {
+ method public java.util.UUID getId();
+ method public androidx.work.Data getOutputData();
+ method public androidx.work.Data getProgress();
+ method @IntRange(from=0) public int getRunAttemptCount();
+ method public androidx.work.WorkInfo.State getState();
+ method public java.util.Set<java.lang.String!> getTags();
+ }
+
+ public enum WorkInfo.State {
+ method public boolean isFinished();
+ enum_constant public static final androidx.work.WorkInfo.State BLOCKED;
+ enum_constant public static final androidx.work.WorkInfo.State CANCELLED;
+ enum_constant public static final androidx.work.WorkInfo.State ENQUEUED;
+ enum_constant public static final androidx.work.WorkInfo.State FAILED;
+ enum_constant public static final androidx.work.WorkInfo.State RUNNING;
+ enum_constant public static final androidx.work.WorkInfo.State SUCCEEDED;
+ }
+
+ public abstract class WorkManager {
+ method public final androidx.work.WorkContinuation beginUniqueWork(String, androidx.work.ExistingWorkPolicy, androidx.work.OneTimeWorkRequest);
+ method public abstract androidx.work.WorkContinuation beginUniqueWork(String, androidx.work.ExistingWorkPolicy, java.util.List<androidx.work.OneTimeWorkRequest!>);
+ method public final androidx.work.WorkContinuation beginWith(androidx.work.OneTimeWorkRequest);
+ method public abstract androidx.work.WorkContinuation beginWith(java.util.List<androidx.work.OneTimeWorkRequest!>);
+ method public abstract androidx.work.Operation cancelAllWork();
+ method public abstract androidx.work.Operation cancelAllWorkByTag(String);
+ method public abstract androidx.work.Operation cancelUniqueWork(String);
+ method public abstract androidx.work.Operation cancelWorkById(java.util.UUID);
+ method public abstract android.app.PendingIntent createCancelPendingIntent(java.util.UUID);
+ method public final androidx.work.Operation enqueue(androidx.work.WorkRequest);
+ method public abstract androidx.work.Operation enqueue(java.util.List<? extends androidx.work.WorkRequest>);
+ method public abstract androidx.work.Operation enqueueUniquePeriodicWork(String, androidx.work.ExistingPeriodicWorkPolicy, androidx.work.PeriodicWorkRequest);
+ method public androidx.work.Operation enqueueUniqueWork(String, androidx.work.ExistingWorkPolicy, androidx.work.OneTimeWorkRequest);
+ method public abstract androidx.work.Operation enqueueUniqueWork(String, androidx.work.ExistingWorkPolicy, java.util.List<androidx.work.OneTimeWorkRequest!>);
+ method @Deprecated public static androidx.work.WorkManager getInstance();
+ method public static androidx.work.WorkManager getInstance(android.content.Context);
+ method public abstract com.google.common.util.concurrent.ListenableFuture<java.lang.Long!> getLastCancelAllTimeMillis();
+ method public abstract androidx.lifecycle.LiveData<java.lang.Long!> getLastCancelAllTimeMillisLiveData();
+ method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.work.WorkInfo!> getWorkInfoById(java.util.UUID);
+ method public abstract androidx.lifecycle.LiveData<androidx.work.WorkInfo!> getWorkInfoByIdLiveData(java.util.UUID);
+ method public abstract com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.work.WorkInfo!>!> getWorkInfosByTag(String);
+ method public abstract androidx.lifecycle.LiveData<java.util.List<androidx.work.WorkInfo!>!> getWorkInfosByTagLiveData(String);
+ method public abstract com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.work.WorkInfo!>!> getWorkInfosForUniqueWork(String);
+ method public abstract androidx.lifecycle.LiveData<java.util.List<androidx.work.WorkInfo!>!> getWorkInfosForUniqueWorkLiveData(String);
+ method public static void initialize(android.content.Context, androidx.work.Configuration);
+ method public abstract androidx.work.Operation pruneWork();
+ }
+
+ public abstract class WorkRequest {
+ method public java.util.UUID getId();
+ field public static final long DEFAULT_BACKOFF_DELAY_MILLIS = 30000L; // 0x7530L
+ field public static final long MAX_BACKOFF_MILLIS = 18000000L; // 0x112a880L
+ field public static final long MIN_BACKOFF_MILLIS = 10000L; // 0x2710L
+ }
+
+ public abstract static class WorkRequest.Builder<B extends androidx.work.WorkRequest.Builder<?, ?>, W extends androidx.work.WorkRequest> {
+ method public final B addTag(String);
+ method public final W build();
+ method public final B keepResultsForAtLeast(long, java.util.concurrent.TimeUnit);
+ method @RequiresApi(26) public final B keepResultsForAtLeast(java.time.Duration);
+ method public final B setBackoffCriteria(androidx.work.BackoffPolicy, long, java.util.concurrent.TimeUnit);
+ method @RequiresApi(26) public final B setBackoffCriteria(androidx.work.BackoffPolicy, java.time.Duration);
+ method public final B setConstraints(androidx.work.Constraints);
+ method public B setInitialDelay(long, java.util.concurrent.TimeUnit);
+ method @RequiresApi(26) public B setInitialDelay(java.time.Duration);
+ method public final B setInputData(androidx.work.Data);
+ }
+
+ public abstract class Worker extends androidx.work.ListenableWorker {
+ ctor @Keep public Worker(android.content.Context, androidx.work.WorkerParameters);
+ method @WorkerThread public abstract androidx.work.ListenableWorker.Result doWork();
+ method public final com.google.common.util.concurrent.ListenableFuture<androidx.work.ListenableWorker.Result!> startWork();
+ }
+
+ public abstract class WorkerFactory {
+ ctor public WorkerFactory();
+ method public abstract androidx.work.ListenableWorker? createWorker(android.content.Context, String, androidx.work.WorkerParameters);
+ }
+
+ public final class WorkerParameters {
+ method public java.util.UUID getId();
+ method public androidx.work.Data getInputData();
+ method @RequiresApi(28) public android.net.Network? getNetwork();
+ method @IntRange(from=0) public int getRunAttemptCount();
+ method public java.util.Set<java.lang.String!> getTags();
+ method @RequiresApi(24) public java.util.List<java.lang.String!> getTriggeredContentAuthorities();
+ method @RequiresApi(24) public java.util.List<android.net.Uri!> getTriggeredContentUris();
+ }
+
+}
+
diff --git a/work/workmanager/api/public_plus_experimental_2.4.0-alpha02.txt b/work/workmanager/api/public_plus_experimental_2.4.0-alpha02.txt
new file mode 100644
index 0000000..c9948b2
--- /dev/null
+++ b/work/workmanager/api/public_plus_experimental_2.4.0-alpha02.txt
@@ -0,0 +1,340 @@
+// Signature format: 3.0
+package androidx.work {
+
+ public final class ArrayCreatingInputMerger extends androidx.work.InputMerger {
+ ctor public ArrayCreatingInputMerger();
+ method public androidx.work.Data merge(java.util.List<androidx.work.Data!>);
+ }
+
+ public enum BackoffPolicy {
+ enum_constant public static final androidx.work.BackoffPolicy EXPONENTIAL;
+ enum_constant public static final androidx.work.BackoffPolicy LINEAR;
+ }
+
+ public final class Configuration {
+ method public java.util.concurrent.Executor getExecutor();
+ method public androidx.work.InputMergerFactory getInputMergerFactory();
+ method public int getMaxJobSchedulerId();
+ method public int getMinJobSchedulerId();
+ method public androidx.work.RunnableScheduler getRunnableScheduler();
+ method public java.util.concurrent.Executor getTaskExecutor();
+ method public androidx.work.WorkerFactory getWorkerFactory();
+ field public static final int MIN_SCHEDULER_LIMIT = 20; // 0x14
+ }
+
+ public static final class Configuration.Builder {
+ ctor public Configuration.Builder();
+ method public androidx.work.Configuration build();
+ method public androidx.work.Configuration.Builder setExecutor(java.util.concurrent.Executor);
+ method public androidx.work.Configuration.Builder setInputMergerFactory(androidx.work.InputMergerFactory);
+ method public androidx.work.Configuration.Builder setJobSchedulerJobIdRange(int, int);
+ method public androidx.work.Configuration.Builder setMaxSchedulerLimit(int);
+ method public androidx.work.Configuration.Builder setMinimumLoggingLevel(int);
+ method public androidx.work.Configuration.Builder setRunnableScheduler(androidx.work.RunnableScheduler);
+ method public androidx.work.Configuration.Builder setTaskExecutor(java.util.concurrent.Executor);
+ method public androidx.work.Configuration.Builder setWorkerFactory(androidx.work.WorkerFactory);
+ }
+
+ public static interface Configuration.Provider {
+ method public androidx.work.Configuration getWorkManagerConfiguration();
+ }
+
+ public final class Constraints {
+ ctor public Constraints(androidx.work.Constraints);
+ method public androidx.work.NetworkType getRequiredNetworkType();
+ method public boolean requiresBatteryNotLow();
+ method public boolean requiresCharging();
+ method @RequiresApi(23) public boolean requiresDeviceIdle();
+ method public boolean requiresStorageNotLow();
+ field public static final androidx.work.Constraints! NONE;
+ }
+
+ public static final class Constraints.Builder {
+ ctor public Constraints.Builder();
+ method @RequiresApi(24) public androidx.work.Constraints.Builder addContentUriTrigger(android.net.Uri, boolean);
+ method public androidx.work.Constraints build();
+ method public androidx.work.Constraints.Builder setRequiredNetworkType(androidx.work.NetworkType);
+ method public androidx.work.Constraints.Builder setRequiresBatteryNotLow(boolean);
+ method public androidx.work.Constraints.Builder setRequiresCharging(boolean);
+ method @RequiresApi(23) public androidx.work.Constraints.Builder setRequiresDeviceIdle(boolean);
+ method public androidx.work.Constraints.Builder setRequiresStorageNotLow(boolean);
+ method @RequiresApi(24) public androidx.work.Constraints.Builder setTriggerContentMaxDelay(long, java.util.concurrent.TimeUnit);
+ method @RequiresApi(26) public androidx.work.Constraints.Builder setTriggerContentMaxDelay(java.time.Duration!);
+ method @RequiresApi(24) public androidx.work.Constraints.Builder setTriggerContentUpdateDelay(long, java.util.concurrent.TimeUnit);
+ method @RequiresApi(26) public androidx.work.Constraints.Builder setTriggerContentUpdateDelay(java.time.Duration!);
+ }
+
+ public final class Data {
+ ctor public Data(androidx.work.Data);
+ method public static androidx.work.Data fromByteArray(byte[]);
+ method public boolean getBoolean(String, boolean);
+ method public boolean[]? getBooleanArray(String);
+ method public byte getByte(String, byte);
+ method public byte[]? getByteArray(String);
+ method public double getDouble(String, double);
+ method public double[]? getDoubleArray(String);
+ method public float getFloat(String, float);
+ method public float[]? getFloatArray(String);
+ method public int getInt(String, int);
+ method public int[]? getIntArray(String);
+ method public java.util.Map<java.lang.String!,java.lang.Object!> getKeyValueMap();
+ method public long getLong(String, long);
+ method public long[]? getLongArray(String);
+ method public String? getString(String);
+ method public String![]? getStringArray(String);
+ method public <T> boolean hasKeyWithValueOfType(String, Class<T!>);
+ method public byte[] toByteArray();
+ field public static final androidx.work.Data! EMPTY;
+ field public static final int MAX_DATA_BYTES = 10240; // 0x2800
+ }
+
+ public static final class Data.Builder {
+ ctor public Data.Builder();
+ method public androidx.work.Data build();
+ method public androidx.work.Data.Builder putAll(androidx.work.Data);
+ method public androidx.work.Data.Builder putAll(java.util.Map<java.lang.String!,java.lang.Object!>);
+ method public androidx.work.Data.Builder putBoolean(String, boolean);
+ method public androidx.work.Data.Builder putBooleanArray(String, boolean[]);
+ method public androidx.work.Data.Builder putByte(String, byte);
+ method public androidx.work.Data.Builder putByteArray(String, byte[]);
+ method public androidx.work.Data.Builder putDouble(String, double);
+ method public androidx.work.Data.Builder putDoubleArray(String, double[]);
+ method public androidx.work.Data.Builder putFloat(String, float);
+ method public androidx.work.Data.Builder putFloatArray(String, float[]);
+ method public androidx.work.Data.Builder putInt(String, int);
+ method public androidx.work.Data.Builder putIntArray(String, int[]);
+ method public androidx.work.Data.Builder putLong(String, long);
+ method public androidx.work.Data.Builder putLongArray(String, long[]);
+ method public androidx.work.Data.Builder putString(String, String?);
+ method public androidx.work.Data.Builder putStringArray(String, String![]);
+ }
+
+ public class DelegatingWorkerFactory extends androidx.work.WorkerFactory {
+ ctor public DelegatingWorkerFactory();
+ method public final void addFactory(androidx.work.WorkerFactory);
+ method public final androidx.work.ListenableWorker? createWorker(android.content.Context, String, androidx.work.WorkerParameters);
+ }
+
+ public enum ExistingPeriodicWorkPolicy {
+ enum_constant public static final androidx.work.ExistingPeriodicWorkPolicy KEEP;
+ enum_constant public static final androidx.work.ExistingPeriodicWorkPolicy REPLACE;
+ }
+
+ public enum ExistingWorkPolicy {
+ enum_constant public static final androidx.work.ExistingWorkPolicy APPEND;
+ enum_constant public static final androidx.work.ExistingWorkPolicy APPEND_OR_REPLACE;
+ enum_constant public static final androidx.work.ExistingWorkPolicy KEEP;
+ enum_constant public static final androidx.work.ExistingWorkPolicy REPLACE;
+ }
+
+ public final class ForegroundInfo {
+ ctor public ForegroundInfo(int, android.app.Notification);
+ ctor public ForegroundInfo(int, android.app.Notification, int);
+ method public int getForegroundServiceType();
+ method public android.app.Notification getNotification();
+ method public int getNotificationId();
+ }
+
+ public interface ForegroundUpdater {
+ method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setForegroundAsync(android.content.Context, java.util.UUID, androidx.work.ForegroundInfo);
+ }
+
+ public abstract class InputMerger {
+ ctor public InputMerger();
+ method public abstract androidx.work.Data merge(java.util.List<androidx.work.Data!>);
+ }
+
+ public abstract class InputMergerFactory {
+ ctor public InputMergerFactory();
+ method public abstract androidx.work.InputMerger? createInputMerger(String);
+ }
+
+ public abstract class ListenableWorker {
+ ctor @Keep public ListenableWorker(android.content.Context, androidx.work.WorkerParameters);
+ method public final android.content.Context getApplicationContext();
+ method public final java.util.UUID getId();
+ method public final androidx.work.Data getInputData();
+ method @RequiresApi(28) public final android.net.Network? getNetwork();
+ method @IntRange(from=0) public final int getRunAttemptCount();
+ method public final java.util.Set<java.lang.String!> getTags();
+ method @RequiresApi(24) public final java.util.List<java.lang.String!> getTriggeredContentAuthorities();
+ method @RequiresApi(24) public final java.util.List<android.net.Uri!> getTriggeredContentUris();
+ method public final boolean isStopped();
+ method public void onStopped();
+ method public final com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setForegroundAsync(androidx.work.ForegroundInfo);
+ method public final com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setProgressAsync(androidx.work.Data);
+ method @MainThread public abstract com.google.common.util.concurrent.ListenableFuture<androidx.work.ListenableWorker.Result!> startWork();
+ }
+
+ public abstract static class ListenableWorker.Result {
+ method public static androidx.work.ListenableWorker.Result failure();
+ method public static androidx.work.ListenableWorker.Result failure(androidx.work.Data);
+ method public static androidx.work.ListenableWorker.Result retry();
+ method public static androidx.work.ListenableWorker.Result success();
+ method public static androidx.work.ListenableWorker.Result success(androidx.work.Data);
+ }
+
+ public enum NetworkType {
+ enum_constant public static final androidx.work.NetworkType CONNECTED;
+ enum_constant public static final androidx.work.NetworkType METERED;
+ enum_constant public static final androidx.work.NetworkType NOT_REQUIRED;
+ enum_constant public static final androidx.work.NetworkType NOT_ROAMING;
+ enum_constant public static final androidx.work.NetworkType UNMETERED;
+ }
+
+ public final class OneTimeWorkRequest extends androidx.work.WorkRequest {
+ method public static androidx.work.OneTimeWorkRequest from(Class<? extends androidx.work.ListenableWorker>);
+ method public static java.util.List<androidx.work.OneTimeWorkRequest!> from(java.util.List<java.lang.Class<? extends androidx.work.ListenableWorker>!>);
+ }
+
+ public static final class OneTimeWorkRequest.Builder extends androidx.work.WorkRequest.Builder<androidx.work.OneTimeWorkRequest.Builder,androidx.work.OneTimeWorkRequest> {
+ ctor public OneTimeWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker>);
+ method public androidx.work.OneTimeWorkRequest.Builder setInputMerger(Class<? extends androidx.work.InputMerger>);
+ }
+
+ public interface Operation {
+ method public com.google.common.util.concurrent.ListenableFuture<androidx.work.Operation.State.SUCCESS!> getResult();
+ method public androidx.lifecycle.LiveData<androidx.work.Operation.State!> getState();
+ }
+
+ public abstract static class Operation.State {
+ }
+
+ public static final class Operation.State.FAILURE extends androidx.work.Operation.State {
+ ctor public Operation.State.FAILURE(Throwable);
+ method public Throwable getThrowable();
+ }
+
+ public static final class Operation.State.IN_PROGRESS extends androidx.work.Operation.State {
+ }
+
+ public static final class Operation.State.SUCCESS extends androidx.work.Operation.State {
+ }
+
+ public final class OverwritingInputMerger extends androidx.work.InputMerger {
+ ctor public OverwritingInputMerger();
+ method public androidx.work.Data merge(java.util.List<androidx.work.Data!>);
+ }
+
+ public final class PeriodicWorkRequest extends androidx.work.WorkRequest {
+ field public static final long MIN_PERIODIC_FLEX_MILLIS = 300000L; // 0x493e0L
+ field public static final long MIN_PERIODIC_INTERVAL_MILLIS = 900000L; // 0xdbba0L
+ }
+
+ public static final class PeriodicWorkRequest.Builder extends androidx.work.WorkRequest.Builder<androidx.work.PeriodicWorkRequest.Builder,androidx.work.PeriodicWorkRequest> {
+ ctor public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker>, long, java.util.concurrent.TimeUnit);
+ ctor @RequiresApi(26) public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker>, java.time.Duration);
+ ctor public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker>, long, java.util.concurrent.TimeUnit, long, java.util.concurrent.TimeUnit);
+ ctor @RequiresApi(26) public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker>, java.time.Duration, java.time.Duration);
+ }
+
+ public interface ProgressUpdater {
+ method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> updateProgress(android.content.Context, java.util.UUID, androidx.work.Data);
+ }
+
+ public interface RunnableScheduler {
+ method public void cancel(Runnable);
+ method public void scheduleWithDelay(long, Runnable);
+ }
+
+ public abstract class WorkContinuation {
+ ctor public WorkContinuation();
+ method public static androidx.work.WorkContinuation combine(java.util.List<androidx.work.WorkContinuation!>);
+ method public abstract androidx.work.Operation enqueue();
+ method public abstract com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.work.WorkInfo!>!> getWorkInfos();
+ method public abstract androidx.lifecycle.LiveData<java.util.List<androidx.work.WorkInfo!>!> getWorkInfosLiveData();
+ method public final androidx.work.WorkContinuation then(androidx.work.OneTimeWorkRequest);
+ method public abstract androidx.work.WorkContinuation then(java.util.List<androidx.work.OneTimeWorkRequest!>);
+ }
+
+ public final class WorkInfo {
+ method public java.util.UUID getId();
+ method public androidx.work.Data getOutputData();
+ method public androidx.work.Data getProgress();
+ method @IntRange(from=0) public int getRunAttemptCount();
+ method public androidx.work.WorkInfo.State getState();
+ method public java.util.Set<java.lang.String!> getTags();
+ }
+
+ public enum WorkInfo.State {
+ method public boolean isFinished();
+ enum_constant public static final androidx.work.WorkInfo.State BLOCKED;
+ enum_constant public static final androidx.work.WorkInfo.State CANCELLED;
+ enum_constant public static final androidx.work.WorkInfo.State ENQUEUED;
+ enum_constant public static final androidx.work.WorkInfo.State FAILED;
+ enum_constant public static final androidx.work.WorkInfo.State RUNNING;
+ enum_constant public static final androidx.work.WorkInfo.State SUCCEEDED;
+ }
+
+ public abstract class WorkManager {
+ method public final androidx.work.WorkContinuation beginUniqueWork(String, androidx.work.ExistingWorkPolicy, androidx.work.OneTimeWorkRequest);
+ method public abstract androidx.work.WorkContinuation beginUniqueWork(String, androidx.work.ExistingWorkPolicy, java.util.List<androidx.work.OneTimeWorkRequest!>);
+ method public final androidx.work.WorkContinuation beginWith(androidx.work.OneTimeWorkRequest);
+ method public abstract androidx.work.WorkContinuation beginWith(java.util.List<androidx.work.OneTimeWorkRequest!>);
+ method public abstract androidx.work.Operation cancelAllWork();
+ method public abstract androidx.work.Operation cancelAllWorkByTag(String);
+ method public abstract androidx.work.Operation cancelUniqueWork(String);
+ method public abstract androidx.work.Operation cancelWorkById(java.util.UUID);
+ method public abstract android.app.PendingIntent createCancelPendingIntent(java.util.UUID);
+ method public final androidx.work.Operation enqueue(androidx.work.WorkRequest);
+ method public abstract androidx.work.Operation enqueue(java.util.List<? extends androidx.work.WorkRequest>);
+ method public abstract androidx.work.Operation enqueueUniquePeriodicWork(String, androidx.work.ExistingPeriodicWorkPolicy, androidx.work.PeriodicWorkRequest);
+ method public androidx.work.Operation enqueueUniqueWork(String, androidx.work.ExistingWorkPolicy, androidx.work.OneTimeWorkRequest);
+ method public abstract androidx.work.Operation enqueueUniqueWork(String, androidx.work.ExistingWorkPolicy, java.util.List<androidx.work.OneTimeWorkRequest!>);
+ method @Deprecated public static androidx.work.WorkManager getInstance();
+ method public static androidx.work.WorkManager getInstance(android.content.Context);
+ method public abstract com.google.common.util.concurrent.ListenableFuture<java.lang.Long!> getLastCancelAllTimeMillis();
+ method public abstract androidx.lifecycle.LiveData<java.lang.Long!> getLastCancelAllTimeMillisLiveData();
+ method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.work.WorkInfo!> getWorkInfoById(java.util.UUID);
+ method public abstract androidx.lifecycle.LiveData<androidx.work.WorkInfo!> getWorkInfoByIdLiveData(java.util.UUID);
+ method public abstract com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.work.WorkInfo!>!> getWorkInfosByTag(String);
+ method public abstract androidx.lifecycle.LiveData<java.util.List<androidx.work.WorkInfo!>!> getWorkInfosByTagLiveData(String);
+ method public abstract com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.work.WorkInfo!>!> getWorkInfosForUniqueWork(String);
+ method public abstract androidx.lifecycle.LiveData<java.util.List<androidx.work.WorkInfo!>!> getWorkInfosForUniqueWorkLiveData(String);
+ method public static void initialize(android.content.Context, androidx.work.Configuration);
+ method public abstract androidx.work.Operation pruneWork();
+ }
+
+ public abstract class WorkRequest {
+ method public java.util.UUID getId();
+ field public static final long DEFAULT_BACKOFF_DELAY_MILLIS = 30000L; // 0x7530L
+ field public static final long MAX_BACKOFF_MILLIS = 18000000L; // 0x112a880L
+ field public static final long MIN_BACKOFF_MILLIS = 10000L; // 0x2710L
+ }
+
+ public abstract static class WorkRequest.Builder<B extends androidx.work.WorkRequest.Builder<?, ?>, W extends androidx.work.WorkRequest> {
+ method public final B addTag(String);
+ method public final W build();
+ method public final B keepResultsForAtLeast(long, java.util.concurrent.TimeUnit);
+ method @RequiresApi(26) public final B keepResultsForAtLeast(java.time.Duration);
+ method public final B setBackoffCriteria(androidx.work.BackoffPolicy, long, java.util.concurrent.TimeUnit);
+ method @RequiresApi(26) public final B setBackoffCriteria(androidx.work.BackoffPolicy, java.time.Duration);
+ method public final B setConstraints(androidx.work.Constraints);
+ method public B setInitialDelay(long, java.util.concurrent.TimeUnit);
+ method @RequiresApi(26) public B setInitialDelay(java.time.Duration);
+ method public final B setInputData(androidx.work.Data);
+ }
+
+ public abstract class Worker extends androidx.work.ListenableWorker {
+ ctor @Keep public Worker(android.content.Context, androidx.work.WorkerParameters);
+ method @WorkerThread public abstract androidx.work.ListenableWorker.Result doWork();
+ method public final com.google.common.util.concurrent.ListenableFuture<androidx.work.ListenableWorker.Result!> startWork();
+ }
+
+ public abstract class WorkerFactory {
+ ctor public WorkerFactory();
+ method public abstract androidx.work.ListenableWorker? createWorker(android.content.Context, String, androidx.work.WorkerParameters);
+ }
+
+ public final class WorkerParameters {
+ method public java.util.UUID getId();
+ method public androidx.work.Data getInputData();
+ method @RequiresApi(28) public android.net.Network? getNetwork();
+ method @IntRange(from=0) public int getRunAttemptCount();
+ method public java.util.Set<java.lang.String!> getTags();
+ method @RequiresApi(24) public java.util.List<java.lang.String!> getTriggeredContentAuthorities();
+ method @RequiresApi(24) public java.util.List<android.net.Uri!> getTriggeredContentUris();
+ }
+
+}
+
diff --git a/lifecycle/lifecycle-extensions/api/res-2.3.0-alpha02.txt b/work/workmanager/api/res-2.4.0-alpha02.txt
similarity index 100%
copy from lifecycle/lifecycle-extensions/api/res-2.3.0-alpha02.txt
copy to work/workmanager/api/res-2.4.0-alpha02.txt
diff --git a/work/workmanager/api/restricted_2.4.0-alpha02.txt b/work/workmanager/api/restricted_2.4.0-alpha02.txt
new file mode 100644
index 0000000..c9948b2
--- /dev/null
+++ b/work/workmanager/api/restricted_2.4.0-alpha02.txt
@@ -0,0 +1,340 @@
+// Signature format: 3.0
+package androidx.work {
+
+ public final class ArrayCreatingInputMerger extends androidx.work.InputMerger {
+ ctor public ArrayCreatingInputMerger();
+ method public androidx.work.Data merge(java.util.List<androidx.work.Data!>);
+ }
+
+ public enum BackoffPolicy {
+ enum_constant public static final androidx.work.BackoffPolicy EXPONENTIAL;
+ enum_constant public static final androidx.work.BackoffPolicy LINEAR;
+ }
+
+ public final class Configuration {
+ method public java.util.concurrent.Executor getExecutor();
+ method public androidx.work.InputMergerFactory getInputMergerFactory();
+ method public int getMaxJobSchedulerId();
+ method public int getMinJobSchedulerId();
+ method public androidx.work.RunnableScheduler getRunnableScheduler();
+ method public java.util.concurrent.Executor getTaskExecutor();
+ method public androidx.work.WorkerFactory getWorkerFactory();
+ field public static final int MIN_SCHEDULER_LIMIT = 20; // 0x14
+ }
+
+ public static final class Configuration.Builder {
+ ctor public Configuration.Builder();
+ method public androidx.work.Configuration build();
+ method public androidx.work.Configuration.Builder setExecutor(java.util.concurrent.Executor);
+ method public androidx.work.Configuration.Builder setInputMergerFactory(androidx.work.InputMergerFactory);
+ method public androidx.work.Configuration.Builder setJobSchedulerJobIdRange(int, int);
+ method public androidx.work.Configuration.Builder setMaxSchedulerLimit(int);
+ method public androidx.work.Configuration.Builder setMinimumLoggingLevel(int);
+ method public androidx.work.Configuration.Builder setRunnableScheduler(androidx.work.RunnableScheduler);
+ method public androidx.work.Configuration.Builder setTaskExecutor(java.util.concurrent.Executor);
+ method public androidx.work.Configuration.Builder setWorkerFactory(androidx.work.WorkerFactory);
+ }
+
+ public static interface Configuration.Provider {
+ method public androidx.work.Configuration getWorkManagerConfiguration();
+ }
+
+ public final class Constraints {
+ ctor public Constraints(androidx.work.Constraints);
+ method public androidx.work.NetworkType getRequiredNetworkType();
+ method public boolean requiresBatteryNotLow();
+ method public boolean requiresCharging();
+ method @RequiresApi(23) public boolean requiresDeviceIdle();
+ method public boolean requiresStorageNotLow();
+ field public static final androidx.work.Constraints! NONE;
+ }
+
+ public static final class Constraints.Builder {
+ ctor public Constraints.Builder();
+ method @RequiresApi(24) public androidx.work.Constraints.Builder addContentUriTrigger(android.net.Uri, boolean);
+ method public androidx.work.Constraints build();
+ method public androidx.work.Constraints.Builder setRequiredNetworkType(androidx.work.NetworkType);
+ method public androidx.work.Constraints.Builder setRequiresBatteryNotLow(boolean);
+ method public androidx.work.Constraints.Builder setRequiresCharging(boolean);
+ method @RequiresApi(23) public androidx.work.Constraints.Builder setRequiresDeviceIdle(boolean);
+ method public androidx.work.Constraints.Builder setRequiresStorageNotLow(boolean);
+ method @RequiresApi(24) public androidx.work.Constraints.Builder setTriggerContentMaxDelay(long, java.util.concurrent.TimeUnit);
+ method @RequiresApi(26) public androidx.work.Constraints.Builder setTriggerContentMaxDelay(java.time.Duration!);
+ method @RequiresApi(24) public androidx.work.Constraints.Builder setTriggerContentUpdateDelay(long, java.util.concurrent.TimeUnit);
+ method @RequiresApi(26) public androidx.work.Constraints.Builder setTriggerContentUpdateDelay(java.time.Duration!);
+ }
+
+ public final class Data {
+ ctor public Data(androidx.work.Data);
+ method public static androidx.work.Data fromByteArray(byte[]);
+ method public boolean getBoolean(String, boolean);
+ method public boolean[]? getBooleanArray(String);
+ method public byte getByte(String, byte);
+ method public byte[]? getByteArray(String);
+ method public double getDouble(String, double);
+ method public double[]? getDoubleArray(String);
+ method public float getFloat(String, float);
+ method public float[]? getFloatArray(String);
+ method public int getInt(String, int);
+ method public int[]? getIntArray(String);
+ method public java.util.Map<java.lang.String!,java.lang.Object!> getKeyValueMap();
+ method public long getLong(String, long);
+ method public long[]? getLongArray(String);
+ method public String? getString(String);
+ method public String![]? getStringArray(String);
+ method public <T> boolean hasKeyWithValueOfType(String, Class<T!>);
+ method public byte[] toByteArray();
+ field public static final androidx.work.Data! EMPTY;
+ field public static final int MAX_DATA_BYTES = 10240; // 0x2800
+ }
+
+ public static final class Data.Builder {
+ ctor public Data.Builder();
+ method public androidx.work.Data build();
+ method public androidx.work.Data.Builder putAll(androidx.work.Data);
+ method public androidx.work.Data.Builder putAll(java.util.Map<java.lang.String!,java.lang.Object!>);
+ method public androidx.work.Data.Builder putBoolean(String, boolean);
+ method public androidx.work.Data.Builder putBooleanArray(String, boolean[]);
+ method public androidx.work.Data.Builder putByte(String, byte);
+ method public androidx.work.Data.Builder putByteArray(String, byte[]);
+ method public androidx.work.Data.Builder putDouble(String, double);
+ method public androidx.work.Data.Builder putDoubleArray(String, double[]);
+ method public androidx.work.Data.Builder putFloat(String, float);
+ method public androidx.work.Data.Builder putFloatArray(String, float[]);
+ method public androidx.work.Data.Builder putInt(String, int);
+ method public androidx.work.Data.Builder putIntArray(String, int[]);
+ method public androidx.work.Data.Builder putLong(String, long);
+ method public androidx.work.Data.Builder putLongArray(String, long[]);
+ method public androidx.work.Data.Builder putString(String, String?);
+ method public androidx.work.Data.Builder putStringArray(String, String![]);
+ }
+
+ public class DelegatingWorkerFactory extends androidx.work.WorkerFactory {
+ ctor public DelegatingWorkerFactory();
+ method public final void addFactory(androidx.work.WorkerFactory);
+ method public final androidx.work.ListenableWorker? createWorker(android.content.Context, String, androidx.work.WorkerParameters);
+ }
+
+ public enum ExistingPeriodicWorkPolicy {
+ enum_constant public static final androidx.work.ExistingPeriodicWorkPolicy KEEP;
+ enum_constant public static final androidx.work.ExistingPeriodicWorkPolicy REPLACE;
+ }
+
+ public enum ExistingWorkPolicy {
+ enum_constant public static final androidx.work.ExistingWorkPolicy APPEND;
+ enum_constant public static final androidx.work.ExistingWorkPolicy APPEND_OR_REPLACE;
+ enum_constant public static final androidx.work.ExistingWorkPolicy KEEP;
+ enum_constant public static final androidx.work.ExistingWorkPolicy REPLACE;
+ }
+
+ public final class ForegroundInfo {
+ ctor public ForegroundInfo(int, android.app.Notification);
+ ctor public ForegroundInfo(int, android.app.Notification, int);
+ method public int getForegroundServiceType();
+ method public android.app.Notification getNotification();
+ method public int getNotificationId();
+ }
+
+ public interface ForegroundUpdater {
+ method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setForegroundAsync(android.content.Context, java.util.UUID, androidx.work.ForegroundInfo);
+ }
+
+ public abstract class InputMerger {
+ ctor public InputMerger();
+ method public abstract androidx.work.Data merge(java.util.List<androidx.work.Data!>);
+ }
+
+ public abstract class InputMergerFactory {
+ ctor public InputMergerFactory();
+ method public abstract androidx.work.InputMerger? createInputMerger(String);
+ }
+
+ public abstract class ListenableWorker {
+ ctor @Keep public ListenableWorker(android.content.Context, androidx.work.WorkerParameters);
+ method public final android.content.Context getApplicationContext();
+ method public final java.util.UUID getId();
+ method public final androidx.work.Data getInputData();
+ method @RequiresApi(28) public final android.net.Network? getNetwork();
+ method @IntRange(from=0) public final int getRunAttemptCount();
+ method public final java.util.Set<java.lang.String!> getTags();
+ method @RequiresApi(24) public final java.util.List<java.lang.String!> getTriggeredContentAuthorities();
+ method @RequiresApi(24) public final java.util.List<android.net.Uri!> getTriggeredContentUris();
+ method public final boolean isStopped();
+ method public void onStopped();
+ method public final com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setForegroundAsync(androidx.work.ForegroundInfo);
+ method public final com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> setProgressAsync(androidx.work.Data);
+ method @MainThread public abstract com.google.common.util.concurrent.ListenableFuture<androidx.work.ListenableWorker.Result!> startWork();
+ }
+
+ public abstract static class ListenableWorker.Result {
+ method public static androidx.work.ListenableWorker.Result failure();
+ method public static androidx.work.ListenableWorker.Result failure(androidx.work.Data);
+ method public static androidx.work.ListenableWorker.Result retry();
+ method public static androidx.work.ListenableWorker.Result success();
+ method public static androidx.work.ListenableWorker.Result success(androidx.work.Data);
+ }
+
+ public enum NetworkType {
+ enum_constant public static final androidx.work.NetworkType CONNECTED;
+ enum_constant public static final androidx.work.NetworkType METERED;
+ enum_constant public static final androidx.work.NetworkType NOT_REQUIRED;
+ enum_constant public static final androidx.work.NetworkType NOT_ROAMING;
+ enum_constant public static final androidx.work.NetworkType UNMETERED;
+ }
+
+ public final class OneTimeWorkRequest extends androidx.work.WorkRequest {
+ method public static androidx.work.OneTimeWorkRequest from(Class<? extends androidx.work.ListenableWorker>);
+ method public static java.util.List<androidx.work.OneTimeWorkRequest!> from(java.util.List<java.lang.Class<? extends androidx.work.ListenableWorker>!>);
+ }
+
+ public static final class OneTimeWorkRequest.Builder extends androidx.work.WorkRequest.Builder<androidx.work.OneTimeWorkRequest.Builder,androidx.work.OneTimeWorkRequest> {
+ ctor public OneTimeWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker>);
+ method public androidx.work.OneTimeWorkRequest.Builder setInputMerger(Class<? extends androidx.work.InputMerger>);
+ }
+
+ public interface Operation {
+ method public com.google.common.util.concurrent.ListenableFuture<androidx.work.Operation.State.SUCCESS!> getResult();
+ method public androidx.lifecycle.LiveData<androidx.work.Operation.State!> getState();
+ }
+
+ public abstract static class Operation.State {
+ }
+
+ public static final class Operation.State.FAILURE extends androidx.work.Operation.State {
+ ctor public Operation.State.FAILURE(Throwable);
+ method public Throwable getThrowable();
+ }
+
+ public static final class Operation.State.IN_PROGRESS extends androidx.work.Operation.State {
+ }
+
+ public static final class Operation.State.SUCCESS extends androidx.work.Operation.State {
+ }
+
+ public final class OverwritingInputMerger extends androidx.work.InputMerger {
+ ctor public OverwritingInputMerger();
+ method public androidx.work.Data merge(java.util.List<androidx.work.Data!>);
+ }
+
+ public final class PeriodicWorkRequest extends androidx.work.WorkRequest {
+ field public static final long MIN_PERIODIC_FLEX_MILLIS = 300000L; // 0x493e0L
+ field public static final long MIN_PERIODIC_INTERVAL_MILLIS = 900000L; // 0xdbba0L
+ }
+
+ public static final class PeriodicWorkRequest.Builder extends androidx.work.WorkRequest.Builder<androidx.work.PeriodicWorkRequest.Builder,androidx.work.PeriodicWorkRequest> {
+ ctor public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker>, long, java.util.concurrent.TimeUnit);
+ ctor @RequiresApi(26) public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker>, java.time.Duration);
+ ctor public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker>, long, java.util.concurrent.TimeUnit, long, java.util.concurrent.TimeUnit);
+ ctor @RequiresApi(26) public PeriodicWorkRequest.Builder(Class<? extends androidx.work.ListenableWorker>, java.time.Duration, java.time.Duration);
+ }
+
+ public interface ProgressUpdater {
+ method public com.google.common.util.concurrent.ListenableFuture<java.lang.Void!> updateProgress(android.content.Context, java.util.UUID, androidx.work.Data);
+ }
+
+ public interface RunnableScheduler {
+ method public void cancel(Runnable);
+ method public void scheduleWithDelay(long, Runnable);
+ }
+
+ public abstract class WorkContinuation {
+ ctor public WorkContinuation();
+ method public static androidx.work.WorkContinuation combine(java.util.List<androidx.work.WorkContinuation!>);
+ method public abstract androidx.work.Operation enqueue();
+ method public abstract com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.work.WorkInfo!>!> getWorkInfos();
+ method public abstract androidx.lifecycle.LiveData<java.util.List<androidx.work.WorkInfo!>!> getWorkInfosLiveData();
+ method public final androidx.work.WorkContinuation then(androidx.work.OneTimeWorkRequest);
+ method public abstract androidx.work.WorkContinuation then(java.util.List<androidx.work.OneTimeWorkRequest!>);
+ }
+
+ public final class WorkInfo {
+ method public java.util.UUID getId();
+ method public androidx.work.Data getOutputData();
+ method public androidx.work.Data getProgress();
+ method @IntRange(from=0) public int getRunAttemptCount();
+ method public androidx.work.WorkInfo.State getState();
+ method public java.util.Set<java.lang.String!> getTags();
+ }
+
+ public enum WorkInfo.State {
+ method public boolean isFinished();
+ enum_constant public static final androidx.work.WorkInfo.State BLOCKED;
+ enum_constant public static final androidx.work.WorkInfo.State CANCELLED;
+ enum_constant public static final androidx.work.WorkInfo.State ENQUEUED;
+ enum_constant public static final androidx.work.WorkInfo.State FAILED;
+ enum_constant public static final androidx.work.WorkInfo.State RUNNING;
+ enum_constant public static final androidx.work.WorkInfo.State SUCCEEDED;
+ }
+
+ public abstract class WorkManager {
+ method public final androidx.work.WorkContinuation beginUniqueWork(String, androidx.work.ExistingWorkPolicy, androidx.work.OneTimeWorkRequest);
+ method public abstract androidx.work.WorkContinuation beginUniqueWork(String, androidx.work.ExistingWorkPolicy, java.util.List<androidx.work.OneTimeWorkRequest!>);
+ method public final androidx.work.WorkContinuation beginWith(androidx.work.OneTimeWorkRequest);
+ method public abstract androidx.work.WorkContinuation beginWith(java.util.List<androidx.work.OneTimeWorkRequest!>);
+ method public abstract androidx.work.Operation cancelAllWork();
+ method public abstract androidx.work.Operation cancelAllWorkByTag(String);
+ method public abstract androidx.work.Operation cancelUniqueWork(String);
+ method public abstract androidx.work.Operation cancelWorkById(java.util.UUID);
+ method public abstract android.app.PendingIntent createCancelPendingIntent(java.util.UUID);
+ method public final androidx.work.Operation enqueue(androidx.work.WorkRequest);
+ method public abstract androidx.work.Operation enqueue(java.util.List<? extends androidx.work.WorkRequest>);
+ method public abstract androidx.work.Operation enqueueUniquePeriodicWork(String, androidx.work.ExistingPeriodicWorkPolicy, androidx.work.PeriodicWorkRequest);
+ method public androidx.work.Operation enqueueUniqueWork(String, androidx.work.ExistingWorkPolicy, androidx.work.OneTimeWorkRequest);
+ method public abstract androidx.work.Operation enqueueUniqueWork(String, androidx.work.ExistingWorkPolicy, java.util.List<androidx.work.OneTimeWorkRequest!>);
+ method @Deprecated public static androidx.work.WorkManager getInstance();
+ method public static androidx.work.WorkManager getInstance(android.content.Context);
+ method public abstract com.google.common.util.concurrent.ListenableFuture<java.lang.Long!> getLastCancelAllTimeMillis();
+ method public abstract androidx.lifecycle.LiveData<java.lang.Long!> getLastCancelAllTimeMillisLiveData();
+ method public abstract com.google.common.util.concurrent.ListenableFuture<androidx.work.WorkInfo!> getWorkInfoById(java.util.UUID);
+ method public abstract androidx.lifecycle.LiveData<androidx.work.WorkInfo!> getWorkInfoByIdLiveData(java.util.UUID);
+ method public abstract com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.work.WorkInfo!>!> getWorkInfosByTag(String);
+ method public abstract androidx.lifecycle.LiveData<java.util.List<androidx.work.WorkInfo!>!> getWorkInfosByTagLiveData(String);
+ method public abstract com.google.common.util.concurrent.ListenableFuture<java.util.List<androidx.work.WorkInfo!>!> getWorkInfosForUniqueWork(String);
+ method public abstract androidx.lifecycle.LiveData<java.util.List<androidx.work.WorkInfo!>!> getWorkInfosForUniqueWorkLiveData(String);
+ method public static void initialize(android.content.Context, androidx.work.Configuration);
+ method public abstract androidx.work.Operation pruneWork();
+ }
+
+ public abstract class WorkRequest {
+ method public java.util.UUID getId();
+ field public static final long DEFAULT_BACKOFF_DELAY_MILLIS = 30000L; // 0x7530L
+ field public static final long MAX_BACKOFF_MILLIS = 18000000L; // 0x112a880L
+ field public static final long MIN_BACKOFF_MILLIS = 10000L; // 0x2710L
+ }
+
+ public abstract static class WorkRequest.Builder<B extends androidx.work.WorkRequest.Builder<?, ?>, W extends androidx.work.WorkRequest> {
+ method public final B addTag(String);
+ method public final W build();
+ method public final B keepResultsForAtLeast(long, java.util.concurrent.TimeUnit);
+ method @RequiresApi(26) public final B keepResultsForAtLeast(java.time.Duration);
+ method public final B setBackoffCriteria(androidx.work.BackoffPolicy, long, java.util.concurrent.TimeUnit);
+ method @RequiresApi(26) public final B setBackoffCriteria(androidx.work.BackoffPolicy, java.time.Duration);
+ method public final B setConstraints(androidx.work.Constraints);
+ method public B setInitialDelay(long, java.util.concurrent.TimeUnit);
+ method @RequiresApi(26) public B setInitialDelay(java.time.Duration);
+ method public final B setInputData(androidx.work.Data);
+ }
+
+ public abstract class Worker extends androidx.work.ListenableWorker {
+ ctor @Keep public Worker(android.content.Context, androidx.work.WorkerParameters);
+ method @WorkerThread public abstract androidx.work.ListenableWorker.Result doWork();
+ method public final com.google.common.util.concurrent.ListenableFuture<androidx.work.ListenableWorker.Result!> startWork();
+ }
+
+ public abstract class WorkerFactory {
+ ctor public WorkerFactory();
+ method public abstract androidx.work.ListenableWorker? createWorker(android.content.Context, String, androidx.work.WorkerParameters);
+ }
+
+ public final class WorkerParameters {
+ method public java.util.UUID getId();
+ method public androidx.work.Data getInputData();
+ method @RequiresApi(28) public android.net.Network? getNetwork();
+ method @IntRange(from=0) public int getRunAttemptCount();
+ method public java.util.Set<java.lang.String!> getTags();
+ method @RequiresApi(24) public java.util.List<java.lang.String!> getTriggeredContentAuthorities();
+ method @RequiresApi(24) public java.util.List<android.net.Uri!> getTriggeredContentUris();
+ }
+
+}
+
diff --git a/work/workmanager/build.gradle b/work/workmanager/build.gradle
index 273ab18..41965a1 100644
--- a/work/workmanager/build.gradle
+++ b/work/workmanager/build.gradle
@@ -62,9 +62,9 @@
}
dependencies {
- annotationProcessor("androidx.room:room-compiler:2.2.3")
- implementation("androidx.room:room-runtime:2.2.3")
- androidTestImplementation("androidx.room:room-testing:2.2.3")
+ annotationProcessor("androidx.room:room-compiler:2.2.5")
+ implementation("androidx.room:room-runtime:2.2.5")
+ androidTestImplementation("androidx.room:room-testing:2.2.5")
implementation("androidx.sqlite:sqlite:2.1.0")
implementation("androidx.sqlite:sqlite-framework:2.1.0")
api(GUAVA_LISTENABLE_FUTURE)
diff --git a/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java b/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java
index 958c239..c45eeb0 100644
--- a/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java
+++ b/work/workmanager/src/androidTest/java/androidx/work/impl/WorkManagerImplTest.java
@@ -167,8 +167,8 @@
mWorkManagerImpl.getConfiguration(),
mWorkManagerImpl.getWorkTaskExecutor(),
mWorkManagerImpl));
- // Return GreedyScheduler alone, because real jobs gets scheduled which slow down tests.
- when(mWorkManagerImpl.getSchedulers()).thenReturn(Collections.singletonList(mScheduler));
+ // Don't return any scheduler. We don't need to actually execute work for most of our tests.
+ when(mWorkManagerImpl.getSchedulers()).thenReturn(Collections.<Scheduler>emptyList());
WorkManagerImpl.setDelegate(mWorkManagerImpl);
mDatabase = mWorkManagerImpl.getWorkDatabase();
}
@@ -1591,6 +1591,7 @@
@Test
@MediumTest
public void testForceStopRunnable_resetsRunningWorkStatuses() {
+ when(mWorkManagerImpl.getSchedulers()).thenReturn(Collections.singletonList(mScheduler));
WorkSpecDao workSpecDao = mDatabase.workSpecDao();
OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(TestWorker.class)
@@ -1729,7 +1730,6 @@
@SdkSuppress(maxSdkVersion = 22)
public void testEnqueueApi22OrLower_withBatteryNotLowConstraint_expectsOriginalWorker()
throws ExecutionException, InterruptedException {
-
OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(TestWorker.class)
.setConstraints(new Constraints.Builder()
.setRequiresBatteryNotLow(true)
@@ -1746,7 +1746,6 @@
@SdkSuppress(maxSdkVersion = 22)
public void testEnqueueApi22OrLower_withStorageNotLowConstraint_expectsOriginalWorker()
throws ExecutionException, InterruptedException {
-
OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(TestWorker.class)
.setConstraints(new Constraints.Builder()
.setRequiresStorageNotLow(true)
@@ -1763,7 +1762,6 @@
@SdkSuppress(minSdkVersion = 23, maxSdkVersion = 25)
public void testEnqueueApi23To25_withBatteryNotLowConstraint_expectsConstraintTrackingWorker()
throws ExecutionException, InterruptedException {
-
OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(TestWorker.class)
.setConstraints(new Constraints.Builder()
.setRequiresBatteryNotLow(true)
@@ -1783,7 +1781,6 @@
@SdkSuppress(minSdkVersion = 23, maxSdkVersion = 25)
public void testEnqueueApi23To25_withStorageNotLowConstraint_expectsConstraintTrackingWorker()
throws ExecutionException, InterruptedException {
-
OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(TestWorker.class)
.setConstraints(new Constraints.Builder()
.setRequiresStorageNotLow(true)
@@ -1803,14 +1800,12 @@
@SdkSuppress(minSdkVersion = 26)
public void testEnqueueApi26OrHigher_withBatteryNotLowConstraint_expectsOriginalWorker()
throws ExecutionException, InterruptedException {
-
OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(TestWorker.class)
.setConstraints(new Constraints.Builder()
.setRequiresBatteryNotLow(true)
.build())
.build();
mWorkManagerImpl.beginWith(work).enqueue().getResult().get();
-
WorkSpec workSpec = mDatabase.workSpecDao().getWorkSpec(work.getStringId());
assertThat(workSpec.workerClassName, is(TestWorker.class.getName()));
}
@@ -1820,14 +1815,12 @@
@SdkSuppress(minSdkVersion = 26)
public void testEnqueueApi26OrHigher_withStorageNotLowConstraint_expectsOriginalWorker()
throws ExecutionException, InterruptedException {
-
OneTimeWorkRequest work = new OneTimeWorkRequest.Builder(TestWorker.class)
.setConstraints(new Constraints.Builder()
.setRequiresStorageNotLow(true)
.build())
.build();
mWorkManagerImpl.beginWith(work).enqueue().getResult().get();
-
WorkSpec workSpec = mDatabase.workSpecDao().getWorkSpec(work.getStringId());
assertThat(workSpec.workerClassName, is(TestWorker.class.getName()));
}