Merge "ui-desktop: different redrawing strategy with DesktopUIDispatcher" into androidx-master-dev
diff --git a/playground-common/CONTRIBUTING.md b/CONTRIBUTING.md
similarity index 100%
rename from playground-common/CONTRIBUTING.md
rename to CONTRIBUTING.md
diff --git a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
index c1ac1ed..426f9b2 100644
--- a/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/LibraryVersions.kt
@@ -118,7 +118,7 @@
val VIEWPAGER2 = Version("1.1.0-alpha02")
val WEAR = Version("1.2.0-alpha01")
val WEAR_INPUT = Version("1.0.0-alpha01")
- val WEBKIT = Version("1.3.0-rc01")
+ val WEBKIT = Version("1.4.0-alpha01")
val WINDOW = Version("1.0.0-alpha02")
val WINDOW_SIDECAR = Version("0.1.0-alpha01")
val WORK = Version("2.4.0-rc01")
diff --git a/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt b/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt
index 6e30585..2e48035 100644
--- a/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt
+++ b/buildSrc/src/main/kotlin/androidx/build/PublishDocsRules.kt
@@ -29,10 +29,10 @@
*/
val RELEASE_RULE = docsRules("public", false) {
ignore(LibraryGroups.ACTIVITY.group, "activity-lint")
- prebuilts(LibraryGroups.ACTIVITY, "1.2.0-alpha06")
+ prebuilts(LibraryGroups.ACTIVITY, "1.2.0-alpha07")
prebuilts(LibraryGroups.ADS, "1.0.0-alpha04")
prebuilts(LibraryGroups.ANNOTATION, "annotation", "1.2.0-alpha01")
- prebuilts(LibraryGroups.ANNOTATION, "annotation-experimental", "1.0.0")
+ prebuilts(LibraryGroups.ANNOTATION, "annotation-experimental", "1.1.0-alpha01")
prebuilts(LibraryGroups.ANNOTATION, "annotation-experimental-lint", "1.0.0")
ignore(LibraryGroups.APPCOMPAT.group, "appcompat-lint")
prebuilts(LibraryGroups.APPCOMPAT, "1.3.0-alpha01")
@@ -48,13 +48,13 @@
ignore(LibraryGroups.CAMERA.group, "camera-testing")
ignore(LibraryGroups.CAMERA.group, "camera-extensions-stub")
ignore(LibraryGroups.CAMERA.group, "camera-testlib-extensions")
- prebuilts(LibraryGroups.CAMERA, "camera-view", "1.0.0-alpha13")
- prebuilts(LibraryGroups.CAMERA, "camera-extensions", "1.0.0-alpha13")
+ prebuilts(LibraryGroups.CAMERA, "camera-view", "1.0.0-alpha14")
+ prebuilts(LibraryGroups.CAMERA, "camera-extensions", "1.0.0-alpha14")
.addStubs("camera/camera-extensions-stub/camera-extensions-stub.jar")
- prebuilts(LibraryGroups.CAMERA, "1.0.0-beta06")
+ prebuilts(LibraryGroups.CAMERA, "1.0.0-beta07")
prebuilts(LibraryGroups.CARDVIEW, "1.0.0")
prebuilts(LibraryGroups.COLLECTION, "1.1.0")
- prebuilts(LibraryGroups.CONCURRENT, "1.1.0-beta01")
+ prebuilts(LibraryGroups.CONCURRENT, "1.1.0-rc01")
prebuilts(LibraryGroups.CONTENTPAGER, "1.0.0")
prebuilts(LibraryGroups.COORDINATORLAYOUT, "1.1.0")
prebuilts(LibraryGroups.CORE, "core", "1.5.0-alpha01")
@@ -74,10 +74,10 @@
ignore(LibraryGroups.FRAGMENT.group, "fragment-lint")
ignore(LibraryGroups.FRAGMENT.group, "fragment-testing-lint")
ignore(LibraryGroups.FRAGMENT.group, "fragment-truth")
- prebuilts(LibraryGroups.FRAGMENT, "1.3.0-alpha06")
+ prebuilts(LibraryGroups.FRAGMENT, "1.3.0-alpha07")
prebuilts(LibraryGroups.GRIDLAYOUT, "1.0.0")
prebuilts(LibraryGroups.HEIFWRITER, "1.1.0-alpha01")
- prebuilts(LibraryGroups.HILT, "1.0.0-alpha01")
+ prebuilts(LibraryGroups.HILT, "1.0.0-alpha02")
prebuilts(LibraryGroups.INTERPOLATOR, "1.0.0")
prebuilts(LibraryGroups.LEANBACK, "1.1.0-alpha03")
prebuilts(LibraryGroups.LEGACY, "1.0.0")
@@ -87,7 +87,7 @@
ignore(LibraryGroups.LIFECYCLE.group, "lifecycle-runtime-ktx-lint")
prebuilts(LibraryGroups.LIFECYCLE, "lifecycle-extensions", "2.2.0") // No longer published
ignore(LibraryGroups.LIFECYCLE.group, "lifecycle-runtime-testing")
- prebuilts(LibraryGroups.LIFECYCLE, "2.3.0-alpha05")
+ prebuilts(LibraryGroups.LIFECYCLE, "2.3.0-alpha06")
ignore(LibraryGroups.LOADER.group, "loader-ktx")
prebuilts(LibraryGroups.LOADER, "1.1.0")
prebuilts(LibraryGroups.LOCALBROADCASTMANAGER, "1.1.0-alpha01")
@@ -95,7 +95,7 @@
ignore(LibraryGroups.MEDIA2.group, "media2-exoplayer")
prebuilts(LibraryGroups.MEDIA2, "media2-widget", "1.1.0-alpha01")
prebuilts(LibraryGroups.MEDIA2, "1.1.0-alpha01")
- prebuilts(LibraryGroups.MEDIAROUTER, "1.2.0-alpha01")
+ prebuilts(LibraryGroups.MEDIAROUTER, "1.2.0-alpha02")
ignore(LibraryGroups.NAVIGATION.group, "navigation-runtime-truth")
ignore(LibraryGroups.NAVIGATION.group, "navigation-safe-args-generator")
ignore(LibraryGroups.NAVIGATION.group, "navigation-safe-args-gradle-plugin")
@@ -108,9 +108,9 @@
prebuilts(LibraryGroups.PERCENTLAYOUT, "1.0.1")
prebuilts(LibraryGroups.PREFERENCE, "preference-ktx", "1.1.1")
prebuilts(LibraryGroups.PREFERENCE, "1.1.1")
- prebuilts(LibraryGroups.PRINT, "1.0.0")
+ prebuilts(LibraryGroups.PRINT, "1.1.0-alpha01")
prebuilts(LibraryGroups.RECOMMENDATION, "1.0.0")
- prebuilts(LibraryGroups.RECYCLERVIEW, "recyclerview", "1.2.0-alpha04")
+ prebuilts(LibraryGroups.RECYCLERVIEW, "recyclerview", "1.2.0-alpha05")
prebuilts(LibraryGroups.RECYCLERVIEW, "recyclerview-selection", "2.0.0-alpha01")
ignore(LibraryGroups.RECYCLERVIEW.group, "recyclerview-lint")
prebuilts(LibraryGroups.REMOTECALLBACK, "1.0.0-alpha02")
@@ -119,7 +119,7 @@
ignore(LibraryGroups.ROOM.group, "room-compiler-xprocessing")
// TODO: Remove during release phase of rxjava3 artifact
ignore(LibraryGroups.ROOM.group, "room-rxjava3")
- prebuilts(LibraryGroups.ROOM, "2.3.0-alpha01")
+ prebuilts(LibraryGroups.ROOM, "2.3.0-alpha02")
prebuilts(LibraryGroups.SAVEDSTATE, "1.1.0-alpha01")
// TODO: Remove this ignore once androidx.security:security-biometric:1.0.0-alpha01 is released
ignore(LibraryGroups.SECURITY.group, "security-biometric")
@@ -139,12 +139,12 @@
prebuilts(LibraryGroups.SLIDINGPANELAYOUT, "1.1.0")
ignore(LibraryGroups.INSPECTION_EXTENSIONS.group, "sqlite-inspection")
prebuilts(LibraryGroups.SQLITE, "2.1.0")
- prebuilts(LibraryGroups.STARTUP, "1.0.0-alpha01")
- prebuilts(LibraryGroups.SWIPEREFRESHLAYOUT, "1.1.0")
+ prebuilts(LibraryGroups.STARTUP, "1.0.0-alpha02")
+ prebuilts(LibraryGroups.SWIPEREFRESHLAYOUT, "1.2.0-alpha01")
prebuilts(LibraryGroups.TEXTCLASSIFIER, "1.0.0-alpha03")
prebuilts(LibraryGroups.TRACING, "1.0.0-beta01")
ignore(LibraryGroups.TRANSITION.group, "transition-ktx")
- prebuilts(LibraryGroups.TRANSITION, "1.4.0-alpha01")
+ prebuilts(LibraryGroups.TRANSITION, "1.4.0-beta01")
prebuilts(LibraryGroups.TVPROVIDER, "1.0.0")
prebuilts(LibraryGroups.VECTORDRAWABLE, "vectordrawable", "1.2.0-alpha01")
prebuilts(LibraryGroups.VECTORDRAWABLE, "vectordrawable-animated", "1.1.0")
@@ -165,7 +165,7 @@
ignore(LibraryGroups.WORK.group, "work-gcm")
ignore(LibraryGroups.WORK.group, "work-runtime-lint")
ignore(LibraryGroups.WORK.group, "work-rxjava3")
- prebuilts(LibraryGroups.WORK, "2.4.0-rc01")
+ prebuilts(LibraryGroups.WORK, "2.4.0")
default(Ignore)
}
diff --git a/development/referenceDocs/stageComposeReferenceDocs.sh b/development/referenceDocs/stageComposeReferenceDocs.sh
index d3c1831..b9802ce8 100755
--- a/development/referenceDocs/stageComposeReferenceDocs.sh
+++ b/development/referenceDocs/stageComposeReferenceDocs.sh
@@ -29,7 +29,7 @@
repo sync -j64
git reset --hard $tipOfTreeSha
-git fetch "https://android.googlesource.com/platform/frameworks/support" refs/changes/23/1215823/4 && git cherry-pick FETCH_HEAD
+git fetch "https://android.googlesource.com/platform/frameworks/support" refs/changes/23/1215823/8 && git cherry-pick FETCH_HEAD
./gradlew distTipOfTreeDokkaDocs
printf "============================ STEP 3 =============================== \n"
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReorderingTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReorderingTest.kt
index c1ef8a0..3539a77 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReorderingTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/FragmentReorderingTest.kt
@@ -21,11 +21,14 @@
import android.widget.EditText
import androidx.fragment.app.test.FragmentTestActivity
import androidx.fragment.test.R
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleEventObserver
import androidx.test.annotation.UiThreadTest
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -50,6 +53,50 @@
instrumentation = InstrumentationRegistry.getInstrumentation()
}
+ // Ensure that a replaced fragment is stopped before its replacement is started
+ // and vice versa when popped
+ @Test
+ fun stopBeforeStart() {
+ if (!FragmentManager.USE_STATE_MANAGER) {
+ return
+ }
+ val fragment1 = StrictViewFragment()
+ fm.beginTransaction()
+ .add(R.id.fragmentContainer, fragment1)
+ .setReorderingAllowed(true)
+ .commit()
+ activityRule.executePendingTransactions()
+
+ val fragment2 = StrictViewFragment()
+ lateinit var replaceStateWhenStopped: Lifecycle.State
+ lateinit var replaceStateWhenPopStarted: Lifecycle.State
+ instrumentation.runOnMainSync {
+ fragment1.lifecycle.addObserver(LifecycleEventObserver { _, event ->
+ if (event == Lifecycle.Event.ON_STOP) {
+ replaceStateWhenStopped = fragment2.lifecycle.currentState
+ } else if (event == Lifecycle.Event.ON_START) {
+ replaceStateWhenPopStarted = fragment2.lifecycle.currentState
+ }
+ })
+ }
+ fm.beginTransaction()
+ .replace(R.id.fragmentContainer, fragment2)
+ .addToBackStack(null)
+ .setReorderingAllowed(true)
+ .commit()
+ activityRule.executePendingTransactions()
+
+ assertWithMessage("Fragment1 should be stopped before Fragment2 moves to " +
+ replaceStateWhenStopped)
+ .that(replaceStateWhenStopped).isLessThan(Lifecycle.State.STARTED)
+
+ activityRule.popBackStackImmediate()
+
+ assertWithMessage("Fragment1 should be started only after Fragment2 moves from " +
+ replaceStateWhenPopStarted)
+ .that(replaceStateWhenPopStarted).isLessThan(Lifecycle.State.STARTED)
+ }
+
// Test that when you add and replace a fragment that only the replace's add
// actually creates a View.
@Test
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
index 18dd954..4c0205f 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/FragmentManager.java
@@ -2117,12 +2117,40 @@
executeOps(records, isRecordPop, startIndex, endIndex);
if (USE_STATE_MANAGER) {
- if (allowReordering) {
- moveToState(mCurState, true);
- }
// The last operation determines the overall direction, this ensures that operations
// such as push, push, pop, push are correctly considered a push
boolean isPop = isRecordPop.get(endIndex - 1);
+ if (allowReordering) {
+ // Ensure that Fragments directly affected by operations
+ // are moved to their expected state in operation order
+ for (int index = startIndex; index < endIndex; index++) {
+ BackStackRecord record = records.get(index);
+ if (isPop) {
+ // Pop operations get applied in reverse order
+ for (int opIndex = record.mOps.size() - 1; opIndex >= 0; opIndex--) {
+ FragmentTransaction.Op op = record.mOps.get(opIndex);
+ Fragment fragment = op.mFragment;
+ if (fragment != null) {
+ FragmentStateManager fragmentStateManager =
+ createOrGetFragmentStateManager(fragment);
+ fragmentStateManager.moveToExpectedState();
+ }
+ }
+ } else {
+ for (FragmentTransaction.Op op : record.mOps) {
+ Fragment fragment = op.mFragment;
+ if (fragment != null) {
+ FragmentStateManager fragmentStateManager =
+ createOrGetFragmentStateManager(fragment);
+ fragmentStateManager.moveToExpectedState();
+ }
+ }
+ }
+
+ }
+ // And only then do we move all other fragments to the current state
+ moveToState(mCurState, true);
+ }
Set<SpecialEffectsController> changedControllers = collectChangedControllers(
records, startIndex, endIndex);
for (SpecialEffectsController controller : changedControllers) {
diff --git a/ui/ui-core/api/0.1.0-dev16.txt b/ui/ui-core/api/0.1.0-dev16.txt
index e8262d5..2673614 100644
--- a/ui/ui-core/api/0.1.0-dev16.txt
+++ b/ui/ui-core/api/0.1.0-dev16.txt
@@ -1981,6 +1981,7 @@
method public int getId();
method public boolean getMergingEnabled();
method public androidx.ui.core.semantics.SemanticsNode? getParent();
+ method public androidx.ui.geometry.Offset getPositionInRoot();
method public androidx.ui.unit.IntSize getSize();
method public boolean isRoot();
property public final androidx.ui.unit.PxBounds boundsInRoot;
@@ -1992,6 +1993,7 @@
property public final int id;
property public final boolean isRoot;
property public final androidx.ui.core.semantics.SemanticsNode? parent;
+ property public final androidx.ui.geometry.Offset positionInRoot;
property public final androidx.ui.unit.IntSize size;
}
diff --git a/ui/ui-core/api/current.txt b/ui/ui-core/api/current.txt
index e8262d5..2673614 100644
--- a/ui/ui-core/api/current.txt
+++ b/ui/ui-core/api/current.txt
@@ -1981,6 +1981,7 @@
method public int getId();
method public boolean getMergingEnabled();
method public androidx.ui.core.semantics.SemanticsNode? getParent();
+ method public androidx.ui.geometry.Offset getPositionInRoot();
method public androidx.ui.unit.IntSize getSize();
method public boolean isRoot();
property public final androidx.ui.unit.PxBounds boundsInRoot;
@@ -1992,6 +1993,7 @@
property public final int id;
property public final boolean isRoot;
property public final androidx.ui.core.semantics.SemanticsNode? parent;
+ property public final androidx.ui.geometry.Offset positionInRoot;
property public final androidx.ui.unit.IntSize size;
}
diff --git a/ui/ui-core/api/public_plus_experimental_0.1.0-dev16.txt b/ui/ui-core/api/public_plus_experimental_0.1.0-dev16.txt
index e8262d5..2673614 100644
--- a/ui/ui-core/api/public_plus_experimental_0.1.0-dev16.txt
+++ b/ui/ui-core/api/public_plus_experimental_0.1.0-dev16.txt
@@ -1981,6 +1981,7 @@
method public int getId();
method public boolean getMergingEnabled();
method public androidx.ui.core.semantics.SemanticsNode? getParent();
+ method public androidx.ui.geometry.Offset getPositionInRoot();
method public androidx.ui.unit.IntSize getSize();
method public boolean isRoot();
property public final androidx.ui.unit.PxBounds boundsInRoot;
@@ -1992,6 +1993,7 @@
property public final int id;
property public final boolean isRoot;
property public final androidx.ui.core.semantics.SemanticsNode? parent;
+ property public final androidx.ui.geometry.Offset positionInRoot;
property public final androidx.ui.unit.IntSize size;
}
diff --git a/ui/ui-core/api/public_plus_experimental_current.txt b/ui/ui-core/api/public_plus_experimental_current.txt
index e8262d5..2673614 100644
--- a/ui/ui-core/api/public_plus_experimental_current.txt
+++ b/ui/ui-core/api/public_plus_experimental_current.txt
@@ -1981,6 +1981,7 @@
method public int getId();
method public boolean getMergingEnabled();
method public androidx.ui.core.semantics.SemanticsNode? getParent();
+ method public androidx.ui.geometry.Offset getPositionInRoot();
method public androidx.ui.unit.IntSize getSize();
method public boolean isRoot();
property public final androidx.ui.unit.PxBounds boundsInRoot;
@@ -1992,6 +1993,7 @@
property public final int id;
property public final boolean isRoot;
property public final androidx.ui.core.semantics.SemanticsNode? parent;
+ property public final androidx.ui.geometry.Offset positionInRoot;
property public final androidx.ui.unit.IntSize size;
}
diff --git a/ui/ui-core/api/restricted_0.1.0-dev16.txt b/ui/ui-core/api/restricted_0.1.0-dev16.txt
index 0780958..8dca1a0 100644
--- a/ui/ui-core/api/restricted_0.1.0-dev16.txt
+++ b/ui/ui-core/api/restricted_0.1.0-dev16.txt
@@ -2033,6 +2033,7 @@
method public int getId();
method public boolean getMergingEnabled();
method public androidx.ui.core.semantics.SemanticsNode? getParent();
+ method public androidx.ui.geometry.Offset getPositionInRoot();
method public androidx.ui.unit.IntSize getSize();
method public boolean isRoot();
property public final androidx.ui.unit.PxBounds boundsInRoot;
@@ -2044,6 +2045,7 @@
property public final int id;
property public final boolean isRoot;
property public final androidx.ui.core.semantics.SemanticsNode? parent;
+ property public final androidx.ui.geometry.Offset positionInRoot;
property public final androidx.ui.unit.IntSize size;
}
diff --git a/ui/ui-core/api/restricted_current.txt b/ui/ui-core/api/restricted_current.txt
index 0780958..8dca1a0 100644
--- a/ui/ui-core/api/restricted_current.txt
+++ b/ui/ui-core/api/restricted_current.txt
@@ -2033,6 +2033,7 @@
method public int getId();
method public boolean getMergingEnabled();
method public androidx.ui.core.semantics.SemanticsNode? getParent();
+ method public androidx.ui.geometry.Offset getPositionInRoot();
method public androidx.ui.unit.IntSize getSize();
method public boolean isRoot();
property public final androidx.ui.unit.PxBounds boundsInRoot;
@@ -2044,6 +2045,7 @@
property public final int id;
property public final boolean isRoot;
property public final androidx.ui.core.semantics.SemanticsNode? parent;
+ property public final androidx.ui.geometry.Offset positionInRoot;
property public final androidx.ui.unit.IntSize size;
}
diff --git a/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsNode.kt b/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsNode.kt
index 1f1817a..f39b11b 100644
--- a/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsNode.kt
+++ b/ui/ui-core/src/commonMain/kotlin/androidx/ui/core/semantics/SemanticsNode.kt
@@ -24,9 +24,10 @@
import androidx.ui.core.findClosestParentNode
import androidx.ui.core.globalBounds
import androidx.ui.core.globalPosition
+import androidx.ui.core.positionInRoot
+import androidx.ui.geometry.Offset
import androidx.ui.unit.IntSize
import androidx.ui.unit.PxBounds
-import androidx.ui.geometry.Offset
import androidx.ui.util.fastForEach
/**
@@ -71,23 +72,45 @@
// GEOMETRY
- /** The size of the bounding box for this node */
+ /**
+ * The size of the bounding box for this node, with no clipping applied
+ */
val size: IntSize
get() {
return componentNode.coordinates.size
}
- /** The bounding box for this node relative to the root of this Compose hierarchy */
+ /**
+ * The bounding box for this node relative to the root of this Compose hierarchy, with
+ * clipping applied. To get the bounds with no clipping applied, use
+ * PxBounds([positionInRoot], [size].toSize())
+ */
val boundsInRoot: PxBounds
get() {
return componentNode.coordinates.boundsInRoot
}
+ /**
+ * The position of this node relative to the root of this Compose hierarchy, with no clipping
+ * applied
+ */
+ val positionInRoot: Offset
+ get() {
+ return componentNode.coordinates.positionInRoot
+ }
+
+ /**
+ * The bounding box for this node relative to the screen, with clipping applied. To get the
+ * bounds with no clipping applied, use PxBounds([globalPosition], [size].toSize())
+ */
val globalBounds: PxBounds
get() {
return componentNode.coordinates.globalBounds
}
+ /**
+ * The position of this node relative to the screen, with no clipping applied
+ */
val globalPosition: Offset
get() {
return componentNode.coordinates.globalPosition
diff --git a/ui/ui-foundation/api/0.1.0-dev16.txt b/ui/ui-foundation/api/0.1.0-dev16.txt
index c418a4c..7022063 100644
--- a/ui/ui-foundation/api/0.1.0-dev16.txt
+++ b/ui/ui-foundation/api/0.1.0-dev16.txt
@@ -264,16 +264,17 @@
method public static androidx.ui.core.Modifier scrollable(androidx.ui.core.Modifier, androidx.ui.core.gesture.scrollorientationlocking.Orientation orientation, androidx.compose.foundation.gestures.ScrollableController controller, boolean enabled = true, boolean reverseDirection = false, kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean> canScroll = { return enabled }, kotlin.jvm.functions.Function1<? super androidx.ui.geometry.Offset,kotlin.Unit> kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> >
}
- public final class ZoomableKt {
- method @androidx.compose.Composable public static androidx.compose.foundation.gestures.ZoomableState ZoomableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
- method @androidx.compose.Composable public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, androidx.compose.foundation.gestures.ZoomableState zoomableState, kotlin.jvm.functions.Function0<kotlin.Unit>? >
- method @androidx.compose.Composable public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ public final class ZoomableController {
+ ctor public ZoomableController(androidx.animation.AnimationClockObservable animationClock, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ method public kotlin.jvm.functions.Function1<java.lang.Float,kotlin.Unit> getOnZoomDelta();
+ method public void smoothScaleBy(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(Spring.StiffnessLow), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit>? >
+ method public void stopAnimation();
}
- public final class ZoomableState {
- ctor public ZoomableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta, androidx.animation.AnimationClockObservable animationClock);
- method public kotlin.jvm.functions.Function1<java.lang.Float,kotlin.Unit> getOnZoomDelta();
- method public void smoothScaleBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit>? >
+ public final class ZoomableKt {
+ method @androidx.compose.Composable public static androidx.compose.foundation.gestures.ZoomableController rememberZoomableController(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ method public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, androidx.compose.foundation.gestures.ZoomableController controller, boolean enabled = true, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function0<kotlin.Unit>? >
+ method public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, boolean enabled = true, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
}
}
diff --git a/ui/ui-foundation/api/current.txt b/ui/ui-foundation/api/current.txt
index c418a4c..7022063 100644
--- a/ui/ui-foundation/api/current.txt
+++ b/ui/ui-foundation/api/current.txt
@@ -264,16 +264,17 @@
method public static androidx.ui.core.Modifier scrollable(androidx.ui.core.Modifier, androidx.ui.core.gesture.scrollorientationlocking.Orientation orientation, androidx.compose.foundation.gestures.ScrollableController controller, boolean enabled = true, boolean reverseDirection = false, kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean> canScroll = { return enabled }, kotlin.jvm.functions.Function1<? super androidx.ui.geometry.Offset,kotlin.Unit> kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> >
}
- public final class ZoomableKt {
- method @androidx.compose.Composable public static androidx.compose.foundation.gestures.ZoomableState ZoomableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
- method @androidx.compose.Composable public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, androidx.compose.foundation.gestures.ZoomableState zoomableState, kotlin.jvm.functions.Function0<kotlin.Unit>? >
- method @androidx.compose.Composable public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ public final class ZoomableController {
+ ctor public ZoomableController(androidx.animation.AnimationClockObservable animationClock, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ method public kotlin.jvm.functions.Function1<java.lang.Float,kotlin.Unit> getOnZoomDelta();
+ method public void smoothScaleBy(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(Spring.StiffnessLow), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit>? >
+ method public void stopAnimation();
}
- public final class ZoomableState {
- ctor public ZoomableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta, androidx.animation.AnimationClockObservable animationClock);
- method public kotlin.jvm.functions.Function1<java.lang.Float,kotlin.Unit> getOnZoomDelta();
- method public void smoothScaleBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit>? >
+ public final class ZoomableKt {
+ method @androidx.compose.Composable public static androidx.compose.foundation.gestures.ZoomableController rememberZoomableController(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ method public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, androidx.compose.foundation.gestures.ZoomableController controller, boolean enabled = true, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function0<kotlin.Unit>? >
+ method public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, boolean enabled = true, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
}
}
diff --git a/ui/ui-foundation/api/public_plus_experimental_0.1.0-dev16.txt b/ui/ui-foundation/api/public_plus_experimental_0.1.0-dev16.txt
index c418a4c..7022063 100644
--- a/ui/ui-foundation/api/public_plus_experimental_0.1.0-dev16.txt
+++ b/ui/ui-foundation/api/public_plus_experimental_0.1.0-dev16.txt
@@ -264,16 +264,17 @@
method public static androidx.ui.core.Modifier scrollable(androidx.ui.core.Modifier, androidx.ui.core.gesture.scrollorientationlocking.Orientation orientation, androidx.compose.foundation.gestures.ScrollableController controller, boolean enabled = true, boolean reverseDirection = false, kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean> canScroll = { return enabled }, kotlin.jvm.functions.Function1<? super androidx.ui.geometry.Offset,kotlin.Unit> kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> >
}
- public final class ZoomableKt {
- method @androidx.compose.Composable public static androidx.compose.foundation.gestures.ZoomableState ZoomableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
- method @androidx.compose.Composable public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, androidx.compose.foundation.gestures.ZoomableState zoomableState, kotlin.jvm.functions.Function0<kotlin.Unit>? >
- method @androidx.compose.Composable public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ public final class ZoomableController {
+ ctor public ZoomableController(androidx.animation.AnimationClockObservable animationClock, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ method public kotlin.jvm.functions.Function1<java.lang.Float,kotlin.Unit> getOnZoomDelta();
+ method public void smoothScaleBy(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(Spring.StiffnessLow), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit>? >
+ method public void stopAnimation();
}
- public final class ZoomableState {
- ctor public ZoomableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta, androidx.animation.AnimationClockObservable animationClock);
- method public kotlin.jvm.functions.Function1<java.lang.Float,kotlin.Unit> getOnZoomDelta();
- method public void smoothScaleBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit>? >
+ public final class ZoomableKt {
+ method @androidx.compose.Composable public static androidx.compose.foundation.gestures.ZoomableController rememberZoomableController(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ method public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, androidx.compose.foundation.gestures.ZoomableController controller, boolean enabled = true, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function0<kotlin.Unit>? >
+ method public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, boolean enabled = true, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
}
}
diff --git a/ui/ui-foundation/api/public_plus_experimental_current.txt b/ui/ui-foundation/api/public_plus_experimental_current.txt
index c418a4c..7022063 100644
--- a/ui/ui-foundation/api/public_plus_experimental_current.txt
+++ b/ui/ui-foundation/api/public_plus_experimental_current.txt
@@ -264,16 +264,17 @@
method public static androidx.ui.core.Modifier scrollable(androidx.ui.core.Modifier, androidx.ui.core.gesture.scrollorientationlocking.Orientation orientation, androidx.compose.foundation.gestures.ScrollableController controller, boolean enabled = true, boolean reverseDirection = false, kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean> canScroll = { return enabled }, kotlin.jvm.functions.Function1<? super androidx.ui.geometry.Offset,kotlin.Unit> kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> >
}
- public final class ZoomableKt {
- method @androidx.compose.Composable public static androidx.compose.foundation.gestures.ZoomableState ZoomableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
- method @androidx.compose.Composable public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, androidx.compose.foundation.gestures.ZoomableState zoomableState, kotlin.jvm.functions.Function0<kotlin.Unit>? >
- method @androidx.compose.Composable public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ public final class ZoomableController {
+ ctor public ZoomableController(androidx.animation.AnimationClockObservable animationClock, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ method public kotlin.jvm.functions.Function1<java.lang.Float,kotlin.Unit> getOnZoomDelta();
+ method public void smoothScaleBy(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(Spring.StiffnessLow), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit>? >
+ method public void stopAnimation();
}
- public final class ZoomableState {
- ctor public ZoomableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta, androidx.animation.AnimationClockObservable animationClock);
- method public kotlin.jvm.functions.Function1<java.lang.Float,kotlin.Unit> getOnZoomDelta();
- method public void smoothScaleBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit>? >
+ public final class ZoomableKt {
+ method @androidx.compose.Composable public static androidx.compose.foundation.gestures.ZoomableController rememberZoomableController(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ method public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, androidx.compose.foundation.gestures.ZoomableController controller, boolean enabled = true, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function0<kotlin.Unit>? >
+ method public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, boolean enabled = true, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
}
}
diff --git a/ui/ui-foundation/api/restricted_0.1.0-dev16.txt b/ui/ui-foundation/api/restricted_0.1.0-dev16.txt
index c418a4c..7022063 100644
--- a/ui/ui-foundation/api/restricted_0.1.0-dev16.txt
+++ b/ui/ui-foundation/api/restricted_0.1.0-dev16.txt
@@ -264,16 +264,17 @@
method public static androidx.ui.core.Modifier scrollable(androidx.ui.core.Modifier, androidx.ui.core.gesture.scrollorientationlocking.Orientation orientation, androidx.compose.foundation.gestures.ScrollableController controller, boolean enabled = true, boolean reverseDirection = false, kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean> canScroll = { return enabled }, kotlin.jvm.functions.Function1<? super androidx.ui.geometry.Offset,kotlin.Unit> kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> >
}
- public final class ZoomableKt {
- method @androidx.compose.Composable public static androidx.compose.foundation.gestures.ZoomableState ZoomableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
- method @androidx.compose.Composable public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, androidx.compose.foundation.gestures.ZoomableState zoomableState, kotlin.jvm.functions.Function0<kotlin.Unit>? >
- method @androidx.compose.Composable public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ public final class ZoomableController {
+ ctor public ZoomableController(androidx.animation.AnimationClockObservable animationClock, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ method public kotlin.jvm.functions.Function1<java.lang.Float,kotlin.Unit> getOnZoomDelta();
+ method public void smoothScaleBy(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(Spring.StiffnessLow), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit>? >
+ method public void stopAnimation();
}
- public final class ZoomableState {
- ctor public ZoomableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta, androidx.animation.AnimationClockObservable animationClock);
- method public kotlin.jvm.functions.Function1<java.lang.Float,kotlin.Unit> getOnZoomDelta();
- method public void smoothScaleBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit>? >
+ public final class ZoomableKt {
+ method @androidx.compose.Composable public static androidx.compose.foundation.gestures.ZoomableController rememberZoomableController(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ method public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, androidx.compose.foundation.gestures.ZoomableController controller, boolean enabled = true, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function0<kotlin.Unit>? >
+ method public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, boolean enabled = true, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
}
}
diff --git a/ui/ui-foundation/api/restricted_current.txt b/ui/ui-foundation/api/restricted_current.txt
index c418a4c..7022063 100644
--- a/ui/ui-foundation/api/restricted_current.txt
+++ b/ui/ui-foundation/api/restricted_current.txt
@@ -264,16 +264,17 @@
method public static androidx.ui.core.Modifier scrollable(androidx.ui.core.Modifier, androidx.ui.core.gesture.scrollorientationlocking.Orientation orientation, androidx.compose.foundation.gestures.ScrollableController controller, boolean enabled = true, boolean reverseDirection = false, kotlin.jvm.functions.Function1<? super androidx.ui.core.Direction,java.lang.Boolean> canScroll = { return enabled }, kotlin.jvm.functions.Function1<? super androidx.ui.geometry.Offset,kotlin.Unit> kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> >
}
- public final class ZoomableKt {
- method @androidx.compose.Composable public static androidx.compose.foundation.gestures.ZoomableState ZoomableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
- method @androidx.compose.Composable public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, androidx.compose.foundation.gestures.ZoomableState zoomableState, kotlin.jvm.functions.Function0<kotlin.Unit>? >
- method @androidx.compose.Composable public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ public final class ZoomableController {
+ ctor public ZoomableController(androidx.animation.AnimationClockObservable animationClock, kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ method public kotlin.jvm.functions.Function1<java.lang.Float,kotlin.Unit> getOnZoomDelta();
+ method public void smoothScaleBy(float value, androidx.animation.AnimationSpec<java.lang.Float> spec = androidx.animation.SpringSpec(Spring.StiffnessLow), kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit>? >
+ method public void stopAnimation();
}
- public final class ZoomableState {
- ctor public ZoomableState(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta, androidx.animation.AnimationClockObservable animationClock);
- method public kotlin.jvm.functions.Function1<java.lang.Float,kotlin.Unit> getOnZoomDelta();
- method public void smoothScaleBy(float value, kotlin.jvm.functions.Function2<? super androidx.animation.AnimationEndReason,? super java.lang.Float,kotlin.Unit>? >
+ public final class ZoomableKt {
+ method @androidx.compose.Composable public static androidx.compose.foundation.gestures.ZoomableController rememberZoomableController(kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
+ method public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, androidx.compose.foundation.gestures.ZoomableController controller, boolean enabled = true, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function0<kotlin.Unit>? >
+ method public static androidx.ui.core.Modifier zoomable(androidx.ui.core.Modifier, boolean enabled = true, kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function0<kotlin.Unit>? kotlin.jvm.functions.Function1<? super java.lang.Float,kotlin.Unit> onZoomDelta);
}
}
diff --git a/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/FoundationDemos.kt b/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/FoundationDemos.kt
index b2d0212..14f0e3a 100644
--- a/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/FoundationDemos.kt
+++ b/ui/ui-foundation/integration-tests/foundation-demos/src/main/java/androidx/compose/foundation/demos/FoundationDemos.kt
@@ -24,7 +24,7 @@
import androidx.compose.foundation.samples.ScrollableColumnSample
val FoundationDemos = DemoCategory("Foundation", listOf(
- ComposableDemo("Draggable and Scrollable") { HighLevelGesturesDemo() },
+ ComposableDemo("Draggable, Scrollable, Zoomable") { HighLevelGesturesDemo() },
ComposableDemo("Scrollable Column") { ScrollableColumnSample() },
ComposableDemo("Controlled Scrollable Row") { ControlledScrollableRowSample() },
ComposableDemo("Dialog") { DialogSample() },
diff --git a/ui/ui-foundation/samples/src/main/java/androidx/compose/foundation/samples/ZoomableSample.kt b/ui/ui-foundation/samples/src/main/java/androidx/compose/foundation/samples/ZoomableSample.kt
index 3d9193a..fbc2b8b 100644
--- a/ui/ui-foundation/samples/src/main/java/androidx/compose/foundation/samples/ZoomableSample.kt
+++ b/ui/ui-foundation/samples/src/main/java/androidx/compose/foundation/samples/ZoomableSample.kt
@@ -18,6 +18,15 @@
import androidx.annotation.Sampled
import androidx.compose.Composable
+import androidx.compose.foundation.Box
+import androidx.compose.foundation.ContentGravity
+import androidx.compose.foundation.Text
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.drawBorder
+import androidx.compose.foundation.gestures.rememberZoomableController
+import androidx.compose.foundation.gestures.zoomable
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.preferredSize
import androidx.compose.getValue
import androidx.compose.setValue
import androidx.compose.state
@@ -25,16 +34,7 @@
import androidx.ui.core.Modifier
import androidx.ui.core.clipToBounds
import androidx.ui.core.drawLayer
-import androidx.compose.foundation.Box
-import androidx.compose.foundation.ContentGravity
-import androidx.compose.foundation.Text
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.drawBorder
-import androidx.compose.foundation.gestures.ZoomableState
-import androidx.compose.foundation.gestures.zoomable
import androidx.ui.graphics.Color
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.preferredSize
import androidx.ui.unit.dp
import androidx.ui.unit.sp
@@ -46,14 +46,13 @@
backgroundColor = Color.LightGray
) {
var scale by state(structuralEqualityPolicy()) { 1f }
- val zoomableState = ZoomableState { scale *= it }
-
+ val zoomableController = rememberZoomableController { scale *= it }
Box(
Modifier
- .zoomable(zoomableState)
+ .zoomable(zoomableController)
.clickable(
indication = null,
- zoomableState.smoothScaleBy(4f) },
+ zoomableController.smoothScaleBy(4f) },
>
)
.fillMaxSize()
diff --git a/ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ZoomableTest.kt b/ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ZoomableTest.kt
index 0dc4545..8dc3a65 100644
--- a/ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ZoomableTest.kt
+++ b/ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/ZoomableTest.kt
@@ -17,11 +17,12 @@
package androidx.compose.foundation
import androidx.compose.Composable
+import androidx.compose.mutableStateOf
import androidx.test.filters.SmallTest
import androidx.ui.core.Modifier
import androidx.ui.core.testTag
-import androidx.compose.foundation.gestures.ZoomableState
import androidx.compose.foundation.gestures.zoomable
+import androidx.compose.foundation.gestures.ZoomableController
import androidx.ui.geometry.Offset
import androidx.compose.foundation.layout.preferredSize
import androidx.ui.test.AnimationClockTestRule
@@ -35,6 +36,7 @@
import androidx.ui.test.size
import androidx.ui.unit.dp
import androidx.ui.unit.toSize
+import com.google.common.truth.Truth
import com.google.common.truth.Truth.assertWithMessage
import org.junit.Rule
import org.junit.Test
@@ -57,12 +59,12 @@
@Test
fun zoomable_zoomIn() {
var cumulativeScale = 1.0f
- val state = ZoomableState(
+ val controller = ZoomableController(
cumulativeScale *= it },
animationClock = clockRule.clock
)
- setZoomableContent { Modifier.zoomable(state) }
+ setZoomableContent { Modifier.zoomable(controller) }
onNodeWithTag(TEST_TAG).performGesture {
val leftStartX = center.x - 10
@@ -88,12 +90,12 @@
@Test
fun zoomable_zoomOut() {
var cumulativeScale = 1.0f
- val state = ZoomableState(
+ val controller = ZoomableController(
cumulativeScale *= it },
animationClock = clockRule.clock
)
- setZoomableContent { Modifier.zoomable(state) }
+ setZoomableContent { Modifier.zoomable(controller) }
onNodeWithTag(TEST_TAG).performGesture {
val leftStartX = size.toSize().width * EDGE_FUZZ_FACTOR
@@ -119,10 +121,159 @@
}
@Test
+ fun zoomable_startStop_notify() {
+ var cumulativeScale = 1.0f
+ var startTriggered = 0f
+ var stopTriggered = 0f
+ val controller = ZoomableController(
+ cumulativeScale *= it },
+ animationClock = clockRule.clock
+ )
+
+ setZoomableContent {
+ Modifier
+ .zoomable(controller = controller,
+ startTriggered++ },
+ stopTriggered++ }
+ )
+ }
+
+ runOnIdle {
+ Truth.assertThat(startTriggered).isEqualTo(0)
+ Truth.assertThat(stopTriggered).isEqualTo(0)
+ }
+
+ onNodeWithTag(TEST_TAG).performGesture {
+ val leftStartX = size.toSize().width * EDGE_FUZZ_FACTOR
+ val leftEndX = center.x - 10
+ val rightStartX = size.toSize().width * (1 - EDGE_FUZZ_FACTOR)
+ val rightEndX = center.x + 10
+
+ pinch(
+ Offset(leftStartX, center.y),
+ Offset(leftEndX, center.y),
+ Offset(rightStartX, center.y),
+ Offset(rightEndX, center.y)
+ )
+ }
+
+ clockRule.advanceClock(milliseconds = 1000)
+
+ runOnIdle {
+ Truth.assertThat(startTriggered).isEqualTo(1)
+ Truth.assertThat(stopTriggered).isEqualTo(1)
+ }
+ }
+
+ @Test
+ fun zoomable_disabledWontCallLambda() {
+ val enabled = mutableStateOf(true)
+ var cumulativeScale = 1.0f
+ val controller = ZoomableController(
+ cumulativeScale *= it },
+ animationClock = clockRule.clock
+ )
+
+ setZoomableContent {
+ Modifier
+ .zoomable(controller = controller, enabled = enabled.value)
+ }
+
+ onNodeWithTag(TEST_TAG).performGesture {
+ val leftStartX = center.x - 10
+ val leftEndX = size.toSize().width * EDGE_FUZZ_FACTOR
+ val rightStartX = center.x + 10
+ val rightEndX = size.toSize().width * (1 - EDGE_FUZZ_FACTOR)
+
+ pinch(
+ Offset(leftStartX, center.y),
+ Offset(leftEndX, center.y),
+ Offset(rightStartX, center.y),
+ Offset(rightEndX, center.y)
+ )
+ }
+
+ clockRule.advanceClock(milliseconds = 1000)
+
+ val prevScale = runOnIdle {
+ assertWithMessage("Should have scaled at least 4x").that(cumulativeScale).isAtLeast(4f)
+ enabled.value = false
+ cumulativeScale
+ }
+
+ onNodeWithTag(TEST_TAG).performGesture {
+ val leftStartX = size.toSize().width * EDGE_FUZZ_FACTOR
+ val leftEndX = center.x - 10
+ val rightStartX = size.toSize().width * (1 - EDGE_FUZZ_FACTOR)
+ val rightEndX = center.x + 10
+
+ pinch(
+ Offset(leftStartX, center.y),
+ Offset(leftEndX, center.y),
+ Offset(rightStartX, center.y),
+ Offset(rightEndX, center.y)
+ )
+ }
+
+ runOnIdle {
+ assertWithMessage("When enabled = false, scale should stay the same")
+ .that(cumulativeScale)
+ .isEqualTo(prevScale)
+ }
+ }
+
+ @Test
+ fun zoomable_callsStop_whenRemoved() {
+ var cumulativeScale = 1.0f
+ var stopTriggered = 0f
+ val controller = ZoomableController(
+ cumulativeScale *= it },
+ animationClock = clockRule.clock
+ )
+
+ setZoomableContent {
+ if (cumulativeScale < 2f) {
+ Modifier
+ .zoomable(
+ controller = controller,
+ stopTriggered++ }
+ )
+ } else {
+ Modifier
+ }
+ }
+
+ runOnIdle {
+ Truth.assertThat(stopTriggered).isEqualTo(0)
+ }
+
+ onNodeWithTag(TEST_TAG).performGesture {
+ val leftStartX = center.x - 10
+ val leftEndX = size.toSize().width * EDGE_FUZZ_FACTOR
+ val rightStartX = center.x + 10
+ val rightEndX = size.toSize().width * (1 - EDGE_FUZZ_FACTOR)
+
+ pinch(
+ Offset(leftStartX, center.y),
+ Offset(leftEndX, center.y),
+ Offset(rightStartX, center.y),
+ Offset(rightEndX, center.y)
+ )
+ }
+
+ clockRule.advanceClock(milliseconds = 1000)
+
+ runOnIdle {
+ Truth.assertThat(cumulativeScale).isAtLeast(2f)
+ Truth.assertThat(stopTriggered).isEqualTo(1f)
+ }
+ }
+
+ @Test
fun zoomable_animateTo() {
var cumulativeScale = 1.0f
var callbackCount = 0
- val state = ZoomableState(
+ val state = ZoomableController(
>
cumulativeScale *= it
callbackCount += 1
diff --git a/ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnItemsTest.kt b/ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnItemsTest.kt
index 764e111..eebe5b4 100644
--- a/ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnItemsTest.kt
+++ b/ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyColumnItemsTest.kt
@@ -29,11 +29,13 @@
import androidx.compose.foundation.Box
import androidx.compose.foundation.Text
import androidx.compose.foundation.layout.InnerPadding
+import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.preferredHeight
+import androidx.compose.foundation.layout.preferredSize
import androidx.compose.foundation.layout.size
import androidx.ui.test.SemanticsNodeInteraction
import androidx.ui.test.assertCountEquals
@@ -55,6 +57,7 @@
import androidx.ui.unit.dp
import com.google.common.collect.Range
import com.google.common.truth.IntegerSubject
+import com.google.common.truth.Truth
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertWithMessage
import org.junit.Rule
@@ -362,6 +365,65 @@
assertThat(itemBounds.top.toIntPx()).isWithin1PixelFrom(0)
assertThat(itemBounds.bottom.toIntPx()).isWithin1PixelFrom(50.dp.toIntPx())
}
+
+ @Test
+ fun lazyColumnWrapsContent() = with(composeTestRule.density) {
+ val itemInsideLazyColumn = "itemInsideLazyColumn"
+ val itemOutsideLazyColumn = "itemOutsideLazyColumn"
+ var sameSizeItems by mutableStateOf(true)
+
+ composeTestRule.setContent {
+ Row {
+ LazyColumnItems(
+ items = listOf(1, 2),
+ modifier = Modifier.testTag(LazyColumnItemsTag)
+ ) {
+ if (it == 1) {
+ Spacer(Modifier.preferredSize(50.dp).testTag(itemInsideLazyColumn))
+ } else {
+ Spacer(Modifier.preferredSize(if (sameSizeItems) 50.dp else 70.dp))
+ }
+ }
+ Spacer(Modifier.preferredSize(50.dp).testTag(itemOutsideLazyColumn))
+ }
+ }
+
+ onNodeWithTag(itemInsideLazyColumn)
+ .assertIsDisplayed()
+
+ onNodeWithTag(itemOutsideLazyColumn)
+ .assertIsDisplayed()
+
+ var lazyColumnBounds = onNodeWithTag(LazyColumnItemsTag)
+ .getBoundsInRoot()
+
+ Truth.assertThat(lazyColumnBounds.left.toIntPx()).isWithin1PixelFrom(0.dp.toIntPx())
+ Truth.assertThat(lazyColumnBounds.right.toIntPx()).isWithin1PixelFrom(50.dp.toIntPx())
+ Truth.assertThat(lazyColumnBounds.top.toIntPx()).isWithin1PixelFrom(0.dp.toIntPx())
+ // TODO: wrap-content on the main-axis must be implemented
+// Truth.assertThat(itemInsideBounds.bottom.toIntPx()).isWithin1PixelFrom(100.dp.toIntPx())
+
+ runOnIdle {
+ sameSizeItems = false
+ }
+
+ waitForIdle()
+
+ onNodeWithTag(itemInsideLazyColumn)
+ .assertIsDisplayed()
+
+ onNodeWithTag(itemOutsideLazyColumn)
+ .assertIsDisplayed()
+
+ lazyColumnBounds = onNodeWithTag(LazyColumnItemsTag)
+ .getBoundsInRoot()
+
+ Truth.assertThat(lazyColumnBounds.left.toIntPx()).isWithin1PixelFrom(0.dp.toIntPx())
+ Truth.assertThat(lazyColumnBounds.right.toIntPx()).isWithin1PixelFrom(70.dp.toIntPx())
+ Truth.assertThat(lazyColumnBounds.top.toIntPx()).isWithin1PixelFrom(0.dp.toIntPx())
+ // TODO: wrap-content on the main-axis must be implemented
+// Truth.assertThat(itemInsideBounds.bottom.toIntPx()).isWithin1PixelFrom(120.dp.toIntPx())
+ }
}
internal fun IntegerSubject.isWithin1PixelFrom(expected: Int) {
diff --git a/ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyRowItemsTest.kt b/ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyRowItemsTest.kt
index 7e16ea6..9cfe680 100644
--- a/ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyRowItemsTest.kt
+++ b/ui/ui-foundation/src/androidAndroidTest/kotlin/androidx/compose/foundation/lazy/LazyRowItemsTest.kt
@@ -16,6 +16,10 @@
package androidx.compose.foundation.lazy
+import androidx.compose.foundation.layout.Column
+import androidx.compose.getValue
+import androidx.compose.mutableStateOf
+import androidx.compose.setValue
import androidx.test.filters.MediumTest
import androidx.ui.core.Modifier
import androidx.ui.core.testTag
@@ -23,12 +27,15 @@
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.Stack
import androidx.compose.foundation.layout.fillMaxHeight
+import androidx.compose.foundation.layout.preferredSize
import androidx.compose.foundation.layout.preferredWidth
import androidx.compose.foundation.layout.size
import androidx.ui.test.assertIsDisplayed
import androidx.ui.test.createComposeRule
import androidx.ui.test.getBoundsInRoot
import androidx.ui.test.onNodeWithTag
+import androidx.ui.test.runOnIdle
+import androidx.ui.test.waitForIdle
import androidx.ui.unit.dp
import com.google.common.truth.Truth
import org.junit.Rule
@@ -189,4 +196,63 @@
Truth.assertThat(itemBounds.left.toIntPx()).isWithin1PixelFrom(0)
Truth.assertThat(itemBounds.right.toIntPx()).isWithin1PixelFrom(50.dp.toIntPx())
}
+
+ @Test
+ fun lazyRowWrapsContent() = with(composeTestRule.density) {
+ val itemInsideLazyRow = "itemInsideLazyRow"
+ val itemOutsideLazyRow = "itemOutsideLazyRow"
+ var sameSizeItems by mutableStateOf(true)
+
+ composeTestRule.setContent {
+ Column {
+ LazyRowItems(
+ items = listOf(1, 2),
+ modifier = Modifier.testTag(LazyRowItemsTag)
+ ) {
+ if (it == 1) {
+ Spacer(Modifier.preferredSize(50.dp).testTag(itemInsideLazyRow))
+ } else {
+ Spacer(Modifier.preferredSize(if (sameSizeItems) 50.dp else 70.dp))
+ }
+ }
+ Spacer(Modifier.preferredSize(50.dp).testTag(itemOutsideLazyRow))
+ }
+ }
+
+ onNodeWithTag(itemInsideLazyRow)
+ .assertIsDisplayed()
+
+ onNodeWithTag(itemOutsideLazyRow)
+ .assertIsDisplayed()
+
+ var lazyRowBounds = onNodeWithTag(LazyRowItemsTag)
+ .getBoundsInRoot()
+
+ Truth.assertThat(lazyRowBounds.left.toIntPx()).isWithin1PixelFrom(0.dp.toIntPx())
+ // TODO: wrap-content on the main-axis must be implemented
+// Truth.assertThat(lazyRowBounds.right.toIntPx()).isWithin1PixelFrom(100.dp.toIntPx())
+ Truth.assertThat(lazyRowBounds.top.toIntPx()).isWithin1PixelFrom(0.dp.toIntPx())
+ Truth.assertThat(lazyRowBounds.bottom.toIntPx()).isWithin1PixelFrom(50.dp.toIntPx())
+
+ runOnIdle {
+ sameSizeItems = false
+ }
+
+ waitForIdle()
+
+ onNodeWithTag(itemInsideLazyRow)
+ .assertIsDisplayed()
+
+ onNodeWithTag(itemOutsideLazyRow)
+ .assertIsDisplayed()
+
+ lazyRowBounds = onNodeWithTag(LazyRowItemsTag)
+ .getBoundsInRoot()
+
+ Truth.assertThat(lazyRowBounds.left.toIntPx()).isWithin1PixelFrom(0.dp.toIntPx())
+ // TODO: wrap-content on the main-axis must be implemented
+// Truth.assertThat(lazyRowBounds.right.toIntPx()).isWithin1PixelFrom(120.dp.toIntPx())
+ Truth.assertThat(lazyRowBounds.top.toIntPx()).isWithin1PixelFrom(0.dp.toIntPx())
+ Truth.assertThat(lazyRowBounds.bottom.toIntPx()).isWithin1PixelFrom(70.dp.toIntPx())
+ }
}
diff --git a/ui/ui-foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Scrollable.kt b/ui/ui-foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Scrollable.kt
index 7aee278..d739d8b 100644
--- a/ui/ui-foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Scrollable.kt
+++ b/ui/ui-foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Scrollable.kt
@@ -157,7 +157,7 @@
* @param controller [ScrollableController] object that is responsible for redirecting scroll
* deltas to [ScrollableController.consumeScrollDelta] callback and provides smooth scrolling
* capabilities
- * @param enabled whether of not scrolling in enabled
+ * @param enabled whether or not scrolling in enabled
* @param reverseDirection reverse the direction of the scroll, so top to bottom scroll will
* behave like bottom to top and left to right will behave like right to left.
* @param canScroll callback to indicate whether or not scroll is allowed for given [Direction]
diff --git a/ui/ui-foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Zoomable.kt b/ui/ui-foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Zoomable.kt
index cdaae83..3f093d2 100644
--- a/ui/ui-foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Zoomable.kt
+++ b/ui/ui-foundation/src/commonMain/kotlin/androidx/compose/foundation/gestures/Zoomable.kt
@@ -19,58 +19,75 @@
import androidx.animation.AnimatedFloat
import androidx.animation.AnimationClockObservable
import androidx.animation.AnimationEndReason
+import androidx.animation.AnimationSpec
import androidx.animation.Spring
import androidx.animation.SpringSpec
import androidx.compose.Composable
+import androidx.compose.onDispose
import androidx.compose.remember
import androidx.ui.animation.asDisposableClock
import androidx.ui.core.AnimationClockAmbient
import androidx.ui.core.Modifier
+import androidx.ui.core.composed
import androidx.ui.core.gesture.ScaleObserver
import androidx.ui.core.gesture.scaleGestureFilter
/**
- * Create [ZoomableState] with default [AnimationClockObservable].
+ * Create and remember [ZoomableController] with default [AnimationClockObservable].
*
* @param onZoomDelta callback to be invoked when pinch/smooth zooming occurs. The callback
* receives the delta as the ratio of the new size compared to the old. Callers should update
* their state and UI in this callback.
*/
@Composable
-fun ZoomableState(onZoomDelta: (Float) -> Unit): ZoomableState {
+fun rememberZoomableController(onZoomDelta: (Float) -> Unit): ZoomableController {
val clocks = AnimationClockAmbient.current.asDisposableClock()
- return remember(clocks) { ZoomableState(onZoomDelta, clocks) }
+ return remember(clocks) { ZoomableController(clocks, onZoomDelta) }
}
/**
- * State of the [zoomable] composable modifier. Provides smooth scaling capabilities.
+ * Controller to control [zoomable] modifier with. Provides smooth scaling capabilities.
*
+ * @param animationClock clock observable to run animation on. Consider querying
+ * [AnimationClockAmbient] to get current composition value
* @param onZoomDelta callback to be invoked when pinch/smooth zooming occurs. The callback
* receives the delta as the ratio of the new size compared to the old. Callers should update
* their state and UI in this callback.
- * @param animationClock clock observable to run animation on. Consider querying
- * [AnimationClockAmbient] to get current composition value
*/
-class ZoomableState(val onZoomDelta: (Float) -> Unit, animationClock: AnimationClockObservable) {
+class ZoomableController(
+ animationClock: AnimationClockObservable,
+ val onZoomDelta: (Float) -> Unit
+) {
/**
* Smooth scale by a ratio of [value] over the current size.
*
* @param value ratio over the current size by which to scale
+ * @param spec [AnimationSpec] to be used for smoothScale animation
* @pram [onEnd] callback invoked when the smooth scaling has ended
*/
fun smoothScaleBy(
value: Float,
+ spec: AnimationSpec<Float> = SpringSpec(stiffness = Spring.StiffnessLow),
onEnd: ((endReason: AnimationEndReason, finishValue: Float) -> Unit)? = null
) {
val to = animatedFloat.value * value
animatedFloat.animateTo(
to,
>
- anim = SpringSpec(stiffness = Spring.StiffnessLow)
+ anim = spec
)
}
+ /**
+ * Stop any ongoing animation or smooth scaling for this controller
+ *
+ * Call this to stop receiving scrollable deltas in [onZoomDelta]
+ */
+ fun stopAnimation() {
+ animatedFloat.stop()
+ }
+
internal fun onScale(scaleFactor: Float) = onZoomDelta(scaleFactor)
private val animatedFloat = DeltaAnimatedScale(1f, animationClock, ::onScale)
@@ -79,27 +96,56 @@
/**
* Enable zooming of the modified UI element.
*
- * [ZoomableState.onZoomDelta] will be invoked with the change in proportion of the UI element's
+ * [ZoomableController.onZoomDelta] will be invoked with the change in proportion of the UI element's
* size at each change in either ratio of the gesture or smooth scaling. Callers should update
* their state and UI in this callback.
*
* @sample androidx.compose.foundation.samples.ZoomableSample
*
- * @param zoomableState [ZoomableState] object that holds the internal state of this zoomable,
+ * @param controller [ZoomableController] object that holds the internal state of this zoomable,
* and provides smooth scaling capabilities.
+ * @param enabled whether zooming by gestures is enabled or not
+ * @param onZoomStarted callback to be invoked when zoom has started.
* @param onZoomStopped callback to be invoked when zoom has stopped.
*/
-@Composable
-fun Modifier.zoomable(zoomableState: ZoomableState, onZoomStopped: (() -> Unit)? = null): Modifier {
- return scaleGestureFilter(
- scaleObserver = object : ScaleObserver {
- override fun onScale(scaleFactor: Float) = zoomableState.onScale(scaleFactor)
+fun Modifier.zoomable(
+ controller: ZoomableController,
+ enabled: Boolean = true,
+ onZoomStarted: (() -> Unit)? = null,
+ onZoomStopped: (() -> Unit)? = null
+) = composed {
+ onDispose {
+ controller.stopAnimation()
+ }
+ scaleGestureFilter(
+ scaleObserver = object : ScaleObserver {
+ override fun onScale(scaleFactor: Float) {
+ if (enabled) {
+ controller.stopAnimation()
+ controller.onScale(scaleFactor)
+ }
+ }
- override fun onStop() {
+ override fun onStop() {
+ if (enabled) {
onZoomStopped?.invoke()
}
}
- )
+
+ override fun onCancel() {
+ if (enabled) {
+ onZoomStopped?.invoke()
+ }
+ }
+
+ override fun onStart() {
+ if (enabled) {
+ controller.stopAnimation()
+ onZoomStarted?.invoke()
+ }
+ }
+ }
+ )
}
/**
@@ -111,16 +157,26 @@
*
* @sample androidx.compose.foundation.samples.ZoomableSample
*
+ * @param enabled whether zooming by gestures is enabled or not
+ * @param onZoomStarted callback to be invoked when zoom has started.
* @param onZoomStopped callback to be invoked when zoom has stopped.
* @param onZoomDelta callback to be invoked when pinch/smooth zooming occurs. The callback
* receives the delta as the ratio of the new size compared to the old. Callers should update
* their state and UI in this callback.
*/
-@Composable
fun Modifier.zoomable(
+ enabled: Boolean = true,
+ onZoomStarted: (() -> Unit)? = null,
onZoomStopped: (() -> Unit)? = null,
onZoomDelta: (Float) -> Unit
-) = Modifier.zoomable(ZoomableState(onZoomDelta), onZoomStopped)
+) = composed {
+ Modifier.zoomable(
+ controller = rememberZoomableController(onZoomDelta),
+ enabled = enabled,
+ >
+ >
+ )
+}
private class DeltaAnimatedScale(
initial: Float,
diff --git a/ui/ui-foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemsState.kt b/ui/ui-foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemsState.kt
index fde5436..3b759e3 100644
--- a/ui/ui-foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemsState.kt
+++ b/ui/ui-foundation/src/commonMain/kotlin/androidx/compose/foundation/lazy/LazyItemsState.kt
@@ -33,8 +33,11 @@
import androidx.ui.core.Ref
import androidx.ui.core.Remeasurement
import androidx.ui.core.RemeasurementModifier
+import androidx.ui.core.constrainHeight
+import androidx.ui.core.constrainWidth
import androidx.ui.core.subcomposeInto
import kotlin.math.abs
+import kotlin.math.max
import kotlin.math.roundToInt
private inline class ScrollDirection(val isForward: Boolean)
@@ -302,6 +305,7 @@
}
var mainAxisUsed = (-firstItemScrollOffset).roundToInt()
+ var maxCrossAxis = 0
// The index of the first item that should be displayed, regardless of what is
// currently displayed. Will be moved forward as we determine what's offscreen
@@ -318,6 +322,8 @@
val childMainAxisSize = placeable.mainAxisSize
mainAxisUsed += childMainAxisSize
+ maxCrossAxis = max(maxCrossAxis, placeable.crossAxisSize)
+
if (mainAxisUsed < 0f) {
// this item is offscreen, remove it and the offset it took up
itemIndexOffset = index + 1
@@ -357,7 +363,19 @@
)
}
- return measureScope.layout(constraints.maxWidth, constraints.maxHeight) {
+ // Wrap the content of the children on the cross axis
+ val layoutWidth = if (isVertical) {
+ constraints.constrainWidth(maxCrossAxis)
+ } else {
+ constraints.maxWidth
+ }
+ val layoutHeight = if (!isVertical) {
+ constraints.constrainHeight(maxCrossAxis)
+ } else {
+ constraints.maxHeight
+ }
+
+ return measureScope.layout(layoutWidth, layoutHeight) {
val currentMainAxis = (-firstItemScrollOffset).roundToInt()
var x = if (isVertical) 0 else currentMainAxis
var y = if (!isVertical) 0 else currentMainAxis
diff --git a/ui/ui-test/src/androidTest/java/androidx/ui/test/assertions/BoundsAssertionsTest.kt b/ui/ui-test/src/androidTest/java/androidx/ui/test/assertions/BoundsAssertionsTest.kt
index 66ac801..53110bf 100644
--- a/ui/ui-test/src/androidTest/java/androidx/ui/test/assertions/BoundsAssertionsTest.kt
+++ b/ui/ui-test/src/androidTest/java/androidx/ui/test/assertions/BoundsAssertionsTest.kt
@@ -19,11 +19,14 @@
import androidx.test.filters.MediumTest
import androidx.ui.core.Alignment
import androidx.ui.core.Modifier
+import androidx.ui.core.clipToBounds
import androidx.ui.core.testTag
import androidx.compose.foundation.Box
import androidx.compose.foundation.background
import androidx.ui.graphics.Color
import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.ltr
+import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.wrapContentSize
@@ -60,7 +63,7 @@
.fillMaxSize()
.wrapContentSize(Alignment.TopStart)
) {
- Box(modifier = Modifier.padding(start = 50.dp, top = 100.dp)) {
+ Box(modifier = Modifier.ltr.padding(start = 50.dp, top = 100.dp)) {
Box(modifier = Modifier
.testTag(tag)
.size(80.dp, 100.dp)
@@ -99,7 +102,7 @@
}
@Test
- fun assertEquals() {
+ fun assertSizeEquals() {
composeBox()
onNodeWithTag(tag)
@@ -108,7 +111,7 @@
}
@Test
- fun assertAtLeast() {
+ fun assertSizeAtLeast() {
composeBox()
onNodeWithTag(tag)
@@ -119,7 +122,7 @@
}
@Test
- fun assertEquals_fail() {
+ fun assertSizeEquals_fail() {
composeBox()
expectError<AssertionError> {
@@ -134,7 +137,7 @@
}
@Test
- fun assertAtLeast_fail() {
+ fun assertSizeAtLeast_fail() {
composeBox()
expectError<AssertionError> {
@@ -172,4 +175,43 @@
.assertPositionInRootIsEqualTo(expectedLeft = 49.dp, expectedTop = 99.dp)
}
}
-}
\ No newline at end of file
+
+ private fun composeClippedBox() {
+ composeTestRule.setContent {
+ Box(modifier = Modifier
+ .fillMaxSize()
+ .clipToBounds()
+ .wrapContentSize(Alignment.TopStart)
+ ) {
+ // Box is shifted 30dp to the left and 10dp to the top,
+ // so it is clipped to a size of 50 x 90
+ Box(modifier = Modifier
+ .testTag(tag)
+ .ltr
+ .offset((-30).dp, (-10).dp)
+ .size(80.dp, 100.dp)
+ .background(color = Color.Black)
+ )
+ }
+ }
+ }
+
+ @Test
+ fun assertClippedPosition() {
+ composeClippedBox()
+
+ onNodeWithTag(tag)
+ .assertPositionInRootIsEqualTo(expectedLeft = (-30).dp, expectedTop = (-10).dp)
+ .assertLeftPositionInRootIsEqualTo((-30).dp)
+ .assertTopPositionInRootIsEqualTo((-10).dp)
+ }
+
+ @Test
+ fun assertClippedSize() {
+ composeClippedBox()
+
+ onNodeWithTag(tag)
+ .assertWidthIsEqualTo(80.dp)
+ .assertHeightIsEqualTo(100.dp)
+ }
+}
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/Assertions.kt b/ui/ui-test/src/main/java/androidx/ui/test/Assertions.kt
index a5641aa..5515009 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/Assertions.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/Assertions.kt
@@ -328,7 +328,7 @@
}
@OptIn(ExperimentalLayoutNodeApi::class)
-private fun SemanticsNode.nodeBoundsInWindow(): Rect {
+private fun SemanticsNode.clippedNodeBoundsInWindow(): Rect {
val composeView = (componentNode.owner as AndroidOwner).view
val rootLocationInWindow = intArrayOf(0, 0).let {
composeView.getLocationInWindow(it)
@@ -342,7 +342,7 @@
val composeView = (componentNode.owner as AndroidOwner).view
// Window relative bounds of our node
- val nodeBoundsInWindow = nodeBoundsInWindow()
+ val nodeBoundsInWindow = clippedNodeBoundsInWindow()
if (nodeBoundsInWindow.width == 0f || nodeBoundsInWindow.height == 0f) {
return false
}
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/BoundsAssertions.kt b/ui/ui-test/src/main/java/androidx/ui/test/BoundsAssertions.kt
index 4555bf6..27fa5a9 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/BoundsAssertions.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/BoundsAssertions.kt
@@ -25,6 +25,7 @@
import androidx.ui.unit.Dp
import androidx.ui.unit.PxBounds
import androidx.ui.unit.height
+import androidx.ui.unit.toSize
import androidx.ui.unit.width
import kotlin.math.absoluteValue
@@ -205,6 +206,11 @@
}
}
+private val SemanticsNode.unclippedBoundsInRoot: PxBounds
+ get() {
+ return PxBounds(positionInRoot, size.toSize())
+ }
+
private fun <R> SemanticsNodeInteraction.withDensity(
operation: Density.(SemanticsNode) -> R
): R {
@@ -221,7 +227,7 @@
@OptIn(ExperimentalLayoutNodeApi::class)
val density = (node.componentNode.owner as AndroidOwner).density
- assertion.invoke(density, node.boundsInRoot)
+ assertion.invoke(density, node.unclippedBoundsInRoot)
return this
}
diff --git a/ui/ui-test/src/main/java/androidx/ui/test/Output.kt b/ui/ui-test/src/main/java/androidx/ui/test/Output.kt
index c0b05a1..6778ad5 100644
--- a/ui/ui-test/src/main/java/androidx/ui/test/Output.kt
+++ b/ui/ui-test/src/main/java/androidx/ui/test/Output.kt
@@ -23,6 +23,7 @@
import androidx.ui.semantics.SemanticsProperties
import androidx.ui.text.AnnotatedString
import androidx.ui.unit.PxBounds
+import androidx.ui.unit.toSize
/**
* Prints all the semantics nodes information it holds into string.
@@ -154,7 +155,7 @@
sb.append("$nestingIndent |-")
}
sb.append("Node #$id at ")
- sb.append(pxBoundsToShortString(globalBounds))
+ sb.append(pxBoundsToShortString(unclippedGlobalBounds))
if (config.contains(SemanticsProperties.TestTag)) {
sb.append(", Tag: '")
@@ -201,6 +202,11 @@
}
}
+private val SemanticsNode.unclippedGlobalBounds: PxBounds
+ get() {
+ return PxBounds(globalPosition, size.toSize())
+ }
+
private fun pxBoundsToShortString(bounds: PxBounds): String {
return "(${bounds.left}, ${bounds.top}, ${bounds.right}, ${bounds.bottom})px"
}
diff --git a/webkit/webkit/api/1.4.0-alpha01.txt b/webkit/webkit/api/1.4.0-alpha01.txt
new file mode 100644
index 0000000..57f9939
--- /dev/null
+++ b/webkit/webkit/api/1.4.0-alpha01.txt
@@ -0,0 +1,270 @@
+// Signature format: 3.0
+package androidx.webkit {
+
+ public abstract class JavaScriptReplyProxy {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(String);
+ }
+
+ public final class ProxyConfig {
+ method public java.util.List<java.lang.String!> getBypassRules();
+ method public java.util.List<androidx.webkit.ProxyConfig.ProxyRule!> getProxyRules();
+ field public static final String MATCH_ALL_SCHEMES = "*";
+ field public static final String MATCH_HTTP = "http";
+ field public static final String MATCH_HTTPS = "https";
+ }
+
+ public static final class ProxyConfig.Builder {
+ ctor public ProxyConfig.Builder();
+ ctor public ProxyConfig.Builder(androidx.webkit.ProxyConfig);
+ method public androidx.webkit.ProxyConfig.Builder addBypassRule(String);
+ method public androidx.webkit.ProxyConfig.Builder addDirect(String);
+ method public androidx.webkit.ProxyConfig.Builder addDirect();
+ method public androidx.webkit.ProxyConfig.Builder addProxyRule(String);
+ method public androidx.webkit.ProxyConfig.Builder addProxyRule(String, String);
+ method public androidx.webkit.ProxyConfig build();
+ method public androidx.webkit.ProxyConfig.Builder bypassSimpleHostnames();
+ method public androidx.webkit.ProxyConfig.Builder removeImplicitRules();
+ }
+
+ public static final class ProxyConfig.ProxyRule {
+ method public String getSchemeFilter();
+ method public String getUrl();
+ }
+
+ public abstract class ProxyController {
+ method public abstract void clearProxyOverride(java.util.concurrent.Executor, Runnable);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.PROXY_OVERRIDE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ProxyController getInstance();
+ method public abstract void setProxyOverride(androidx.webkit.ProxyConfig, java.util.concurrent.Executor, Runnable);
+ }
+
+ public abstract class SafeBrowsingResponseCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void backToSafety(boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void proceed(boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void showInterstitial(boolean);
+ }
+
+ public abstract class ServiceWorkerClientCompat {
+ ctor public ServiceWorkerClientCompat();
+ method @WorkerThread public abstract android.webkit.WebResourceResponse? shouldInterceptRequest(android.webkit.WebResourceRequest);
+ }
+
+ public abstract class ServiceWorkerControllerCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ServiceWorkerControllerCompat getInstance();
+ method public abstract androidx.webkit.ServiceWorkerWebSettingsCompat getServiceWorkerWebSettings();
+ method public abstract void setServiceWorkerClient(androidx.webkit.ServiceWorkerClientCompat?);
+ }
+
+ public abstract class ServiceWorkerWebSettingsCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowContentAccess();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowFileAccess();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getBlockNetworkLoads();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getCacheMode();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowContentAccess(boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowFileAccess(boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setBlockNetworkLoads(boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setCacheMode(int);
+ }
+
+ public class TracingConfig {
+ method public java.util.List<java.lang.String!> getCustomIncludedCategories();
+ method public int getPredefinedCategories();
+ method public int getTracingMode();
+ field public static final int CATEGORIES_ALL = 1; // 0x1
+ field public static final int CATEGORIES_ANDROID_WEBVIEW = 2; // 0x2
+ field public static final int CATEGORIES_FRAME_VIEWER = 64; // 0x40
+ field public static final int CATEGORIES_INPUT_LATENCY = 8; // 0x8
+ field public static final int CATEGORIES_JAVASCRIPT_AND_RENDERING = 32; // 0x20
+ field public static final int CATEGORIES_NONE = 0; // 0x0
+ field public static final int CATEGORIES_RENDERING = 16; // 0x10
+ field public static final int CATEGORIES_WEB_DEVELOPER = 4; // 0x4
+ field public static final int RECORD_CONTINUOUSLY = 1; // 0x1
+ field public static final int RECORD_UNTIL_FULL = 0; // 0x0
+ }
+
+ public static class TracingConfig.Builder {
+ ctor public TracingConfig.Builder();
+ method public androidx.webkit.TracingConfig.Builder addCategories(int...);
+ method public androidx.webkit.TracingConfig.Builder addCategories(java.lang.String!...);
+ method public androidx.webkit.TracingConfig.Builder addCategories(java.util.Collection<java.lang.String!>);
+ method public androidx.webkit.TracingConfig build();
+ method public androidx.webkit.TracingConfig.Builder setTracingMode(int);
+ }
+
+ public abstract class TracingController {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.TRACING_CONTROLLER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.TracingController getInstance();
+ method public abstract boolean isTracing();
+ method public abstract void start(androidx.webkit.TracingConfig);
+ method public abstract boolean stop(java.io.OutputStream?, java.util.concurrent.Executor);
+ }
+
+ public class WebMessageCompat {
+ ctor public WebMessageCompat(String?);
+ ctor public WebMessageCompat(String?, androidx.webkit.WebMessagePortCompat![]?);
+ method public String? getData();
+ method public androidx.webkit.WebMessagePortCompat![]? getPorts();
+ }
+
+ public abstract class WebMessagePortCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_CLOSE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void close();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_POST_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(androidx.webkit.WebMessageCompat);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(android.os.Handler?, androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
+ }
+
+ public abstract static class WebMessagePortCompat.WebMessageCallbackCompat {
+ ctor public WebMessagePortCompat.WebMessageCallbackCompat();
+ method public void onMessage(androidx.webkit.WebMessagePortCompat, androidx.webkit.WebMessageCompat?);
+ }
+
+ public abstract class WebResourceErrorCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract CharSequence getDescription();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getErrorCode();
+ }
+
+ public class WebResourceRequestCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isRedirect(android.webkit.WebResourceRequest);
+ }
+
+ public class WebSettingsCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getDisabledActionModeMenuItems(android.webkit.WebSettings);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getForceDark(android.webkit.WebSettings);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK_STRATEGY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getForceDarkStrategy(android.webkit.WebSettings);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getOffscreenPreRaster(android.webkit.WebSettings);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getSafeBrowsingEnabled(android.webkit.WebSettings);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setDisabledActionModeMenuItems(android.webkit.WebSettings, int);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setForceDark(android.webkit.WebSettings, int);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK_STRATEGY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setForceDarkStrategy(android.webkit.WebSettings, int);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setOffscreenPreRaster(android.webkit.WebSettings, boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingEnabled(android.webkit.WebSettings, boolean);
+ field public static final int DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING = 2; // 0x2
+ field public static final int DARK_STRATEGY_USER_AGENT_DARKENING_ONLY = 0; // 0x0
+ field public static final int DARK_STRATEGY_WEB_THEME_DARKENING_ONLY = 1; // 0x1
+ field public static final int FORCE_DARK_AUTO = 1; // 0x1
+ field public static final int FORCE_DARK_OFF = 0; // 0x0
+ field public static final int FORCE_DARK_ON = 2; // 0x2
+ }
+
+ public final class WebViewAssetLoader {
+ method @WorkerThread public android.webkit.WebResourceResponse? shouldInterceptRequest(android.net.Uri);
+ field public static final String DEFAULT_DOMAIN = "appassets.androidplatform.net";
+ }
+
+ public static final class WebViewAssetLoader.AssetsPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+ ctor public WebViewAssetLoader.AssetsPathHandler(android.content.Context);
+ method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+ }
+
+ public static final class WebViewAssetLoader.Builder {
+ ctor public WebViewAssetLoader.Builder();
+ method public androidx.webkit.WebViewAssetLoader.Builder addPathHandler(String, androidx.webkit.WebViewAssetLoader.PathHandler);
+ method public androidx.webkit.WebViewAssetLoader build();
+ method public androidx.webkit.WebViewAssetLoader.Builder setDomain(String);
+ method public androidx.webkit.WebViewAssetLoader.Builder setHttpAllowed(boolean);
+ }
+
+ public static final class WebViewAssetLoader.InternalStoragePathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+ ctor public WebViewAssetLoader.InternalStoragePathHandler(android.content.Context, java.io.File);
+ method @WorkerThread public android.webkit.WebResourceResponse handle(String);
+ }
+
+ public static interface WebViewAssetLoader.PathHandler {
+ method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+ }
+
+ public static final class WebViewAssetLoader.ResourcesPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+ ctor public WebViewAssetLoader.ResourcesPathHandler(android.content.Context);
+ method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+ }
+
+ public class WebViewClientCompat extends android.webkit.WebViewClient {
+ ctor public WebViewClientCompat();
+ method @RequiresApi(23) public final void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceError);
+ method @RequiresApi(21) @UiThread public void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, androidx.webkit.WebResourceErrorCompat);
+ method @RequiresApi(27) public final void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, android.webkit.SafeBrowsingResponse);
+ method @UiThread public void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, androidx.webkit.SafeBrowsingResponseCompat);
+ }
+
+ public class WebViewCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void addWebMessageListener(android.webkit.WebView, String, java.util.Set<java.lang.String!>, androidx.webkit.WebViewCompat.WebMessageListener);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebMessagePortCompat![] createWebMessageChannel(android.webkit.WebView);
+ method public static android.content.pm.PackageInfo? getCurrentWebViewPackage(android.content.Context);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.net.Uri getSafeBrowsingPrivacyPolicyUrl();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_CHROME_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebChromeClient? getWebChromeClient(android.webkit.WebView);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebViewClient getWebViewClient(android.webkit.WebView);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_RENDERER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcess? getWebViewRenderProcess(android.webkit.WebView);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcessClient? getWebViewRenderProcessClient(android.webkit.WebView);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isMultiProcessEnabled();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.VISUAL_STATE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postVisualStateCallback(android.webkit.WebView, long, androidx.webkit.WebViewCompat.VisualStateCallback);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.POST_WEB_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postWebMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void removeWebMessageListener(android.webkit.WebView, String);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_WHITELIST, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingWhitelist(java.util.List<java.lang.String!>, android.webkit.ValueCallback<java.lang.Boolean!>?);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, java.util.concurrent.Executor, androidx.webkit.WebViewRenderProcessClient);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, androidx.webkit.WebViewRenderProcessClient?);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.START_SAFE_BROWSING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void startSafeBrowsing(android.content.Context, android.webkit.ValueCallback<java.lang.Boolean!>?);
+ }
+
+ public static interface WebViewCompat.VisualStateCallback {
+ method @UiThread public void onComplete(long);
+ }
+
+ public static interface WebViewCompat.WebMessageListener {
+ method @UiThread public void onPostMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri, boolean, androidx.webkit.JavaScriptReplyProxy);
+ }
+
+ public class WebViewFeature {
+ method public static boolean isFeatureSupported(String);
+ field public static final String CREATE_WEB_MESSAGE_CHANNEL = "CREATE_WEB_MESSAGE_CHANNEL";
+ field public static final String DISABLED_ACTION_MODE_MENU_ITEMS = "DISABLED_ACTION_MODE_MENU_ITEMS";
+ field public static final String FORCE_DARK = "FORCE_DARK";
+ field public static final String FORCE_DARK_STRATEGY = "FORCE_DARK_STRATEGY";
+ field public static final String GET_WEB_CHROME_CLIENT = "GET_WEB_CHROME_CLIENT";
+ field public static final String GET_WEB_VIEW_CLIENT = "GET_WEB_VIEW_CLIENT";
+ field public static final String GET_WEB_VIEW_RENDERER = "GET_WEB_VIEW_RENDERER";
+ field public static final String MULTI_PROCESS = "MULTI_PROCESS";
+ field public static final String OFF_SCREEN_PRERASTER = "OFF_SCREEN_PRERASTER";
+ field public static final String POST_WEB_MESSAGE = "POST_WEB_MESSAGE";
+ field public static final String PROXY_OVERRIDE = "PROXY_OVERRIDE";
+ field public static final String RECEIVE_HTTP_ERROR = "RECEIVE_HTTP_ERROR";
+ field public static final String RECEIVE_WEB_RESOURCE_ERROR = "RECEIVE_WEB_RESOURCE_ERROR";
+ field public static final String SAFE_BROWSING_ENABLE = "SAFE_BROWSING_ENABLE";
+ field public static final String SAFE_BROWSING_HIT = "SAFE_BROWSING_HIT";
+ field public static final String SAFE_BROWSING_PRIVACY_POLICY_URL = "SAFE_BROWSING_PRIVACY_POLICY_URL";
+ field public static final String SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY = "SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY";
+ field public static final String SAFE_BROWSING_RESPONSE_PROCEED = "SAFE_BROWSING_RESPONSE_PROCEED";
+ field public static final String SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL = "SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL";
+ field public static final String SAFE_BROWSING_WHITELIST = "SAFE_BROWSING_WHITELIST";
+ field public static final String SERVICE_WORKER_BASIC_USAGE = "SERVICE_WORKER_BASIC_USAGE";
+ field public static final String SERVICE_WORKER_BLOCK_NETWORK_LOADS = "SERVICE_WORKER_BLOCK_NETWORK_LOADS";
+ field public static final String SERVICE_WORKER_CACHE_MODE = "SERVICE_WORKER_CACHE_MODE";
+ field public static final String SERVICE_WORKER_CONTENT_ACCESS = "SERVICE_WORKER_CONTENT_ACCESS";
+ field public static final String SERVICE_WORKER_FILE_ACCESS = "SERVICE_WORKER_FILE_ACCESS";
+ field public static final String SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST = "SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST";
+ field public static final String SHOULD_OVERRIDE_WITH_REDIRECTS = "SHOULD_OVERRIDE_WITH_REDIRECTS";
+ field public static final String START_SAFE_BROWSING = "START_SAFE_BROWSING";
+ field public static final String TRACING_CONTROLLER_BASIC_USAGE = "TRACING_CONTROLLER_BASIC_USAGE";
+ field public static final String VISUAL_STATE_CALLBACK = "VISUAL_STATE_CALLBACK";
+ field public static final String WEB_MESSAGE_CALLBACK_ON_MESSAGE = "WEB_MESSAGE_CALLBACK_ON_MESSAGE";
+ field public static final String WEB_MESSAGE_LISTENER = "WEB_MESSAGE_LISTENER";
+ field public static final String WEB_MESSAGE_PORT_CLOSE = "WEB_MESSAGE_PORT_CLOSE";
+ field public static final String WEB_MESSAGE_PORT_POST_MESSAGE = "WEB_MESSAGE_PORT_POST_MESSAGE";
+ field public static final String WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK = "WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK";
+ field public static final String WEB_RESOURCE_ERROR_GET_CODE = "WEB_RESOURCE_ERROR_GET_CODE";
+ field public static final String WEB_RESOURCE_ERROR_GET_DESCRIPTION = "WEB_RESOURCE_ERROR_GET_DESCRIPTION";
+ field public static final String WEB_RESOURCE_REQUEST_IS_REDIRECT = "WEB_RESOURCE_REQUEST_IS_REDIRECT";
+ field public static final String WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE = "WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE";
+ field public static final String WEB_VIEW_RENDERER_TERMINATE = "WEB_VIEW_RENDERER_TERMINATE";
+ }
+
+ public abstract class WebViewRenderProcess {
+ ctor public WebViewRenderProcess();
+ method public abstract boolean terminate();
+ }
+
+ public abstract class WebViewRenderProcessClient {
+ ctor public WebViewRenderProcessClient();
+ method public abstract void onRenderProcessResponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
+ method public abstract void onRenderProcessUnresponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
+ }
+
+}
+
diff --git a/webkit/webkit/api/public_plus_experimental_1.4.0-alpha01.txt b/webkit/webkit/api/public_plus_experimental_1.4.0-alpha01.txt
new file mode 100644
index 0000000..57f9939
--- /dev/null
+++ b/webkit/webkit/api/public_plus_experimental_1.4.0-alpha01.txt
@@ -0,0 +1,270 @@
+// Signature format: 3.0
+package androidx.webkit {
+
+ public abstract class JavaScriptReplyProxy {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(String);
+ }
+
+ public final class ProxyConfig {
+ method public java.util.List<java.lang.String!> getBypassRules();
+ method public java.util.List<androidx.webkit.ProxyConfig.ProxyRule!> getProxyRules();
+ field public static final String MATCH_ALL_SCHEMES = "*";
+ field public static final String MATCH_HTTP = "http";
+ field public static final String MATCH_HTTPS = "https";
+ }
+
+ public static final class ProxyConfig.Builder {
+ ctor public ProxyConfig.Builder();
+ ctor public ProxyConfig.Builder(androidx.webkit.ProxyConfig);
+ method public androidx.webkit.ProxyConfig.Builder addBypassRule(String);
+ method public androidx.webkit.ProxyConfig.Builder addDirect(String);
+ method public androidx.webkit.ProxyConfig.Builder addDirect();
+ method public androidx.webkit.ProxyConfig.Builder addProxyRule(String);
+ method public androidx.webkit.ProxyConfig.Builder addProxyRule(String, String);
+ method public androidx.webkit.ProxyConfig build();
+ method public androidx.webkit.ProxyConfig.Builder bypassSimpleHostnames();
+ method public androidx.webkit.ProxyConfig.Builder removeImplicitRules();
+ }
+
+ public static final class ProxyConfig.ProxyRule {
+ method public String getSchemeFilter();
+ method public String getUrl();
+ }
+
+ public abstract class ProxyController {
+ method public abstract void clearProxyOverride(java.util.concurrent.Executor, Runnable);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.PROXY_OVERRIDE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ProxyController getInstance();
+ method public abstract void setProxyOverride(androidx.webkit.ProxyConfig, java.util.concurrent.Executor, Runnable);
+ }
+
+ public abstract class SafeBrowsingResponseCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void backToSafety(boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void proceed(boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void showInterstitial(boolean);
+ }
+
+ public abstract class ServiceWorkerClientCompat {
+ ctor public ServiceWorkerClientCompat();
+ method @WorkerThread public abstract android.webkit.WebResourceResponse? shouldInterceptRequest(android.webkit.WebResourceRequest);
+ }
+
+ public abstract class ServiceWorkerControllerCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ServiceWorkerControllerCompat getInstance();
+ method public abstract androidx.webkit.ServiceWorkerWebSettingsCompat getServiceWorkerWebSettings();
+ method public abstract void setServiceWorkerClient(androidx.webkit.ServiceWorkerClientCompat?);
+ }
+
+ public abstract class ServiceWorkerWebSettingsCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowContentAccess();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowFileAccess();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getBlockNetworkLoads();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getCacheMode();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowContentAccess(boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowFileAccess(boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setBlockNetworkLoads(boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setCacheMode(int);
+ }
+
+ public class TracingConfig {
+ method public java.util.List<java.lang.String!> getCustomIncludedCategories();
+ method public int getPredefinedCategories();
+ method public int getTracingMode();
+ field public static final int CATEGORIES_ALL = 1; // 0x1
+ field public static final int CATEGORIES_ANDROID_WEBVIEW = 2; // 0x2
+ field public static final int CATEGORIES_FRAME_VIEWER = 64; // 0x40
+ field public static final int CATEGORIES_INPUT_LATENCY = 8; // 0x8
+ field public static final int CATEGORIES_JAVASCRIPT_AND_RENDERING = 32; // 0x20
+ field public static final int CATEGORIES_NONE = 0; // 0x0
+ field public static final int CATEGORIES_RENDERING = 16; // 0x10
+ field public static final int CATEGORIES_WEB_DEVELOPER = 4; // 0x4
+ field public static final int RECORD_CONTINUOUSLY = 1; // 0x1
+ field public static final int RECORD_UNTIL_FULL = 0; // 0x0
+ }
+
+ public static class TracingConfig.Builder {
+ ctor public TracingConfig.Builder();
+ method public androidx.webkit.TracingConfig.Builder addCategories(int...);
+ method public androidx.webkit.TracingConfig.Builder addCategories(java.lang.String!...);
+ method public androidx.webkit.TracingConfig.Builder addCategories(java.util.Collection<java.lang.String!>);
+ method public androidx.webkit.TracingConfig build();
+ method public androidx.webkit.TracingConfig.Builder setTracingMode(int);
+ }
+
+ public abstract class TracingController {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.TRACING_CONTROLLER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.TracingController getInstance();
+ method public abstract boolean isTracing();
+ method public abstract void start(androidx.webkit.TracingConfig);
+ method public abstract boolean stop(java.io.OutputStream?, java.util.concurrent.Executor);
+ }
+
+ public class WebMessageCompat {
+ ctor public WebMessageCompat(String?);
+ ctor public WebMessageCompat(String?, androidx.webkit.WebMessagePortCompat![]?);
+ method public String? getData();
+ method public androidx.webkit.WebMessagePortCompat![]? getPorts();
+ }
+
+ public abstract class WebMessagePortCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_CLOSE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void close();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_POST_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(androidx.webkit.WebMessageCompat);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(android.os.Handler?, androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
+ }
+
+ public abstract static class WebMessagePortCompat.WebMessageCallbackCompat {
+ ctor public WebMessagePortCompat.WebMessageCallbackCompat();
+ method public void onMessage(androidx.webkit.WebMessagePortCompat, androidx.webkit.WebMessageCompat?);
+ }
+
+ public abstract class WebResourceErrorCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract CharSequence getDescription();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getErrorCode();
+ }
+
+ public class WebResourceRequestCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isRedirect(android.webkit.WebResourceRequest);
+ }
+
+ public class WebSettingsCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getDisabledActionModeMenuItems(android.webkit.WebSettings);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getForceDark(android.webkit.WebSettings);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK_STRATEGY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getForceDarkStrategy(android.webkit.WebSettings);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getOffscreenPreRaster(android.webkit.WebSettings);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getSafeBrowsingEnabled(android.webkit.WebSettings);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setDisabledActionModeMenuItems(android.webkit.WebSettings, int);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setForceDark(android.webkit.WebSettings, int);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK_STRATEGY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setForceDarkStrategy(android.webkit.WebSettings, int);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setOffscreenPreRaster(android.webkit.WebSettings, boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingEnabled(android.webkit.WebSettings, boolean);
+ field public static final int DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING = 2; // 0x2
+ field public static final int DARK_STRATEGY_USER_AGENT_DARKENING_ONLY = 0; // 0x0
+ field public static final int DARK_STRATEGY_WEB_THEME_DARKENING_ONLY = 1; // 0x1
+ field public static final int FORCE_DARK_AUTO = 1; // 0x1
+ field public static final int FORCE_DARK_OFF = 0; // 0x0
+ field public static final int FORCE_DARK_ON = 2; // 0x2
+ }
+
+ public final class WebViewAssetLoader {
+ method @WorkerThread public android.webkit.WebResourceResponse? shouldInterceptRequest(android.net.Uri);
+ field public static final String DEFAULT_DOMAIN = "appassets.androidplatform.net";
+ }
+
+ public static final class WebViewAssetLoader.AssetsPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+ ctor public WebViewAssetLoader.AssetsPathHandler(android.content.Context);
+ method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+ }
+
+ public static final class WebViewAssetLoader.Builder {
+ ctor public WebViewAssetLoader.Builder();
+ method public androidx.webkit.WebViewAssetLoader.Builder addPathHandler(String, androidx.webkit.WebViewAssetLoader.PathHandler);
+ method public androidx.webkit.WebViewAssetLoader build();
+ method public androidx.webkit.WebViewAssetLoader.Builder setDomain(String);
+ method public androidx.webkit.WebViewAssetLoader.Builder setHttpAllowed(boolean);
+ }
+
+ public static final class WebViewAssetLoader.InternalStoragePathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+ ctor public WebViewAssetLoader.InternalStoragePathHandler(android.content.Context, java.io.File);
+ method @WorkerThread public android.webkit.WebResourceResponse handle(String);
+ }
+
+ public static interface WebViewAssetLoader.PathHandler {
+ method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+ }
+
+ public static final class WebViewAssetLoader.ResourcesPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+ ctor public WebViewAssetLoader.ResourcesPathHandler(android.content.Context);
+ method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+ }
+
+ public class WebViewClientCompat extends android.webkit.WebViewClient {
+ ctor public WebViewClientCompat();
+ method @RequiresApi(23) public final void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceError);
+ method @RequiresApi(21) @UiThread public void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, androidx.webkit.WebResourceErrorCompat);
+ method @RequiresApi(27) public final void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, android.webkit.SafeBrowsingResponse);
+ method @UiThread public void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, androidx.webkit.SafeBrowsingResponseCompat);
+ }
+
+ public class WebViewCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void addWebMessageListener(android.webkit.WebView, String, java.util.Set<java.lang.String!>, androidx.webkit.WebViewCompat.WebMessageListener);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebMessagePortCompat![] createWebMessageChannel(android.webkit.WebView);
+ method public static android.content.pm.PackageInfo? getCurrentWebViewPackage(android.content.Context);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.net.Uri getSafeBrowsingPrivacyPolicyUrl();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_CHROME_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebChromeClient? getWebChromeClient(android.webkit.WebView);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebViewClient getWebViewClient(android.webkit.WebView);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_RENDERER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcess? getWebViewRenderProcess(android.webkit.WebView);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcessClient? getWebViewRenderProcessClient(android.webkit.WebView);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isMultiProcessEnabled();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.VISUAL_STATE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postVisualStateCallback(android.webkit.WebView, long, androidx.webkit.WebViewCompat.VisualStateCallback);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.POST_WEB_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postWebMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void removeWebMessageListener(android.webkit.WebView, String);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_WHITELIST, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingWhitelist(java.util.List<java.lang.String!>, android.webkit.ValueCallback<java.lang.Boolean!>?);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, java.util.concurrent.Executor, androidx.webkit.WebViewRenderProcessClient);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, androidx.webkit.WebViewRenderProcessClient?);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.START_SAFE_BROWSING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void startSafeBrowsing(android.content.Context, android.webkit.ValueCallback<java.lang.Boolean!>?);
+ }
+
+ public static interface WebViewCompat.VisualStateCallback {
+ method @UiThread public void onComplete(long);
+ }
+
+ public static interface WebViewCompat.WebMessageListener {
+ method @UiThread public void onPostMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri, boolean, androidx.webkit.JavaScriptReplyProxy);
+ }
+
+ public class WebViewFeature {
+ method public static boolean isFeatureSupported(String);
+ field public static final String CREATE_WEB_MESSAGE_CHANNEL = "CREATE_WEB_MESSAGE_CHANNEL";
+ field public static final String DISABLED_ACTION_MODE_MENU_ITEMS = "DISABLED_ACTION_MODE_MENU_ITEMS";
+ field public static final String FORCE_DARK = "FORCE_DARK";
+ field public static final String FORCE_DARK_STRATEGY = "FORCE_DARK_STRATEGY";
+ field public static final String GET_WEB_CHROME_CLIENT = "GET_WEB_CHROME_CLIENT";
+ field public static final String GET_WEB_VIEW_CLIENT = "GET_WEB_VIEW_CLIENT";
+ field public static final String GET_WEB_VIEW_RENDERER = "GET_WEB_VIEW_RENDERER";
+ field public static final String MULTI_PROCESS = "MULTI_PROCESS";
+ field public static final String OFF_SCREEN_PRERASTER = "OFF_SCREEN_PRERASTER";
+ field public static final String POST_WEB_MESSAGE = "POST_WEB_MESSAGE";
+ field public static final String PROXY_OVERRIDE = "PROXY_OVERRIDE";
+ field public static final String RECEIVE_HTTP_ERROR = "RECEIVE_HTTP_ERROR";
+ field public static final String RECEIVE_WEB_RESOURCE_ERROR = "RECEIVE_WEB_RESOURCE_ERROR";
+ field public static final String SAFE_BROWSING_ENABLE = "SAFE_BROWSING_ENABLE";
+ field public static final String SAFE_BROWSING_HIT = "SAFE_BROWSING_HIT";
+ field public static final String SAFE_BROWSING_PRIVACY_POLICY_URL = "SAFE_BROWSING_PRIVACY_POLICY_URL";
+ field public static final String SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY = "SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY";
+ field public static final String SAFE_BROWSING_RESPONSE_PROCEED = "SAFE_BROWSING_RESPONSE_PROCEED";
+ field public static final String SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL = "SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL";
+ field public static final String SAFE_BROWSING_WHITELIST = "SAFE_BROWSING_WHITELIST";
+ field public static final String SERVICE_WORKER_BASIC_USAGE = "SERVICE_WORKER_BASIC_USAGE";
+ field public static final String SERVICE_WORKER_BLOCK_NETWORK_LOADS = "SERVICE_WORKER_BLOCK_NETWORK_LOADS";
+ field public static final String SERVICE_WORKER_CACHE_MODE = "SERVICE_WORKER_CACHE_MODE";
+ field public static final String SERVICE_WORKER_CONTENT_ACCESS = "SERVICE_WORKER_CONTENT_ACCESS";
+ field public static final String SERVICE_WORKER_FILE_ACCESS = "SERVICE_WORKER_FILE_ACCESS";
+ field public static final String SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST = "SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST";
+ field public static final String SHOULD_OVERRIDE_WITH_REDIRECTS = "SHOULD_OVERRIDE_WITH_REDIRECTS";
+ field public static final String START_SAFE_BROWSING = "START_SAFE_BROWSING";
+ field public static final String TRACING_CONTROLLER_BASIC_USAGE = "TRACING_CONTROLLER_BASIC_USAGE";
+ field public static final String VISUAL_STATE_CALLBACK = "VISUAL_STATE_CALLBACK";
+ field public static final String WEB_MESSAGE_CALLBACK_ON_MESSAGE = "WEB_MESSAGE_CALLBACK_ON_MESSAGE";
+ field public static final String WEB_MESSAGE_LISTENER = "WEB_MESSAGE_LISTENER";
+ field public static final String WEB_MESSAGE_PORT_CLOSE = "WEB_MESSAGE_PORT_CLOSE";
+ field public static final String WEB_MESSAGE_PORT_POST_MESSAGE = "WEB_MESSAGE_PORT_POST_MESSAGE";
+ field public static final String WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK = "WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK";
+ field public static final String WEB_RESOURCE_ERROR_GET_CODE = "WEB_RESOURCE_ERROR_GET_CODE";
+ field public static final String WEB_RESOURCE_ERROR_GET_DESCRIPTION = "WEB_RESOURCE_ERROR_GET_DESCRIPTION";
+ field public static final String WEB_RESOURCE_REQUEST_IS_REDIRECT = "WEB_RESOURCE_REQUEST_IS_REDIRECT";
+ field public static final String WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE = "WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE";
+ field public static final String WEB_VIEW_RENDERER_TERMINATE = "WEB_VIEW_RENDERER_TERMINATE";
+ }
+
+ public abstract class WebViewRenderProcess {
+ ctor public WebViewRenderProcess();
+ method public abstract boolean terminate();
+ }
+
+ public abstract class WebViewRenderProcessClient {
+ ctor public WebViewRenderProcessClient();
+ method public abstract void onRenderProcessResponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
+ method public abstract void onRenderProcessUnresponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
+ }
+
+}
+
diff --git a/webkit/webkit/api/res-1.4.0-alpha01.txt b/webkit/webkit/api/res-1.4.0-alpha01.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/webkit/webkit/api/res-1.4.0-alpha01.txt
diff --git a/webkit/webkit/api/restricted_1.4.0-alpha01.txt b/webkit/webkit/api/restricted_1.4.0-alpha01.txt
new file mode 100644
index 0000000..57f9939
--- /dev/null
+++ b/webkit/webkit/api/restricted_1.4.0-alpha01.txt
@@ -0,0 +1,270 @@
+// Signature format: 3.0
+package androidx.webkit {
+
+ public abstract class JavaScriptReplyProxy {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(String);
+ }
+
+ public final class ProxyConfig {
+ method public java.util.List<java.lang.String!> getBypassRules();
+ method public java.util.List<androidx.webkit.ProxyConfig.ProxyRule!> getProxyRules();
+ field public static final String MATCH_ALL_SCHEMES = "*";
+ field public static final String MATCH_HTTP = "http";
+ field public static final String MATCH_HTTPS = "https";
+ }
+
+ public static final class ProxyConfig.Builder {
+ ctor public ProxyConfig.Builder();
+ ctor public ProxyConfig.Builder(androidx.webkit.ProxyConfig);
+ method public androidx.webkit.ProxyConfig.Builder addBypassRule(String);
+ method public androidx.webkit.ProxyConfig.Builder addDirect(String);
+ method public androidx.webkit.ProxyConfig.Builder addDirect();
+ method public androidx.webkit.ProxyConfig.Builder addProxyRule(String);
+ method public androidx.webkit.ProxyConfig.Builder addProxyRule(String, String);
+ method public androidx.webkit.ProxyConfig build();
+ method public androidx.webkit.ProxyConfig.Builder bypassSimpleHostnames();
+ method public androidx.webkit.ProxyConfig.Builder removeImplicitRules();
+ }
+
+ public static final class ProxyConfig.ProxyRule {
+ method public String getSchemeFilter();
+ method public String getUrl();
+ }
+
+ public abstract class ProxyController {
+ method public abstract void clearProxyOverride(java.util.concurrent.Executor, Runnable);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.PROXY_OVERRIDE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ProxyController getInstance();
+ method public abstract void setProxyOverride(androidx.webkit.ProxyConfig, java.util.concurrent.Executor, Runnable);
+ }
+
+ public abstract class SafeBrowsingResponseCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void backToSafety(boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_PROCEED, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void proceed(boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void showInterstitial(boolean);
+ }
+
+ public abstract class ServiceWorkerClientCompat {
+ ctor public ServiceWorkerClientCompat();
+ method @WorkerThread public abstract android.webkit.WebResourceResponse? shouldInterceptRequest(android.webkit.WebResourceRequest);
+ }
+
+ public abstract class ServiceWorkerControllerCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.ServiceWorkerControllerCompat getInstance();
+ method public abstract androidx.webkit.ServiceWorkerWebSettingsCompat getServiceWorkerWebSettings();
+ method public abstract void setServiceWorkerClient(androidx.webkit.ServiceWorkerClientCompat?);
+ }
+
+ public abstract class ServiceWorkerWebSettingsCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowContentAccess();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getAllowFileAccess();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract boolean getBlockNetworkLoads();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getCacheMode();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CONTENT_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowContentAccess(boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_FILE_ACCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setAllowFileAccess(boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_BLOCK_NETWORK_LOADS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setBlockNetworkLoads(boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SERVICE_WORKER_CACHE_MODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setCacheMode(int);
+ }
+
+ public class TracingConfig {
+ method public java.util.List<java.lang.String!> getCustomIncludedCategories();
+ method public int getPredefinedCategories();
+ method public int getTracingMode();
+ field public static final int CATEGORIES_ALL = 1; // 0x1
+ field public static final int CATEGORIES_ANDROID_WEBVIEW = 2; // 0x2
+ field public static final int CATEGORIES_FRAME_VIEWER = 64; // 0x40
+ field public static final int CATEGORIES_INPUT_LATENCY = 8; // 0x8
+ field public static final int CATEGORIES_JAVASCRIPT_AND_RENDERING = 32; // 0x20
+ field public static final int CATEGORIES_NONE = 0; // 0x0
+ field public static final int CATEGORIES_RENDERING = 16; // 0x10
+ field public static final int CATEGORIES_WEB_DEVELOPER = 4; // 0x4
+ field public static final int RECORD_CONTINUOUSLY = 1; // 0x1
+ field public static final int RECORD_UNTIL_FULL = 0; // 0x0
+ }
+
+ public static class TracingConfig.Builder {
+ ctor public TracingConfig.Builder();
+ method public androidx.webkit.TracingConfig.Builder addCategories(int...);
+ method public androidx.webkit.TracingConfig.Builder addCategories(java.lang.String!...);
+ method public androidx.webkit.TracingConfig.Builder addCategories(java.util.Collection<java.lang.String!>);
+ method public androidx.webkit.TracingConfig build();
+ method public androidx.webkit.TracingConfig.Builder setTracingMode(int);
+ }
+
+ public abstract class TracingController {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.TRACING_CONTROLLER_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.TracingController getInstance();
+ method public abstract boolean isTracing();
+ method public abstract void start(androidx.webkit.TracingConfig);
+ method public abstract boolean stop(java.io.OutputStream?, java.util.concurrent.Executor);
+ }
+
+ public class WebMessageCompat {
+ ctor public WebMessageCompat(String?);
+ ctor public WebMessageCompat(String?, androidx.webkit.WebMessagePortCompat![]?);
+ method public String? getData();
+ method public androidx.webkit.WebMessagePortCompat![]? getPorts();
+ }
+
+ public abstract class WebMessagePortCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_CLOSE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void close();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_POST_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void postMessage(androidx.webkit.WebMessageCompat);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract void setWebMessageCallback(android.os.Handler?, androidx.webkit.WebMessagePortCompat.WebMessageCallbackCompat);
+ }
+
+ public abstract static class WebMessagePortCompat.WebMessageCallbackCompat {
+ ctor public WebMessagePortCompat.WebMessageCallbackCompat();
+ method public void onMessage(androidx.webkit.WebMessagePortCompat, androidx.webkit.WebMessageCompat?);
+ }
+
+ public abstract class WebResourceErrorCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_DESCRIPTION, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract CharSequence getDescription();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_ERROR_GET_CODE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public abstract int getErrorCode();
+ }
+
+ public class WebResourceRequestCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_RESOURCE_REQUEST_IS_REDIRECT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isRedirect(android.webkit.WebResourceRequest);
+ }
+
+ public class WebSettingsCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getDisabledActionModeMenuItems(android.webkit.WebSettings);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getForceDark(android.webkit.WebSettings);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK_STRATEGY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static int getForceDarkStrategy(android.webkit.WebSettings);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getOffscreenPreRaster(android.webkit.WebSettings);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean getSafeBrowsingEnabled(android.webkit.WebSettings);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.DISABLED_ACTION_MODE_MENU_ITEMS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setDisabledActionModeMenuItems(android.webkit.WebSettings, int);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setForceDark(android.webkit.WebSettings, int);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.FORCE_DARK_STRATEGY, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setForceDarkStrategy(android.webkit.WebSettings, int);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.OFF_SCREEN_PRERASTER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setOffscreenPreRaster(android.webkit.WebSettings, boolean);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_ENABLE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingEnabled(android.webkit.WebSettings, boolean);
+ field public static final int DARK_STRATEGY_PREFER_WEB_THEME_OVER_USER_AGENT_DARKENING = 2; // 0x2
+ field public static final int DARK_STRATEGY_USER_AGENT_DARKENING_ONLY = 0; // 0x0
+ field public static final int DARK_STRATEGY_WEB_THEME_DARKENING_ONLY = 1; // 0x1
+ field public static final int FORCE_DARK_AUTO = 1; // 0x1
+ field public static final int FORCE_DARK_OFF = 0; // 0x0
+ field public static final int FORCE_DARK_ON = 2; // 0x2
+ }
+
+ public final class WebViewAssetLoader {
+ method @WorkerThread public android.webkit.WebResourceResponse? shouldInterceptRequest(android.net.Uri);
+ field public static final String DEFAULT_DOMAIN = "appassets.androidplatform.net";
+ }
+
+ public static final class WebViewAssetLoader.AssetsPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+ ctor public WebViewAssetLoader.AssetsPathHandler(android.content.Context);
+ method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+ }
+
+ public static final class WebViewAssetLoader.Builder {
+ ctor public WebViewAssetLoader.Builder();
+ method public androidx.webkit.WebViewAssetLoader.Builder addPathHandler(String, androidx.webkit.WebViewAssetLoader.PathHandler);
+ method public androidx.webkit.WebViewAssetLoader build();
+ method public androidx.webkit.WebViewAssetLoader.Builder setDomain(String);
+ method public androidx.webkit.WebViewAssetLoader.Builder setHttpAllowed(boolean);
+ }
+
+ public static final class WebViewAssetLoader.InternalStoragePathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+ ctor public WebViewAssetLoader.InternalStoragePathHandler(android.content.Context, java.io.File);
+ method @WorkerThread public android.webkit.WebResourceResponse handle(String);
+ }
+
+ public static interface WebViewAssetLoader.PathHandler {
+ method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+ }
+
+ public static final class WebViewAssetLoader.ResourcesPathHandler implements androidx.webkit.WebViewAssetLoader.PathHandler {
+ ctor public WebViewAssetLoader.ResourcesPathHandler(android.content.Context);
+ method @WorkerThread public android.webkit.WebResourceResponse? handle(String);
+ }
+
+ public class WebViewClientCompat extends android.webkit.WebViewClient {
+ ctor public WebViewClientCompat();
+ method @RequiresApi(23) public final void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, android.webkit.WebResourceError);
+ method @RequiresApi(21) @UiThread public void onReceivedError(android.webkit.WebView, android.webkit.WebResourceRequest, androidx.webkit.WebResourceErrorCompat);
+ method @RequiresApi(27) public final void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, android.webkit.SafeBrowsingResponse);
+ method @UiThread public void onSafeBrowsingHit(android.webkit.WebView, android.webkit.WebResourceRequest, int, androidx.webkit.SafeBrowsingResponseCompat);
+ }
+
+ public class WebViewCompat {
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void addWebMessageListener(android.webkit.WebView, String, java.util.Set<java.lang.String!>, androidx.webkit.WebViewCompat.WebMessageListener);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.CREATE_WEB_MESSAGE_CHANNEL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebMessagePortCompat![] createWebMessageChannel(android.webkit.WebView);
+ method public static android.content.pm.PackageInfo? getCurrentWebViewPackage(android.content.Context);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_PRIVACY_POLICY_URL, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.net.Uri getSafeBrowsingPrivacyPolicyUrl();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_CHROME_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebChromeClient? getWebChromeClient(android.webkit.WebView);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_CLIENT, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static android.webkit.WebViewClient getWebViewClient(android.webkit.WebView);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.GET_WEB_VIEW_RENDERER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcess? getWebViewRenderProcess(android.webkit.WebView);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static androidx.webkit.WebViewRenderProcessClient? getWebViewRenderProcessClient(android.webkit.WebView);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.MULTI_PROCESS, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static boolean isMultiProcessEnabled();
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.VISUAL_STATE_CALLBACK, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postVisualStateCallback(android.webkit.WebView, long, androidx.webkit.WebViewCompat.VisualStateCallback);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.POST_WEB_MESSAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void postWebMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_MESSAGE_LISTENER, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void removeWebMessageListener(android.webkit.WebView, String);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.SAFE_BROWSING_WHITELIST, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setSafeBrowsingWhitelist(java.util.List<java.lang.String!>, android.webkit.ValueCallback<java.lang.Boolean!>?);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, java.util.concurrent.Executor, androidx.webkit.WebViewRenderProcessClient);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void setWebViewRenderProcessClient(android.webkit.WebView, androidx.webkit.WebViewRenderProcessClient?);
+ method @RequiresFeature(name=androidx.webkit.WebViewFeature.START_SAFE_BROWSING, enforcement="androidx.webkit.WebViewFeature#isFeatureSupported") public static void startSafeBrowsing(android.content.Context, android.webkit.ValueCallback<java.lang.Boolean!>?);
+ }
+
+ public static interface WebViewCompat.VisualStateCallback {
+ method @UiThread public void onComplete(long);
+ }
+
+ public static interface WebViewCompat.WebMessageListener {
+ method @UiThread public void onPostMessage(android.webkit.WebView, androidx.webkit.WebMessageCompat, android.net.Uri, boolean, androidx.webkit.JavaScriptReplyProxy);
+ }
+
+ public class WebViewFeature {
+ method public static boolean isFeatureSupported(String);
+ field public static final String CREATE_WEB_MESSAGE_CHANNEL = "CREATE_WEB_MESSAGE_CHANNEL";
+ field public static final String DISABLED_ACTION_MODE_MENU_ITEMS = "DISABLED_ACTION_MODE_MENU_ITEMS";
+ field public static final String FORCE_DARK = "FORCE_DARK";
+ field public static final String FORCE_DARK_STRATEGY = "FORCE_DARK_STRATEGY";
+ field public static final String GET_WEB_CHROME_CLIENT = "GET_WEB_CHROME_CLIENT";
+ field public static final String GET_WEB_VIEW_CLIENT = "GET_WEB_VIEW_CLIENT";
+ field public static final String GET_WEB_VIEW_RENDERER = "GET_WEB_VIEW_RENDERER";
+ field public static final String MULTI_PROCESS = "MULTI_PROCESS";
+ field public static final String OFF_SCREEN_PRERASTER = "OFF_SCREEN_PRERASTER";
+ field public static final String POST_WEB_MESSAGE = "POST_WEB_MESSAGE";
+ field public static final String PROXY_OVERRIDE = "PROXY_OVERRIDE";
+ field public static final String RECEIVE_HTTP_ERROR = "RECEIVE_HTTP_ERROR";
+ field public static final String RECEIVE_WEB_RESOURCE_ERROR = "RECEIVE_WEB_RESOURCE_ERROR";
+ field public static final String SAFE_BROWSING_ENABLE = "SAFE_BROWSING_ENABLE";
+ field public static final String SAFE_BROWSING_HIT = "SAFE_BROWSING_HIT";
+ field public static final String SAFE_BROWSING_PRIVACY_POLICY_URL = "SAFE_BROWSING_PRIVACY_POLICY_URL";
+ field public static final String SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY = "SAFE_BROWSING_RESPONSE_BACK_TO_SAFETY";
+ field public static final String SAFE_BROWSING_RESPONSE_PROCEED = "SAFE_BROWSING_RESPONSE_PROCEED";
+ field public static final String SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL = "SAFE_BROWSING_RESPONSE_SHOW_INTERSTITIAL";
+ field public static final String SAFE_BROWSING_WHITELIST = "SAFE_BROWSING_WHITELIST";
+ field public static final String SERVICE_WORKER_BASIC_USAGE = "SERVICE_WORKER_BASIC_USAGE";
+ field public static final String SERVICE_WORKER_BLOCK_NETWORK_LOADS = "SERVICE_WORKER_BLOCK_NETWORK_LOADS";
+ field public static final String SERVICE_WORKER_CACHE_MODE = "SERVICE_WORKER_CACHE_MODE";
+ field public static final String SERVICE_WORKER_CONTENT_ACCESS = "SERVICE_WORKER_CONTENT_ACCESS";
+ field public static final String SERVICE_WORKER_FILE_ACCESS = "SERVICE_WORKER_FILE_ACCESS";
+ field public static final String SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST = "SERVICE_WORKER_SHOULD_INTERCEPT_REQUEST";
+ field public static final String SHOULD_OVERRIDE_WITH_REDIRECTS = "SHOULD_OVERRIDE_WITH_REDIRECTS";
+ field public static final String START_SAFE_BROWSING = "START_SAFE_BROWSING";
+ field public static final String TRACING_CONTROLLER_BASIC_USAGE = "TRACING_CONTROLLER_BASIC_USAGE";
+ field public static final String VISUAL_STATE_CALLBACK = "VISUAL_STATE_CALLBACK";
+ field public static final String WEB_MESSAGE_CALLBACK_ON_MESSAGE = "WEB_MESSAGE_CALLBACK_ON_MESSAGE";
+ field public static final String WEB_MESSAGE_LISTENER = "WEB_MESSAGE_LISTENER";
+ field public static final String WEB_MESSAGE_PORT_CLOSE = "WEB_MESSAGE_PORT_CLOSE";
+ field public static final String WEB_MESSAGE_PORT_POST_MESSAGE = "WEB_MESSAGE_PORT_POST_MESSAGE";
+ field public static final String WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK = "WEB_MESSAGE_PORT_SET_MESSAGE_CALLBACK";
+ field public static final String WEB_RESOURCE_ERROR_GET_CODE = "WEB_RESOURCE_ERROR_GET_CODE";
+ field public static final String WEB_RESOURCE_ERROR_GET_DESCRIPTION = "WEB_RESOURCE_ERROR_GET_DESCRIPTION";
+ field public static final String WEB_RESOURCE_REQUEST_IS_REDIRECT = "WEB_RESOURCE_REQUEST_IS_REDIRECT";
+ field public static final String WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE = "WEB_VIEW_RENDERER_CLIENT_BASIC_USAGE";
+ field public static final String WEB_VIEW_RENDERER_TERMINATE = "WEB_VIEW_RENDERER_TERMINATE";
+ }
+
+ public abstract class WebViewRenderProcess {
+ ctor public WebViewRenderProcess();
+ method public abstract boolean terminate();
+ }
+
+ public abstract class WebViewRenderProcessClient {
+ ctor public WebViewRenderProcessClient();
+ method public abstract void onRenderProcessResponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
+ method public abstract void onRenderProcessUnresponsive(android.webkit.WebView, androidx.webkit.WebViewRenderProcess?);
+ }
+
+}
+
diff --git a/webkit/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java b/webkit/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java
index 1ec5043..846a80f 100644
--- a/webkit/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java
+++ b/webkit/webkit/src/main/java/androidx/webkit/WebSettingsCompat.java
@@ -302,6 +302,14 @@
* so as to emulate a dark theme. WebViews that are not attached to the view hierarchy will not
* be inverted.
*
+ * <p class="note"> If your app uses a dark theme, WebView will not be inverted. Similarly, if
+ * your app's theme inherits from a {@code DayNight} theme, WebView will not be inverted.
+ * In either of these cases, you should control the mode manually with
+ * {@link ForceDark#FORCE_DARK_ON} or {@link ForceDark#FORCE_DARK_OFF}.
+ *
+ * <p> See <a href="https://developer.android.com/guide/topics/ui/look-and-feel/darktheme#force_dark">
+ * Force Dark documentation</a> for more information.
+ *
* @see #setForceDark
*/
public static final int FORCE_DARK_AUTO = WebSettings.FORCE_DARK_AUTO;
@@ -389,8 +397,10 @@
/**
* In this mode WebView content will be darkened by a user agent and it will ignore the
- * web page's dark theme if it exists.
- * See <a href="https://drafts.csswg.org/css-color-adjust-1/">specification</a>
+ * web page's dark theme if it exists. To avoid mixing two different darkening strategies,
+ * the {@code prefers-color-scheme} media query will evaluate to light.
+ *
+ * <p> See <a href="https://drafts.csswg.org/css-color-adjust-1/">specification</a>
* for more information.
*
* @see #setForceDarkStrategy
@@ -403,6 +413,9 @@
* If web page does not provide dark theme support WebView content will be rendered with a
* default theme.
*
+ * <p> See <a href="https://drafts.csswg.org/css-color-adjust-1/">specification</a>
+ * for more information.
+ *
* @see #setForceDarkStrategy
*/
public static final int DARK_STRATEGY_WEB_THEME_DARKENING_ONLY =
@@ -410,7 +423,14 @@
/**
* In this mode WebView content will be darkened by a user agent unless web page supports dark
- * theme.
+ * theme. WebView determines whether web pages supports dark theme by the presence of
+ * {@code color-scheme} metadata containing "dark" value. For example,
+ * {@code <meta name="color-scheme" content="dark light">"}.
+ * If the metadata is not presented WebView content will be darkened by a user agent and
+ * {@code prefers-color-scheme} media query will evaluate to light.
+ *
+ * <p> See <a href="https://drafts.csswg.org/css-color-adjust-1/">specification</a>
+ * for more information.
*
* @see #setForceDarkStrategy
*/