1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.statusbar.phone 18 19 import android.view.LayoutInflater 20 import android.view.MotionEvent 21 import android.view.ViewGroup 22 import android.view.ViewTreeObserver 23 import android.view.ViewTreeObserver.OnPreDrawListener 24 import android.widget.FrameLayout 25 import androidx.test.filters.SmallTest 26 import androidx.test.platform.app.InstrumentationRegistry 27 import com.android.systemui.R 28 import com.android.systemui.SysuiTestCase 29 import com.android.systemui.unfold.SysUIUnfoldComponent 30 import com.android.systemui.unfold.config.UnfoldTransitionConfig 31 import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider 32 import com.android.systemui.util.mockito.any 33 import com.google.common.truth.Truth.assertThat 34 import org.junit.Before 35 import org.junit.Test 36 import org.mockito.ArgumentCaptor 37 import org.mockito.Mock 38 import org.mockito.Mockito.spy 39 import org.mockito.Mockito.mock 40 import org.mockito.Mockito.`when` 41 import org.mockito.Mockito.verify 42 import org.mockito.MockitoAnnotations 43 import java.util.Optional 44 45 @SmallTest 46 class PhoneStatusBarViewControllerTest : SysuiTestCase() { 47 48 private val touchEventHandler = TestTouchEventHandler() 49 50 @Mock 51 private lateinit var panelViewController: PanelViewController 52 @Mock 53 private lateinit var panelView: ViewGroup 54 @Mock 55 private lateinit var moveFromCenterAnimation: StatusBarMoveFromCenterAnimationController 56 @Mock 57 private lateinit var sysuiUnfoldComponent: SysUIUnfoldComponent 58 @Mock 59 private lateinit var progressProvider: ScopedUnfoldTransitionProgressProvider 60 61 private lateinit var view: PhoneStatusBarView 62 private lateinit var controller: PhoneStatusBarViewController 63 64 private val unfoldConfig = UnfoldConfig() 65 66 @Before 67 fun setUp() { 68 MockitoAnnotations.initMocks(this) 69 `when`(panelViewController.view).thenReturn(panelView) 70 `when`(sysuiUnfoldComponent.getStatusBarMoveFromCenterAnimationController()) 71 .thenReturn(moveFromCenterAnimation) 72 // create the view on main thread as it requires main looper 73 InstrumentationRegistry.getInstrumentation().runOnMainSync { 74 val parent = FrameLayout(mContext) // add parent to keep layout params 75 view = LayoutInflater.from(mContext) 76 .inflate(R.layout.status_bar, parent, false) as PhoneStatusBarView 77 } 78 79 controller = createController(view) 80 } 81 82 @Test 83 fun constructor_setsTouchHandlerOnView() { 84 val interceptEvent = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 10f, 10f, 0) 85 val event = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0) 86 87 view.onInterceptTouchEvent(interceptEvent) 88 view.onTouchEvent(event) 89 90 assertThat(touchEventHandler.lastInterceptEvent).isEqualTo(interceptEvent) 91 assertThat(touchEventHandler.lastEvent).isEqualTo(event) 92 } 93 94 @Test 95 fun onViewAttachedAndDrawn_moveFromCenterAnimationEnabled_moveFromCenterAnimationInitialized() { 96 val view = createViewMock() 97 val argumentCaptor = ArgumentCaptor.forClass(OnPreDrawListener::class.java) 98 unfoldConfig.isEnabled = true 99 controller = createController(view) 100 controller.init() 101 102 verify(view.viewTreeObserver).addOnPreDrawListener(argumentCaptor.capture()) 103 argumentCaptor.value.onPreDraw() 104 105 verify(moveFromCenterAnimation).onViewsReady(any()) 106 } 107 108 private fun createViewMock(): PhoneStatusBarView { 109 val view = spy(view) 110 val viewTreeObserver = mock(ViewTreeObserver::class.java) 111 `when`(view.viewTreeObserver).thenReturn(viewTreeObserver) 112 `when`(view.isAttachedToWindow).thenReturn(true) 113 return view 114 } 115 116 private fun createController(view: PhoneStatusBarView): PhoneStatusBarViewController { 117 return PhoneStatusBarViewController.Factory( 118 Optional.of(sysuiUnfoldComponent), 119 Optional.of(progressProvider) 120 ).create(view, touchEventHandler) 121 } 122 123 private class UnfoldConfig : UnfoldTransitionConfig { 124 override var isEnabled: Boolean = false 125 override var isHingeAngleEnabled: Boolean = false 126 } 127 128 private class TestTouchEventHandler : PhoneStatusBarView.TouchEventHandler { 129 var lastEvent: MotionEvent? = null 130 var lastInterceptEvent: MotionEvent? = null 131 132 override fun onInterceptTouchEvent(event: MotionEvent?) { 133 lastInterceptEvent = event 134 } 135 override fun handleTouchEvent(event: MotionEvent?): Boolean { 136 lastEvent = event 137 return false 138 } 139 } 140 } 141