diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 912060fc9..08333e6fa 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -81,7 +81,7 @@ jobs:
# Allow tests to continue on other devices if they fail on one device.
fail-fast: false
matrix:
- api-level: [ 22, 26, 29 ]
+ api-level: [ 22, 26, 30 ]
shard: [ 0, 1 ] # Need to update shard-count below if this changes
env:
@@ -96,6 +96,12 @@ jobs:
- name: Copy CI gradle.properties
run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties
+ - name: Enable KVM
+ run: |
+ echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
+ sudo udevadm control --reload-rules
+ sudo udevadm trigger --name-match=kvm
+
- name: Setup java
uses: actions/setup-java@v3
with:
@@ -126,7 +132,7 @@ jobs:
API_LEVEL: ${{ matrix.api-level }}
run: |
ARCH="x86"
- if [ "$API_LEVEL" -ge "31" ]; then
+ if [ "$API_LEVEL" -ge "29" ]; then
ARCH="x86_64"
fi
echo "ARCH=$ARCH" >> $GITHUB_OUTPUT
diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
new file mode 100644
index 000000000..a670cf458
--- /dev/null
+++ b/.idea/deploymentTargetSelector.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/flowlayout/src/sharedTest/kotlin/com/google/accompanist/flowlayout/LayoutTest.kt b/flowlayout/src/sharedTest/kotlin/com/google/accompanist/flowlayout/LayoutTest.kt
index 6827e0ec8..45d979b13 100644
--- a/flowlayout/src/sharedTest/kotlin/com/google/accompanist/flowlayout/LayoutTest.kt
+++ b/flowlayout/src/sharedTest/kotlin/com/google/accompanist/flowlayout/LayoutTest.kt
@@ -60,7 +60,7 @@ open class LayoutTest {
size: Ref,
position: Ref,
positionedLatch: CountDownLatch
- ): Modifier = this then onGloballyPositioned { coordinates ->
+ ): Modifier = onGloballyPositioned { coordinates ->
size.value = IntSize(coordinates.size.width, coordinates.size.height)
position.value = coordinates.localToRoot(Offset(0f, 0f))
positionedLatch.countDown()
diff --git a/gradle.properties b/gradle.properties
index c66568c7b..f827bf0c9 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -33,7 +33,7 @@ systemProp.org.gradle.internal.http.socketTimeout=120000
GROUP=com.google.accompanist
# !! No longer need to update this manually when using a Compose SNAPSHOT
-VERSION_NAME=0.35.2-SNAPSHOT
+VERSION_NAME=0.35.2-beta
POM_DESCRIPTION=Utilities for Jetpack Compose
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 307fcd00f..2fcdafbc5 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -1,6 +1,6 @@
[versions]
-compose = "1.7.0-alpha02"
+compose = "1.7.0-beta07"
composeCompiler = "1.5.8"
composeMaterial3 = "1.0.1"
composesnapshot = "-" # a single character = no snapshot
@@ -8,7 +8,7 @@ composesnapshot = "-" # a single character = no snapshot
dokka = "1.8.10"
# gradlePlugin and lint need to be updated together
-gradlePlugin = "8.2.2"
+gradlePlugin = "8.5.2"
lintMinCompose = "30.0.0"
ktlint = "0.45.2"
@@ -18,8 +18,8 @@ okhttp = "3.12.13"
coil = "1.3.2"
androidlint = "25.3.0"
-androidxtest = "1.4.0"
-androidxnavigation = "2.7.0-alpha01"
+androidxtest = "1.6.1"
+androidxnavigation = "2.7.7"
androidxWindow = "1.0.0"
metalava = "0.3.2"
@@ -68,8 +68,8 @@ coil-compose = { module = "io.coil-kt:coil-compose", version.ref = "coil" }
androidx-appcompat = "androidx.appcompat:appcompat:1.4.2"
androidx-core = "androidx.core:core-ktx:1.8.0"
-androidx-activity-compose = "androidx.activity:activity-compose:1.7.2"
-androidx-fragment = "androidx.fragment:fragment-ktx:1.5.1"
+androidx-activity-compose = "androidx.activity:activity-compose:1.9.0"
+androidx-fragment = "androidx.fragment:fragment-ktx:1.8.1"
androidx-dynamicanimation = "androidx.dynamicanimation:dynamicanimation-ktx:1.0.0-alpha03"
androidx-lifecycle-runtime = "androidx.lifecycle:lifecycle-runtime-ktx:2.6.1"
androidx-lifecycle-viewmodel-compose = "androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1"
@@ -82,19 +82,18 @@ androidx-navigation-testing = { module = "androidx.navigation:navigation-testing
mdc = "com.google.android.material:material:1.8.0"
-androidx-test-core = "androidx.test:core-ktx:1.5.0-alpha02"
-androidx-test-runner = "androidx.test:runner:1.5.0-alpha04"
+androidx-test-core = "androidx.test:core-ktx:1.6.1"
+androidx-test-runner = "androidx.test:runner:1.6.1"
androidx-test-rules = { module = "androidx.test:rules", version.ref = "androidxtest" }
-androidx-test-orchestrator = "androidx.test:orchestrator:1.4.1"
-androidx-test-uiAutomator = "androidx.test.uiautomator:uiautomator:2.2.0"
+androidx-test-orchestrator = "androidx.test:orchestrator:1.5.0"
+androidx-test-uiAutomator = "androidx.test.uiautomator:uiautomator:2.3.0"
-# alpha for robolectric x compose fix
-androidx-test-espressoCore = "androidx.test.espresso:espresso-core:3.5.1"
-androidx-test-espressoWeb = "androidx.test.espresso:espresso-web:3.5.1"
+androidx-test-espressoCore = "androidx.test.espresso:espresso-core:3.6.1"
+androidx-test-espressoWeb = "androidx.test.espresso:espresso-web:3.6.1"
junit = "junit:junit:4.13.2"
-truth = "com.google.truth:truth:1.1.2"
-robolectric = "org.robolectric:robolectric:4.9"
+truth = "com.google.truth:truth:1.1.3"
+robolectric = "org.robolectric:robolectric:4.12.1"
affectedmoduledetector = "com.dropbox.affectedmoduledetector:affectedmoduledetector:0.1.2"
@@ -103,7 +102,7 @@ android-tools-lint-lint = { module = "com.android.tools.lint:lint", version.ref
android-tools-lint-api = { module = "com.android.tools.lint:lint-api", version.ref = "lintMinCompose" }
android-tools-lint-tests = { module = "com.android.tools.lint:lint-tests", version.ref = "lintMinCompose" }
-squareup-mockwebserver = "com.squareup.okhttp3:mockwebserver:4.9.3"
+squareup-mockwebserver = "com.squareup.okhttp3:mockwebserver:4.10.0"
[plugins]
android-application = { id = "com.android.application", version.ref = "gradlePlugin" }
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 3499ded5c..d62b91ae6 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,7 @@
+#Wed Jul 10 11:49:25 AEST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/SheetContentHostTest.kt b/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/SheetContentHostTest.kt
index bf41d7a2d..1f199579e 100644
--- a/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/SheetContentHostTest.kt
+++ b/navigation-material/src/androidTest/java/com/google/accompanist/navigation.material/SheetContentHostTest.kt
@@ -28,9 +28,13 @@ import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
+import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
+import androidx.compose.ui.layout.onPlaced
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.test.junit4.ComposeContentTestRule
import androidx.compose.ui.test.junit4.createComposeRule
@@ -174,10 +178,8 @@ internal class SheetContentHostTest {
onSheetDismissed: (NavBackStackEntry) -> Unit
) {
setContent {
+ var anchored by remember { mutableStateOf(false) }
val saveableStateHolder = rememberSaveableStateHolder()
- LaunchedEffect(backStackEntry.value) {
- if (backStackEntry.value == null) sheetState.hide() else sheetState.show()
- }
ModalBottomSheetLayout(
sheetContent = {
SheetContentHost(
@@ -189,6 +191,7 @@ internal class SheetContentHostTest {
)
},
sheetState = sheetState,
+ modifier = Modifier.onPlaced { anchored = true },
content = {
Box(
Modifier
@@ -197,6 +200,12 @@ internal class SheetContentHostTest {
)
}
)
+
+ if (anchored) {
+ LaunchedEffect(backStackEntry.value) {
+ if (backStackEntry.value == null) sheetState.hide() else sheetState.show()
+ }
+ }
}
}
diff --git a/permissions/src/androidTest/AndroidManifest.xml b/permissions/src/androidTest/AndroidManifest.xml
index 7a37a0c0e..8bf897268 100644
--- a/permissions/src/androidTest/AndroidManifest.xml
+++ b/permissions/src/androidTest/AndroidManifest.xml
@@ -17,7 +17,7 @@
-
+
simulateAppComingFromTheBackground(
composeTestRule: AndroidComposeTestRule, T>
@@ -57,22 +59,15 @@ internal fun grantPermissionInDialog(
) {
val uiDevice = UiDevice.getInstance(instrumentation)
val sdkVersion = Build.VERSION.SDK_INT
- val clicked = uiDevice.findPermissionButton(
+ val button = uiDevice.findPermissionButton(
when (sdkVersion) {
in 24..28 -> "ALLOW"
- else -> "Allow"
+ 29 -> "Allow"
+ else -> "While using the app"
}
- ).clickForPermission(instrumentation)
-
- // Or maybe this permission doesn't have the Allow option
- if (!clicked && sdkVersion > 28) {
- uiDevice.findPermissionButton(
- when (sdkVersion) {
- 29 -> "Allow only while using the app"
- else -> "While using the app"
- }
- ).clickForPermission(instrumentation)
- }
+ )
+
+ button.clickForPermission(instrumentation)
}
internal fun denyPermissionInDialog(
@@ -81,7 +76,7 @@ internal fun denyPermissionInDialog(
val text = when (Build.VERSION.SDK_INT) {
in 24..28 -> "DENY"
in 29..30 -> "Deny"
- else -> "Don’t allow"
+ else -> "t allow" // Different sdks and devices seem to have either ' or ’
}
val permissionButton = UiDevice.getInstance(instrumentation).findPermissionButton(text)
permissionButton.clickForPermission(instrumentation)
@@ -95,54 +90,53 @@ internal fun doNotAskAgainPermissionInDialog(
Build.VERSION.SDK_INT >= 30 -> {
denyPermissionInDialog(instrumentation)
}
+
Build.VERSION.SDK_INT > 28 -> {
uiDevice
.findPermissionButton("Deny & don’t ask again")
.clickForPermission(instrumentation)
}
+
Build.VERSION.SDK_INT == 23 -> {
- uiDevice.findObject(
- UiSelector().text("Never ask again")
- ).clickForPermission(instrumentation)
+ uiDevice.findPermissionButton("Never ask again")
+ .clickForPermission(instrumentation)
denyPermissionInDialog(instrumentation)
}
+
else -> {
- uiDevice.findObject(
- UiSelector().text("Don't ask again")
+ uiDevice.findPermissionButton(
+ "Don't ask again"
).clickForPermission(instrumentation)
denyPermissionInDialog(instrumentation)
}
}
}
-private fun UiDevice.findPermissionButton(text: String): UiObject =
- findObject(
- UiSelector()
- .textMatches(text)
- .clickable(true)
- .className("android.widget.Button")
- )
+private fun UiDevice.findPermissionButton(
+ text: String
+): UiObject2 {
+ val selector = By
+ .textContains(text)
+ .clickable(true)
-private fun UiObject.clickForPermission(
- instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
-): Boolean {
- waitUntil { exists() }
- if (!exists()) return false
+ val found = wait(Until.hasObject(selector), 3000)
- val clicked = waitUntil { exists() && click() }
- // Make sure that the tests waits for this click to be processed
- if (clicked) { instrumentation.waitForIdleSync() }
- return clicked
-}
+ if (!found) {
+ val output = ByteArrayOutputStream()
+ dumpWindowHierarchy(output)
+ println(output.toByteArray().decodeToString())
-private fun waitUntil(timeoutMillis: Long = 2_000, condition: () -> Boolean): Boolean {
- val startTime = System.nanoTime()
- while (true) {
- if (condition()) return true
- // Let Android run measure, draw and in general any other async operations.
- Thread.sleep(10)
- if (System.nanoTime() - startTime > timeoutMillis * 1_000_000) {
- return false
- }
+ error("Could not find button with text $text")
}
+
+ return findObject(selector)
+}
+
+private fun UiObject2.clickForPermission(
+ instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
+): Boolean {
+ click()
+ // Make sure that the tests waits for this click to be processed
+ instrumentation.waitForIdleSync()
+ return true
}
diff --git a/permissions/src/main/java/com/google/accompanist/permissions/PermissionsUtil.kt b/permissions/src/main/java/com/google/accompanist/permissions/PermissionsUtil.kt
index a15a01e21..9ba75827b 100644
--- a/permissions/src/main/java/com/google/accompanist/permissions/PermissionsUtil.kt
+++ b/permissions/src/main/java/com/google/accompanist/permissions/PermissionsUtil.kt
@@ -24,7 +24,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.Stable
import androidx.compose.runtime.remember
-import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.Lifecycle
@@ -87,7 +86,7 @@ internal fun PermissionLifecycleCheckerEffect(
}
}
}
- val lifecycle = LocalLifecycleOwner.current.lifecycle
+ val lifecycle = androidx.lifecycle.compose.LocalLifecycleOwner.current.lifecycle
DisposableEffect(lifecycle, permissionCheckerObserver) {
lifecycle.addObserver(permissionCheckerObserver)
onDispose { lifecycle.removeObserver(permissionCheckerObserver) }
@@ -119,7 +118,7 @@ internal fun PermissionsLifecycleCheckerEffect(
}
}
}
- val lifecycle = LocalLifecycleOwner.current.lifecycle
+ val lifecycle = androidx.lifecycle.compose.LocalLifecycleOwner.current.lifecycle
DisposableEffect(lifecycle, permissionsCheckerObserver) {
lifecycle.addObserver(permissionsCheckerObserver)
onDispose { lifecycle.removeObserver(permissionsCheckerObserver) }
diff --git a/sample/src/main/java/com/google/accompanist/sample/adaptive/DraggableFoldAwareColumnSample.kt b/sample/src/main/java/com/google/accompanist/sample/adaptive/DraggableFoldAwareColumnSample.kt
index d4d190db2..925753e25 100644
--- a/sample/src/main/java/com/google/accompanist/sample/adaptive/DraggableFoldAwareColumnSample.kt
+++ b/sample/src/main/java/com/google/accompanist/sample/adaptive/DraggableFoldAwareColumnSample.kt
@@ -67,7 +67,6 @@ class DraggableFoldAwareColumnSample : ComponentActivity() {
@Composable
fun DraggableExample(activity: Activity) {
var offset by remember { mutableStateOf(Offset(0f, 0f)) }
-
FoldAwareColumn(
modifier = Modifier
.offset { IntOffset(offset.x.roundToInt(), offset.y.roundToInt()) }
diff --git a/sample/src/main/java/com/google/accompanist/sample/navigation/animation/AnimatedNavHostSample.kt b/sample/src/main/java/com/google/accompanist/sample/navigation/animation/AnimatedNavHostSample.kt
index c47590988..4a64d6fd1 100644
--- a/sample/src/main/java/com/google/accompanist/sample/navigation/animation/AnimatedNavHostSample.kt
+++ b/sample/src/main/java/com/google/accompanist/sample/navigation/animation/AnimatedNavHostSample.kt
@@ -47,7 +47,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
@@ -330,7 +329,7 @@ fun NavigateButton(
fun NavigateBackButton(navController: NavController) {
// Use LocalLifecycleOwner.current as a proxy for the NavBackStackEntry
// associated with this Composable
- if (navController.currentBackStackEntry == LocalLifecycleOwner.current &&
+ if (navController.currentBackStackEntry == androidx.lifecycle.compose.LocalLifecycleOwner.current &&
navController.previousBackStackEntry != null
) {
Button(
diff --git a/testharness/src/sharedTest/kotlin/com/google/accompanist/testharness/TestHarnessTest.kt b/testharness/src/sharedTest/kotlin/com/google/accompanist/testharness/TestHarnessTest.kt
index c2d3bc004..501e00dc6 100644
--- a/testharness/src/sharedTest/kotlin/com/google/accompanist/testharness/TestHarnessTest.kt
+++ b/testharness/src/sharedTest/kotlin/com/google/accompanist/testharness/TestHarnessTest.kt
@@ -96,13 +96,13 @@ class TestHarnessTest {
fun size_ExtremelyBig_measuredWidthIsCorrect() {
var width = 0.dp
composeTestRule.setContent {
- TestHarness(size = DpSize(10000.dp, 10000.dp)) {
- BoxOfSize(10000.dp, onWidth = { width = it })
+ TestHarness(size = DpSize(5000.dp, 5000.dp)) {
+ BoxOfSize(5000.dp, onWidth = { width = it })
}
}
composeTestRule.waitForIdle()
- val ratio = width / 10000.dp
+ val ratio = width / 5000.dp
assertEquals(ratio, 1f, 0.01f)
}