blob: 894b35cbf4b4cf57a3139fd5b364c190b7bce16e [file] [log] [blame]
/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.compose.foundation.layout
import android.view.View
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.test.junit4.createAndroidComposeRule
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.WindowInsetsControllerCompat
import androidx.test.filters.MediumTest
import java.util.concurrent.TimeUnit
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@MediumTest
class WindowInsetsAnimationTest {
@get:Rule
val rule = createAndroidComposeRule<WindowInsetsActionBarActivity>()
@Before
fun setup() {
rule.activity.createdLatch.await(1, TimeUnit.SECONDS)
rule.activity.attachedToWindowLatch.await(1, TimeUnit.SECONDS)
}
@After
fun teardown() {
rule.runOnUiThread {
val window = rule.activity.window
val view = window.decorView
WindowInsetsControllerCompat(window, view).hide(WindowInsetsCompat.Type.ime())
}
}
@OptIn(ExperimentalLayoutApi::class)
@Test
fun imeAnimationWhenShowingIme() {
val imeAnimationSourceValues = mutableListOf<Int>()
val imeAnimationTargetValues = mutableListOf<Int>()
val focusRequester = FocusRequester()
rule.setContent {
val density = LocalDensity.current
val source = WindowInsets.imeAnimationSource
val target = WindowInsets.imeAnimationTarget
val sourceBottom = source.getBottom(density)
imeAnimationSourceValues += sourceBottom
val targetBottom = target.getBottom(density)
imeAnimationTargetValues += targetBottom
BasicTextField(
value = "Hello World",
onValueChange = {},
Modifier.focusRequester(focusRequester)
)
}
rule.waitForIdle()
rule.runOnUiThread {
focusRequester.requestFocus()
}
rule.waitForIdle()
rule.waitUntil(timeoutMillis = 3000) {
imeAnimationSourceValues.last() > imeAnimationTargetValues.first()
}
rule.waitUntil(timeoutMillis = 3000) {
imeAnimationTargetValues.last() == imeAnimationSourceValues.last()
}
}
@OptIn(ExperimentalLayoutApi::class)
@Test
fun imeAnimationWhenHidingIme() {
val imeAnimationSourceValues = mutableListOf<Int>()
val imeAnimationTargetValues = mutableListOf<Int>()
val focusRequester = FocusRequester()
lateinit var view: View
rule.setContent {
view = LocalView.current
val density = LocalDensity.current
val source = WindowInsets.imeAnimationSource
val target = WindowInsets.imeAnimationTarget
val sourceBottom = source.getBottom(density)
imeAnimationSourceValues += sourceBottom
val targetBottom = target.getBottom(density)
imeAnimationTargetValues += targetBottom
BasicTextField(
value = "Hello World",
onValueChange = {},
Modifier.focusRequester(focusRequester)
)
}
rule.waitForIdle()
rule.runOnUiThread {
focusRequester.requestFocus()
}
rule.waitUntil(timeoutMillis = 3000) {
val target = imeAnimationTargetValues.last()
val source = imeAnimationSourceValues.last()
target > imeAnimationSourceValues.first() && target == source
}
rule.runOnUiThread {
val window = rule.activity.window
WindowInsetsControllerCompat(window, view).hide(WindowInsetsCompat.Type.ime())
}
rule.waitForIdle()
rule.waitUntil(timeoutMillis = 3000) {
imeAnimationTargetValues.last() == imeAnimationSourceValues.first()
}
}
}