1 /* 2 * Copyright (C) 2023 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 package com.android.launcher3.taskbar; 17 18 import static androidx.test.core.app.ApplicationProvider.getApplicationContext; 19 20 import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS; 21 22 import static com.google.common.truth.Truth.assertThat; 23 24 import static org.mockito.ArgumentMatchers.any; 25 import static org.mockito.ArgumentMatchers.anyInt; 26 import static org.mockito.ArgumentMatchers.anyString; 27 import static org.mockito.Mockito.doAnswer; 28 import static org.mockito.Mockito.doReturn; 29 import static org.mockito.Mockito.spy; 30 import static org.mockito.Mockito.verify; 31 import static org.mockito.Mockito.when; 32 33 import android.content.Context; 34 import android.testing.AndroidTestingRunner; 35 import android.testing.TestableLooper; 36 import android.view.Display; 37 import android.view.MotionEvent; 38 39 import androidx.test.filters.SmallTest; 40 41 import com.android.launcher3.BubbleTextView; 42 import com.android.launcher3.folder.Folder; 43 import com.android.launcher3.folder.FolderIcon; 44 import com.android.launcher3.model.data.FolderInfo; 45 import com.android.launcher3.util.ActivityContextWrapper; 46 47 import org.junit.Before; 48 import org.junit.Test; 49 import org.junit.runner.RunWith; 50 import org.mockito.Mock; 51 import org.mockito.MockitoAnnotations; 52 import org.mockito.stubbing.Answer; 53 54 /** 55 * Tests for TaskbarHoverToolTipController. 56 */ 57 @SmallTest 58 @RunWith(AndroidTestingRunner.class) 59 @TestableLooper.RunWithLooper(setAsMainLooper = true) 60 public class TaskbarHoverToolTipControllerTest extends TaskbarBaseTestCase { 61 62 private TaskbarHoverToolTipController mTaskbarHoverToolTipController; 63 private TestableLooper mTestableLooper; 64 65 @Mock private TaskbarView mTaskbarView; 66 @Mock private MotionEvent mMotionEvent; 67 @Mock private BubbleTextView mHoverBubbleTextView; 68 @Mock private FolderIcon mHoverFolderIcon; 69 @Mock private Display mDisplay; 70 @Mock private TaskbarDragLayer mTaskbarDragLayer; 71 private Folder mSpyFolderView; 72 73 @Before setup()74 public void setup() { 75 MockitoAnnotations.initMocks(this); 76 77 Context context = getApplicationContext(); 78 79 doAnswer((Answer<Object>) invocation -> context.getSystemService( 80 (String) invocation.getArgument(0))) 81 .when(taskbarActivityContext).getSystemService(anyString()); 82 when(taskbarActivityContext.getResources()).thenReturn(context.getResources()); 83 when(taskbarActivityContext.getApplicationInfo()).thenReturn( 84 context.getApplicationInfo()); 85 when(taskbarActivityContext.getDragLayer()).thenReturn(mTaskbarDragLayer); 86 when(taskbarActivityContext.getMainLooper()).thenReturn(context.getMainLooper()); 87 when(taskbarActivityContext.getDisplay()).thenReturn(mDisplay); 88 89 when(mTaskbarDragLayer.getChildCount()).thenReturn(1); 90 mSpyFolderView = spy(new Folder(new ActivityContextWrapper(context), null)); 91 when(mTaskbarDragLayer.getChildAt(anyInt())).thenReturn(mSpyFolderView); 92 doReturn(false).when(mSpyFolderView).isOpen(); 93 94 when(mHoverBubbleTextView.getText()).thenReturn("tooltip"); 95 doAnswer((Answer<Void>) invocation -> { 96 Object[] args = invocation.getArguments(); 97 ((int[]) args[0])[0] = 0; 98 ((int[]) args[0])[1] = 0; 99 return null; 100 }).when(mHoverBubbleTextView).getLocationOnScreen(any(int[].class)); 101 when(mHoverBubbleTextView.getWidth()).thenReturn(100); 102 when(mHoverBubbleTextView.getHeight()).thenReturn(100); 103 104 mHoverFolderIcon.mInfo = new FolderInfo(); 105 mHoverFolderIcon.mInfo.title = "tooltip"; 106 doAnswer((Answer<Void>) invocation -> { 107 Object[] args = invocation.getArguments(); 108 ((int[]) args[0])[0] = 0; 109 ((int[]) args[0])[1] = 0; 110 return null; 111 }).when(mHoverFolderIcon).getLocationOnScreen(any(int[].class)); 112 when(mHoverFolderIcon.getWidth()).thenReturn(100); 113 when(mHoverFolderIcon.getHeight()).thenReturn(100); 114 115 when(mTaskbarView.getTop()).thenReturn(200); 116 117 mTaskbarHoverToolTipController = new TaskbarHoverToolTipController( 118 taskbarActivityContext, mTaskbarView, mHoverBubbleTextView); 119 mTestableLooper = TestableLooper.get(this); 120 } 121 122 @Test onHover_hoverEnterIcon_revealToolTip()123 public void onHover_hoverEnterIcon_revealToolTip() { 124 when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_ENTER); 125 when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_ENTER); 126 127 boolean hoverHandled = 128 mTaskbarHoverToolTipController.onHover(mHoverBubbleTextView, mMotionEvent); 129 waitForIdleSync(); 130 131 assertThat(hoverHandled).isTrue(); 132 verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS, 133 true); 134 } 135 136 @Test onHover_hoverExitIcon_closeToolTip()137 public void onHover_hoverExitIcon_closeToolTip() { 138 when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_EXIT); 139 when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_EXIT); 140 141 boolean hoverHandled = 142 mTaskbarHoverToolTipController.onHover(mHoverBubbleTextView, mMotionEvent); 143 waitForIdleSync(); 144 145 assertThat(hoverHandled).isTrue(); 146 verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS, 147 false); 148 } 149 150 @Test onHover_hoverEnterFolderIcon_revealToolTip()151 public void onHover_hoverEnterFolderIcon_revealToolTip() { 152 when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_ENTER); 153 when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_ENTER); 154 155 boolean hoverHandled = 156 mTaskbarHoverToolTipController.onHover(mHoverFolderIcon, mMotionEvent); 157 waitForIdleSync(); 158 159 assertThat(hoverHandled).isTrue(); 160 verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS, 161 true); 162 } 163 164 @Test onHover_hoverExitFolderIcon_closeToolTip()165 public void onHover_hoverExitFolderIcon_closeToolTip() { 166 when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_EXIT); 167 when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_EXIT); 168 169 boolean hoverHandled = 170 mTaskbarHoverToolTipController.onHover(mHoverFolderIcon, mMotionEvent); 171 waitForIdleSync(); 172 173 assertThat(hoverHandled).isTrue(); 174 verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS, 175 false); 176 } 177 178 @Test onHover_hoverExitFolderOpen_closeToolTip()179 public void onHover_hoverExitFolderOpen_closeToolTip() { 180 when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_EXIT); 181 when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_EXIT); 182 doReturn(true).when(mSpyFolderView).isOpen(); 183 184 boolean hoverHandled = 185 mTaskbarHoverToolTipController.onHover(mHoverFolderIcon, mMotionEvent); 186 waitForIdleSync(); 187 188 assertThat(hoverHandled).isTrue(); 189 verify(taskbarActivityContext).setAutohideSuspendFlag(FLAG_AUTOHIDE_SUSPEND_HOVERING_ICONS, 190 false); 191 } 192 193 @Test onHover_hoverEnterFolderOpen_noToolTip()194 public void onHover_hoverEnterFolderOpen_noToolTip() { 195 when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_ENTER); 196 when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_ENTER); 197 doReturn(true).when(mSpyFolderView).isOpen(); 198 199 boolean hoverHandled = 200 mTaskbarHoverToolTipController.onHover(mHoverFolderIcon, mMotionEvent); 201 202 assertThat(hoverHandled).isFalse(); 203 } 204 205 @Test onHover_hoverMove_noUpdate()206 public void onHover_hoverMove_noUpdate() { 207 when(mMotionEvent.getAction()).thenReturn(MotionEvent.ACTION_HOVER_MOVE); 208 when(mMotionEvent.getActionMasked()).thenReturn(MotionEvent.ACTION_HOVER_MOVE); 209 210 boolean hoverHandled = 211 mTaskbarHoverToolTipController.onHover(mHoverFolderIcon, mMotionEvent); 212 213 assertThat(hoverHandled).isFalse(); 214 } 215 waitForIdleSync()216 private void waitForIdleSync() { 217 mTestableLooper.processAllMessages(); 218 } 219 } 220