Loading packages/SystemUI/multivalentTests/src/com/android/systemui/topwindoweffects/ui/compose/SqueezeEffectMotionTest.kt 0 → 100644 +129 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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 com.android.systemui.topwindoweffects.ui.compose import android.platform.test.annotations.MotionTest import androidx.annotation.DrawableRes import androidx.compose.runtime.Composable import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest import com.android.systemui.SysuiTestCase import com.android.systemui.jank.interactionJankMonitor import com.android.systemui.keyevent.data.repository.fakeKeyEventRepository import com.android.systemui.motion.createSysUiComposeMotionTestRule import com.android.systemui.res.R import com.android.systemui.testKosmos import com.android.systemui.topwindoweffects.data.repository.SqueezeEffectRepositoryImpl import com.android.systemui.topwindoweffects.ui.viewmodel.squeezeEffectViewModelFactory import com.android.wm.shell.appzoomout.appZoomOutOptional import com.android.wm.shell.appzoomout.fakeAppZoomOut import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import platform.test.motion.compose.ComposeRecordingSpec import platform.test.motion.compose.MotionControl import platform.test.motion.compose.feature import platform.test.motion.compose.recordMotion import platform.test.motion.compose.runTest import platform.test.motion.golden.DataPointTypes import platform.test.motion.golden.FeatureCapture import platform.test.motion.golden.asDataPoint @RunWith(AndroidJUnit4::class) @LargeTest @MotionTest class SqueezeEffectMotionTest : SysuiTestCase() { private val kosmos = testKosmos() @get:Rule val motionTestRule = createSysUiComposeMotionTestRule(kosmos) @DrawableRes private val topResId = R.drawable.rounded_corner_top @DrawableRes private val bottomResId = R.drawable.rounded_corner_bottom @Composable private fun SqueezeEffectUnderTest(onEffectFinished: () -> Unit) { SqueezeEffect( viewModelFactory = kosmos.squeezeEffectViewModelFactory, topRoundedCornerResourceId = topResId, bottomRoundedCornerResourceId = bottomResId, physicalPixelDisplaySizeRatio = 1f, onEffectFinished = onEffectFinished, appZoomOutOptional = kosmos.appZoomOutOptional, interactionJankMonitor = kosmos.interactionJankMonitor, onEffectStarted = {}, ) } @Test fun testSqueezeEffectMotion() = motionTestRule.runTest(timeout = 30.seconds) { kosmos.fakeKeyEventRepository.setPowerButtonDown(true) kosmos.fakeKeyEventRepository.setPowerButtonLongPressed(true) var effectFinished = false val motion = recordMotion( content = { play -> if (play) { SqueezeEffectUnderTest(onEffectFinished = { effectFinished = true }) } }, ComposeRecordingSpec.until(checkDone = { effectFinished }) { feature( FeatureCapture("topLevelZoom") { kosmos.fakeAppZoomOut.lastTopLevelScale.asDataPoint() } ) feature(MotionTestKeys.squeezeThickness, DataPointTypes.float) }, ) assertThat(motion).timeSeriesMatchesGolden() } @Test fun testSqueezeEffectCancelMotion() = motionTestRule.runTest(timeout = 30.seconds) { kosmos.fakeKeyEventRepository.setPowerButtonDown(true) kosmos.fakeKeyEventRepository.setPowerButtonLongPressed(false) var effectFinished = false val motionControl = MotionControl { awaitDelay(SqueezeEffectRepositoryImpl.DEFAULT_INITIAL_DELAY_MILLIS.milliseconds) kosmos.fakeKeyEventRepository.setPowerButtonDown(false) awaitCondition { effectFinished } } val motion = recordMotion( content = { play -> if (play) { SqueezeEffectUnderTest(onEffectFinished = { effectFinished = true }) } }, ComposeRecordingSpec(motionControl = motionControl) { feature( FeatureCapture("topLevelZoom") { kosmos.fakeAppZoomOut.lastTopLevelScale.asDataPoint() } ) feature(MotionTestKeys.squeezeThickness, DataPointTypes.float) }, ) assertThat(motion).timeSeriesMatchesGolden() } } packages/SystemUI/src/com/android/systemui/topwindoweffects/ui/compose/SqueezeEffect.kt +19 −3 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.topwindoweffects.ui.compose import androidx.annotation.DrawableRes import androidx.annotation.VisibleForTesting import androidx.compose.animation.core.Animatable import androidx.compose.animation.core.tween import androidx.compose.foundation.Canvas Loading Loading @@ -50,6 +51,8 @@ import com.android.systemui.topwindoweffects.ui.viewmodel.SqueezeEffectViewModel import com.android.wm.shell.appzoomout.AppZoomOut import java.util.Optional import kotlin.math.max import platform.test.motion.compose.values.MotionTestValueKey import platform.test.motion.compose.values.motionTestValues private val SqueezeColor = Color.Black private val SqueezeEffectMaxThickness = 16.dp Loading Loading @@ -140,11 +143,12 @@ fun SqueezeEffect( } } val density = LocalDensity.current val screenWidthPx = LocalWindowInfo.current.containerSize.width val screenHeightPx = LocalWindowInfo.current.containerSize.height val longEdgePx = max(screenHeightPx, screenWidthPx) val zoomPotentialPx = with(LocalDensity.current) { with(density) { (SqueezeEffectMaxThickness.toPx() - SqueezeEffectOverlapShortEdgeThickness.toPx()) * 2 } val zoomOutScale = 1f - (longEdgePx - zoomPotentialPx) / longEdgePx Loading @@ -155,11 +159,18 @@ fun SqueezeEffect( } } Canvas(modifier = Modifier.fillMaxSize()) { val squeezeThickness = with(density) { SqueezeEffectMaxThickness.toPx() * squeezeProgress.value } Canvas( modifier = Modifier.fillMaxSize().motionTestValues { squeezeThickness exportAs MotionTestKeys.squeezeThickness } ) { if (squeezeProgress.value <= 0) { return@Canvas } val squeezeThickness = SqueezeEffectMaxThickness.toPx() * squeezeProgress.value drawRect(color = SqueezeColor, size = Size(size.width, squeezeThickness)) Loading Loading @@ -242,3 +253,8 @@ private fun DrawScope.drawTransform( } } } @VisibleForTesting object MotionTestKeys { val squeezeThickness = MotionTestValueKey<Float>("squeezeThickness") } packages/SystemUI/tests/goldens/testSqueezeEffectCancelMotion.json 0 → 100644 +128 −0 Original line number Diff line number Diff line { "frame_ids": [ "before", 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256, 272, 288, 304, 320, 336, 352, 368, 384, 400, 416, 432, 448, 464, 480, 496, 512, 528, "after" ], "features": [ { "name": "topLevelZoom", "type": "float", "data_points": [ 1, 1, 1, 1, 0.99997663, 0.99990267, 0.99977136, 0.9995748, 0.9993037, 0.9989471, 0.99849236, 0.99792534, 0.99723065, 0.99639374, 0.99639374, 0.9964129, 0.9964791, 0.9966101, 0.99683064, 0.9971648, 0.9976032, 0.998071, 0.9984877, 0.9988274, 0.9990975, 0.9993119, 0.9994826, 0.99961853, 0.9997264, 0.99981135, 0.99987704, 0.9999264, 0.9999617, 0.99998474, 0.999997, 1 ] }, { "name": "squeezeThickness", "type": "float", "data_points": [ { "type": "not_found" }, 0, 0, 0, 0.0485566, 0.20243222, 0.47556558, 0.8844038, 1.4483277, 2.1900382, 3.135834, 4.3153386, 5.760244, 7.5010285, 7.5010285, 7.461228, 7.323543, 7.050966, 6.592264, 5.8971934, 4.9853473, 4.012273, 3.145575, 2.4389622, 1.8771063, 1.4311807, 1.0762641, 0.7935125, 0.5689978, 0.3923689, 0.25576895, 0.15314473, 0.07974452, 0.031769313, 0.006137736, 0 ] } ] } No newline at end of file packages/SystemUI/tests/goldens/testSqueezeEffectMotion.json 0 → 100644 +248 −0 Original line number Diff line number Diff line { "frame_ids": [ "before", 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256, 272, 288, 304, 320, 336, 352, 368, 384, 400, 416, 432, 448, 464, 480, 496, 512, 528, 544, 560, 576, 592, 608, 624, 640, 656, 672, 688, 704, 720, 736, 752, 768, 784, 800, 816, 832, 848, 864, 880, 896, 912, 928, 944, 960, 976, 992, 1008, 1024, 1040, 1056, 1072, 1088, 1104, 1120, 1136, 1152, 1168, "after" ], "features": [ { "name": "topLevelZoom", "type": "float", "data_points": [ 1, 1, 1, 1, 0.99997663, 0.99990267, 0.99977136, 0.9995748, 0.9993037, 0.9989471, 0.99849236, 0.99792534, 0.99723065, 0.99639374, 0.99540365, 0.9942581, 0.99297, 0.9915714, 0.9901113, 0.9886452, 0.9872224, 0.985877, 0.9846275, 0.98348016, 0.9824334, 0.98148155, 0.9806171, 0.9798323, 0.9791195, 0.9784718, 0.97788286, 0.97734714, 0.9768597, 0.9764163, 0.97601295, 0.97564644, 0.9753137, 0.97501224, 0.97473955, 0.9744936, 0.9742726, 0.9740748, 0.97389865, 0.9737428, 0.9736061, 0.9734873, 0.97338545, 0.9732996, 0.97322893, 0.9731726, 0.97312987, 0.97310007, 0.9730826, 0.97307694, 0.97307694, 0.9732198, 0.973714, 0.97469234, 0.97633874, 0.9788335, 0.9821063, 0.985599, 0.98870975, 0.991246, 0.9932626, 0.99486315, 0.996137, 0.9971519, 0.9979577, 0.99859166, 0.99908197, 0.9994503, 0.9997138, 0.999886, 0.99997795, 1 ] }, { "name": "squeezeThickness", "type": "float", "data_points": [ { "type": "not_found" }, 0, 0, 0, 0.0485566, 0.20243222, 0.47556558, 0.8844038, 1.4483277, 2.1900382, 3.135834, 4.3153386, 5.760244, 7.5010285, 9.560463, 11.943141, 14.622387, 17.531492, 20.568546, 23.617954, 26.577538, 29.37596, 31.974844, 34.361305, 36.53857, 38.518456, 40.31645, 41.94887, 43.43146, 44.77871, 46.00368, 47.11797, 48.131817, 49.054203, 49.89308, 50.655434, 51.347454, 51.974613, 52.541767, 53.053272, 53.51303, 53.924522, 54.290886, 54.61499, 54.899387, 55.14641, 55.35824, 55.53677, 55.683823, 55.801037, 55.889915, 55.951866, 55.988163, 56, 56, 55.70286, 54.674953, 52.63999, 49.21549, 44.02634, 37.218822, 29.954193, 23.483738, 18.20842, 14.013805, 10.684684, 8.035004, 5.924081, 4.2479343, 2.929286, 1.9094796, 1.1433239, 0.59534407, 0.23717833, 0.045822144, 0 ] } ] } No newline at end of file packages/SystemUI/tests/utils/src/com/android/systemui/topwindoweffects/ui/viewmodel/SqueezeEffectViewModelKosmos.kt 0 → 100644 +36 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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 com.android.systemui.topwindoweffects.ui.viewmodel import com.android.systemui.keyevent.domain.interactor.keyEventInteractor import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture val Kosmos.squeezeEffectViewModel by Fixture { SqueezeEffectViewModel( keyEventInteractor = keyEventInteractor, squeezeEffectHapticPlayerFactory = squeezeEffectHapticPlayerFactory, ) } val Kosmos.squeezeEffectViewModelFactory by Fixture { object : SqueezeEffectViewModel.Factory { override fun create(): SqueezeEffectViewModel { return squeezeEffectViewModel } } } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/topwindoweffects/ui/compose/SqueezeEffectMotionTest.kt 0 → 100644 +129 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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 com.android.systemui.topwindoweffects.ui.compose import android.platform.test.annotations.MotionTest import androidx.annotation.DrawableRes import androidx.compose.runtime.Composable import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.LargeTest import com.android.systemui.SysuiTestCase import com.android.systemui.jank.interactionJankMonitor import com.android.systemui.keyevent.data.repository.fakeKeyEventRepository import com.android.systemui.motion.createSysUiComposeMotionTestRule import com.android.systemui.res.R import com.android.systemui.testKosmos import com.android.systemui.topwindoweffects.data.repository.SqueezeEffectRepositoryImpl import com.android.systemui.topwindoweffects.ui.viewmodel.squeezeEffectViewModelFactory import com.android.wm.shell.appzoomout.appZoomOutOptional import com.android.wm.shell.appzoomout.fakeAppZoomOut import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import platform.test.motion.compose.ComposeRecordingSpec import platform.test.motion.compose.MotionControl import platform.test.motion.compose.feature import platform.test.motion.compose.recordMotion import platform.test.motion.compose.runTest import platform.test.motion.golden.DataPointTypes import platform.test.motion.golden.FeatureCapture import platform.test.motion.golden.asDataPoint @RunWith(AndroidJUnit4::class) @LargeTest @MotionTest class SqueezeEffectMotionTest : SysuiTestCase() { private val kosmos = testKosmos() @get:Rule val motionTestRule = createSysUiComposeMotionTestRule(kosmos) @DrawableRes private val topResId = R.drawable.rounded_corner_top @DrawableRes private val bottomResId = R.drawable.rounded_corner_bottom @Composable private fun SqueezeEffectUnderTest(onEffectFinished: () -> Unit) { SqueezeEffect( viewModelFactory = kosmos.squeezeEffectViewModelFactory, topRoundedCornerResourceId = topResId, bottomRoundedCornerResourceId = bottomResId, physicalPixelDisplaySizeRatio = 1f, onEffectFinished = onEffectFinished, appZoomOutOptional = kosmos.appZoomOutOptional, interactionJankMonitor = kosmos.interactionJankMonitor, onEffectStarted = {}, ) } @Test fun testSqueezeEffectMotion() = motionTestRule.runTest(timeout = 30.seconds) { kosmos.fakeKeyEventRepository.setPowerButtonDown(true) kosmos.fakeKeyEventRepository.setPowerButtonLongPressed(true) var effectFinished = false val motion = recordMotion( content = { play -> if (play) { SqueezeEffectUnderTest(onEffectFinished = { effectFinished = true }) } }, ComposeRecordingSpec.until(checkDone = { effectFinished }) { feature( FeatureCapture("topLevelZoom") { kosmos.fakeAppZoomOut.lastTopLevelScale.asDataPoint() } ) feature(MotionTestKeys.squeezeThickness, DataPointTypes.float) }, ) assertThat(motion).timeSeriesMatchesGolden() } @Test fun testSqueezeEffectCancelMotion() = motionTestRule.runTest(timeout = 30.seconds) { kosmos.fakeKeyEventRepository.setPowerButtonDown(true) kosmos.fakeKeyEventRepository.setPowerButtonLongPressed(false) var effectFinished = false val motionControl = MotionControl { awaitDelay(SqueezeEffectRepositoryImpl.DEFAULT_INITIAL_DELAY_MILLIS.milliseconds) kosmos.fakeKeyEventRepository.setPowerButtonDown(false) awaitCondition { effectFinished } } val motion = recordMotion( content = { play -> if (play) { SqueezeEffectUnderTest(onEffectFinished = { effectFinished = true }) } }, ComposeRecordingSpec(motionControl = motionControl) { feature( FeatureCapture("topLevelZoom") { kosmos.fakeAppZoomOut.lastTopLevelScale.asDataPoint() } ) feature(MotionTestKeys.squeezeThickness, DataPointTypes.float) }, ) assertThat(motion).timeSeriesMatchesGolden() } }
packages/SystemUI/src/com/android/systemui/topwindoweffects/ui/compose/SqueezeEffect.kt +19 −3 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.systemui.topwindoweffects.ui.compose import androidx.annotation.DrawableRes import androidx.annotation.VisibleForTesting import androidx.compose.animation.core.Animatable import androidx.compose.animation.core.tween import androidx.compose.foundation.Canvas Loading Loading @@ -50,6 +51,8 @@ import com.android.systemui.topwindoweffects.ui.viewmodel.SqueezeEffectViewModel import com.android.wm.shell.appzoomout.AppZoomOut import java.util.Optional import kotlin.math.max import platform.test.motion.compose.values.MotionTestValueKey import platform.test.motion.compose.values.motionTestValues private val SqueezeColor = Color.Black private val SqueezeEffectMaxThickness = 16.dp Loading Loading @@ -140,11 +143,12 @@ fun SqueezeEffect( } } val density = LocalDensity.current val screenWidthPx = LocalWindowInfo.current.containerSize.width val screenHeightPx = LocalWindowInfo.current.containerSize.height val longEdgePx = max(screenHeightPx, screenWidthPx) val zoomPotentialPx = with(LocalDensity.current) { with(density) { (SqueezeEffectMaxThickness.toPx() - SqueezeEffectOverlapShortEdgeThickness.toPx()) * 2 } val zoomOutScale = 1f - (longEdgePx - zoomPotentialPx) / longEdgePx Loading @@ -155,11 +159,18 @@ fun SqueezeEffect( } } Canvas(modifier = Modifier.fillMaxSize()) { val squeezeThickness = with(density) { SqueezeEffectMaxThickness.toPx() * squeezeProgress.value } Canvas( modifier = Modifier.fillMaxSize().motionTestValues { squeezeThickness exportAs MotionTestKeys.squeezeThickness } ) { if (squeezeProgress.value <= 0) { return@Canvas } val squeezeThickness = SqueezeEffectMaxThickness.toPx() * squeezeProgress.value drawRect(color = SqueezeColor, size = Size(size.width, squeezeThickness)) Loading Loading @@ -242,3 +253,8 @@ private fun DrawScope.drawTransform( } } } @VisibleForTesting object MotionTestKeys { val squeezeThickness = MotionTestValueKey<Float>("squeezeThickness") }
packages/SystemUI/tests/goldens/testSqueezeEffectCancelMotion.json 0 → 100644 +128 −0 Original line number Diff line number Diff line { "frame_ids": [ "before", 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256, 272, 288, 304, 320, 336, 352, 368, 384, 400, 416, 432, 448, 464, 480, 496, 512, 528, "after" ], "features": [ { "name": "topLevelZoom", "type": "float", "data_points": [ 1, 1, 1, 1, 0.99997663, 0.99990267, 0.99977136, 0.9995748, 0.9993037, 0.9989471, 0.99849236, 0.99792534, 0.99723065, 0.99639374, 0.99639374, 0.9964129, 0.9964791, 0.9966101, 0.99683064, 0.9971648, 0.9976032, 0.998071, 0.9984877, 0.9988274, 0.9990975, 0.9993119, 0.9994826, 0.99961853, 0.9997264, 0.99981135, 0.99987704, 0.9999264, 0.9999617, 0.99998474, 0.999997, 1 ] }, { "name": "squeezeThickness", "type": "float", "data_points": [ { "type": "not_found" }, 0, 0, 0, 0.0485566, 0.20243222, 0.47556558, 0.8844038, 1.4483277, 2.1900382, 3.135834, 4.3153386, 5.760244, 7.5010285, 7.5010285, 7.461228, 7.323543, 7.050966, 6.592264, 5.8971934, 4.9853473, 4.012273, 3.145575, 2.4389622, 1.8771063, 1.4311807, 1.0762641, 0.7935125, 0.5689978, 0.3923689, 0.25576895, 0.15314473, 0.07974452, 0.031769313, 0.006137736, 0 ] } ] } No newline at end of file
packages/SystemUI/tests/goldens/testSqueezeEffectMotion.json 0 → 100644 +248 −0 Original line number Diff line number Diff line { "frame_ids": [ "before", 0, 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240, 256, 272, 288, 304, 320, 336, 352, 368, 384, 400, 416, 432, 448, 464, 480, 496, 512, 528, 544, 560, 576, 592, 608, 624, 640, 656, 672, 688, 704, 720, 736, 752, 768, 784, 800, 816, 832, 848, 864, 880, 896, 912, 928, 944, 960, 976, 992, 1008, 1024, 1040, 1056, 1072, 1088, 1104, 1120, 1136, 1152, 1168, "after" ], "features": [ { "name": "topLevelZoom", "type": "float", "data_points": [ 1, 1, 1, 1, 0.99997663, 0.99990267, 0.99977136, 0.9995748, 0.9993037, 0.9989471, 0.99849236, 0.99792534, 0.99723065, 0.99639374, 0.99540365, 0.9942581, 0.99297, 0.9915714, 0.9901113, 0.9886452, 0.9872224, 0.985877, 0.9846275, 0.98348016, 0.9824334, 0.98148155, 0.9806171, 0.9798323, 0.9791195, 0.9784718, 0.97788286, 0.97734714, 0.9768597, 0.9764163, 0.97601295, 0.97564644, 0.9753137, 0.97501224, 0.97473955, 0.9744936, 0.9742726, 0.9740748, 0.97389865, 0.9737428, 0.9736061, 0.9734873, 0.97338545, 0.9732996, 0.97322893, 0.9731726, 0.97312987, 0.97310007, 0.9730826, 0.97307694, 0.97307694, 0.9732198, 0.973714, 0.97469234, 0.97633874, 0.9788335, 0.9821063, 0.985599, 0.98870975, 0.991246, 0.9932626, 0.99486315, 0.996137, 0.9971519, 0.9979577, 0.99859166, 0.99908197, 0.9994503, 0.9997138, 0.999886, 0.99997795, 1 ] }, { "name": "squeezeThickness", "type": "float", "data_points": [ { "type": "not_found" }, 0, 0, 0, 0.0485566, 0.20243222, 0.47556558, 0.8844038, 1.4483277, 2.1900382, 3.135834, 4.3153386, 5.760244, 7.5010285, 9.560463, 11.943141, 14.622387, 17.531492, 20.568546, 23.617954, 26.577538, 29.37596, 31.974844, 34.361305, 36.53857, 38.518456, 40.31645, 41.94887, 43.43146, 44.77871, 46.00368, 47.11797, 48.131817, 49.054203, 49.89308, 50.655434, 51.347454, 51.974613, 52.541767, 53.053272, 53.51303, 53.924522, 54.290886, 54.61499, 54.899387, 55.14641, 55.35824, 55.53677, 55.683823, 55.801037, 55.889915, 55.951866, 55.988163, 56, 56, 55.70286, 54.674953, 52.63999, 49.21549, 44.02634, 37.218822, 29.954193, 23.483738, 18.20842, 14.013805, 10.684684, 8.035004, 5.924081, 4.2479343, 2.929286, 1.9094796, 1.1433239, 0.59534407, 0.23717833, 0.045822144, 0 ] } ] } No newline at end of file
packages/SystemUI/tests/utils/src/com/android/systemui/topwindoweffects/ui/viewmodel/SqueezeEffectViewModelKosmos.kt 0 → 100644 +36 −0 Original line number Diff line number Diff line /* * Copyright (C) 2025 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 com.android.systemui.topwindoweffects.ui.viewmodel import com.android.systemui.keyevent.domain.interactor.keyEventInteractor import com.android.systemui.kosmos.Kosmos import com.android.systemui.kosmos.Kosmos.Fixture val Kosmos.squeezeEffectViewModel by Fixture { SqueezeEffectViewModel( keyEventInteractor = keyEventInteractor, squeezeEffectHapticPlayerFactory = squeezeEffectHapticPlayerFactory, ) } val Kosmos.squeezeEffectViewModelFactory by Fixture { object : SqueezeEffectViewModel.Factory { override fun create(): SqueezeEffectViewModel { return squeezeEffectViewModel } } }