1 /* 2 * Copyright (C) 2016 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.documentsui.selection; 18 19 import static com.android.documentsui.testing.TestEvents.Mouse.ALT_CLICK; 20 import static com.android.documentsui.testing.TestEvents.Mouse.CLICK; 21 import static com.android.documentsui.testing.TestEvents.Mouse.CTRL_CLICK; 22 import static com.android.documentsui.testing.TestEvents.Mouse.SECONDARY_CLICK; 23 import static com.android.documentsui.testing.TestEvents.Mouse.SHIFT_CLICK; 24 import static com.android.documentsui.testing.TestEvents.Mouse.TERTIARY_CLICK; 25 import static org.junit.Assert.assertFalse; 26 import static org.junit.Assert.assertTrue; 27 28 import android.support.test.filters.SmallTest; 29 import android.support.test.runner.AndroidJUnit4; 30 import android.support.v7.widget.RecyclerView; 31 import android.view.MotionEvent; 32 33 import com.android.documentsui.selection.SelectionHelper; 34 import com.android.documentsui.selection.testing.SelectionHelpers; 35 import com.android.documentsui.selection.testing.SelectionProbe; 36 import com.android.documentsui.selection.testing.TestData; 37 import com.android.documentsui.selection.testing.TestEvents; 38 import com.android.documentsui.selection.testing.TestMouseCallbacks; 39 40 import org.junit.Before; 41 import org.junit.Test; 42 import org.junit.runner.RunWith; 43 44 import java.util.List; 45 46 @RunWith(AndroidJUnit4.class) 47 @SmallTest 48 public final class MouseInputHandlerTest { 49 50 private static final List<String> ITEMS = TestData.create(100); 51 52 private MouseInputHandler mInputDelegate; 53 private TestMouseCallbacks mCallbacks; 54 private TestItemDetailsLookup mDetailsLookup; 55 private SelectionProbe mSelection; 56 private SelectionHelper mSelectionMgr; 57 58 private TestEvents.Builder mEvent; 59 60 @Before setUp()61 public void setUp() { 62 63 mSelectionMgr = SelectionHelpers.createTestInstance(ITEMS); 64 mDetailsLookup = new TestItemDetailsLookup(); 65 mSelection = new SelectionProbe(mSelectionMgr); 66 67 mCallbacks = new TestMouseCallbacks(); 68 mInputDelegate = new MouseInputHandler(mSelectionMgr, mDetailsLookup, mCallbacks); 69 70 mEvent = TestEvents.builder().mouse(); 71 mDetailsLookup.initAt(RecyclerView.NO_POSITION); 72 } 73 74 @Test testConfirmedClick_StartsSelection()75 public void testConfirmedClick_StartsSelection() { 76 mDetailsLookup.initAt(11).setInItemSelectRegion(true); 77 mInputDelegate.onSingleTapConfirmed(CLICK); 78 79 mSelection.assertSelection(11); 80 } 81 82 @Test testClickOnSelectRegion_AddsToSelection()83 public void testClickOnSelectRegion_AddsToSelection() { 84 mDetailsLookup.initAt(11).setInItemSelectRegion(true); 85 mInputDelegate.onSingleTapConfirmed(CLICK); 86 87 mDetailsLookup.initAt(10).setInItemSelectRegion(true); 88 mInputDelegate.onSingleTapUp(CLICK); 89 90 mSelection.assertSelected(10, 11); 91 } 92 93 @Test testClickOnIconOfSelectedItem_RemovesFromSelection()94 public void testClickOnIconOfSelectedItem_RemovesFromSelection() { 95 mDetailsLookup.initAt(8).setInItemSelectRegion(true); 96 mInputDelegate.onSingleTapConfirmed(CLICK); 97 98 mDetailsLookup.initAt(11); 99 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 100 mSelection.assertSelected(8, 9, 10, 11); 101 102 mDetailsLookup.initAt(9); 103 mInputDelegate.onSingleTapUp(CLICK); 104 mSelection.assertSelected(8, 10, 11); 105 } 106 107 @Test testRightClickDown_StartsContextMenu()108 public void testRightClickDown_StartsContextMenu() { 109 mInputDelegate.onDown(SECONDARY_CLICK); 110 111 mCallbacks.assertLastEvent(SECONDARY_CLICK); 112 } 113 114 @Test testAltClickDown_StartsContextMenu()115 public void testAltClickDown_StartsContextMenu() { 116 mInputDelegate.onDown(ALT_CLICK); 117 118 mCallbacks.assertLastEvent(ALT_CLICK); 119 } 120 121 @Test testScroll_shouldTrap()122 public void testScroll_shouldTrap() { 123 mDetailsLookup.initAt(0); 124 assertTrue(mInputDelegate.onScroll( 125 null, 126 mEvent.action(MotionEvent.ACTION_MOVE).primary().build(), 127 -1, 128 -1)); 129 } 130 131 @Test testScroll_NoTrapForTwoFinger()132 public void testScroll_NoTrapForTwoFinger() { 133 mDetailsLookup.initAt(0); 134 assertFalse(mInputDelegate.onScroll( 135 null, 136 mEvent.action(MotionEvent.ACTION_MOVE).build(), 137 -1, 138 -1)); 139 } 140 141 @Test testUnconfirmedCtrlClick_AddsToExistingSelection()142 public void testUnconfirmedCtrlClick_AddsToExistingSelection() { 143 mDetailsLookup.initAt(7).setInItemSelectRegion(true); 144 mInputDelegate.onSingleTapConfirmed(CLICK); 145 146 mDetailsLookup.initAt(11); 147 mInputDelegate.onSingleTapUp(CTRL_CLICK); 148 149 mSelection.assertSelection(7, 11); 150 } 151 152 @Test testUnconfirmedShiftClick_ExtendsSelection()153 public void testUnconfirmedShiftClick_ExtendsSelection() { 154 mDetailsLookup.initAt(7).setInItemSelectRegion(true); 155 mInputDelegate.onSingleTapConfirmed(CLICK); 156 157 mDetailsLookup.initAt(11); 158 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 159 160 mSelection.assertSelection(7, 8, 9, 10, 11); 161 } 162 163 @Test testConfirmedShiftClick_ExtendsSelectionFromOriginFocus()164 public void testConfirmedShiftClick_ExtendsSelectionFromOriginFocus() { 165 TestItemDetails item = mDetailsLookup.initAt(7); 166 mCallbacks.focusItem(item); 167 168 // This is a hack-y test, since the real FocusManager would've set range begin itself. 169 mSelectionMgr.anchorRange(7); 170 mSelection.assertNoSelection(); 171 172 mDetailsLookup.initAt(11); 173 mInputDelegate.onSingleTapConfirmed(SHIFT_CLICK); 174 mSelection.assertSelection(7, 8, 9, 10, 11); 175 } 176 177 @Test testUnconfirmedShiftClick_RotatesAroundOrigin()178 public void testUnconfirmedShiftClick_RotatesAroundOrigin() { 179 mDetailsLookup.initAt(7).setInItemSelectRegion(true); 180 mInputDelegate.onSingleTapConfirmed(CLICK); 181 182 mDetailsLookup.initAt(11); 183 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 184 mSelection.assertSelection(7, 8, 9, 10, 11); 185 186 mDetailsLookup.initAt(5); 187 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 188 189 mSelection.assertSelection(5, 6, 7); 190 mSelection.assertNotSelected(8, 9, 10, 11); 191 } 192 193 @Test testUnconfirmedShiftCtrlClick_Combination()194 public void testUnconfirmedShiftCtrlClick_Combination() { 195 mDetailsLookup.initAt(7).setInItemSelectRegion(true); 196 mInputDelegate.onSingleTapConfirmed(CLICK); 197 198 mDetailsLookup.initAt(11); 199 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 200 mSelection.assertSelection(7, 8, 9, 10, 11); 201 202 mDetailsLookup.initAt(5); 203 mInputDelegate.onSingleTapUp(CTRL_CLICK); 204 205 mSelection.assertSelection(5, 7, 8, 9, 10, 11); 206 } 207 208 @Test testUnconfirmedShiftCtrlClick_ShiftTakesPriority()209 public void testUnconfirmedShiftCtrlClick_ShiftTakesPriority() { 210 mDetailsLookup.initAt(7).setInItemSelectRegion(true); 211 mInputDelegate.onSingleTapConfirmed(CLICK); 212 213 mDetailsLookup.initAt(11); 214 mInputDelegate.onSingleTapUp(mEvent.ctrl().shift().build()); 215 216 mSelection.assertSelection(7, 8, 9, 10, 11); 217 } 218 219 // TODO: Add testSpaceBar_Previews, but we need to set a system property 220 // to have a deterministic state. 221 222 @Test testDoubleClick_Opens()223 public void testDoubleClick_Opens() { 224 TestItemDetails doc = mDetailsLookup.initAt(11); 225 mInputDelegate.onDoubleTap(CLICK); 226 227 mCallbacks.assertActivated(doc); 228 } 229 230 @Test testMiddleClick_DoesNothing()231 public void testMiddleClick_DoesNothing() { 232 mDetailsLookup.initAt(11).setInItemSelectRegion(true); 233 mInputDelegate.onSingleTapConfirmed(TERTIARY_CLICK); 234 235 mSelection.assertNoSelection(); 236 } 237 238 @Test testClickOff_ClearsSelection()239 public void testClickOff_ClearsSelection() { 240 mDetailsLookup.initAt(11).setInItemSelectRegion(true); 241 mInputDelegate.onSingleTapConfirmed(CLICK); 242 243 mDetailsLookup.initAt(RecyclerView.NO_POSITION); 244 mInputDelegate.onSingleTapUp(CLICK); 245 246 mSelection.assertNoSelection(); 247 } 248 249 @Test testClick_Focuses()250 public void testClick_Focuses() { 251 mDetailsLookup.initAt(11).setInItemSelectRegion(false); 252 mInputDelegate.onSingleTapConfirmed(CLICK); 253 254 mCallbacks.assertHasFocus(true); 255 mCallbacks.assertFocused("11"); 256 } 257 258 @Test testClickOff_ClearsFocus()259 public void testClickOff_ClearsFocus() { 260 mDetailsLookup.initAt(11).setInItemSelectRegion(false); 261 mInputDelegate.onSingleTapConfirmed(CLICK); 262 mCallbacks.assertHasFocus(true); 263 264 mDetailsLookup.initAt(RecyclerView.NO_POSITION); 265 mInputDelegate.onSingleTapUp(CLICK); 266 mCallbacks.assertHasFocus(false); 267 } 268 269 @Test testClickOffSelection_RemovesSelectionAndFocuses()270 public void testClickOffSelection_RemovesSelectionAndFocuses() { 271 mDetailsLookup.initAt(1).setInItemSelectRegion(true); 272 mInputDelegate.onSingleTapConfirmed(CLICK); 273 274 mDetailsLookup.initAt(5); 275 mInputDelegate.onSingleTapUp(SHIFT_CLICK); 276 277 mSelection.assertSelection(1, 2, 3, 4, 5); 278 279 mDetailsLookup.initAt(11); 280 mInputDelegate.onSingleTapUp(CLICK); 281 282 mCallbacks.assertFocused("11"); 283 mSelection.assertNoSelection(); 284 } 285 } 286