Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/MagneticDividerUtils.kt +4 −6 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.wm.shell.common.split import android.content.res.Resources import androidx.annotation.VisibleForTesting import androidx.compose.ui.unit.dp import com.android.mechanics.spec.Mapping import com.android.mechanics.spec.MotionSpec Loading @@ -37,7 +38,7 @@ object MagneticDividerUtils { * When the user moves the divider towards or away from a snap point, a magnetic spring movement * and haptic will take place at this distance. */ private val DEFAULT_MAGNETIC_ATTACH_THRESHOLD = 56.dp @VisibleForTesting val DEFAULT_MAGNETIC_ATTACH_THRESHOLD = 56.dp /** The minimum spacing between snap zones, to prevent overlap on smaller displays. */ private val MINIMUM_SPACE_BETWEEN_SNAP_ZONES = 4.dp /** The stiffness of the magnetic snap effect. */ Loading @@ -53,7 +54,7 @@ object MagneticDividerUtils { * A key that can be passed into a MotionValue to retrieve the SnapPosition associated with the * current drag. */ @JvmStatic val SNAP_POSITION_KEY = SemanticKey<Int?>() @JvmStatic val SNAP_POSITION_KEY = SemanticKey<Int?>(debugLabel = "snapPosition") /** * Create a MotionSpec that has "snap zones" for each of the SnapTargets provided. Loading Loading @@ -83,8 +84,6 @@ object MagneticDividerUtils { semantics = listOf(SNAP_POSITION_KEY with topLeftDismissTarget.snapPosition), defaultSpring = MagneticSpring, ) { // NOTE: This block is a trailing lambda passed in as the "init" parameter. // A DirectionalMotionSpec is essentially a number line from -infinity to infinity, // with instructions on how to interpret the value at each point. We create each // individual segment below to fill out our number line. Loading Loading @@ -149,8 +148,7 @@ object MagneticDividerUtils { fixedValue( breakpoint = bottomRightDismissPosition, value = bottomRightDismissPosition, semantics = listOf(SNAP_POSITION_KEY with bottomRightDismissTarget.snapPosition), semantics = listOf(SNAP_POSITION_KEY with bottomRightDismissTarget.snapPosition), ) } ) Loading libs/WindowManager/Shell/tests/unittest/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ android_test { ], static_libs: [ "//frameworks/libs/systemui/mechanics:mechanics-testing", "TestParameterInjector", "WMShellTests-utils", "WindowManager-Shell", Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/MagneticDividerUtilsTests.kt +49 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,11 @@ package com.android.wm.shell.common.split import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import com.android.mechanics.spec.Mapping import com.android.mechanics.spec.builder.MotionBuilderContext import com.android.mechanics.testing.DirectionalMotionSpecSubject.Companion.assertThat import com.android.mechanics.testing.FakeMotionSpecBuilderContext import com.android.mechanics.testing.MotionSpecSubject.Companion.assertThat import com.android.wm.shell.common.split.DividerSnapAlgorithm.SnapTarget import com.android.wm.shell.common.split.MagneticDividerUtils.generateMotionSpec import com.android.wm.shell.shared.split.SplitScreenConstants Loading @@ -26,7 +31,7 @@ import org.junit.Test import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class MagneticDividerUtilsTests { class MagneticDividerUtilsTests : MotionBuilderContext by FakeMotionSpecBuilderContext.Default { @Test fun generateMotionSpec_worksOnThisDeviceWithoutCrashing() { Loading @@ -53,4 +58,47 @@ class MagneticDividerUtilsTests { // screens. assertThat(generateMotionSpec(targets, resources)).isNotNull() } @Test fun generateMotionSpec_specMatchesExpectations() { val zoneHalfSizePx = MagneticDividerUtils.DEFAULT_MAGNETIC_ATTACH_THRESHOLD.toPx() val targets = listOf( SnapTarget(0, SplitScreenConstants.SNAP_TO_START_AND_DISMISS), SnapTarget(500, SplitScreenConstants.SNAP_TO_2_50_50), SnapTarget(1000, SplitScreenConstants.SNAP_TO_END_AND_DISMISS), ) val generated = generateMotionSpec(targets) assertThat(generated.minDirection).isSameInstanceAs(generated.maxDirection) val spec = generated.minDirection assertThat(spec) .breakpoints() .positions() .containsExactly(0f, 500f - zoneHalfSizePx, 500f + zoneHalfSizePx, 1000f) .inOrder() assertThat(spec) .mappingsMatch( Mapping.Fixed(0f), Mapping.Identity, Mapping.Linear(0.5f, offset = 250f), Mapping.Identity, Mapping.Fixed(1000f), ) assertThat(spec) .semantics() .withKey(MagneticDividerUtils.SNAP_POSITION_KEY) .containsExactly( SplitScreenConstants.SNAP_TO_START_AND_DISMISS, null, SplitScreenConstants.SNAP_TO_2_50_50, null, SplitScreenConstants.SNAP_TO_END_AND_DISMISS, ) } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/MagneticDividerUtils.kt +4 −6 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.wm.shell.common.split import android.content.res.Resources import androidx.annotation.VisibleForTesting import androidx.compose.ui.unit.dp import com.android.mechanics.spec.Mapping import com.android.mechanics.spec.MotionSpec Loading @@ -37,7 +38,7 @@ object MagneticDividerUtils { * When the user moves the divider towards or away from a snap point, a magnetic spring movement * and haptic will take place at this distance. */ private val DEFAULT_MAGNETIC_ATTACH_THRESHOLD = 56.dp @VisibleForTesting val DEFAULT_MAGNETIC_ATTACH_THRESHOLD = 56.dp /** The minimum spacing between snap zones, to prevent overlap on smaller displays. */ private val MINIMUM_SPACE_BETWEEN_SNAP_ZONES = 4.dp /** The stiffness of the magnetic snap effect. */ Loading @@ -53,7 +54,7 @@ object MagneticDividerUtils { * A key that can be passed into a MotionValue to retrieve the SnapPosition associated with the * current drag. */ @JvmStatic val SNAP_POSITION_KEY = SemanticKey<Int?>() @JvmStatic val SNAP_POSITION_KEY = SemanticKey<Int?>(debugLabel = "snapPosition") /** * Create a MotionSpec that has "snap zones" for each of the SnapTargets provided. Loading Loading @@ -83,8 +84,6 @@ object MagneticDividerUtils { semantics = listOf(SNAP_POSITION_KEY with topLeftDismissTarget.snapPosition), defaultSpring = MagneticSpring, ) { // NOTE: This block is a trailing lambda passed in as the "init" parameter. // A DirectionalMotionSpec is essentially a number line from -infinity to infinity, // with instructions on how to interpret the value at each point. We create each // individual segment below to fill out our number line. Loading Loading @@ -149,8 +148,7 @@ object MagneticDividerUtils { fixedValue( breakpoint = bottomRightDismissPosition, value = bottomRightDismissPosition, semantics = listOf(SNAP_POSITION_KEY with bottomRightDismissTarget.snapPosition), semantics = listOf(SNAP_POSITION_KEY with bottomRightDismissTarget.snapPosition), ) } ) Loading
libs/WindowManager/Shell/tests/unittest/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -37,6 +37,7 @@ android_test { ], static_libs: [ "//frameworks/libs/systemui/mechanics:mechanics-testing", "TestParameterInjector", "WMShellTests-utils", "WindowManager-Shell", Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/MagneticDividerUtilsTests.kt +49 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,11 @@ package com.android.wm.shell.common.split import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import com.android.mechanics.spec.Mapping import com.android.mechanics.spec.builder.MotionBuilderContext import com.android.mechanics.testing.DirectionalMotionSpecSubject.Companion.assertThat import com.android.mechanics.testing.FakeMotionSpecBuilderContext import com.android.mechanics.testing.MotionSpecSubject.Companion.assertThat import com.android.wm.shell.common.split.DividerSnapAlgorithm.SnapTarget import com.android.wm.shell.common.split.MagneticDividerUtils.generateMotionSpec import com.android.wm.shell.shared.split.SplitScreenConstants Loading @@ -26,7 +31,7 @@ import org.junit.Test import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class MagneticDividerUtilsTests { class MagneticDividerUtilsTests : MotionBuilderContext by FakeMotionSpecBuilderContext.Default { @Test fun generateMotionSpec_worksOnThisDeviceWithoutCrashing() { Loading @@ -53,4 +58,47 @@ class MagneticDividerUtilsTests { // screens. assertThat(generateMotionSpec(targets, resources)).isNotNull() } @Test fun generateMotionSpec_specMatchesExpectations() { val zoneHalfSizePx = MagneticDividerUtils.DEFAULT_MAGNETIC_ATTACH_THRESHOLD.toPx() val targets = listOf( SnapTarget(0, SplitScreenConstants.SNAP_TO_START_AND_DISMISS), SnapTarget(500, SplitScreenConstants.SNAP_TO_2_50_50), SnapTarget(1000, SplitScreenConstants.SNAP_TO_END_AND_DISMISS), ) val generated = generateMotionSpec(targets) assertThat(generated.minDirection).isSameInstanceAs(generated.maxDirection) val spec = generated.minDirection assertThat(spec) .breakpoints() .positions() .containsExactly(0f, 500f - zoneHalfSizePx, 500f + zoneHalfSizePx, 1000f) .inOrder() assertThat(spec) .mappingsMatch( Mapping.Fixed(0f), Mapping.Identity, Mapping.Linear(0.5f, offset = 250f), Mapping.Identity, Mapping.Fixed(1000f), ) assertThat(spec) .semantics() .withKey(MagneticDividerUtils.SNAP_POSITION_KEY) .containsExactly( SplitScreenConstants.SNAP_TO_START_AND_DISMISS, null, SplitScreenConstants.SNAP_TO_2_50_50, null, SplitScreenConstants.SNAP_TO_END_AND_DISMISS, ) } }