[Media TTT] Don't hide the chip if the user taps the chip.
Fixes: 214274529 Fixes: 211487971 Test: manual (verify tapping chip doesn't hide chip) Test: media.taptotransfer tests Change-Id: Iba58f1d4adb694502a2f847c2d75779ff7fa92c0
This commit is contained in:
@@ -22,6 +22,7 @@ import android.content.Context
|
||||
import android.graphics.PixelFormat
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
@@ -31,6 +32,7 @@ import com.android.systemui.R
|
||||
import com.android.systemui.dagger.qualifiers.Main
|
||||
import com.android.systemui.statusbar.gesture.TapGestureDetector
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor
|
||||
import com.android.systemui.util.view.ViewUtil
|
||||
|
||||
/**
|
||||
* A superclass controller that provides common functionality for showing chips on the sender device
|
||||
@@ -42,6 +44,7 @@ import com.android.systemui.util.concurrency.DelayableExecutor
|
||||
abstract class MediaTttChipControllerCommon<T : MediaTttChipState>(
|
||||
internal val context: Context,
|
||||
private val windowManager: WindowManager,
|
||||
private val viewUtil: ViewUtil,
|
||||
@Main private val mainExecutor: DelayableExecutor,
|
||||
private val tapGestureDetector: TapGestureDetector,
|
||||
@LayoutRes private val chipLayoutRes: Int
|
||||
@@ -84,7 +87,7 @@ abstract class MediaTttChipControllerCommon<T : MediaTttChipState>(
|
||||
|
||||
// Add view if necessary
|
||||
if (oldChipView == null) {
|
||||
tapGestureDetector.addOnGestureDetectedCallback(TAG, this::removeChip)
|
||||
tapGestureDetector.addOnGestureDetectedCallback(TAG, this::onScreenTapped)
|
||||
windowManager.addView(chipView, windowLayoutParams)
|
||||
}
|
||||
|
||||
@@ -127,6 +130,15 @@ abstract class MediaTttChipControllerCommon<T : MediaTttChipState>(
|
||||
appIconView.setImageDrawable(appIcon)
|
||||
appIconView.visibility = visibility
|
||||
}
|
||||
|
||||
private fun onScreenTapped(e: MotionEvent) {
|
||||
val view = chipView ?: return
|
||||
// If the tap is within the chip bounds, we shouldn't hide the chip (in case users think the
|
||||
// chip is tappable).
|
||||
if (!viewUtil.touchIsWithinView(view, e.x, e.y)) {
|
||||
removeChip()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Used in CTS tests UpdateMediaTapToTransferSenderDisplayTest and
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.android.systemui.media.taptotransfer.common.MediaTttChipControllerCom
|
||||
import com.android.systemui.statusbar.CommandQueue
|
||||
import com.android.systemui.statusbar.gesture.TapGestureDetector
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor
|
||||
import com.android.systemui.util.view.ViewUtil
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
@@ -43,11 +44,17 @@ class MediaTttChipControllerReceiver @Inject constructor(
|
||||
commandQueue: CommandQueue,
|
||||
context: Context,
|
||||
windowManager: WindowManager,
|
||||
viewUtil: ViewUtil,
|
||||
mainExecutor: DelayableExecutor,
|
||||
tapGestureDetector: TapGestureDetector,
|
||||
@Main private val mainHandler: Handler,
|
||||
) : MediaTttChipControllerCommon<ChipStateReceiver>(
|
||||
context, windowManager, mainExecutor, tapGestureDetector, R.layout.media_ttt_chip_receiver
|
||||
context,
|
||||
windowManager,
|
||||
viewUtil,
|
||||
mainExecutor,
|
||||
tapGestureDetector,
|
||||
R.layout.media_ttt_chip_receiver
|
||||
) {
|
||||
private val commandQueueCallbacks = object : CommandQueue.Callbacks {
|
||||
override fun updateMediaTapToTransferReceiverDisplay(
|
||||
|
||||
@@ -32,6 +32,7 @@ import com.android.systemui.media.taptotransfer.common.MediaTttChipControllerCom
|
||||
import com.android.systemui.statusbar.CommandQueue
|
||||
import com.android.systemui.statusbar.gesture.TapGestureDetector
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor
|
||||
import com.android.systemui.util.view.ViewUtil
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
@@ -43,10 +44,11 @@ class MediaTttChipControllerSender @Inject constructor(
|
||||
commandQueue: CommandQueue,
|
||||
context: Context,
|
||||
windowManager: WindowManager,
|
||||
viewUtil: ViewUtil,
|
||||
@Main mainExecutor: DelayableExecutor,
|
||||
tapGestureDetector: TapGestureDetector,
|
||||
) : MediaTttChipControllerCommon<ChipStateSender>(
|
||||
context, windowManager, mainExecutor, tapGestureDetector, R.layout.media_ttt_chip
|
||||
context, windowManager, viewUtil, mainExecutor, tapGestureDetector, R.layout.media_ttt_chip
|
||||
) {
|
||||
private val commandQueueCallbacks = object : CommandQueue.Callbacks {
|
||||
override fun updateMediaTapToTransferSenderDisplay(
|
||||
|
||||
@@ -22,6 +22,7 @@ import android.os.Looper
|
||||
import android.view.Choreographer
|
||||
import android.view.Display
|
||||
import android.view.InputEvent
|
||||
import android.view.MotionEvent
|
||||
import com.android.systemui.shared.system.InputChannelCompat
|
||||
import com.android.systemui.shared.system.InputMonitorCompat
|
||||
|
||||
@@ -43,13 +44,17 @@ abstract class GenericGestureDetector(
|
||||
* Active callbacks, each associated with a tag. Gestures will only be monitored if
|
||||
* [callbacks.size] > 0.
|
||||
*/
|
||||
private val callbacks: MutableMap<String, () -> Unit> = mutableMapOf()
|
||||
private val callbacks: MutableMap<String, (MotionEvent) -> Unit> = mutableMapOf()
|
||||
|
||||
private var inputMonitor: InputMonitorCompat? = null
|
||||
private var inputReceiver: InputChannelCompat.InputEventReceiver? = null
|
||||
|
||||
/** Adds a callback that will be triggered when the tap gesture is detected. */
|
||||
fun addOnGestureDetectedCallback(tag: String, callback: () -> Unit) {
|
||||
/**
|
||||
* Adds a callback that will be triggered when the tap gesture is detected.
|
||||
*
|
||||
* The callback receive the last motion event in the gesture.
|
||||
*/
|
||||
fun addOnGestureDetectedCallback(tag: String, callback: (MotionEvent) -> Unit) {
|
||||
val callbacksWasEmpty = callbacks.isEmpty()
|
||||
callbacks[tag] = callback
|
||||
if (callbacksWasEmpty) {
|
||||
@@ -68,9 +73,12 @@ abstract class GenericGestureDetector(
|
||||
/** Triggered each time a touch event occurs (and at least one callback is registered). */
|
||||
abstract fun onInputEvent(ev: InputEvent)
|
||||
|
||||
/** Should be called by subclasses when their specific gesture is detected. */
|
||||
internal fun onGestureDetected() {
|
||||
callbacks.values.forEach { it.invoke() }
|
||||
/**
|
||||
* Should be called by subclasses when their specific gesture is detected with the last motion
|
||||
* event in the gesture.
|
||||
*/
|
||||
internal fun onGestureDetected(e: MotionEvent) {
|
||||
callbacks.values.forEach { it.invoke(e) }
|
||||
}
|
||||
|
||||
/** Start listening to touch events. */
|
||||
|
||||
@@ -80,7 +80,7 @@ open class SwipeStatusBarAwayGestureHandler @Inject constructor(
|
||||
) {
|
||||
monitoringCurrentTouch = false
|
||||
logger.logGestureDetected(ev.y.toInt())
|
||||
onGestureDetected()
|
||||
onGestureDetected(ev)
|
||||
}
|
||||
}
|
||||
ACTION_CANCEL, ACTION_UP -> {
|
||||
|
||||
@@ -33,8 +33,8 @@ class TapGestureDetector @Inject constructor(
|
||||
) : GenericGestureDetector(TapGestureDetector::class.simpleName!!) {
|
||||
|
||||
private val gestureListener = object : GestureDetector.SimpleOnGestureListener() {
|
||||
override fun onSingleTapUp(e: MotionEvent?): Boolean {
|
||||
onGestureDetected()
|
||||
override fun onSingleTapUp(e: MotionEvent): Boolean {
|
||||
onGestureDetected(e)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.android.systemui.unfold.UNFOLD_STATUS_BAR
|
||||
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
|
||||
import com.android.systemui.util.ViewController
|
||||
import com.android.systemui.util.kotlin.getOrNull
|
||||
import com.android.systemui.util.view.ViewUtil
|
||||
|
||||
import java.util.Optional
|
||||
|
||||
@@ -43,6 +44,7 @@ class PhoneStatusBarViewController private constructor(
|
||||
@Named(UNFOLD_STATUS_BAR) private val progressProvider: ScopedUnfoldTransitionProgressProvider?,
|
||||
private val moveFromCenterAnimationController: StatusBarMoveFromCenterAnimationController?,
|
||||
private val userSwitcherController: StatusBarUserSwitcherController,
|
||||
private val viewUtil: ViewUtil,
|
||||
touchEventHandler: PhoneStatusBarView.TouchEventHandler,
|
||||
private val configurationController: ConfigurationController
|
||||
) : ViewController<PhoneStatusBarView>(view) {
|
||||
@@ -118,12 +120,7 @@ class PhoneStatusBarViewController private constructor(
|
||||
* view's range and false otherwise.
|
||||
*/
|
||||
fun touchIsWithinView(x: Float, y: Float): Boolean {
|
||||
val left = mView.locationOnScreen[0]
|
||||
val top = mView.locationOnScreen[1]
|
||||
return left <= x &&
|
||||
x <= left + mView.width &&
|
||||
top <= y &&
|
||||
y <= top + mView.height
|
||||
return viewUtil.touchIsWithinView(mView, x, y)
|
||||
}
|
||||
|
||||
class StatusBarViewsCenterProvider : UnfoldMoveFromCenterAnimator.ViewCenterProvider {
|
||||
@@ -163,6 +160,7 @@ class PhoneStatusBarViewController private constructor(
|
||||
@Named(UNFOLD_STATUS_BAR)
|
||||
private val progressProvider: Optional<ScopedUnfoldTransitionProgressProvider>,
|
||||
private val userSwitcherController: StatusBarUserSwitcherController,
|
||||
private val viewUtil: ViewUtil,
|
||||
private val configurationController: ConfigurationController
|
||||
) {
|
||||
fun create(
|
||||
@@ -174,6 +172,7 @@ class PhoneStatusBarViewController private constructor(
|
||||
progressProvider.getOrNull(),
|
||||
unfoldComponent.getOrNull()?.getStatusBarMoveFromCenterAnimationController(),
|
||||
userSwitcherController,
|
||||
viewUtil,
|
||||
touchEventHandler,
|
||||
configurationController
|
||||
)
|
||||
|
||||
@@ -295,7 +295,7 @@ class OngoingCallController @Inject constructor(
|
||||
swipeStatusBarAwayGestureHandler.ifPresent { it.removeOnGestureDetectedCallback(TAG) }
|
||||
} else {
|
||||
swipeStatusBarAwayGestureHandler.ifPresent {
|
||||
it.addOnGestureDetectedCallback(TAG, this::onSwipeAwayGestureDetected)
|
||||
it.addOnGestureDetectedCallback(TAG) { _ -> onSwipeAwayGestureDetected() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.android.systemui.util.view
|
||||
|
||||
import android.view.View
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* A class with generic view utility methods.
|
||||
*
|
||||
* Doesn't use static methods so that it can be easily mocked out in tests.
|
||||
*/
|
||||
@SysUISingleton
|
||||
class ViewUtil @Inject constructor() {
|
||||
/**
|
||||
* Returns true if the given (x, y) point (in screen coordinates) is within the status bar
|
||||
* view's range and false otherwise.
|
||||
*/
|
||||
fun touchIsWithinView(view: View, x: Float, y: Float): Boolean {
|
||||
val left = view.locationOnScreen[0]
|
||||
val top = view.locationOnScreen[1]
|
||||
return left <= x &&
|
||||
x <= left + view.width &&
|
||||
top <= y &&
|
||||
y <= top + view.height
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package com.android.systemui.media.taptotransfer.common
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
@@ -30,7 +31,10 @@ import com.android.systemui.statusbar.gesture.TapGestureDetector
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor
|
||||
import com.android.systemui.util.concurrency.FakeExecutor
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.argumentCaptor
|
||||
import com.android.systemui.util.mockito.capture
|
||||
import com.android.systemui.util.time.FakeSystemClock
|
||||
import com.android.systemui.util.view.ViewUtil
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
@@ -39,6 +43,7 @@ import org.mockito.Mock
|
||||
import org.mockito.Mockito.never
|
||||
import org.mockito.Mockito.reset
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
@SmallTest
|
||||
@@ -52,6 +57,8 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
|
||||
@Mock
|
||||
private lateinit var windowManager: WindowManager
|
||||
@Mock
|
||||
private lateinit var viewUtil: ViewUtil
|
||||
@Mock
|
||||
private lateinit var tapGestureDetector: TapGestureDetector
|
||||
|
||||
@Before
|
||||
@@ -62,7 +69,7 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
|
||||
fakeExecutor = FakeExecutor(fakeClock)
|
||||
|
||||
controllerCommon = TestControllerCommon(
|
||||
context, windowManager, fakeExecutor, tapGestureDetector
|
||||
context, windowManager, viewUtil, fakeExecutor, tapGestureDetector
|
||||
)
|
||||
}
|
||||
|
||||
@@ -169,6 +176,40 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
|
||||
.isEqualTo(state.getAppName(context))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun tapGestureDetected_outsideViewBounds_viewHidden() {
|
||||
controllerCommon.displayChip(getState())
|
||||
whenever(viewUtil.touchIsWithinView(any(), any(), any())).thenReturn(false)
|
||||
val gestureCallbackCaptor = argumentCaptor<(MotionEvent) -> Unit>()
|
||||
verify(tapGestureDetector).addOnGestureDetectedCallback(
|
||||
any(), capture(gestureCallbackCaptor)
|
||||
)
|
||||
val callback = gestureCallbackCaptor.value!!
|
||||
|
||||
callback.invoke(
|
||||
MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
|
||||
)
|
||||
|
||||
verify(windowManager).removeView(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun tapGestureDetected_insideViewBounds_viewNotHidden() {
|
||||
controllerCommon.displayChip(getState())
|
||||
whenever(viewUtil.touchIsWithinView(any(), any(), any())).thenReturn(true)
|
||||
val gestureCallbackCaptor = argumentCaptor<(MotionEvent) -> Unit>()
|
||||
verify(tapGestureDetector).addOnGestureDetectedCallback(
|
||||
any(), capture(gestureCallbackCaptor)
|
||||
)
|
||||
val callback = gestureCallbackCaptor.value!!
|
||||
|
||||
callback.invoke(
|
||||
MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
|
||||
)
|
||||
|
||||
verify(windowManager, never()).removeView(any())
|
||||
}
|
||||
|
||||
private fun getState() = MediaTttChipState(PACKAGE_NAME)
|
||||
|
||||
private fun getChipView(): ViewGroup {
|
||||
@@ -182,10 +223,11 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
|
||||
inner class TestControllerCommon(
|
||||
context: Context,
|
||||
windowManager: WindowManager,
|
||||
viewUtil: ViewUtil,
|
||||
@Main mainExecutor: DelayableExecutor,
|
||||
tapGestureDetector: TapGestureDetector,
|
||||
) : MediaTttChipControllerCommon<MediaTttChipState>(
|
||||
context, windowManager, mainExecutor, tapGestureDetector, R.layout.media_ttt_chip
|
||||
context, windowManager, viewUtil, mainExecutor, tapGestureDetector, R.layout.media_ttt_chip
|
||||
) {
|
||||
override fun updateChipView(chipState: MediaTttChipState, currentChipView: ViewGroup) {
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import com.android.systemui.util.concurrency.FakeExecutor
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.eq
|
||||
import com.android.systemui.util.time.FakeSystemClock
|
||||
import com.android.systemui.util.view.ViewUtil
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
@@ -61,6 +62,8 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
|
||||
@Mock
|
||||
private lateinit var windowManager: WindowManager
|
||||
@Mock
|
||||
private lateinit var viewUtil: ViewUtil
|
||||
@Mock
|
||||
private lateinit var commandQueue: CommandQueue
|
||||
private lateinit var commandQueueCallback: CommandQueue.Callbacks
|
||||
private lateinit var fakeAppIconDrawable: Drawable
|
||||
@@ -81,6 +84,7 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
|
||||
commandQueue,
|
||||
context,
|
||||
windowManager,
|
||||
viewUtil,
|
||||
FakeExecutor(FakeSystemClock()),
|
||||
TapGestureDetector(context),
|
||||
Handler.getMain(),
|
||||
|
||||
@@ -38,6 +38,8 @@ import com.android.systemui.util.concurrency.FakeExecutor
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.eq
|
||||
import com.android.systemui.util.time.FakeSystemClock
|
||||
import com.android.systemui.util.view.ViewUtil
|
||||
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
@@ -62,6 +64,8 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
|
||||
@Mock
|
||||
private lateinit var windowManager: WindowManager
|
||||
@Mock
|
||||
private lateinit var viewUtil: ViewUtil
|
||||
@Mock
|
||||
private lateinit var commandQueue: CommandQueue
|
||||
private lateinit var commandQueueCallback: CommandQueue.Callbacks
|
||||
private lateinit var fakeAppIconDrawable: Drawable
|
||||
@@ -82,6 +86,7 @@ class MediaTttChipControllerSenderTest : SysuiTestCase() {
|
||||
commandQueue,
|
||||
context,
|
||||
windowManager,
|
||||
viewUtil,
|
||||
FakeExecutor(FakeSystemClock()),
|
||||
TapGestureDetector(context)
|
||||
)
|
||||
|
||||
@@ -111,7 +111,7 @@ class GenericGestureDetectorTest : SysuiTestCase() {
|
||||
|
||||
override fun onInputEvent(ev: InputEvent) {
|
||||
if (ev is MotionEvent && ev.x == CORRECT_X) {
|
||||
onGestureDetected()
|
||||
onGestureDetected(ev)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import com.android.systemui.statusbar.policy.ConfigurationController
|
||||
import com.android.systemui.unfold.SysUIUnfoldComponent
|
||||
import com.android.systemui.unfold.config.UnfoldTransitionConfig
|
||||
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
|
||||
import com.android.systemui.util.view.ViewUtil
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
@@ -63,6 +64,8 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() {
|
||||
private lateinit var configurationController: ConfigurationController
|
||||
@Mock
|
||||
private lateinit var userSwitcherController: StatusBarUserSwitcherController
|
||||
@Mock
|
||||
private lateinit var viewUtil: ViewUtil
|
||||
|
||||
private lateinit var view: PhoneStatusBarView
|
||||
private lateinit var controller: PhoneStatusBarViewController
|
||||
@@ -80,7 +83,6 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() {
|
||||
val parent = FrameLayout(mContext) // add parent to keep layout params
|
||||
view = LayoutInflater.from(mContext)
|
||||
.inflate(R.layout.status_bar, parent, false) as PhoneStatusBarView
|
||||
view.setLeftTopRightBottom(VIEW_LEFT, VIEW_TOP, VIEW_RIGHT, VIEW_BOTTOM)
|
||||
}
|
||||
|
||||
controller = createAndInitController(view)
|
||||
@@ -111,64 +113,6 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() {
|
||||
verify(moveFromCenterAnimation).onViewsReady(any())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun touchIsWithinView_inBounds_returnsTrue() {
|
||||
val view = createViewMockWithScreenLocation()
|
||||
controller = createAndInitController(view)
|
||||
|
||||
assertThat(controller.touchIsWithinView(VIEW_LEFT + 1f, VIEW_TOP + 1f)).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun touchIsWithinView_onTopLeftCorner_returnsTrue() {
|
||||
val view = createViewMockWithScreenLocation()
|
||||
controller = createAndInitController(view)
|
||||
|
||||
assertThat(controller.touchIsWithinView(VIEW_LEFT.toFloat(), VIEW_TOP.toFloat())).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun touchIsWithinView_onBottomRightCorner_returnsTrue() {
|
||||
val view = createViewMockWithScreenLocation()
|
||||
controller = createAndInitController(view)
|
||||
|
||||
assertThat(controller.touchIsWithinView(
|
||||
VIEW_RIGHT.toFloat(), VIEW_BOTTOM.toFloat())
|
||||
).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun touchIsWithinView_xTooSmall_returnsFalse() {
|
||||
val view = createViewMockWithScreenLocation()
|
||||
controller = createAndInitController(view)
|
||||
|
||||
assertThat(controller.touchIsWithinView(VIEW_LEFT - 1f, VIEW_TOP + 1f)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun touchIsWithinView_xTooLarge_returnsFalse() {
|
||||
val view = createViewMockWithScreenLocation()
|
||||
controller = createAndInitController(view)
|
||||
|
||||
assertThat(controller.touchIsWithinView(VIEW_RIGHT + 1f, VIEW_TOP + 1f)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun touchIsWithinView_yTooSmall_returnsFalse() {
|
||||
val view = createViewMockWithScreenLocation()
|
||||
controller = createAndInitController(view)
|
||||
|
||||
assertThat(controller.touchIsWithinView(VIEW_LEFT + 1f, VIEW_TOP - 1f)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun touchIsWithinView_yTooLarge_returnsFalse() {
|
||||
val view = createViewMockWithScreenLocation()
|
||||
controller = createAndInitController(view)
|
||||
|
||||
assertThat(controller.touchIsWithinView(VIEW_LEFT + 1f, VIEW_BOTTOM + 1f)).isFalse()
|
||||
}
|
||||
|
||||
private fun createViewMock(): PhoneStatusBarView {
|
||||
val view = spy(view)
|
||||
val viewTreeObserver = mock(ViewTreeObserver::class.java)
|
||||
@@ -177,20 +121,12 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() {
|
||||
return view
|
||||
}
|
||||
|
||||
private fun createViewMockWithScreenLocation(): PhoneStatusBarView {
|
||||
val view = spy(view)
|
||||
val location = IntArray(2)
|
||||
location[0] = VIEW_LEFT
|
||||
location[1] = VIEW_TOP
|
||||
`when`(view.locationOnScreen).thenReturn(location)
|
||||
return view
|
||||
}
|
||||
|
||||
private fun createAndInitController(view: PhoneStatusBarView): PhoneStatusBarViewController {
|
||||
return PhoneStatusBarViewController.Factory(
|
||||
Optional.of(sysuiUnfoldComponent),
|
||||
Optional.of(progressProvider),
|
||||
userSwitcherController,
|
||||
viewUtil,
|
||||
configurationController
|
||||
).create(view, touchEventHandler).also {
|
||||
it.init()
|
||||
@@ -215,8 +151,3 @@ class PhoneStatusBarViewControllerTest : SysuiTestCase() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const val VIEW_LEFT = 30
|
||||
private const val VIEW_RIGHT = 100
|
||||
private const val VIEW_TOP = 40
|
||||
private const val VIEW_BOTTOM = 100
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.android.systemui.util.view
|
||||
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.mockito.Mockito.spy
|
||||
import org.mockito.Mockito.`when`
|
||||
|
||||
@SmallTest
|
||||
class ViewUtilTest : SysuiTestCase() {
|
||||
private val viewUtil = ViewUtil()
|
||||
private lateinit var view: View
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
view = TextView(context)
|
||||
view.setLeftTopRightBottom(VIEW_LEFT, VIEW_TOP, VIEW_RIGHT, VIEW_BOTTOM)
|
||||
|
||||
view = spy(view)
|
||||
val location = IntArray(2)
|
||||
location[0] = VIEW_LEFT
|
||||
location[1] = VIEW_TOP
|
||||
`when`(view.locationOnScreen).thenReturn(location)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun touchIsWithinView_inBounds_returnsTrue() {
|
||||
assertThat(viewUtil.touchIsWithinView(view, VIEW_LEFT + 1f, VIEW_TOP + 1f)).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun touchIsWithinView_onTopLeftCorner_returnsTrue() {
|
||||
assertThat(viewUtil.touchIsWithinView(
|
||||
view, VIEW_LEFT.toFloat(), VIEW_TOP.toFloat())
|
||||
).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun touchIsWithinView_onBottomRightCorner_returnsTrue() {
|
||||
assertThat(viewUtil.touchIsWithinView(view, VIEW_RIGHT.toFloat(), VIEW_BOTTOM.toFloat()))
|
||||
.isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun touchIsWithinView_xTooSmall_returnsFalse() {
|
||||
assertThat(viewUtil.touchIsWithinView(view, VIEW_LEFT - 1f, VIEW_TOP + 1f)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun touchIsWithinView_xTooLarge_returnsFalse() {
|
||||
assertThat(viewUtil.touchIsWithinView(view, VIEW_RIGHT + 1f, VIEW_TOP + 1f)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun touchIsWithinView_yTooSmall_returnsFalse() {
|
||||
assertThat(viewUtil.touchIsWithinView(view, VIEW_LEFT + 1f, VIEW_TOP - 1f)).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun touchIsWithinView_yTooLarge_returnsFalse() {
|
||||
assertThat(viewUtil.touchIsWithinView(view, VIEW_LEFT + 1f, VIEW_BOTTOM + 1f)).isFalse()
|
||||
}
|
||||
}
|
||||
|
||||
private const val VIEW_LEFT = 30
|
||||
private const val VIEW_RIGHT = 100
|
||||
private const val VIEW_TOP = 40
|
||||
private const val VIEW_BOTTOM = 100
|
||||
Reference in New Issue
Block a user