commit | 1778aebfb0de3d8e6177fb940c0601db08bb3f9c | [log] [tgz] |
---|---|---|
author | Treehugger Robot | Mon Dec 11 20:39:38 2023 +0000 |
committer | Gerrit Code Review | Mon Dec 11 20:39:38 2023 +0000 |
tree | 6f2d094ae8570f6eb6f254bf9b030e545b708b29 | |
parent | 365ec8f873a716088d6eae876ae0542008845b45 [diff] | |
parent | 65a41afa53785831fa1414eb39f7957b66f4b262 [diff] |
Merge "Deprecate TextInputService and related APIs." into androidx-main
diff --git a/appcompat/appcompat-resources/api/restricted_current.txt b/appcompat/appcompat-resources/api/restricted_current.txt index 1278c5d..4b180e0 100644 --- a/appcompat/appcompat-resources/api/restricted_current.txt +++ b/appcompat/appcompat-resources/api/restricted_current.txt
@@ -98,7 +98,7 @@ method public int getColor(int) throws android.content.res.Resources.NotFoundException; method public android.content.res.ColorStateList! getColorStateList(int) throws android.content.res.Resources.NotFoundException; method public android.graphics.drawable.Drawable! getDrawable(int) throws android.content.res.Resources.NotFoundException; - method @RequiresApi(15) public android.graphics.drawable.Drawable! getDrawableForDensity(int, int) throws android.content.res.Resources.NotFoundException; + method public android.graphics.drawable.Drawable! getDrawableForDensity(int, int) throws android.content.res.Resources.NotFoundException; method public android.graphics.Movie! getMovie(int) throws android.content.res.Resources.NotFoundException; method public static boolean isCompatVectorFromResourcesEnabled(); method public static void setCompatVectorFromResourcesEnabled(boolean);
diff --git a/appcompat/appcompat-resources/src/main/java/androidx/appcompat/graphics/drawable/AnimatedStateListDrawableCompat.java b/appcompat/appcompat-resources/src/main/java/androidx/appcompat/graphics/drawable/AnimatedStateListDrawableCompat.java index 02e7743..ecff44f 100644 --- a/appcompat/appcompat-resources/src/main/java/androidx/appcompat/graphics/drawable/AnimatedStateListDrawableCompat.java +++ b/appcompat/appcompat-resources/src/main/java/androidx/appcompat/graphics/drawable/AnimatedStateListDrawableCompat.java
@@ -30,7 +30,6 @@ import android.graphics.drawable.Animatable; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.Drawable; -import android.os.Build; import android.util.AttributeSet; import android.util.Log; import android.util.StateSet; @@ -396,9 +395,7 @@ @SuppressLint("ObjectAnimatorBinding") final ObjectAnimator anim = ObjectAnimator.ofInt(ad, "currentIndex", fromFrame, toFrame); - if (SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - Compatibility.Api18Impl.setAutoCancel(anim, true); - } + anim.setAutoCancel(true); anim.setDuration(interp.getTotalDuration()); anim.setInterpolator(interp); mHasReversibleFlag = hasReversibleFlag;
diff --git a/appcompat/appcompat-resources/src/main/java/androidx/appcompat/resources/Compatibility.java b/appcompat/appcompat-resources/src/main/java/androidx/appcompat/resources/Compatibility.java index 1dd7e91..31658ce 100644 --- a/appcompat/appcompat-resources/src/main/java/androidx/appcompat/resources/Compatibility.java +++ b/appcompat/appcompat-resources/src/main/java/androidx/appcompat/resources/Compatibility.java
@@ -16,12 +16,10 @@ package androidx.appcompat.resources; -import android.animation.ObjectAnimator; import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.util.AttributeSet; -import android.util.TypedValue; import androidx.annotation.DoNotInline; import androidx.annotation.NonNull; @@ -70,29 +68,4 @@ return Drawable.createFromXmlInner(r, parser, attrs, theme); } } - - @RequiresApi(18) - public static class Api18Impl { - private Api18Impl() { - // This class is not instantiable. - } - - @DoNotInline - public static void setAutoCancel(@NonNull ObjectAnimator objectAnimator, boolean cancel) { - objectAnimator.setAutoCancel(cancel); - } - } - - @RequiresApi(15) - public static class Api15Impl { - private Api15Impl() { - // This class is not instantiable. - } - - @DoNotInline - public static void getValueForDensity(@NonNull Resources resources, int id, int density, - @NonNull TypedValue outValue, boolean resolveRefs) { - resources.getValueForDensity(id, density, outValue, resolveRefs); - } - } }
diff --git a/appcompat/appcompat-resources/src/main/java/androidx/appcompat/widget/ResourcesWrapper.java b/appcompat/appcompat-resources/src/main/java/androidx/appcompat/widget/ResourcesWrapper.java index b854a9e..1ddfb16 100644 --- a/appcompat/appcompat-resources/src/main/java/androidx/appcompat/widget/ResourcesWrapper.java +++ b/appcompat/appcompat-resources/src/main/java/androidx/appcompat/widget/ResourcesWrapper.java
@@ -29,7 +29,6 @@ import android.util.TypedValue; import androidx.annotation.RequiresApi; -import androidx.appcompat.resources.Compatibility; import androidx.core.content.res.ResourcesCompat; import org.xmlpull.v1.XmlPullParserException; @@ -156,7 +155,6 @@ } @SuppressWarnings("deprecation") - @RequiresApi(15) @Override public Drawable getDrawableForDensity(int id, int density) throws NotFoundException { // If the developer only overrode the three-arg method, this will cause issues; however, @@ -235,11 +233,10 @@ mResources.getValue(id, outValue, resolveRefs); } - @RequiresApi(15) @Override public void getValueForDensity(int id, int density, TypedValue outValue, boolean resolveRefs) throws NotFoundException { - Compatibility.Api15Impl.getValueForDensity(mResources, id, density, outValue, resolveRefs); + mResources.getValueForDensity(id, density, outValue, resolveRefs); } @Override
diff --git a/appsearch/appsearch-play-services-storage/api/current.txt b/appsearch/appsearch-play-services-storage/api/current.txt index 8d9c55f..77fe2c7 100644 --- a/appsearch/appsearch-play-services-storage/api/current.txt +++ b/appsearch/appsearch-play-services-storage/api/current.txt
@@ -7,20 +7,24 @@ } public static final class PlayServicesStorage.GlobalSearchContext { + method public java.util.concurrent.Executor getWorkerExecutor(); } public static final class PlayServicesStorage.GlobalSearchContext.Builder { ctor public PlayServicesStorage.GlobalSearchContext.Builder(android.content.Context); method public androidx.appsearch.playservicesstorage.PlayServicesStorage.GlobalSearchContext build(); + method public androidx.appsearch.playservicesstorage.PlayServicesStorage.GlobalSearchContext.Builder setWorkerExecutor(java.util.concurrent.Executor); } public static final class PlayServicesStorage.SearchContext { method public String getDatabaseName(); + method public java.util.concurrent.Executor getWorkerExecutor(); } public static final class PlayServicesStorage.SearchContext.Builder { ctor public PlayServicesStorage.SearchContext.Builder(android.content.Context, String); method public androidx.appsearch.playservicesstorage.PlayServicesStorage.SearchContext build(); + method public androidx.appsearch.playservicesstorage.PlayServicesStorage.SearchContext.Builder setWorkerExecutor(java.util.concurrent.Executor); } }
diff --git a/appsearch/appsearch-play-services-storage/api/restricted_current.txt b/appsearch/appsearch-play-services-storage/api/restricted_current.txt index 8d9c55f..77fe2c7 100644 --- a/appsearch/appsearch-play-services-storage/api/restricted_current.txt +++ b/appsearch/appsearch-play-services-storage/api/restricted_current.txt
@@ -7,20 +7,24 @@ } public static final class PlayServicesStorage.GlobalSearchContext { + method public java.util.concurrent.Executor getWorkerExecutor(); } public static final class PlayServicesStorage.GlobalSearchContext.Builder { ctor public PlayServicesStorage.GlobalSearchContext.Builder(android.content.Context); method public androidx.appsearch.playservicesstorage.PlayServicesStorage.GlobalSearchContext build(); + method public androidx.appsearch.playservicesstorage.PlayServicesStorage.GlobalSearchContext.Builder setWorkerExecutor(java.util.concurrent.Executor); } public static final class PlayServicesStorage.SearchContext { method public String getDatabaseName(); + method public java.util.concurrent.Executor getWorkerExecutor(); } public static final class PlayServicesStorage.SearchContext.Builder { ctor public PlayServicesStorage.SearchContext.Builder(android.content.Context, String); method public androidx.appsearch.playservicesstorage.PlayServicesStorage.SearchContext build(); + method public androidx.appsearch.playservicesstorage.PlayServicesStorage.SearchContext.Builder setWorkerExecutor(java.util.concurrent.Executor); } }
diff --git a/appsearch/appsearch-play-services-storage/build.gradle b/appsearch/appsearch-play-services-storage/build.gradle index 27b0fba..4fbcd2fa 100644 --- a/appsearch/appsearch-play-services-storage/build.gradle +++ b/appsearch/appsearch-play-services-storage/build.gradle
@@ -50,4 +50,7 @@ android { namespace "androidx.appsearch.playservicesstorage" + defaultConfig { + minSdkVersion 19 + } }
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/GlobalSearchSessionImpl.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/GlobalSearchSessionImpl.java index dc693e8..61c90ac 100644 --- a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/GlobalSearchSessionImpl.java +++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/GlobalSearchSessionImpl.java
@@ -54,12 +54,15 @@ private final GlobalSearchClient mGmsClient; private final Features mFeatures; + private final Executor mExecutor; GlobalSearchSessionImpl( @NonNull GlobalSearchClient gmsClient, - @NonNull Features features) { + @NonNull Features features, + @NonNull Executor executor) { mGmsClient = Preconditions.checkNotNull(gmsClient); mFeatures = Preconditions.checkNotNull(features); + mExecutor = Preconditions.checkNotNull(executor); } @NonNull @Override @@ -70,7 +73,8 @@ mGmsClient.getByDocumentId(packageName, databaseName, RequestToGmsConverter.toGmsGetByDocumentIdRequest(request)), result -> AppSearchResultToGmsConverter.gmsAppSearchBatchResultToJetpack( - result, GenericDocumentToGmsConverter::toJetpackGenericDocument)); + result, GenericDocumentToGmsConverter::toJetpackGenericDocument), + mExecutor); } @NonNull @@ -79,7 +83,7 @@ com.google.android.gms.appsearch.SearchResults searchResults = mGmsClient.search(queryExpression, SearchSpecToGmsConverter.toGmsSearchSpec(searchSpec)); - return new SearchResultsImpl(searchResults, searchSpec); + return new SearchResultsImpl(searchResults, mExecutor); } @NonNull @@ -87,7 +91,8 @@ public ListenableFuturereportSystemUsageAsync( @NonNull ReportSystemUsageRequest request) { TaskflushTask = Tasks.forResult(null); - return AppSearchTaskFutures.toListenableFuture(flushTask, /* valueMapper= */ i-> i); + return AppSearchTaskFutures.toListenableFuture(flushTask, /* valueMapper= */ i-> i, + mExecutor); } @NonNull @@ -96,7 +101,7 @@ @NonNull String databaseName) { return AppSearchTaskFutures.toListenableFuture( mGmsClient.getSchema(packageName, databaseName), - GetSchemaResponseToGmsConverter::toJetpackGetSchemaResponse); + GetSchemaResponseToGmsConverter::toJetpackGetSchemaResponse, mExecutor); } @NonNull
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/PlayServicesStorage.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/PlayServicesStorage.java index eab92f9..ca2bee2 100644 --- a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/PlayServicesStorage.java +++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/PlayServicesStorage.java
@@ -26,10 +26,15 @@ import com.google.android.gms.appsearch.AppSearch; import com.google.android.gms.appsearch.AppSearchClient; +import com.google.android.gms.appsearch.AppSearchOptions; import com.google.android.gms.appsearch.GlobalSearchClient; import com.google.android.gms.tasks.Task; import com.google.common.util.concurrent.ListenableFuture; +import java.util.concurrent.Executor; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + /** * An AppSearch storage system which stores data in the central AppSearch service in Google * Play Services. @@ -43,10 +48,13 @@ public static final class SearchContext { final Context mContext; final String mDatabaseName; + final Executor mExecutor; - SearchContext(@NonNull Context context, @NonNull String databaseName) { + SearchContext(@NonNull Context context, @NonNull String databaseName, + @NonNull Executor executor) { mContext = Preconditions.checkNotNull(context); mDatabaseName = Preconditions.checkNotNull(databaseName); + mExecutor = Preconditions.checkNotNull(executor); } /** @@ -57,10 +65,26 @@ return mDatabaseName; } + /** + * Returns the worker executor associated with {@link AppSearchSession}. + * + *If an executor is not provided to {@link Builder}, the AppSearch default executor will
+ * be returned. You should never cast the executor to + * {@link java.util.concurrent.ExecutorService} and call + * {@link ExecutorService#shutdownNow()}. It will cancel the futures it's returned. And + * since {@link Executor#execute} won't return anything, we will hang forever waiting for + * the execution. + */ + @NonNull + public Executor getWorkerExecutor() { + return mExecutor; + } + /** Builder for {@link SearchContext} objects. */ public static final class Builder { private final Context mContext; private final String mDatabaseName; + private Executor mExecutor; /** * Creates a {@link SearchContext.Builder} instance. @@ -89,10 +113,26 @@ mDatabaseName = databaseName; } + /** + * Sets the worker executor associated with {@link AppSearchSession}. + * + *If an executor is not provided, the AppSearch default executor will be used.
+ * + * @param executor the worker executor used to run heavy background tasks. + */ + @NonNull + public Builder setWorkerExecutor(@NonNull Executor executor) { + mExecutor = Preconditions.checkNotNull(executor); + return this; + } + /** Builds a {@link SearchContext} instance. */ @NonNull public SearchContext build() { - return new SearchContext(mContext, mDatabaseName); + if (mExecutor == null) { + mExecutor = EXECUTOR; + } + return new SearchContext(mContext, mDatabaseName, mExecutor); } } } @@ -100,27 +140,68 @@ /** Contains information relevant to creating a global search session. */ public static final class GlobalSearchContext { final Context mContext; + final Executor mExecutor; - GlobalSearchContext(@NonNull Context context) { + GlobalSearchContext(@NonNull Context context, Executor executor) { mContext = Preconditions.checkNotNull(context); + mExecutor = Preconditions.checkNotNull(executor); + } + + /** + * Returns the worker executor associated with {@link GlobalSearchSession}. + * + *If an executor is not provided to {@link Builder}, the AppSearch default executor will
+ * be returned. You should never cast the executor to + * {@link java.util.concurrent.ExecutorService} and call + * {@link ExecutorService#shutdownNow()}. It will cancel the futures it's returned. And + * since {@link Executor#execute} won't return anything, we will hang forever waiting for + * the execution. + */ + @NonNull + public Executor getWorkerExecutor() { + return mExecutor; } /** Builder for {@link GlobalSearchContext} objects. */ public static final class Builder { private final Context mContext; + private Executor mExecutor; public Builder(@NonNull Context context) { mContext = Preconditions.checkNotNull(context); } + /** + * Sets the worker executor associated with {@link GlobalSearchSession}. + * + *If an executor is not provided, the AppSearch default executor will be used.
+ * + * @param executor the worker executor used to run heavy background tasks. + */ + @NonNull + public Builder setWorkerExecutor(@NonNull Executor executor) { + Preconditions.checkNotNull(executor); + mExecutor = executor; + return this; + } + /** Builds a {@link GlobalSearchContext} instance. */ @NonNull public GlobalSearchContext build() { - return new GlobalSearchContext(mContext); + if (mExecutor == null) { + mExecutor = EXECUTOR; + } + return new GlobalSearchContext(mContext, mExecutor); } } } + // Never call Executor.shutdownNow(), it will cancel the futures it's returned. And since + // execute() won't return anything, we will hang forever waiting for the execution. + // AppSearch multi-thread execution is guarded by Read & Write Lock in AppSearchImpl, all + // mutate requests will need to gain write lock and query requests need to gain read lock. + static final Executor EXECUTOR = Executors.newCachedThreadPool(); + /** * Opens a new {@link AppSearchSession} on this storage. * @@ -132,10 +213,14 @@ @NonNull SearchContext context) { Preconditions.checkNotNull(context); TaskappSearchClientTask = AppSearch - .createAppSearchClient(context.mContext); + .createAppSearchClient(context.mContext, new AppSearchOptions.Builder() + .setWorkerExecutor(context.mExecutor) + .build()); return AppSearchTaskFutures.toListenableFuture( appSearchClientTask, - task -> new SearchSessionImpl(task, new FeaturesImpl(), context.mDatabaseName)); + task -> new SearchSessionImpl(task, new FeaturesImpl(), context.mDatabaseName, + context.mExecutor), + context.mExecutor); } /** @@ -149,9 +234,12 @@ @NonNull GlobalSearchContext context) { Preconditions.checkNotNull(context); TaskglobalSearchClientTask = AppSearch - .createGlobalSearchClient(context.mContext); + .createGlobalSearchClient(context.mContext, new AppSearchOptions.Builder() + .setWorkerExecutor(context.mExecutor) + .build()); return AppSearchTaskFutures.toListenableFuture( globalSearchClientTask, - task -> new GlobalSearchSessionImpl(task, new FeaturesImpl())); + task -> new GlobalSearchSessionImpl(task, new FeaturesImpl(), context.mExecutor), + context.mExecutor); } }
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/SearchResultsImpl.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/SearchResultsImpl.java index ba23844..3a50203 100644 --- a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/SearchResultsImpl.java +++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/SearchResultsImpl.java
@@ -20,7 +20,6 @@ import androidx.annotation.RestrictTo; import androidx.appsearch.app.SearchResult; import androidx.appsearch.app.SearchResults; -import androidx.appsearch.app.SearchSpec; import androidx.appsearch.playservicesstorage.converter.SearchResultToGmsConverter; import androidx.appsearch.playservicesstorage.util.AppSearchTaskFutures; import androidx.core.util.Preconditions; @@ -28,6 +27,7 @@ import com.google.common.util.concurrent.ListenableFuture; import java.util.List; +import java.util.concurrent.Executor; /** * GooglePlayService's implementation of {@link SearchResults} which proxies to the @@ -37,11 +37,13 @@ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) class SearchResultsImpl implements SearchResults { private final com.google.android.gms.appsearch.SearchResults mGmsResults; + private final Executor mExecutor; SearchResultsImpl( @NonNull com.google.android.gms.appsearch.SearchResults gmsResults, - @NonNull SearchSpec searchSpec) { + @NonNull Executor executor) { mGmsResults = Preconditions.checkNotNull(gmsResults); + mExecutor = Preconditions.checkNotNull(executor); } @Override @@ -49,7 +51,8 @@ public ListenableFuture> getNextPageAsync() {
return AppSearchTaskFutures.toListenableFuture( mGmsResults.getNextPage(), - SearchResultToGmsConverter::toJetpackSearchResultList + SearchResultToGmsConverter::toJetpackSearchResultList, + mExecutor ); }
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/SearchSessionImpl.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/SearchSessionImpl.java index e34c08c..df99af7 100644 --- a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/SearchSessionImpl.java +++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/SearchSessionImpl.java
@@ -52,6 +52,7 @@ import java.io.Closeable; import java.util.List; import java.util.Set; +import java.util.concurrent.Executor; /** * An implementation of {@link AppSearchSession} which proxies to a Google Play Service's @@ -62,15 +63,17 @@ private final AppSearchClient mGmsClient; private final Features mFeatures; private final String mDatabaseName; - + private final Executor mExecutor; SearchSessionImpl( @NonNull AppSearchClient gmsClient, @NonNull Features features, - @NonNull String databaseName) { + @NonNull String databaseName, + @NonNull Executor executor) { mGmsClient = Preconditions.checkNotNull(gmsClient); mFeatures = Preconditions.checkNotNull(features); mDatabaseName = Preconditions.checkNotNull(databaseName); + mExecutor = Preconditions.checkNotNull(executor); } @NonNull @@ -82,7 +85,7 @@ SetSchemaRequestToGmsConverter.toGmsSetSchemaRequest( request), mDatabaseName), - SetSchemaRequestToGmsConverter::toJetpackSetSchemaResponse); + SetSchemaRequestToGmsConverter::toJetpackSetSchemaResponse, mExecutor); } @NonNull @@ -90,7 +93,7 @@ public ListenableFuturegetSchemaAsync() { return AppSearchTaskFutures.toListenableFuture( mGmsClient.getSchema(mDatabaseName), - GetSchemaResponseToGmsConverter::toJetpackGetSchemaResponse); + GetSchemaResponseToGmsConverter::toJetpackGetSchemaResponse, mExecutor); } @NonNull @@ -98,7 +101,7 @@ public ListenableFuture> getNamespacesAsync() { return AppSearchTaskFutures.toListenableFuture( mGmsClient.getNamespaces(mDatabaseName), - /* valueMapper= */ i -> i); + /* valueMapper= */ i -> i, mExecutor); } @NonNull @@ -111,7 +114,7 @@ RequestToGmsConverter.toGmsPutDocumentsRequest(request), mDatabaseName), result -> AppSearchResultToGmsConverter.gmsAppSearchBatchResultToJetpack( - result, /* valueMapper= */ i -> i)); + result, /* valueMapper= */ i -> i), mExecutor); } @NonNull @@ -124,7 +127,8 @@ RequestToGmsConverter.toGmsGetByDocumentIdRequest(request), mDatabaseName), result -> AppSearchResultToGmsConverter.gmsAppSearchBatchResultToJetpack( - result, GenericDocumentToGmsConverter::toJetpackGenericDocument)); + result, GenericDocumentToGmsConverter::toJetpackGenericDocument), + mExecutor); } @NonNull @@ -137,7 +141,7 @@ queryExpression, SearchSpecToGmsConverter.toGmsSearchSpec(searchSpec), mDatabaseName); - return new SearchResultsImpl(gmsSearchResults, searchSpec); + return new SearchResultsImpl(gmsSearchResults, mExecutor); } @NonNull @@ -158,7 +162,7 @@ mGmsClient.reportUsage( RequestToGmsConverter.toGmsReportUsageRequest(request), mDatabaseName), - /* valueMapper= */ i -> i); + /* valueMapper= */ i -> i, mExecutor); } @NonNull @@ -172,7 +176,7 @@ .toGmsRemoveByDocumentIdRequest(request), mDatabaseName), result -> AppSearchResultToGmsConverter.gmsAppSearchBatchResultToJetpack( - result, /* valueMapper= */ i -> i)); + result, /* valueMapper= */ i -> i), mExecutor); } @NonNull @@ -185,7 +189,7 @@ queryExpression, SearchSpecToGmsConverter.toGmsSearchSpec(searchSpec), mDatabaseName), - /* valueMapper= */ i -> i); + /* valueMapper= */ i -> i, mExecutor); } @NonNull @@ -193,14 +197,15 @@ public ListenableFuturegetStorageInfoAsync() { return AppSearchTaskFutures.toListenableFuture( mGmsClient.getStorageInfo(mDatabaseName), - ResponseToGmsConverter::toJetpackStorageInfo); + ResponseToGmsConverter::toJetpackStorageInfo, mExecutor); } @NonNull @Override public ListenableFuturerequestFlushAsync() { TaskflushTask = Tasks.forResult(null); - return AppSearchTaskFutures.toListenableFuture(flushTask, /* valueMapper= */ i-> i); + return AppSearchTaskFutures.toListenableFuture(flushTask, /* valueMapper= */ i-> i, + mExecutor); } @NonNull
diff --git a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/util/AppSearchTaskFutures.java b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/util/AppSearchTaskFutures.java index d737512a..04e80c1 100644 --- a/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/util/AppSearchTaskFutures.java +++ b/appsearch/appsearch-play-services-storage/src/main/java/androidx/appsearch/playservicesstorage/util/AppSearchTaskFutures.java
@@ -30,12 +30,12 @@ import com.google.android.gms.tasks.Task; import com.google.common.util.concurrent.ListenableFuture; +import java.util.concurrent.Executor; + /** Utilities for converting {@link Task} to {@link ListenableFuture}. */ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) public class AppSearchTaskFutures { - private static final String TAG = "AppSearchTaskFutures"; - private AppSearchTaskFutures() {} /** @@ -43,13 +43,19 @@ * androidx apis. *Note: Calling {@link java.util.concurrent.Future#cancel(boolean)} on the returned result
* is a no-op since {@link Task} has no equivalent method. + * + * @param task The {@link Task} that needs to be converted to {@link ListenableFuture}. + * @param valueMapper The transformation function to apply to the task's result. + * @param executor The {@link Executor} to execute task's onCompleteListener logic. */ @NonNull public staticListenableFuture @NonNull TasktoListenableFuture( task, - @NonNull FunctionvalueMapper) { + @NonNull FunctionvalueMapper, + @NonNull Executor executor) { return CallbackToFutureAdapter.getFuture( completer -> task.addOnCompleteListener( + executor, completedTask -> { if (completedTask.isCanceled()) { completer.setCancelled();
diff --git a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/BenchmarkStateTest.kt b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/BenchmarkStateTest.kt index fa4f233..711330c 100644 --- a/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/BenchmarkStateTest.kt +++ b/benchmark/benchmark-common/src/androidTest/java/androidx/benchmark/BenchmarkStateTest.kt
@@ -17,7 +17,6 @@ package androidx.benchmark import android.Manifest -import android.os.Build import androidx.benchmark.BenchmarkState.Companion.ExperimentalExternalReport import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.FlakyTest @@ -168,8 +167,7 @@ if (simplifiedTimingOnlyMode) 0 else BenchmarkState.REPEAT_COUNT_ALLOCATION val expectedCount = report.warmupIterations + report.repeatIterations * expectedRepeatCount + - // method tracing phase by default only when API in 22..33, and simplified timing off - if (Build.VERSION.SDK_INT in 22..30 && !simplifiedTimingOnlyMode) 1 else 0 + if (Arguments.profiler == MethodTracing && !simplifiedTimingOnlyMode) 1 else 0 assertEquals(expectedCount, total) if (Arguments.iterations != null) {
diff --git a/benchmark/benchmark-common/src/main/java/androidx/benchmark/Arguments.kt b/benchmark/benchmark-common/src/main/java/androidx/benchmark/Arguments.kt index 9531d74..da4e257 100644 --- a/benchmark/benchmark-common/src/main/java/androidx/benchmark/Arguments.kt +++ b/benchmark/benchmark-common/src/main/java/androidx/benchmark/Arguments.kt
@@ -16,7 +16,6 @@ package androidx.benchmark -import android.os.Build import android.os.Bundle import android.util.Log import androidx.annotation.RestrictTo @@ -91,14 +90,11 @@ val argumentName = "profiling.mode" val argumentValue = getBenchmarkArgument(argumentName, "DEFAULT_VAL") if (argumentValue == "DEFAULT_VAL") { - return if (Build.VERSION.SDK_INT in 22..30) { - MethodTracing to true - } else { - // Method tracing can corrupt the stack on API 21, see b/300658578 - // On API 31+ (where ART mainline updates are available), it causes regressions in - // jit behavior, see b/303686344 - null to true - } + // NOTE: Method tracing currently off by default, as it is unsafe in many OS versions + // API 21 (b/300658578) Can corrupt the stack + // API 29/30 (b/313868903) causes regressions in subsequent benchmark runs, but no jit + // API 31+ (b/303686344) can causes regressions with jit depending on mainline version + return null to true } val profiler = Profiler.getByName(argumentValue)
diff --git a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt index a4c6c70..6932f78 100644 --- a/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt +++ b/buildSrc/private/src/main/kotlin/androidx/build/AndroidXImplPlugin.kt
@@ -1359,25 +1359,26 @@ if (!extension.runProjectParser) return@whenReady val parsed = project.parse() + val errorPrefix = "ProjectParser error parsing ${project.path}." check(extension.type == parsed.libraryType) { - "ProjectParser incorrectly computed libraryType = ${parsed.libraryType} " + + "$errorPrefix Incorrectly computed libraryType = ${parsed.libraryType} " + "instead of ${extension.type}" } check(extension.publish == parsed.publish) { - "ProjectParser incorrectly computed publish = ${parsed.publish} " + + "$errorPrefix Incorrectly computed publish = ${parsed.publish} " + "instead of ${extension.publish}" } check(extension.shouldPublish() == parsed.shouldPublish()) { - "ProjectParser incorrectly computed shouldPublish() = ${parsed.shouldPublish()} " + + "$errorPrefix Incorrectly computed shouldPublish() = ${parsed.shouldPublish()} " + "instead of ${extension.shouldPublish()}" } check(extension.shouldRelease() == parsed.shouldRelease()) { - "ProjectParser incorrectly computed shouldRelease() = ${parsed.shouldRelease()} " + + "$errorPrefix Incorrectly computed shouldRelease() = ${parsed.shouldRelease()} " + "instead of ${extension.shouldRelease()}" } check(extension.projectDirectlySpecifiesMavenVersion == parsed.specifiesVersion) { - "ProjectParser incorrectly computed specifiesVersion = ${parsed.specifiesVersion}" + - "instead of ${extension.projectDirectlySpecifiesMavenVersion}" + "$errorPrefix Incorrectly computed specifiesVersion = ${parsed.specifiesVersion} " + + " instead of ${extension.projectDirectlySpecifiesMavenVersion}" } } }
diff --git a/compose/material3/material3-adaptive/benchmark/build.gradle b/compose/material3/material3-adaptive/benchmark/build.gradle new file mode 100644 index 0000000..48f6444 --- /dev/null +++ b/compose/material3/material3-adaptive/benchmark/build.gradle
@@ -0,0 +1,38 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +plugins { + id("AndroidXPlugin") + id("com.android.library") + id("AndroidXComposePlugin") + id("org.jetbrains.kotlin.android") + id("androidx.benchmark") +} + +dependencies { + androidTestImplementation(project(":compose:material3:material3-adaptive")) + androidTestImplementation(project(":benchmark:benchmark-junit4")) + androidTestImplementation(project(":compose:runtime:runtime")) + androidTestImplementation(project(":compose:benchmark-utils")) + androidTestImplementation(libs.testRules) + androidTestImplementation(libs.kotlinStdlib) + androidTestImplementation(libs.kotlinTestCommon) + androidTestImplementation(libs.junit) +} + +android { + namespace "androidx.compose.material3.adaptive.benchmark" +}
diff --git a/compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/ListDetailPaneScaffoldBenchmark.kt b/compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/ListDetailPaneScaffoldBenchmark.kt new file mode 100644 index 0000000..9f22773 --- /dev/null +++ b/compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/ListDetailPaneScaffoldBenchmark.kt
@@ -0,0 +1,180 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.material3.adaptive.benchmark + +import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi +import androidx.compose.material3.adaptive.ListDetailPaneScaffold +import androidx.compose.material3.adaptive.ListDetailPaneScaffoldRole +import androidx.compose.material3.adaptive.calculateListDetailPaneScaffoldState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.testutils.benchmark.ComposeBenchmarkRule +import androidx.compose.testutils.benchmark.benchmarkFirstCompose +import androidx.compose.testutils.benchmark.benchmarkToFirstPixel +import androidx.compose.testutils.benchmark.toggleStateBenchmarkComposeMeasureLayout +import androidx.compose.ui.graphics.Color +import org.junit.Rule +import org.junit.Test + +@OptIn(ExperimentalMaterial3AdaptiveApi::class) +class ListDetailPaneScaffoldBenchmark { + @get:Rule + val benchmarkRule = ComposeBenchmarkRule() + + @Test + fun singlePane_firstPixel() { + benchmarkRule.benchmarkToFirstPixel { + ListDetailPaneScaffoldTestCase().apply { + currentScaffoldDirective = singlePaneDirective + } + } + } + + @Test + fun dualPane_firstPixel() { + benchmarkRule.benchmarkToFirstPixel { + ListDetailPaneScaffoldTestCase().apply { + currentScaffoldDirective = dualPaneDirective + } + } + } + + @Test + fun singlePane_firstCompose() { + benchmarkRule.benchmarkFirstCompose { + ListDetailPaneScaffoldTestCase().apply { + currentScaffoldDirective = singlePaneDirective + } + } + } + + @Test + fun dualPane_firstCompose() { + benchmarkRule.benchmarkFirstCompose { + ListDetailPaneScaffoldTestCase().apply { + currentScaffoldDirective = dualPaneDirective + } + } + } + + @Test + fun singlePane_navigateToDetail() { + benchmarkRule.toggleStateBenchmarkComposeMeasureLayout( + { + object : ListDetailPaneScaffoldTestCase() { + override fun toggleState() { + currentDestination = + if (currentDestination == ListDetailPaneScaffoldRole.List) { + ListDetailPaneScaffoldRole.Detail + } else { + ListDetailPaneScaffoldRole.List + } + } + }.apply { + currentScaffoldDirective = singlePaneDirective + } + } + ) + } + + @Test + fun dualPane_navigateToExtra() { + benchmarkRule.toggleStateBenchmarkComposeMeasureLayout( + { + object : ListDetailPaneScaffoldTestCase() { + override fun toggleState() { + currentDestination = + if (currentDestination == ListDetailPaneScaffoldRole.List) { + ListDetailPaneScaffoldRole.Extra + } else { + ListDetailPaneScaffoldRole.List + } + } + }.apply { + currentScaffoldDirective = dualPaneDirective + } + } + ) + } + + @Test + fun singlePane_navigateToDetail_animated() { + benchmarkRule.toggleStateBenchmarkComposeMeasureLayout( + { + object : ListDetailPaneScaffoldTestCase(animated = true) { + override fun toggleState() { + currentDestination = + if (currentDestination == ListDetailPaneScaffoldRole.List) { + ListDetailPaneScaffoldRole.Detail + } else { + ListDetailPaneScaffoldRole.List + } + } + }.apply { + currentScaffoldDirective = singlePaneDirective + } + }, + // For skipping animations + assertOneRecomposition = false + ) + } + + @Test + fun dualPane_navigateToExtra_animated() { + benchmarkRule.toggleStateBenchmarkComposeMeasureLayout( + { + object : ListDetailPaneScaffoldTestCase(animated = true) { + override fun toggleState() { + currentDestination = + if (currentDestination == ListDetailPaneScaffoldRole.List) { + ListDetailPaneScaffoldRole.Extra + } else { + ListDetailPaneScaffoldRole.List + } + } + }.apply { + currentScaffoldDirective = dualPaneDirective + } + }, + // For skipping animations + assertOneRecomposition = false + ) + } +} + +@OptIn(ExperimentalMaterial3AdaptiveApi::class) +internal open class ListDetailPaneScaffoldTestCase( + animated: Boolean = false +) : ThreePaneScaffoldTestCase(animated) { + override var currentDestination by mutableStateOf(ListDetailPaneScaffoldRole.List) + + @Composable + override fun MeasuredContent() { + ListDetailPaneScaffold( + scaffoldState = calculateListDetailPaneScaffoldState( + scaffoldDirective = currentScaffoldDirective, + currentPaneDestination = currentDestination + ), + listPane = { TestPane(Color.Red) }, + extraPane = { TestPane(Color.Blue) } + ) { + TestPane(Color.Yellow) + } + } +}
diff --git a/compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/SupportingPaneScaffoldBenchmark.kt b/compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/SupportingPaneScaffoldBenchmark.kt new file mode 100644 index 0000000..b867976 --- /dev/null +++ b/compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/SupportingPaneScaffoldBenchmark.kt
@@ -0,0 +1,180 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.material3.adaptive.benchmark + +import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi +import androidx.compose.material3.adaptive.SupportingPaneScaffold +import androidx.compose.material3.adaptive.SupportingPaneScaffoldRole +import androidx.compose.material3.adaptive.calculateSupportingPaneScaffoldState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.testutils.benchmark.ComposeBenchmarkRule +import androidx.compose.testutils.benchmark.benchmarkFirstCompose +import androidx.compose.testutils.benchmark.benchmarkToFirstPixel +import androidx.compose.testutils.benchmark.toggleStateBenchmarkComposeMeasureLayout +import androidx.compose.ui.graphics.Color +import org.junit.Rule +import org.junit.Test + +@OptIn(ExperimentalMaterial3AdaptiveApi::class) +class SupportingPaneScaffoldBenchmark { + @get:Rule + val benchmarkRule = ComposeBenchmarkRule() + + @Test + fun singlePane_firstPixel() { + benchmarkRule.benchmarkToFirstPixel { + SupportingPaneScaffoldTestCase().apply { + currentScaffoldDirective = singlePaneDirective + } + } + } + + @Test + fun dualPane_firstPixel() { + benchmarkRule.benchmarkToFirstPixel { + SupportingPaneScaffoldTestCase().apply { + currentScaffoldDirective = dualPaneDirective + } + } + } + + @Test + fun singlePane_firstCompose() { + benchmarkRule.benchmarkFirstCompose { + SupportingPaneScaffoldTestCase().apply { + currentScaffoldDirective = singlePaneDirective + } + } + } + + @Test + fun dualPane_firstCompose() { + benchmarkRule.benchmarkFirstCompose { + SupportingPaneScaffoldTestCase().apply { + currentScaffoldDirective = dualPaneDirective + } + } + } + + @Test + fun singlePane_navigateBetweenMainAndSupporting() { + benchmarkRule.toggleStateBenchmarkComposeMeasureLayout( + { + object : SupportingPaneScaffoldTestCase() { + override fun toggleState() { + currentDestination = + if (currentDestination == SupportingPaneScaffoldRole.Main) { + SupportingPaneScaffoldRole.Supporting + } else { + SupportingPaneScaffoldRole.Main + } + } + }.apply { + currentScaffoldDirective = singlePaneDirective + } + } + ) + } + + @Test + fun dualPane_navigateToExtra() { + benchmarkRule.toggleStateBenchmarkComposeMeasureLayout( + { + object : SupportingPaneScaffoldTestCase() { + override fun toggleState() { + currentDestination = + if (currentDestination == SupportingPaneScaffoldRole.Main) { + SupportingPaneScaffoldRole.Extra + } else { + SupportingPaneScaffoldRole.Main + } + } + }.apply { + currentScaffoldDirective = dualPaneDirective + } + } + ) + } + + @Test + fun singlePane_navigateToSupporting_animated() { + benchmarkRule.toggleStateBenchmarkComposeMeasureLayout( + { + object : SupportingPaneScaffoldTestCase(animated = true) { + override fun toggleState() { + currentDestination = + if (currentDestination == SupportingPaneScaffoldRole.Main) { + SupportingPaneScaffoldRole.Supporting + } else { + SupportingPaneScaffoldRole.Main + } + } + }.apply { + currentScaffoldDirective = singlePaneDirective + } + }, + // For skipping animations + assertOneRecomposition = false + ) + } + + @Test + fun dualPane_navigateToExtra_animated() { + benchmarkRule.toggleStateBenchmarkComposeMeasureLayout( + { + object : SupportingPaneScaffoldTestCase(animated = true) { + override fun toggleState() { + currentDestination = + if (currentDestination == SupportingPaneScaffoldRole.Main) { + SupportingPaneScaffoldRole.Extra + } else { + SupportingPaneScaffoldRole.Main + } + } + }.apply { + currentScaffoldDirective = dualPaneDirective + } + }, + // For skipping animations + assertOneRecomposition = false + ) + } +} + +@OptIn(ExperimentalMaterial3AdaptiveApi::class) +internal open class SupportingPaneScaffoldTestCase( + animated: Boolean = false +) : ThreePaneScaffoldTestCase(animated) { + override var currentDestination by mutableStateOf(SupportingPaneScaffoldRole.Main) + + @Composable + override fun MeasuredContent() { + SupportingPaneScaffold( + scaffoldState = calculateSupportingPaneScaffoldState( + scaffoldDirective = currentScaffoldDirective, + currentPaneDestination = currentDestination + ), + supportingPane = { TestPane(Color.Red) }, + extraPane = { TestPane(Color.Blue) } + ) { + TestPane(Color.Yellow) + } + } +}
diff --git a/compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/TestUtils.kt b/compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/TestUtils.kt new file mode 100644 index 0000000..eda6035 --- /dev/null +++ b/compose/material3/material3-adaptive/benchmark/src/androidTest/java/androidx/compose/material3/adaptive/benchmark/TestUtils.kt
@@ -0,0 +1,80 @@ +/* + * Copyright 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.compose.material3.adaptive.benchmark + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.adaptive.AnimatedPane +import androidx.compose.material3.adaptive.ExperimentalMaterial3AdaptiveApi +import androidx.compose.material3.adaptive.PaneScaffoldDirective +import androidx.compose.material3.adaptive.ThreePaneScaffoldRole +import androidx.compose.material3.adaptive.ThreePaneScaffoldScope +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.testutils.LayeredComposeTestCase +import androidx.compose.testutils.ToggleableTestCase +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp + +@OptIn(ExperimentalMaterial3AdaptiveApi::class) +val singlePaneDirective = PaneScaffoldDirective( + contentPadding = PaddingValues(16.dp), + maxHorizontalPartitions = 1, + horizontalPartitionSpacerSize = 0.dp, + maxVerticalPartitions = 1, + verticalPartitionSpacerSize = 0.dp, + excludedBounds = emptyList() +) + +@OptIn(ExperimentalMaterial3AdaptiveApi::class) +val dualPaneDirective = PaneScaffoldDirective( + contentPadding = PaddingValues(24.dp), + maxHorizontalPartitions = 2, + horizontalPartitionSpacerSize = 24.dp, + maxVerticalPartitions = 1, + verticalPartitionSpacerSize = 0.dp, + excludedBounds = emptyList() +) + +@OptIn(ExperimentalMaterial3AdaptiveApi::class) +internal abstract class ThreePaneScaffoldTestCase( + private val animated: Boolean +) : LayeredComposeTestCase(), ToggleableTestCase { + var currentScaffoldDirective by mutableStateOf(singlePaneDirective) + abstract var currentDestination: ThreePaneScaffoldRole + + override fun toggleState() {} + + @Composable + fun ThreePaneScaffoldScope.TestPane(color: Color) { + val content = @Composable { + Box(modifier = Modifier.fillMaxSize().background(color)) + } + if (animated) { + AnimatedPane(Modifier) { + content() + } + } else { + content() + } + } +}
diff --git a/compose/material3/material3/api/1.2.0-beta01.txt b/compose/material3/material3/api/1.2.0-beta01.txt index 50beef8..e966507 100644 --- a/compose/material3/material3/api/1.2.0-beta01.txt +++ b/compose/material3/material3/api/1.2.0-beta01.txt
@@ -1537,39 +1537,39 @@ } public final class SwipeToDismissBoxKt { - method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material3.SwipeToDismissState state, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set extends androidx.compose.material3.SwipeToDismissValue> directions); - method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismissBox(androidx.compose.material3.SwipeToDismissState state, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> backgroundContent, optional androidx.compose.ui.Modifier modifier, optional boolean enableDismissFromStartToEnd, optional boolean enableDismissFromEndToStart, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content); - method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SwipeToDismissState rememberSwipeToDismissState(optional androidx.compose.material3.SwipeToDismissValue initialValue, optional kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold); + method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material3.SwipeToDismissBoxState state, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set extends androidx.compose.material3.SwipeToDismissBoxValue> directions); + method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismissBox(androidx.compose.material3.SwipeToDismissBoxState state, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> backgroundContent, optional androidx.compose.ui.Modifier modifier, optional boolean enableDismissFromStartToEnd, optional boolean enableDismissFromEndToStart, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content); + method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SwipeToDismissBoxState rememberSwipeToDismissBoxState(optional androidx.compose.material3.SwipeToDismissBoxValue initialValue, optional kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissBoxValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold); } - @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SwipeToDismissState { - ctor public SwipeToDismissState(androidx.compose.material3.SwipeToDismissValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold); - method public suspend Object? dismiss(androidx.compose.material3.SwipeToDismissValue direction, kotlin.coroutines.Continuation super kotlin.Unit>); - method public androidx.compose.material3.SwipeToDismissValue getCurrentValue(); - method public androidx.compose.material3.SwipeToDismissValue getDismissDirection(); + @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SwipeToDismissBoxState { + ctor public SwipeToDismissBoxState(androidx.compose.material3.SwipeToDismissBoxValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissBoxValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold); + method public suspend Object? dismiss(androidx.compose.material3.SwipeToDismissBoxValue direction, kotlin.coroutines.Continuation super kotlin.Unit>); + method public androidx.compose.material3.SwipeToDismissBoxValue getCurrentValue(); + method public androidx.compose.material3.SwipeToDismissBoxValue getDismissDirection(); method @FloatRange(from=0.0, to=1.0) public float getProgress(); - method public androidx.compose.material3.SwipeToDismissValue getTargetValue(); + method public androidx.compose.material3.SwipeToDismissBoxValue getTargetValue(); method @Deprecated public boolean isDismissed(androidx.compose.material3.DismissDirection direction); method public float requireOffset(); method public suspend Object? reset(kotlin.coroutines.Continuation super kotlin.Unit>); - method public suspend Object? snapTo(androidx.compose.material3.SwipeToDismissValue targetValue, kotlin.coroutines.Continuation super kotlin.Unit>); - property public final androidx.compose.material3.SwipeToDismissValue currentValue; - property public final androidx.compose.material3.SwipeToDismissValue dismissDirection; + method public suspend Object? snapTo(androidx.compose.material3.SwipeToDismissBoxValue targetValue, kotlin.coroutines.Continuation super kotlin.Unit>); + property public final androidx.compose.material3.SwipeToDismissBoxValue currentValue; + property public final androidx.compose.material3.SwipeToDismissBoxValue dismissDirection; property @FloatRange(from=0.0, to=1.0) public final float progress; - property public final androidx.compose.material3.SwipeToDismissValue targetValue; - field public static final androidx.compose.material3.SwipeToDismissState.Companion Companion; + property public final androidx.compose.material3.SwipeToDismissBoxValue targetValue; + field public static final androidx.compose.material3.SwipeToDismissBoxState.Companion Companion; } - public static final class SwipeToDismissState.Companion { - method public androidx.compose.runtime.saveable.SaverSaver(kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold, androidx.compose.ui.unit.Density density); + public static final class SwipeToDismissBoxState.Companion { + method public androidx.compose.runtime.saveable.SaverSaver(kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissBoxValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold, androidx.compose.ui.unit.Density density); } - @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum SwipeToDismissValue { - method public static androidx.compose.material3.SwipeToDismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException; - method public static androidx.compose.material3.SwipeToDismissValue[] values(); - enum_constant public static final androidx.compose.material3.SwipeToDismissValue EndToStart; - enum_constant public static final androidx.compose.material3.SwipeToDismissValue Settled; - enum_constant public static final androidx.compose.material3.SwipeToDismissValue StartToEnd; + @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum SwipeToDismissBoxValue { + method public static androidx.compose.material3.SwipeToDismissBoxValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException; + method public static androidx.compose.material3.SwipeToDismissBoxValue[] values(); + enum_constant public static final androidx.compose.material3.SwipeToDismissBoxValue EndToStart; + enum_constant public static final androidx.compose.material3.SwipeToDismissBoxValue Settled; + enum_constant public static final androidx.compose.material3.SwipeToDismissBoxValue StartToEnd; } @androidx.compose.runtime.Immutable public final class SwitchColors {
diff --git a/compose/material3/material3/api/current.txt b/compose/material3/material3/api/current.txt index 50beef8..e966507 100644 --- a/compose/material3/material3/api/current.txt +++ b/compose/material3/material3/api/current.txt
@@ -1537,39 +1537,39 @@ } public final class SwipeToDismissBoxKt { - method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material3.SwipeToDismissState state, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set extends androidx.compose.material3.SwipeToDismissValue> directions); - method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismissBox(androidx.compose.material3.SwipeToDismissState state, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> backgroundContent, optional androidx.compose.ui.Modifier modifier, optional boolean enableDismissFromStartToEnd, optional boolean enableDismissFromEndToStart, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content); - method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SwipeToDismissState rememberSwipeToDismissState(optional androidx.compose.material3.SwipeToDismissValue initialValue, optional kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold); + method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material3.SwipeToDismissBoxState state, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set extends androidx.compose.material3.SwipeToDismissBoxValue> directions); + method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismissBox(androidx.compose.material3.SwipeToDismissBoxState state, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> backgroundContent, optional androidx.compose.ui.Modifier modifier, optional boolean enableDismissFromStartToEnd, optional boolean enableDismissFromEndToStart, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content); + method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SwipeToDismissBoxState rememberSwipeToDismissBoxState(optional androidx.compose.material3.SwipeToDismissBoxValue initialValue, optional kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissBoxValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold); } - @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SwipeToDismissState { - ctor public SwipeToDismissState(androidx.compose.material3.SwipeToDismissValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold); - method public suspend Object? dismiss(androidx.compose.material3.SwipeToDismissValue direction, kotlin.coroutines.Continuation super kotlin.Unit>); - method public androidx.compose.material3.SwipeToDismissValue getCurrentValue(); - method public androidx.compose.material3.SwipeToDismissValue getDismissDirection(); + @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SwipeToDismissBoxState { + ctor public SwipeToDismissBoxState(androidx.compose.material3.SwipeToDismissBoxValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissBoxValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold); + method public suspend Object? dismiss(androidx.compose.material3.SwipeToDismissBoxValue direction, kotlin.coroutines.Continuation super kotlin.Unit>); + method public androidx.compose.material3.SwipeToDismissBoxValue getCurrentValue(); + method public androidx.compose.material3.SwipeToDismissBoxValue getDismissDirection(); method @FloatRange(from=0.0, to=1.0) public float getProgress(); - method public androidx.compose.material3.SwipeToDismissValue getTargetValue(); + method public androidx.compose.material3.SwipeToDismissBoxValue getTargetValue(); method @Deprecated public boolean isDismissed(androidx.compose.material3.DismissDirection direction); method public float requireOffset(); method public suspend Object? reset(kotlin.coroutines.Continuation super kotlin.Unit>); - method public suspend Object? snapTo(androidx.compose.material3.SwipeToDismissValue targetValue, kotlin.coroutines.Continuation super kotlin.Unit>); - property public final androidx.compose.material3.SwipeToDismissValue currentValue; - property public final androidx.compose.material3.SwipeToDismissValue dismissDirection; + method public suspend Object? snapTo(androidx.compose.material3.SwipeToDismissBoxValue targetValue, kotlin.coroutines.Continuation super kotlin.Unit>); + property public final androidx.compose.material3.SwipeToDismissBoxValue currentValue; + property public final androidx.compose.material3.SwipeToDismissBoxValue dismissDirection; property @FloatRange(from=0.0, to=1.0) public final float progress; - property public final androidx.compose.material3.SwipeToDismissValue targetValue; - field public static final androidx.compose.material3.SwipeToDismissState.Companion Companion; + property public final androidx.compose.material3.SwipeToDismissBoxValue targetValue; + field public static final androidx.compose.material3.SwipeToDismissBoxState.Companion Companion; } - public static final class SwipeToDismissState.Companion { - method public androidx.compose.runtime.saveable.SaverSaver(kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold, androidx.compose.ui.unit.Density density); + public static final class SwipeToDismissBoxState.Companion { + method public androidx.compose.runtime.saveable.SaverSaver(kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissBoxValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold, androidx.compose.ui.unit.Density density); } - @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum SwipeToDismissValue { - method public static androidx.compose.material3.SwipeToDismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException; - method public static androidx.compose.material3.SwipeToDismissValue[] values(); - enum_constant public static final androidx.compose.material3.SwipeToDismissValue EndToStart; - enum_constant public static final androidx.compose.material3.SwipeToDismissValue Settled; - enum_constant public static final androidx.compose.material3.SwipeToDismissValue StartToEnd; + @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum SwipeToDismissBoxValue { + method public static androidx.compose.material3.SwipeToDismissBoxValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException; + method public static androidx.compose.material3.SwipeToDismissBoxValue[] values(); + enum_constant public static final androidx.compose.material3.SwipeToDismissBoxValue EndToStart; + enum_constant public static final androidx.compose.material3.SwipeToDismissBoxValue Settled; + enum_constant public static final androidx.compose.material3.SwipeToDismissBoxValue StartToEnd; } @androidx.compose.runtime.Immutable public final class SwitchColors {
diff --git a/compose/material3/material3/api/restricted_1.2.0-beta01.txt b/compose/material3/material3/api/restricted_1.2.0-beta01.txt index 50beef8..e966507 100644 --- a/compose/material3/material3/api/restricted_1.2.0-beta01.txt +++ b/compose/material3/material3/api/restricted_1.2.0-beta01.txt
@@ -1537,39 +1537,39 @@ } public final class SwipeToDismissBoxKt { - method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material3.SwipeToDismissState state, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set extends androidx.compose.material3.SwipeToDismissValue> directions); - method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismissBox(androidx.compose.material3.SwipeToDismissState state, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> backgroundContent, optional androidx.compose.ui.Modifier modifier, optional boolean enableDismissFromStartToEnd, optional boolean enableDismissFromEndToStart, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content); - method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SwipeToDismissState rememberSwipeToDismissState(optional androidx.compose.material3.SwipeToDismissValue initialValue, optional kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold); + method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material3.SwipeToDismissBoxState state, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set extends androidx.compose.material3.SwipeToDismissBoxValue> directions); + method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismissBox(androidx.compose.material3.SwipeToDismissBoxState state, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> backgroundContent, optional androidx.compose.ui.Modifier modifier, optional boolean enableDismissFromStartToEnd, optional boolean enableDismissFromEndToStart, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content); + method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SwipeToDismissBoxState rememberSwipeToDismissBoxState(optional androidx.compose.material3.SwipeToDismissBoxValue initialValue, optional kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissBoxValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold); } - @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SwipeToDismissState { - ctor public SwipeToDismissState(androidx.compose.material3.SwipeToDismissValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold); - method public suspend Object? dismiss(androidx.compose.material3.SwipeToDismissValue direction, kotlin.coroutines.Continuation super kotlin.Unit>); - method public androidx.compose.material3.SwipeToDismissValue getCurrentValue(); - method public androidx.compose.material3.SwipeToDismissValue getDismissDirection(); + @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SwipeToDismissBoxState { + ctor public SwipeToDismissBoxState(androidx.compose.material3.SwipeToDismissBoxValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissBoxValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold); + method public suspend Object? dismiss(androidx.compose.material3.SwipeToDismissBoxValue direction, kotlin.coroutines.Continuation super kotlin.Unit>); + method public androidx.compose.material3.SwipeToDismissBoxValue getCurrentValue(); + method public androidx.compose.material3.SwipeToDismissBoxValue getDismissDirection(); method @FloatRange(from=0.0, to=1.0) public float getProgress(); - method public androidx.compose.material3.SwipeToDismissValue getTargetValue(); + method public androidx.compose.material3.SwipeToDismissBoxValue getTargetValue(); method @Deprecated public boolean isDismissed(androidx.compose.material3.DismissDirection direction); method public float requireOffset(); method public suspend Object? reset(kotlin.coroutines.Continuation super kotlin.Unit>); - method public suspend Object? snapTo(androidx.compose.material3.SwipeToDismissValue targetValue, kotlin.coroutines.Continuation super kotlin.Unit>); - property public final androidx.compose.material3.SwipeToDismissValue currentValue; - property public final androidx.compose.material3.SwipeToDismissValue dismissDirection; + method public suspend Object? snapTo(androidx.compose.material3.SwipeToDismissBoxValue targetValue, kotlin.coroutines.Continuation super kotlin.Unit>); + property public final androidx.compose.material3.SwipeToDismissBoxValue currentValue; + property public final androidx.compose.material3.SwipeToDismissBoxValue dismissDirection; property @FloatRange(from=0.0, to=1.0) public final float progress; - property public final androidx.compose.material3.SwipeToDismissValue targetValue; - field public static final androidx.compose.material3.SwipeToDismissState.Companion Companion; + property public final androidx.compose.material3.SwipeToDismissBoxValue targetValue; + field public static final androidx.compose.material3.SwipeToDismissBoxState.Companion Companion; } - public static final class SwipeToDismissState.Companion { - method public androidx.compose.runtime.saveable.SaverSaver(kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold, androidx.compose.ui.unit.Density density); + public static final class SwipeToDismissBoxState.Companion { + method public androidx.compose.runtime.saveable.SaverSaver(kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissBoxValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold, androidx.compose.ui.unit.Density density); } - @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum SwipeToDismissValue { - method public static androidx.compose.material3.SwipeToDismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException; - method public static androidx.compose.material3.SwipeToDismissValue[] values(); - enum_constant public static final androidx.compose.material3.SwipeToDismissValue EndToStart; - enum_constant public static final androidx.compose.material3.SwipeToDismissValue Settled; - enum_constant public static final androidx.compose.material3.SwipeToDismissValue StartToEnd; + @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum SwipeToDismissBoxValue { + method public static androidx.compose.material3.SwipeToDismissBoxValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException; + method public static androidx.compose.material3.SwipeToDismissBoxValue[] values(); + enum_constant public static final androidx.compose.material3.SwipeToDismissBoxValue EndToStart; + enum_constant public static final androidx.compose.material3.SwipeToDismissBoxValue Settled; + enum_constant public static final androidx.compose.material3.SwipeToDismissBoxValue StartToEnd; } @androidx.compose.runtime.Immutable public final class SwitchColors {
diff --git a/compose/material3/material3/api/restricted_current.txt b/compose/material3/material3/api/restricted_current.txt index 50beef8..e966507 100644 --- a/compose/material3/material3/api/restricted_current.txt +++ b/compose/material3/material3/api/restricted_current.txt
@@ -1537,39 +1537,39 @@ } public final class SwipeToDismissBoxKt { - method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material3.SwipeToDismissState state, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set extends androidx.compose.material3.SwipeToDismissValue> directions); - method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismissBox(androidx.compose.material3.SwipeToDismissState state, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> backgroundContent, optional androidx.compose.ui.Modifier modifier, optional boolean enableDismissFromStartToEnd, optional boolean enableDismissFromEndToStart, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content); - method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SwipeToDismissState rememberSwipeToDismissState(optional androidx.compose.material3.SwipeToDismissValue initialValue, optional kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold); + method @Deprecated @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismiss(androidx.compose.material3.SwipeToDismissBoxState state, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> background, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> dismissContent, optional androidx.compose.ui.Modifier modifier, optional java.util.Set extends androidx.compose.material3.SwipeToDismissBoxValue> directions); + method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void SwipeToDismissBox(androidx.compose.material3.SwipeToDismissBoxState state, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> backgroundContent, optional androidx.compose.ui.Modifier modifier, optional boolean enableDismissFromStartToEnd, optional boolean enableDismissFromEndToStart, kotlin.jvm.functions.Function1 super androidx.compose.foundation.layout.RowScope,kotlin.Unit> content); + method @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static androidx.compose.material3.SwipeToDismissBoxState rememberSwipeToDismissBoxState(optional androidx.compose.material3.SwipeToDismissBoxValue initialValue, optional kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissBoxValue,java.lang.Boolean> confirmValueChange, optional kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold); } - @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SwipeToDismissState { - ctor public SwipeToDismissState(androidx.compose.material3.SwipeToDismissValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold); - method public suspend Object? dismiss(androidx.compose.material3.SwipeToDismissValue direction, kotlin.coroutines.Continuation super kotlin.Unit>); - method public androidx.compose.material3.SwipeToDismissValue getCurrentValue(); - method public androidx.compose.material3.SwipeToDismissValue getDismissDirection(); + @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public final class SwipeToDismissBoxState { + ctor public SwipeToDismissBoxState(androidx.compose.material3.SwipeToDismissBoxValue initialValue, androidx.compose.ui.unit.Density density, optional kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissBoxValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold); + method public suspend Object? dismiss(androidx.compose.material3.SwipeToDismissBoxValue direction, kotlin.coroutines.Continuation super kotlin.Unit>); + method public androidx.compose.material3.SwipeToDismissBoxValue getCurrentValue(); + method public androidx.compose.material3.SwipeToDismissBoxValue getDismissDirection(); method @FloatRange(from=0.0, to=1.0) public float getProgress(); - method public androidx.compose.material3.SwipeToDismissValue getTargetValue(); + method public androidx.compose.material3.SwipeToDismissBoxValue getTargetValue(); method @Deprecated public boolean isDismissed(androidx.compose.material3.DismissDirection direction); method public float requireOffset(); method public suspend Object? reset(kotlin.coroutines.Continuation super kotlin.Unit>); - method public suspend Object? snapTo(androidx.compose.material3.SwipeToDismissValue targetValue, kotlin.coroutines.Continuation super kotlin.Unit>); - property public final androidx.compose.material3.SwipeToDismissValue currentValue; - property public final androidx.compose.material3.SwipeToDismissValue dismissDirection; + method public suspend Object? snapTo(androidx.compose.material3.SwipeToDismissBoxValue targetValue, kotlin.coroutines.Continuation super kotlin.Unit>); + property public final androidx.compose.material3.SwipeToDismissBoxValue currentValue; + property public final androidx.compose.material3.SwipeToDismissBoxValue dismissDirection; property @FloatRange(from=0.0, to=1.0) public final float progress; - property public final androidx.compose.material3.SwipeToDismissValue targetValue; - field public static final androidx.compose.material3.SwipeToDismissState.Companion Companion; + property public final androidx.compose.material3.SwipeToDismissBoxValue targetValue; + field public static final androidx.compose.material3.SwipeToDismissBoxState.Companion Companion; } - public static final class SwipeToDismissState.Companion { - method public androidx.compose.runtime.saveable.SaverSaver(kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold, androidx.compose.ui.unit.Density density); + public static final class SwipeToDismissBoxState.Companion { + method public androidx.compose.runtime.saveable.SaverSaver(kotlin.jvm.functions.Function1 super androidx.compose.material3.SwipeToDismissBoxValue,java.lang.Boolean> confirmValueChange, kotlin.jvm.functions.Function1 super java.lang.Float,java.lang.Float> positionalThreshold, androidx.compose.ui.unit.Density density); } - @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum SwipeToDismissValue { - method public static androidx.compose.material3.SwipeToDismissValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException; - method public static androidx.compose.material3.SwipeToDismissValue[] values(); - enum_constant public static final androidx.compose.material3.SwipeToDismissValue EndToStart; - enum_constant public static final androidx.compose.material3.SwipeToDismissValue Settled; - enum_constant public static final androidx.compose.material3.SwipeToDismissValue StartToEnd; + @SuppressCompatibility @androidx.compose.material3.ExperimentalMaterial3Api public enum SwipeToDismissBoxValue { + method public static androidx.compose.material3.SwipeToDismissBoxValue valueOf(String value) throws java.lang.IllegalArgumentException, java.lang.NullPointerException; + method public static androidx.compose.material3.SwipeToDismissBoxValue[] values(); + enum_constant public static final androidx.compose.material3.SwipeToDismissBoxValue EndToStart; + enum_constant public static final androidx.compose.material3.SwipeToDismissBoxValue Settled; + enum_constant public static final androidx.compose.material3.SwipeToDismissBoxValue StartToEnd; } @androidx.compose.runtime.Immutable public final class SwitchColors {
diff --git a/compose/material3/material3/integration-tests/material3-demos/src/main/java/androidx/compose/material3/demos/SwipeToDismissDemo.kt b/compose/material3/material3/integration-tests/material3-demos/src/main/java/androidx/compose/material3/demos/SwipeToDismissDemo.kt index f751e9f..cecf379 100644 --- a/compose/material3/material3/integration-tests/material3-demos/src/main/java/androidx/compose/material3/demos/SwipeToDismissDemo.kt +++ b/compose/material3/material3/integration-tests/material3-demos/src/main/java/androidx/compose/material3/demos/SwipeToDismissDemo.kt
@@ -32,9 +32,9 @@ import androidx.compose.material3.Icon import androidx.compose.material3.ListItem import androidx.compose.material3.SwipeToDismissBox -import androidx.compose.material3.SwipeToDismissValue +import androidx.compose.material3.SwipeToDismissBoxValue import androidx.compose.material3.Text -import androidx.compose.material3.rememberSwipeToDismissState +import androidx.compose.material3.rememberSwipeToDismissBoxState import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -83,10 +83,10 @@ var unread by remember { mutableStateOf(false) } val scope = rememberCoroutineScope() - val dismissState = rememberSwipeToDismissState( + val dismissState = rememberSwipeToDismissBoxState( confirmValueChange = { - if (it == SwipeToDismissValue.StartToEnd) unread = !unread - it != SwipeToDismissValue.StartToEnd + if (it == SwipeToDismissBoxValue.StartToEnd) unread = !unread + it != SwipeToDismissBoxValue.StartToEnd }, positionalThreshold = { distance -> distance * .25f } ) @@ -97,23 +97,23 @@ val direction = dismissState.dismissDirection val color by animateColorAsState( when (dismissState.targetValue) { - SwipeToDismissValue.Settled -> Color.LightGray - SwipeToDismissValue.StartToEnd -> Color.Green - SwipeToDismissValue.EndToStart -> Color.Red + SwipeToDismissBoxValue.Settled -> Color.LightGray + SwipeToDismissBoxValue.StartToEnd -> Color.Green + SwipeToDismissBoxValue.EndToStart -> Color.Red } ) val alignment = when (direction) { - SwipeToDismissValue.StartToEnd, - SwipeToDismissValue.Settled -> Alignment.CenterStart - SwipeToDismissValue.EndToStart -> Alignment.CenterEnd + SwipeToDismissBoxValue.StartToEnd, + SwipeToDismissBoxValue.Settled -> Alignment.CenterStart + SwipeToDismissBoxValue.EndToStart -> Alignment.CenterEnd } val icon = when (direction) { - SwipeToDismissValue.StartToEnd, - SwipeToDismissValue.Settled -> Icons.Default.Done - SwipeToDismissValue.EndToStart -> Icons.Default.Delete + SwipeToDismissBoxValue.StartToEnd, + SwipeToDismissBoxValue.Settled -> Icons.Default.Done + SwipeToDismissBoxValue.EndToStart -> Icons.Default.Delete } val scale by animateFloatAsState( - if (dismissState.targetValue == SwipeToDismissValue.Settled) + if (dismissState.targetValue == SwipeToDismissBoxValue.Settled) 0.75f else 1f ) Box( @@ -143,7 +143,7 @@ CustomAccessibilityAction(label) { unread = !unread; true }, CustomAccessibilityAction("Delete") { scope.launch { - dismissState.dismiss(SwipeToDismissValue.EndToStart) + dismissState.dismiss(SwipeToDismissBoxValue.EndToStart) } true }
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/SwipeToDismissSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/SwipeToDismissSamples.kt index b883b78..43d0a6b 100644 --- a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/SwipeToDismissSamples.kt +++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/SwipeToDismissSamples.kt
@@ -26,9 +26,9 @@ import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.ListItem import androidx.compose.material3.SwipeToDismissBox -import androidx.compose.material3.SwipeToDismissValue +import androidx.compose.material3.SwipeToDismissBoxValue import androidx.compose.material3.Text -import androidx.compose.material3.rememberSwipeToDismissState +import androidx.compose.material3.rememberSwipeToDismissBoxState import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier @@ -40,15 +40,15 @@ @Composable @ExperimentalMaterial3Api fun SwipeToDismissListItems() { - val dismissState = rememberSwipeToDismissState() + val dismissState = rememberSwipeToDismissBoxState() SwipeToDismissBox( state = dismissState, backgroundContent = { val color by animateColorAsState( when (dismissState.targetValue) { - SwipeToDismissValue.Settled -> Color.LightGray - SwipeToDismissValue.StartToEnd -> Color.Green - SwipeToDismissValue.EndToStart -> Color.Red + SwipeToDismissBoxValue.Settled -> Color.LightGray + SwipeToDismissBoxValue.StartToEnd -> Color.Green + SwipeToDismissBoxValue.EndToStart -> Color.Red } ) Box(Modifier.fillMaxSize().background(color))
diff --git a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SwipeToDismissTest.kt b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SwipeToDismissTest.kt index 05a5858..3997f34 100644 --- a/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SwipeToDismissTest.kt +++ b/compose/material3/material3/src/androidInstrumentedTest/kotlin/androidx/compose/material3/SwipeToDismissTest.kt
@@ -69,7 +69,7 @@ fun swipeDismiss_testOffset_whenDefault() { rule.setContent { SwipeToDismissBox( - state = rememberSwipeToDismissState(SwipeToDismissValue.Settled), + state = rememberSwipeToDismissBoxState(SwipeToDismissBoxValue.Settled), backgroundContent = { } ) { Box( @@ -87,7 +87,7 @@ fun swipeDismiss_testOffset_whenDismissedToEnd() { rule.setContent { SwipeToDismissBox( - state = rememberSwipeToDismissState(SwipeToDismissValue.StartToEnd), + state = rememberSwipeToDismissBoxState(SwipeToDismissBoxValue.StartToEnd), backgroundContent = { } ) { Box( @@ -106,7 +106,7 @@ fun swipeDismiss_testOffset_whenDismissedToStart() { rule.setContent { SwipeToDismissBox( - state = rememberSwipeToDismissState(SwipeToDismissValue.EndToStart), + state = rememberSwipeToDismissBoxState(SwipeToDismissBoxValue.EndToStart), backgroundContent = { }, ) { Box( @@ -125,7 +125,7 @@ fun swipeDismiss_testBackgroundMatchesContentSize() { rule.setContent { SwipeToDismissBox( - state = rememberSwipeToDismissState(SwipeToDismissValue.Settled), + state = rememberSwipeToDismissBoxState(SwipeToDismissBoxValue.Settled), backgroundContent = { Box( Modifier @@ -142,11 +142,11 @@ @Test fun swipeDismiss_dismissBySwipe_toEnd() { - lateinit var swipeToDismissState: SwipeToDismissState + lateinit var swipeToDismissBoxState: SwipeToDismissBoxState rule.setContent { - swipeToDismissState = rememberSwipeToDismissState(SwipeToDismissValue.Settled) + swipeToDismissBoxState = rememberSwipeToDismissBoxState(SwipeToDismissBoxValue.Settled) SwipeToDismissBox( - state = swipeToDismissState, + state = swipeToDismissBoxState, modifier = Modifier.testTag(swipeDismissTag), enableDismissFromStartToEnd = true, enableDismissFromEndToStart = false, @@ -159,17 +159,18 @@ advanceClock() rule.runOnIdle { - assertThat(swipeToDismissState.currentValue).isEqualTo(SwipeToDismissValue.StartToEnd) + assertThat(swipeToDismissBoxState.currentValue) + .isEqualTo(SwipeToDismissBoxValue.StartToEnd) } } @Test fun swipeDismiss_dismissBySwipe_toStart() { - lateinit var swipeToDismissState: SwipeToDismissState + lateinit var swipeToDismissBoxState: SwipeToDismissBoxState rule.setContent { - swipeToDismissState = rememberSwipeToDismissState(SwipeToDismissValue.Settled) + swipeToDismissBoxState = rememberSwipeToDismissBoxState(SwipeToDismissBoxValue.Settled) SwipeToDismissBox( - state = swipeToDismissState, + state = swipeToDismissBoxState, modifier = Modifier.testTag(swipeDismissTag), enableDismissFromStartToEnd = false, enableDismissFromEndToStart = true, @@ -182,18 +183,19 @@ advanceClock() rule.runOnIdle { - assertThat(swipeToDismissState.currentValue).isEqualTo(SwipeToDismissValue.EndToStart) + assertThat(swipeToDismissBoxState.currentValue) + .isEqualTo(SwipeToDismissBoxValue.EndToStart) } } @Test fun swipeDismiss_dismissBySwipe_toEnd_rtl() { - lateinit var swipeToDismissState: SwipeToDismissState + lateinit var swipeToDismissBoxState: SwipeToDismissBoxState rule.setContent { - swipeToDismissState = rememberSwipeToDismissState() + swipeToDismissBoxState = rememberSwipeToDismissBoxState() CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { SwipeToDismissBox( - state = swipeToDismissState, + state = swipeToDismissBoxState, modifier = Modifier.testTag(swipeDismissTag), enableDismissFromStartToEnd = true, enableDismissFromEndToStart = false, @@ -207,18 +209,19 @@ advanceClock() rule.runOnIdle { - assertThat(swipeToDismissState.currentValue).isEqualTo(SwipeToDismissValue.StartToEnd) + assertThat(swipeToDismissBoxState.currentValue) + .isEqualTo(SwipeToDismissBoxValue.StartToEnd) } } @Test fun swipeDismiss_dismissBySwipe_toStart_rtl() { - lateinit var swipeToDismissState: SwipeToDismissState + lateinit var swipeToDismissBoxState: SwipeToDismissBoxState rule.setContent { - swipeToDismissState = rememberSwipeToDismissState(SwipeToDismissValue.Settled) + swipeToDismissBoxState = rememberSwipeToDismissBoxState(SwipeToDismissBoxValue.Settled) CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl) { SwipeToDismissBox( - state = swipeToDismissState, + state = swipeToDismissBoxState, modifier = Modifier.testTag(swipeDismissTag), enableDismissFromStartToEnd = false, enableDismissFromEndToStart = true, @@ -232,17 +235,18 @@ advanceClock() rule.runOnIdle { - assertThat(swipeToDismissState.currentValue).isEqualTo(SwipeToDismissValue.EndToStart) + assertThat(swipeToDismissBoxState.currentValue) + .isEqualTo(SwipeToDismissBoxValue.EndToStart) } } @Test fun swipeDismiss_dismissBySwipe_disabled() { - lateinit var swipeToDismissState: SwipeToDismissState + lateinit var swipeToDismissBoxState: SwipeToDismissBoxState rule.setContent { - swipeToDismissState = rememberSwipeToDismissState(SwipeToDismissValue.Settled) + swipeToDismissBoxState = rememberSwipeToDismissBoxState(SwipeToDismissBoxValue.Settled) SwipeToDismissBox( - state = swipeToDismissState, + state = swipeToDismissBoxState, modifier = Modifier.testTag(swipeDismissTag), enableDismissFromStartToEnd = false, enableDismissFromEndToStart = false, @@ -255,7 +259,8 @@ advanceClock() rule.runOnIdle { - assertThat(swipeToDismissState.currentValue).isEqualTo(SwipeToDismissValue.Settled) + assertThat(swipeToDismissBoxState.currentValue) + .isEqualTo(SwipeToDismissBoxValue.Settled) } rule.onNodeWithTag(swipeDismissTag).performTouchInput { swipeLeft() } @@ -263,7 +268,8 @@ advanceClock() rule.runOnIdle { - assertThat(swipeToDismissState.currentValue).isEqualTo(SwipeToDismissValue.Settled) + assertThat(swipeToDismissBoxState.currentValue) + .isEqualTo(SwipeToDismissBoxValue.Settled) } } @@ -278,7 +284,7 @@ lateinit var lazyState: LazyListState lateinit var scope: CoroutineScope val amountOfItems = 100 - val composedItems = mutableMapOf() + val composedItems = mutableMapOf() rule.setContent { scope = rememberCoroutineScope() @@ -286,9 +292,9 @@ lazyState = rememberLazyListState() LazyColumn(state = lazyState) { items(amountOfItems, key = { item -> item }) { index -> - composedItems[index] = rememberSwipeToDismissState() + composedItems[index] = rememberSwipeToDismissBoxState() val isDismissed = - composedItems[index]!!.currentValue == SwipeToDismissValue.EndToStart + composedItems[index]!!.currentValue == SwipeToDismissBoxValue.EndToStart AnimatedVisibility(visible = !isDismissed) { SwipeToDismissBox( modifier = Modifier @@ -325,7 +331,7 @@ // Dismiss an item so that the lazy layout is required to compose a new item scope.launch { - composedItems[initiallyVisibleItems - 1]!!.dismiss(SwipeToDismissValue.EndToStart) + composedItems[initiallyVisibleItems - 1]!!.dismiss(SwipeToDismissBoxValue.EndToStart) } rule.waitForIdle()
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismissBox.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismissBox.kt index ebbe7c7..0b492f03 100644 --- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismissBox.kt +++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/SwipeToDismissBox.kt
@@ -21,7 +21,7 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.RowScope -import androidx.compose.material3.SwipeToDismissState.Companion.Saver +import androidx.compose.material3.SwipeToDismissBoxState.Companion.Saver import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.Saver @@ -47,7 +47,7 @@ * The directions in which a [SwipeToDismissBox] can be dismissed. */ @ExperimentalMaterial3Api -enum class SwipeToDismissValue { +enum class SwipeToDismissBoxValue { /** * Can be dismissed by swiping in the reading direction. */ @@ -76,10 +76,10 @@ * subtracted from/to the origin offset. It should always be a positive value. */ @ExperimentalMaterial3Api -class SwipeToDismissState( - initialValue: SwipeToDismissValue, +class SwipeToDismissBoxState( + initialValue: SwipeToDismissBoxValue, internal val density: Density, - confirmValueChange: (SwipeToDismissValue) -> Boolean = { true }, + confirmValueChange: (SwipeToDismissBoxValue) -> Boolean = { true }, positionalThreshold: (totalDistance: Float) -> Float ) { internal val anchoredDraggableState = AnchoredDraggableState( @@ -100,16 +100,16 @@ fun requireOffset(): Float = anchoredDraggableState.requireOffset() /** - * The current state value of the [SwipeToDismissState]. + * The current state value of the [SwipeToDismissBoxState]. */ - val currentValue: SwipeToDismissValue get() = anchoredDraggableState.currentValue + val currentValue: SwipeToDismissBoxValue get() = anchoredDraggableState.currentValue /** * The target state. This is the closest state to the current offset (taking into account * positional thresholds). If no interactions like animations or drags are in progress, this * will be the current state. */ - val targetValue: SwipeToDismissValue get() = anchoredDraggableState.targetValue + val targetValue: SwipeToDismissBoxValue get() = anchoredDraggableState.targetValue /** * The fraction of the progress going from currentValue to targetValue, within [0f..1f] bounds. @@ -123,10 +123,11 @@ * Use this to change the background of the [SwipeToDismissBox] if you want different actions on each * side. */ - val dismissDirection: SwipeToDismissValue + val dismissDirection: SwipeToDismissBoxValue get() = if (offset == 0f || offset.isNaN()) - SwipeToDismissValue.Settled - else if (offset > 0f) SwipeToDismissValue.StartToEnd else SwipeToDismissValue.EndToStart + SwipeToDismissBoxValue.Settled + else if (offset > 0f) + SwipeToDismissBoxValue.StartToEnd else SwipeToDismissBoxValue.EndToStart /** * Whether the component has been dismissed in the given [direction]. @@ -134,7 +135,7 @@ * @param direction The dismiss direction. */ @Deprecated( - message = "DismissDirection is no longer used by SwipeToDismissState. Please compare " + + message = "DismissDirection is no longer used by SwipeToDismissBoxState. Please compare " + "currentValue against SwipeToDismissValue instead.", level = DeprecationLevel.HIDDEN ) @@ -142,9 +143,9 @@ fun isDismissed(direction: DismissDirection): Boolean { return currentValue == ( if (direction == DismissDirection.StartToEnd) { - SwipeToDismissValue.StartToEnd + SwipeToDismissBoxValue.StartToEnd } else { - SwipeToDismissValue.EndToStart + SwipeToDismissBoxValue.EndToStart } ) } @@ -154,7 +155,7 @@ * * @param targetValue The new target value */ - suspend fun snapTo(targetValue: SwipeToDismissValue) { + suspend fun snapTo(targetValue: SwipeToDismissBoxValue) { anchoredDraggableState.snapTo(targetValue) } @@ -166,7 +167,7 @@ * @return the reason the reset animation ended */ suspend fun reset() = anchoredDraggableState.animateTo( - targetValue = SwipeToDismissValue.Settled + targetValue = SwipeToDismissBoxValue.Settled ) /** @@ -175,23 +176,23 @@ * * @param direction The dismiss direction. */ - suspend fun dismiss(direction: SwipeToDismissValue) { + suspend fun dismiss(direction: SwipeToDismissBoxValue) { anchoredDraggableState.animateTo(targetValue = direction) } companion object { /** - * The default [Saver] implementation for [SwipeToDismissState]. + * The default [Saver] implementation for [SwipeToDismissBoxState]. */ fun Saver( - confirmValueChange: (SwipeToDismissValue) -> Boolean, + confirmValueChange: (SwipeToDismissBoxValue) -> Boolean, positionalThreshold: (totalDistance: Float) -> Float, density: Density - ) = Saver( + ) = Saver( save = { it.currentValue }, restore = { - SwipeToDismissState( + SwipeToDismissBoxState( it, density, confirmValueChange, positionalThreshold ) } @@ -200,7 +201,7 @@ } /** - * Create and [remember] a [SwipeToDismissState]. + * Create and [remember] a [SwipeToDismissBoxState]. * * @param initialValue The initial value of the state. * @param confirmValueChange Optional callback invoked to confirm or veto a pending state change. @@ -211,12 +212,12 @@ */ @Composable @ExperimentalMaterial3Api -fun rememberSwipeToDismissState( - initialValue: SwipeToDismissValue = SwipeToDismissValue.Settled, - confirmValueChange: (SwipeToDismissValue) -> Boolean = { true }, +fun rememberSwipeToDismissBoxState( + initialValue: SwipeToDismissBoxValue = SwipeToDismissBoxValue.Settled, + confirmValueChange: (SwipeToDismissBoxValue) -> Boolean = { true }, positionalThreshold: (totalDistance: Float) -> Float = SwipeToDismissBoxDefaults.positionalThreshold, -): SwipeToDismissState { +): SwipeToDismissBoxState { val density = LocalDensity.current return rememberSaveable( saver = Saver( @@ -225,7 +226,7 @@ positionalThreshold = positionalThreshold ) ) { - SwipeToDismissState(initialValue, density, confirmValueChange, positionalThreshold) + SwipeToDismissBoxState(initialValue, density, confirmValueChange, positionalThreshold) } } @@ -251,19 +252,19 @@ ) @ExperimentalMaterial3Api fun SwipeToDismiss( - state: SwipeToDismissState, + state: SwipeToDismissBoxState, background: @Composable RowScope.() -> Unit, dismissContent: @Composable RowScope.() -> Unit, modifier: Modifier = Modifier, - directions: Set= setOf(SwipeToDismissValue.EndToStart, - SwipeToDismissValue.StartToEnd + directions: Set= setOf(SwipeToDismissBoxValue.EndToStart, + SwipeToDismissBoxValue.StartToEnd ), ) = SwipeToDismissBox( state = state, backgroundContent = background, modifier = modifier, - enableDismissFromStartToEnd = SwipeToDismissValue.StartToEnd in directions, - enableDismissFromEndToStart = SwipeToDismissValue.EndToStart in directions, + enableDismissFromStartToEnd = SwipeToDismissBoxValue.StartToEnd in directions, + enableDismissFromEndToStart = SwipeToDismissBoxValue.EndToStart in directions, content = dismissContent ) @@ -283,7 +284,7 @@ @Composable @ExperimentalMaterial3Api fun SwipeToDismissBox( - state: SwipeToDismissState, + state: SwipeToDismissBoxState, backgroundContent: @Composable RowScope.() -> Unit, modifier: Modifier = Modifier, enableDismissFromStartToEnd: Boolean = true, @@ -297,7 +298,7 @@ .anchoredDraggable( state = state.anchoredDraggableState, orientation = Orientation.Horizontal, - enabled = state.currentValue == SwipeToDismissValue.Settled, + enabled = state.currentValue == SwipeToDismissBoxValue.Settled, reverseDirection = isRtl, ), propagateMinConstraints = true @@ -308,7 +309,7 @@ ) Row( content = content, - modifier = Modifier.swipeToDismissAnchors( + modifier = Modifier.swipeToDismissBoxAnchors( state, enableDismissFromStartToEnd, enableDismissFromEndToStart @@ -317,10 +318,10 @@ } } -/** Contains default values for [SwipeToDismissBox] and [SwipeToDismissState]. */ +/** Contains default values for [SwipeToDismissBox] and [SwipeToDismissBoxState]. */ @ExperimentalMaterial3Api object SwipeToDismissBoxDefaults { - /** Default positional threshold of 56.dp for [SwipeToDismissState]. */ + /** Default positional threshold of 56.dp for [SwipeToDismissBoxState]. */ val positionalThreshold: (totalDistance: Float) -> Float @Composable get() = with(LocalDensity.current) { { 56.dp.toPx() } @@ -332,8 +333,8 @@ */ @ExperimentalMaterial3Api @Deprecated( - message = "Dismiss direction is no longer used by SwipeToDismissState. Please use " + - "SwipeToDismissValue instead.", + message = "Dismiss direction is no longer used by SwipeToDismissBoxState. Please use " + + "SwipeToDismissBoxValue instead.", level = DeprecationLevel.WARNING ) enum class DismissDirection { @@ -349,12 +350,12 @@ } /** - * Possible values of [SwipeToDismissState]. + * Possible values of [SwipeToDismissBoxState]. */ @ExperimentalMaterial3Api @Deprecated( - message = "DismissValue is no longer used by SwipeToDismissState. Please use " + - "SwipeToDismissValue instead.", + message = "DismissValue is no longer used by SwipeToDismissBoxState. Please use " + + "SwipeToDismissBoxValue instead.", level = DeprecationLevel.WARNING ) enum class DismissValue { @@ -377,8 +378,8 @@ private val DismissThreshold = 125.dp @OptIn(ExperimentalMaterial3Api::class) -private fun Modifier.swipeToDismissAnchors( - state: SwipeToDismissState, +private fun Modifier.swipeToDismissBoxAnchors( + state: SwipeToDismissBoxState, enableDismissFromStartToEnd: Boolean, enableDismissFromEndToStart: Boolean ) = this then SwipeToDismissAnchorsElement( @@ -389,7 +390,7 @@ @OptIn(ExperimentalMaterial3Api::class) private class SwipeToDismissAnchorsElement( - private val state: SwipeToDismissState, + private val state: SwipeToDismissBoxState, private val enableDismissFromStartToEnd: Boolean, private val enableDismissFromEndToStart: Boolean, ) : ModifierNodeElement() { @@ -433,7 +434,7 @@ @OptIn(ExperimentalMaterial3Api::class) private class SwipeToDismissAnchorsNode( - var state: SwipeToDismissState, + var state: SwipeToDismissBoxState, var enableDismissFromStartToEnd: Boolean, var enableDismissFromEndToStart: Boolean, ) : Modifier.Node(), LayoutModifierNode { @@ -454,12 +455,12 @@ if (isLookingAhead || !didLookahead) { val width = placeable.width.toFloat() val newAnchors = DraggableAnchors { - SwipeToDismissValue.Settled at 0f + SwipeToDismissBoxValue.Settled at 0f if (enableDismissFromStartToEnd) { - SwipeToDismissValue.StartToEnd at width + SwipeToDismissBoxValue.StartToEnd at width } if (enableDismissFromEndToStart) { - SwipeToDismissValue.EndToStart at -width + SwipeToDismissBoxValue.EndToStart at -width } } state.anchoredDraggableState.updateAnchors(newAnchors)
diff --git a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/pointer/AndroidPointerInputTest.kt b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/pointer/AndroidPointerInputTest.kt index 3642a41..407c8a6 100644 --- a/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/pointer/AndroidPointerInputTest.kt +++ b/compose/ui/ui/src/androidInstrumentedTest/kotlin/androidx/compose/ui/input/pointer/AndroidPointerInputTest.kt
@@ -27,6 +27,7 @@ import android.view.MotionEvent.ACTION_HOVER_EXIT import android.view.MotionEvent.ACTION_HOVER_MOVE import android.view.MotionEvent.ACTION_MOVE +import android.view.MotionEvent.ACTION_OUTSIDE import android.view.MotionEvent.ACTION_POINTER_DOWN import android.view.MotionEvent.ACTION_POINTER_INDEX_SHIFT import android.view.MotionEvent.ACTION_POINTER_UP @@ -1181,6 +1182,206 @@ } } + /* + * This is a simple test that makes sure a bad ACTION_OUTSIDE MotionEvent doesn't negatively + * impact Compose (b/299074463#comment31). (We actually ignore them in Compose.) + * The event order of MotionEvents: + * 1. Hover enter on box 1 + * 2. Hover move into box 2 + * 3. Hover exit on box 2 + * 4. Outside event on box 3 + * 5. Down on box 2 + * 6. Up on box 2 + */ + @Test + fun hoverAndClickMotionEvent_badOutsideMotionEvent_outsideMotionEventIgnored() { + // --> Arrange + var box1LayoutCoordinates: LayoutCoordinates? = null + var box2LayoutCoordinates: LayoutCoordinates? = null + var box3LayoutCoordinates: LayoutCoordinates? = null + + val setUpFinishedLatch = CountDownLatch(1) + // One less than total because outside is not sent to Compose. + val totalEventLatch = CountDownLatch(5) + + // Events for Box 1 + var enterBox1 = false + var exitBox1 = false + + // Events for Box 2 + var enterBox2 = false + var exitBox2 = false + var pressBox2 = false + var releaseBox2 = false + + // All other events that should never be triggered in this test + var eventsThatShouldNotTrigger = false + + var pointerEvent: PointerEvent? = null + + rule.runOnUiThread { + container.setContent { + Column( + Modifier + .fillMaxSize() + .onGloballyPositioned { + setUpFinishedLatch.countDown() + } + .pointerInput(Unit) { + awaitPointerEventScope { + while (true) { + awaitPointerEvent() + totalEventLatch.countDown() + } + } + } + ) { + // Box 1 + Box( + Modifier + .size(50.dp) + .onGloballyPositioned { + box1LayoutCoordinates = it + } + .pointerInput(Unit) { + awaitPointerEventScope { + while (true) { + pointerEvent = awaitPointerEvent() + + when (pointerEvent!!.type) { + PointerEventType.Enter -> { + enterBox1 = true + } + PointerEventType.Exit -> { + exitBox1 = true + } + else -> { + eventsThatShouldNotTrigger = true + } + } + } + } + } + ) { } + + // Box 2 + Box( + Modifier + .size(50.dp) + .onGloballyPositioned { + box2LayoutCoordinates = it + } + .pointerInput(Unit) { + awaitPointerEventScope { + while (true) { + pointerEvent = awaitPointerEvent() + + when (pointerEvent!!.type) { + PointerEventType.Enter -> { + enterBox2 = true + } + PointerEventType.Press -> { + pressBox2 = true + } + PointerEventType.Release -> { + releaseBox2 = true + } + PointerEventType.Exit -> { + exitBox2 = true + } + else -> { + eventsThatShouldNotTrigger = true + } + } + } + } + } + ) { } + + // Box 3 + Box( + Modifier + .size(50.dp) + .onGloballyPositioned { + box3LayoutCoordinates = it + } + .pointerInput(Unit) { + awaitPointerEventScope { + while (true) { + pointerEvent = awaitPointerEvent() + eventsThatShouldNotTrigger = true + } + } + } + ) { } + } + } + } + // Ensure Arrange (setup) step is finished + assertTrue(setUpFinishedLatch.await(1, TimeUnit.SECONDS)) + + // --> Act + Assert (interwoven) + // Hover Enter on Box 1 + dispatchMouseEvent(ACTION_HOVER_ENTER, box1LayoutCoordinates!!) + rule.runOnUiThread { + assertThat(enterBox1).isTrue() + assertThat(pointerEvent).isNotNull() + assertThat(eventsThatShouldNotTrigger).isFalse() + assertHoverEvent(pointerEvent!!, isEnter = true) + } + + // Hover Move to Box 2 + pointerEvent = null // Reset before each event + dispatchMouseEvent(ACTION_HOVER_MOVE, box2LayoutCoordinates!!) + rule.runOnUiThread { + assertThat(exitBox1).isTrue() + assertThat(enterBox2).isTrue() + assertThat(pointerEvent).isNotNull() + assertThat(eventsThatShouldNotTrigger).isFalse() + assertHoverEvent(pointerEvent!!, isEnter = true) + } + + // Hover Exit on Box 2 + pointerEvent = null // Reset before each event + dispatchMouseEvent(ACTION_HOVER_EXIT, box2LayoutCoordinates!!) + + rule.runOnUiThread { + assertThat(exitBox2).isTrue() + assertThat(pointerEvent).isNotNull() + assertThat(eventsThatShouldNotTrigger).isFalse() + } + + // Outside event with Box 3 coordinates + pointerEvent = null // Reset before each event + dispatchMouseEvent(ACTION_OUTSIDE, box3LayoutCoordinates!!) + + // No Compose event should be triggered (b/299074463#comment31) + rule.runOnUiThread { + assertThat(eventsThatShouldNotTrigger).isFalse() + assertThat(pointerEvent).isNull() + } + + // Press on Box 2 + pointerEvent = null // Reset before each event + dispatchMouseEvent(ACTION_DOWN, box2LayoutCoordinates!!) + rule.runOnUiThread { + assertThat(pressBox2).isTrue() + assertThat(eventsThatShouldNotTrigger).isFalse() + assertThat(pointerEvent).isNotNull() + } + + // Release on Box 2 + pointerEvent = null // Reset before each event + dispatchMouseEvent(ACTION_UP, box2LayoutCoordinates!!) + rule.runOnUiThread { + assertThat(releaseBox2).isTrue() + assertThat(eventsThatShouldNotTrigger).isFalse() + assertThat(pointerEvent).isNotNull() + } + + assertTrue(totalEventLatch.await(1, TimeUnit.SECONDS)) + } + @Test fun dispatchHoverMove() { var layoutCoordinates: LayoutCoordinates? = null @@ -1890,6 +2091,7 @@ } } + // TODO (jjw): Another option @Test fun syntheticEventSentAfterUp() { val eventLog = mutableListOf()
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/MotionEventAdapter.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/MotionEventAdapter.android.kt index cf0b7e1..1882f1c 100644 --- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/MotionEventAdapter.android.kt +++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/input/pointer/MotionEventAdapter.android.kt
@@ -25,6 +25,7 @@ import android.view.MotionEvent.ACTION_HOVER_ENTER import android.view.MotionEvent.ACTION_HOVER_EXIT import android.view.MotionEvent.ACTION_HOVER_MOVE +import android.view.MotionEvent.ACTION_OUTSIDE import android.view.MotionEvent.ACTION_POINTER_DOWN import android.view.MotionEvent.ACTION_POINTER_UP import android.view.MotionEvent.ACTION_SCROLL @@ -85,7 +86,7 @@ positionCalculator: PositionCalculator ): PointerInputEvent? { val action = motionEvent.actionMasked - if (action == ACTION_CANCEL) { + if (action == ACTION_CANCEL || action == ACTION_OUTSIDE) { motionEventToComposePointerIdMap.clear() canHover.clear() return null
diff --git a/core/core/src/main/java/androidx/core/app/NotificationCompat.java b/core/core/src/main/java/androidx/core/app/NotificationCompat.java index 33b1459..d684a7b 100644 --- a/core/core/src/main/java/androidx/core/app/NotificationCompat.java +++ b/core/core/src/main/java/androidx/core/app/NotificationCompat.java
@@ -5622,8 +5622,8 @@ @Override public void apply(NotificationBuilderWithBuilderAccessor builder) { if (Build.VERSION.SDK_INT >= 24) { - Api16Impl.setStyle(builder.getBuilder(), - Api24Impl.createDecoratedCustomViewStyle()); + Notification.Builder builder1 = builder.getBuilder(); + builder1.setStyle(Api24Impl.createDecoratedCustomViewStyle()); } } @@ -5737,51 +5737,12 @@ if (!tombstone) { button.setOnClickPendingIntent(R.id.action_container, action.actionIntent); } - if (Build.VERSION.SDK_INT >= 15) { - Api15Impl.setContentDescription(button, R.id.action_container, action.title); - } + button.setContentDescription(R.id.action_container, action.title); return button; } /** * A class for wrapping calls to {@link Notification.DecoratedCustomViewStyle} methods which - * were added in API 15; these calls must be wrapped to avoid performance issues. - * See the UnsafeNewApiCall lint rule for more details. - */ - @RequiresApi(15) - static class Api15Impl { - private Api15Impl() { } - - @DoNotInline - static void setContentDescription(RemoteViews remoteViews, int viewId, - CharSequence contentDescription) { - remoteViews.setContentDescription(viewId, contentDescription); - } - } - - /** - * A class for wrapping calls to {@link Notification.DecoratedCustomViewStyle} methods which - * were added in API 16; these calls must be wrapped to avoid performance issues. - * See the UnsafeNewApiCall lint rule for more details. - * Note that the runtime converts NewApi classes to Object during init, but only for - * initialized classes; if setStyle is passed style objects from newer API versions, if - * the type of those objects will be unknown, and a VerifyError will occur. To prevent - * this, we explicitly cast the provided style Object to Notification.Style. - */ - @RequiresApi(16) - static class Api16Impl { - private Api16Impl() { } - - @DoNotInline - static Notification.Builder setStyle(Notification.Builder builder, - Object style) { - return builder.setStyle((Notification.Style) style); - } - - } - - /** - * A class for wrapping calls to {@link Notification.DecoratedCustomViewStyle} methods which * were added in API 24; these calls must be wrapped to avoid performance issues. * See the UnsafeNewApiCall lint rule for more details. */ @@ -5790,7 +5751,7 @@ private Api24Impl() { } @DoNotInline - static Notification.DecoratedCustomViewStyle createDecoratedCustomViewStyle() { + static Notification.Style createDecoratedCustomViewStyle() { return new Notification.DecoratedCustomViewStyle(); }
diff --git a/core/core/src/main/java/androidx/core/content/IntentCompat.java b/core/core/src/main/java/androidx/core/content/IntentCompat.java index db25773..0e4196d 100644 --- a/core/core/src/main/java/androidx/core/content/IntentCompat.java +++ b/core/core/src/main/java/androidx/core/content/IntentCompat.java
@@ -120,16 +120,7 @@ @NonNull public static Intent makeMainSelectorActivity(@NonNull String selectorAction, @NonNull String selectorCategory) { - if (Build.VERSION.SDK_INT >= 15) { - return Api15Impl.makeMainSelectorActivity(selectorAction, selectorCategory); - } else { - // Before api 15 you couldn't set a selector intent. - // Fall back and just return an intent with the requested action/category, - // even though it won't be a proper "main" intent. - Intent intent = new Intent(selectorAction); - intent.addCategory(selectorCategory); - return intent; - } + return Intent.makeMainSelectorActivity(selectorAction, selectorCategory); } /** @@ -298,18 +289,6 @@ } } - @RequiresApi(15) - static class Api15Impl { - private Api15Impl() { - // This class is not instantiable. - } - - @DoNotInline - static Intent makeMainSelectorActivity(String selectorAction, String selectorCategory) { - return Intent.makeMainSelectorActivity(selectorAction, selectorCategory); - } - } - @RequiresApi(33) static class Api33Impl { private Api33Impl() {
diff --git a/core/core/src/main/java/androidx/core/content/IntentSanitizer.java b/core/core/src/main/java/androidx/core/content/IntentSanitizer.java index aab9a33..421ba7c 100644 --- a/core/core/src/main/java/androidx/core/content/IntentSanitizer.java +++ b/core/core/src/main/java/androidx/core/content/IntentSanitizer.java
@@ -207,10 +207,8 @@ } } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { - Api16Impl.sanitizeClipData(in, intent, mAllowedClipData, mAllowClipDataText, - mAllowedClipDataUri, penalty); - } + sanitizeClipData(in, intent, mAllowedClipData, mAllowClipDataText, mAllowedClipDataUri, + penalty); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { if (mAllowIdentifier) { @@ -220,12 +218,10 @@ } } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { - if (mAllowSelector) { - Api15Impl.setSelector(intent, Api15Impl.getSelector(in)); - } else if (Api15Impl.getSelector(in) != null) { - penalty.accept("Selector is not allowed: " + Api15Impl.getSelector(in)); - } + if (mAllowSelector) { + intent.setSelector(in.getSelector()); + } else if (in.getSelector() != null) { + penalty.accept("Selector is not allowed: " + in.getSelector()); } if (mAllowSourceBounds) { @@ -879,113 +875,89 @@ } } - @RequiresApi(15) - private static class Api15Impl { - private Api15Impl() { - // This class is not instantiable. - } + static void sanitizeClipData(@NonNull Intent in, Intent out, + PredicatemAllowedClipData, + boolean mAllowClipDataText, + PredicatemAllowedClipDataUri, Consumer + ClipData clipData = in.getClipData(); - @DoNotInline - static void setSelector(Intent intent, Intent selector) { - intent.setSelector(selector); - } + if (clipData == null) return; - @DoNotInline - static Intent getSelector(Intent intent) { - return intent.getSelector(); + ClipData newClipData = null; + if (mAllowedClipData != null && mAllowedClipData.test(clipData)) { + out.setClipData(clipData); + } else { + for (int i = 0; i < clipData.getItemCount(); i++) { + ClipData.Item item = clipData.getItemAt(i); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + Api31Impl.checkOtherMembers(i, item, penalty); + } else { + checkOtherMembers(i, item, penalty); + } + + CharSequence itemText = null; + if (mAllowClipDataText) { + itemText = item.getText(); + } else { + if (item.getText() != null) { + penalty.accept( + "Item text cannot contain value. Item position: " + i + "." + + " Text: " + item.getText()); + } + } + + Uri itemUri = null; + if (mAllowedClipDataUri == null) { + if (item.getUri() != null) { + penalty.accept( + "Item URI is not allowed. Item position: " + i + ". URI: " + + item.getUri()); + } + } else { + if (item.getUri() == null || mAllowedClipDataUri.test(item.getUri())) { + itemUri = item.getUri(); + } else { + penalty.accept( + "Item URI is not allowed. Item position: " + i + ". URI: " + + item.getUri()); + } + } + + if (itemText != null || itemUri != null) { + if (newClipData == null) { + newClipData = new ClipData(clipData.getDescription(), + new ClipData.Item(itemText, null, itemUri)); + } else { + newClipData.addItem(new ClipData.Item(itemText, null, itemUri)); + } + } + } + if (newClipData != null) { + out.setClipData(newClipData); + } } } - @RequiresApi(16) - private static class Api16Impl { - private Api16Impl() { + private static void checkOtherMembers(int i, ClipData.Item item, Consumerpenalty) { penalty) { + if (item.getHtmlText() != null || item.getIntent() != null) { + penalty.accept("ClipData item at position " + i + " contains htmlText, " + + "textLinks or intent: " + item); + } + } + + @RequiresApi(31) + private static class Api31Impl { + private Api31Impl() { } @DoNotInline - static void sanitizeClipData(@NonNull Intent in, Intent out, - PredicatemAllowedClipData, - boolean mAllowClipDataText, - PredicatemAllowedClipDataUri, Consumer - ClipData clipData = in.getClipData(); - - if (clipData == null) return; - - ClipData newClipData = null; - if (mAllowedClipData != null && mAllowedClipData.test(clipData)) { - out.setClipData(clipData); - } else { - for (int i = 0; i < clipData.getItemCount(); i++) { - ClipData.Item item = clipData.getItemAt(i); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - Api31Impl.checkOtherMembers(i, item, penalty); - } else { - checkOtherMembers(i, item, penalty); - } - - CharSequence itemText = null; - if (mAllowClipDataText) { - itemText = item.getText(); - } else { - if (item.getText() != null) { - penalty.accept( - "Item text cannot contain value. Item position: " + i + "." - + " Text: " + item.getText()); - } - } - - Uri itemUri = null; - if (mAllowedClipDataUri == null) { - if (item.getUri() != null) { - penalty.accept( - "Item URI is not allowed. Item position: " + i + ". URI: " - + item.getUri()); - } - } else { - if (item.getUri() == null || mAllowedClipDataUri.test(item.getUri())) { - itemUri = item.getUri(); - } else { - penalty.accept( - "Item URI is not allowed. Item position: " + i + ". URI: " - + item.getUri()); - } - } - - if (itemText != null || itemUri != null) { - if (newClipData == null) { - newClipData = new ClipData(clipData.getDescription(), - new ClipData.Item(itemText, null, itemUri)); - } else { - newClipData.addItem(new ClipData.Item(itemText, null, itemUri)); - } - } - } - if (newClipData != null) { - out.setClipData(newClipData); - } - } - } - - private static void checkOtherMembers(int i, ClipData.Item item, Consumerpenalty) { penalty) { - if (item.getHtmlText() != null || item.getIntent() != null) { + static void checkOtherMembers(int i, ClipData.Item item, Consumerpenalty) { + if (item.getHtmlText() != null || item.getIntent() != null + || item.getTextLinks() != null) { penalty.accept("ClipData item at position " + i + " contains htmlText, " + "textLinks or intent: " + item); } } - - @RequiresApi(31) - private static class Api31Impl { - private Api31Impl() { - } - - @DoNotInline - static void checkOtherMembers(int i, ClipData.Item item, Consumerpenalty) { - if (item.getHtmlText() != null || item.getIntent() != null - || item.getTextLinks() != null) { - penalty.accept("ClipData item at position " + i + " contains htmlText, " - + "textLinks or intent: " + item); - } - } - } } @RequiresApi(29)
diff --git a/core/core/src/main/java/androidx/core/content/res/ResourcesCompat.java b/core/core/src/main/java/androidx/core/content/res/ResourcesCompat.java index 681aa16..a46e557 100644 --- a/core/core/src/main/java/androidx/core/content/res/ResourcesCompat.java +++ b/core/core/src/main/java/androidx/core/content/res/ResourcesCompat.java
@@ -170,10 +170,8 @@ int density, @Nullable Theme theme) throws NotFoundException { if (SDK_INT >= 21) { return Api21Impl.getDrawableForDensity(res, id, density, theme); - } else if (SDK_INT >= 15) { - return Api15Impl.getDrawableForDensity(res, id, density); } else { - return res.getDrawable(id); + return res.getDrawableForDensity(id, density); } } @@ -713,19 +711,6 @@ } } - @RequiresApi(15) - static class Api15Impl { - private Api15Impl() { - // This class is not instantiable. - } - - @DoNotInline - static Drawable getDrawableForDensity(Resources resources, int id, int density) { - return resources.getDrawableForDensity(id, density); - } - - } - private ResourcesCompat() { }
diff --git a/core/core/src/main/java/androidx/core/database/CursorWindowCompat.java b/core/core/src/main/java/androidx/core/database/CursorWindowCompat.java index 03b0c8f..a2c5681 100644 --- a/core/core/src/main/java/androidx/core/database/CursorWindowCompat.java +++ b/core/core/src/main/java/androidx/core/database/CursorWindowCompat.java
@@ -43,10 +43,8 @@ public static CursorWindow create(@Nullable String name, long windowSizeBytes) { if (Build.VERSION.SDK_INT >= 28) { return Api28Impl.createCursorWindow(name, windowSizeBytes); - } else if (Build.VERSION.SDK_INT >= 15) { - return Api15Impl.createCursorWindow(name); } else { - return new CursorWindow(false); + return new CursorWindow(name); } } @@ -61,16 +59,4 @@ return new CursorWindow(name, windowSizeBytes); } } - - @RequiresApi(15) - static class Api15Impl { - private Api15Impl() { - // This class is not instantiable. - } - - @DoNotInline - static CursorWindow createCursorWindow(String name) { - return new CursorWindow(name); - } - } }
diff --git a/emoji2/emoji2-views/src/androidTest/java/androidx/emoji2/widget/EmojiExtractTextLayoutTest.java b/emoji2/emoji2-views/src/androidTest/java/androidx/emoji2/widget/EmojiExtractTextLayoutTest.java index c7995bf..458819de 100644 --- a/emoji2/emoji2-views/src/androidTest/java/androidx/emoji2/widget/EmojiExtractTextLayoutTest.java +++ b/emoji2/emoji2-views/src/androidTest/java/androidx/emoji2/widget/EmojiExtractTextLayoutTest.java
@@ -31,14 +31,12 @@ import android.content.Context; import android.inputmethodservice.InputMethodService; -import android.os.Build; import android.text.InputType; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.EditorInfo; -import androidx.annotation.RequiresApi; import androidx.emoji2.text.EmojiCompat; import androidx.test.annotation.UiThreadTest; import androidx.test.core.app.ApplicationProvider; @@ -150,7 +148,6 @@ eq(EmojiCompat.REPLACE_STRATEGY_NON_EXISTENT)); } - @RequiresApi(api = Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) @Test @UiThreadTest public void testOnUpdateExtractingViews() { @@ -179,7 +176,6 @@ assertTrue(extractButton.hasOnClickListeners()); } - @RequiresApi(api = Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) @Test @UiThreadTest public void testOnUpdateExtractingViews_hidesAccessoriesIfNoAction() {
diff --git a/glance/glance-preview/api/current.txt b/glance/glance-preview/api/current.txt index 46a9a9d..fc59a6d 100644 --- a/glance/glance-preview/api/current.txt +++ b/glance/glance-preview/api/current.txt
@@ -4,13 +4,13 @@ @SuppressCompatibility @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalGlancePreviewApi { } - @SuppressCompatibility @androidx.glance.preview.ExperimentalGlancePreviewApi @kotlin.annotation.Repeatable @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface GlancePreview { + @SuppressCompatibility @androidx.glance.preview.ExperimentalGlancePreviewApi @kotlin.annotation.Repeatable @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface Preview { method public abstract String surface(); property public abstract String surface; } - @SuppressCompatibility @androidx.glance.preview.ExperimentalGlancePreviewApi @kotlin.annotation.Repeatable @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public static @interface GlancePreview.Container { - method public abstract androidx.glance.preview.GlancePreview[] value(); + @SuppressCompatibility @androidx.glance.preview.ExperimentalGlancePreviewApi @kotlin.annotation.Repeatable @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public static @interface Preview.Container { + method public abstract androidx.glance.preview.Preview[] value(); } @SuppressCompatibility @androidx.glance.preview.ExperimentalGlancePreviewApi public final class Surfaces {
diff --git a/glance/glance-preview/api/restricted_current.txt b/glance/glance-preview/api/restricted_current.txt index 46a9a9d..fc59a6d 100644 --- a/glance/glance-preview/api/restricted_current.txt +++ b/glance/glance-preview/api/restricted_current.txt
@@ -4,13 +4,13 @@ @SuppressCompatibility @kotlin.RequiresOptIn(message="This API is experimental and is likely to change in the future.") @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.BINARY) public @interface ExperimentalGlancePreviewApi { } - @SuppressCompatibility @androidx.glance.preview.ExperimentalGlancePreviewApi @kotlin.annotation.Repeatable @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface GlancePreview { + @SuppressCompatibility @androidx.glance.preview.ExperimentalGlancePreviewApi @kotlin.annotation.Repeatable @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public @interface Preview { method public abstract String surface(); property public abstract String surface; } - @SuppressCompatibility @androidx.glance.preview.ExperimentalGlancePreviewApi @kotlin.annotation.Repeatable @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public static @interface GlancePreview.Container { - method public abstract androidx.glance.preview.GlancePreview[] value(); + @SuppressCompatibility @androidx.glance.preview.ExperimentalGlancePreviewApi @kotlin.annotation.Repeatable @kotlin.annotation.Retention(kotlin.annotation.AnnotationRetention.SOURCE) @kotlin.annotation.Target(allowedTargets={kotlin.annotation.AnnotationTarget.ANNOTATION_CLASS, kotlin.annotation.AnnotationTarget.FUNCTION}) public static @interface Preview.Container { + method public abstract androidx.glance.preview.Preview[] value(); } @SuppressCompatibility @androidx.glance.preview.ExperimentalGlancePreviewApi public final class Surfaces {
diff --git a/glance/glance-preview/src/main/java/androidx/glance/preview/GlancePreview.kt b/glance/glance-preview/src/main/java/androidx/glance/preview/Preview.kt similarity index 93% rename from glance/glance-preview/src/main/java/androidx/glance/preview/GlancePreview.kt rename to glance/glance-preview/src/main/java/androidx/glance/preview/Preview.kt index cdc9027..fb20c35 100644 --- a/glance/glance-preview/src/main/java/androidx/glance/preview/GlancePreview.kt +++ b/glance/glance-preview/src/main/java/androidx/glance/preview/Preview.kt
@@ -26,4 +26,4 @@ ) @ExperimentalGlancePreviewApi @Repeatable -annotation class GlancePreview(@Surface val surface: String) +annotation class Preview(@Surface val surface: String)
diff --git a/glance/glance-preview/src/main/java/androidx/glance/preview/Surface.kt b/glance/glance-preview/src/main/java/androidx/glance/preview/Surface.kt index 6e118cf..e543b6f 100644 --- a/glance/glance-preview/src/main/java/androidx/glance/preview/Surface.kt +++ b/glance/glance-preview/src/main/java/androidx/glance/preview/Surface.kt
@@ -22,7 +22,7 @@ /** * The list of glance surfaces that have preview available. The list will grow as more glance * surfaces are added and allow the preview functionality. Items should be used as values for - * surface parameter in [GlancePreview] annotation. + * surface parameter in glance [Preview] annotation. */ @ExperimentalGlancePreviewApi object Surfaces { @@ -33,7 +33,7 @@ /** * The annotation that ensures that the variable value is strictly a recognized glance surface. * - * @see GlancePreview annotation + * @see glance [Preview] annotation */ @Retention(AnnotationRetention.SOURCE) @OptIn(ExperimentalGlancePreviewApi::class)
diff --git a/media/media/src/main/java/androidx/media/app/NotificationCompat.java b/media/media/src/main/java/androidx/media/app/NotificationCompat.java index 56928a6..bde7799 100644 --- a/media/media/src/main/java/androidx/media/app/NotificationCompat.java +++ b/media/media/src/main/java/androidx/media/app/NotificationCompat.java
@@ -320,9 +320,8 @@ if (!tombstone) { button.setOnClickPendingIntent(R.id.action0, action.getActionIntent()); } - if (Build.VERSION.SDK_INT >= 15) { - Api15Impl.setContentDescription(button, R.id.action0, action.getTitle()); - } + CharSequence contentDescription = action.getTitle(); + button.setContentDescription(R.id.action0, contentDescription); return button; } @@ -539,17 +538,6 @@ } } - @RequiresApi(15) - private static class Api15Impl { - private Api15Impl() {} - - @DoNotInline - static void setContentDescription(RemoteViews remoteViews, int viewId, - CharSequence contentDescription) { - remoteViews.setContentDescription(viewId, contentDescription); - } - } - @RequiresApi(21) private static class Api21Impl { private Api21Impl() {}
diff --git a/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/JankStatsTest.kt b/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/JankStatsTest.kt index 1e9c73d..5f5f9ec 100644 --- a/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/JankStatsTest.kt +++ b/metrics/metrics-performance/src/androidTest/java/androidx/metrics/performance/test/JankStatsTest.kt
@@ -15,7 +15,6 @@ */ package androidx.metrics.performance.test -import android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1 import android.view.Choreographer import androidx.metrics.performance.FrameData import androidx.metrics.performance.FrameDataApi24 @@ -28,7 +27,6 @@ import androidx.test.ext.junit.rules.ActivityScenarioRule import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest -import androidx.test.filters.SdkSuppress import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit import kotlin.math.max @@ -430,23 +428,6 @@ latchedListener.reset() } - /** - * JankStats doesn't do anything pre API 16. But it would be nice to not crash running - * code that calls JankStats functionality on that version. This test just calls basic APIs - * to make sure they don't crash. - */ - @SdkSuppress(maxSdkVersion = ICE_CREAM_SANDWICH_MR1) - @Test - fun testPreAPI16() { - delayedActivityRule.getScenario().onActivity { - val state0 = StateInfo("Testing State 0", "sampleStateA") - val state1 = StateInfo("Testing State 1", "sampleStateB") - metricsState.putState(state0.key, state0.value) - metricsState.putSingleFrameState(state1.key, state1.value) - } - runDelayTest(0, NUM_FRAMES, latchedListener) - } - @Test fun testComplexFrameStateData() { initFramePipeline()
diff --git a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewBasicTest.java b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewBasicTest.java index de765ab3..f524970 100644 --- a/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewBasicTest.java +++ b/recyclerview/recyclerview/src/androidTest/java/androidx/recyclerview/widget/RecyclerViewBasicTest.java
@@ -554,15 +554,10 @@ measure(); layout(); - boolean isIcsOrLower = Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1; - - // On API 15 and lower, focus forward get's translated to focus down. - View expected = isIcsOrLower ? focusAdapter.mBottomRight : focusAdapter.mBottomLeft; + View expected = focusAdapter.mBottomLeft; assertEquals(expected, focusAdapter.mTopRight.focusSearch(View.FOCUS_FORWARD)); - // On API 15 and lower, focus forward get's translated to focus down, which in this case - // runs out of the RecyclerView, thus returning null. - expected = isIcsOrLower ? null : focusAdapter.mBottomRight; + expected = focusAdapter.mBottomRight; assertSame(expected, focusAdapter.mBottomLeft.focusSearch(View.FOCUS_FORWARD)); // we don't want looping within RecyclerView
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendingQueryTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendingQueryTest.kt index 37f6425..5356759 100644 --- a/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendingQueryTest.kt +++ b/room/integration-tests/kotlintestapp/src/androidTest/java/androidx/room/integration/kotlintestapp/test/SuspendingQueryTest.kt
@@ -17,7 +17,6 @@ package androidx.room.integration.kotlintestapp.test import android.content.Context -import android.os.Build import android.os.StrictMode import android.os.StrictMode.ThreadPolicy import androidx.arch.core.executor.ArchTaskExecutor @@ -1017,16 +1016,11 @@ database.endTransaction() } } catch (ex: IllegalStateException) { - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { - assertThat(ex).hasMessageThat() - .contains( - "Cannot perform this operation because there is no current " + - "transaction" - ) - } else { - assertThat(ex).hasMessageThat() - .contains("Don't have database lock") - } + assertThat(ex).hasMessageThat() + .contains( + "Cannot perform this operation because there is no current " + + "transaction" + ) } } } @@ -1044,16 +1038,11 @@ throw RuntimeException() } } catch (ex: IllegalStateException) { - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { - assertThat(ex).hasMessageThat() - .contains( - "Cannot perform this operation because there is no current " + - "transaction" - ) - } else { - assertThat(ex).hasMessageThat() - .contains("Don't have database lock") - } + assertThat(ex).hasMessageThat() + .contains( + "Cannot perform this operation because there is no current " + + "transaction" + ) } } }
diff --git a/room/room-runtime/src/androidMain/kotlin/androidx/room/util/CursorUtil.android.kt b/room/room-runtime/src/androidMain/kotlin/androidx/room/util/CursorUtil.android.kt index 6e94283..b079c79 100644 --- a/room/room-runtime/src/androidMain/kotlin/androidx/room/util/CursorUtil.android.kt +++ b/room/room-runtime/src/androidMain/kotlin/androidx/room/util/CursorUtil.android.kt
@@ -142,15 +142,7 @@ * closes the Cursor. */ inline funCursor.useCursor(block: (Cursor) -> R): R { - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { - return this.use(block) - } else { - try { - return block(this) - } finally { - this.close() - } - } + return this.use(block) } /**
diff --git a/settings.gradle b/settings.gradle index 8160f4c..114e351 100644 --- a/settings.gradle +++ b/settings.gradle
@@ -505,6 +505,7 @@ includeProject(":compose:material3:benchmark", [BuildType.COMPOSE]) includeProject(":compose:material3:material3-adaptive", [BuildType.COMPOSE]) includeProject(":compose:material3:material3-adaptive:material3-adaptive-samples", "compose/material3/material3-adaptive/samples", [BuildType.COMPOSE]) +includeProject(":compose:material3:material3-adaptive:material3-adaptive-benchmark", "compose/material3/material3-adaptive/benchmark", [BuildType.COMPOSE]) includeProject(":compose:material3:material3-adaptive-navigation-suite", [BuildType.COMPOSE]) includeProject(":compose:material3:material3-adaptive-navigation-suite:material3-adaptive-navigation-suite-samples", "compose/material3/material3-adaptive-navigation-suite/samples", [BuildType.COMPOSE]) includeProject(":compose:material3:material3-common", [BuildType.COMPOSE])
diff --git a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt index 721e6f1..48f23b3 100644 --- a/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt +++ b/viewpager2/viewpager2/src/androidTest/java/androidx/viewpager2/widget/BaseTest.kt
@@ -403,12 +403,6 @@ } waitForRenderLatch.await(5, TimeUnit.SECONDS) - - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { - // Give slow devices some time to warm up, - // to prevent severe frame drops in the smooth scroll - Thread.sleep(1000) - } } fun ViewPager2.addWaitForLayoutChangeLatch(): CountDownLatch {