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 17package com.android.documentsui.dirlist; 18 19import static org.junit.Assert.assertFalse; 20import static org.junit.Assert.assertTrue; 21 22import android.support.test.filters.SmallTest; 23import android.support.test.runner.AndroidJUnit4; 24import android.support.v7.widget.RecyclerView; 25import android.view.MotionEvent; 26 27import com.android.documentsui.base.Events.InputEvent; 28import com.android.documentsui.selection.SelectionManager; 29import com.android.documentsui.selection.SelectionProbe; 30import com.android.documentsui.testing.SelectionManagers; 31import com.android.documentsui.testing.TestActionHandler; 32import com.android.documentsui.testing.TestEvent; 33import com.android.documentsui.testing.TestEvent.Builder; 34import com.android.documentsui.testing.TestEventHandler; 35import com.android.documentsui.testing.TestPredicate; 36 37import org.junit.Before; 38import org.junit.Test; 39import org.junit.runner.RunWith; 40 41import java.util.List; 42 43@RunWith(AndroidJUnit4.class) 44@SmallTest 45public final class UserInputHandler_MouseTest { 46 47 private static final List<String> ITEMS = TestData.create(100); 48 49 private UserInputHandler<TestEvent> mInputHandler; 50 private TestActionHandler mActionHandler; 51 private TestFocusHandler mFocusHandler; 52 private SelectionProbe mSelection; 53 private SelectionManager mSelectionMgr; 54 private TestPredicate<DocumentDetails> mCanSelect; 55 private TestEventHandler<InputEvent> mContextMenuClickHandler; 56 private TestEventHandler<InputEvent> mDragAndDropHandler; 57 private TestEventHandler<InputEvent> mGestureSelectHandler; 58 private TestEventHandler<Void> mPerformHapticFeedback; 59 60 private Builder mEvent; 61 62 @Before 63 public void setUp() { 64 65 mSelectionMgr = SelectionManagers.createTestInstance(ITEMS); 66 mActionHandler = new TestActionHandler(); 67 68 mSelection = new SelectionProbe(mSelectionMgr); 69 mCanSelect = new TestPredicate<>(); 70 mContextMenuClickHandler = new TestEventHandler<>(); 71 mDragAndDropHandler = new TestEventHandler<>(); 72 mGestureSelectHandler = new TestEventHandler<>(); 73 mFocusHandler = new TestFocusHandler(); 74 75 mInputHandler = new UserInputHandler<>( 76 mActionHandler, 77 mFocusHandler, 78 mSelectionMgr, 79 (MotionEvent event) -> { 80 throw new UnsupportedOperationException("Not exercised in tests."); 81 }, 82 mCanSelect, 83 mContextMenuClickHandler::accept, 84 mDragAndDropHandler::accept, 85 mGestureSelectHandler::accept, 86 () -> mPerformHapticFeedback.accept(null)); 87 88 mEvent = TestEvent.builder().mouse().overDocIcon(); 89 } 90 91 @Test 92 public void testConfirmedClick_StartsSelection() { 93 mInputHandler.onSingleTapConfirmed(mEvent.at(11).build()); 94 mSelection.assertSelection(11); 95 } 96 97 @Test 98 public void testClickOnIconWithExistingSelection_AddsToSelection() { 99 mInputHandler.onSingleTapConfirmed(mEvent.at(11).build()); 100 mInputHandler.onSingleTapUp(mEvent.at(10).build()); 101 mSelection.assertSelected(10, 11); 102 } 103 104 @Test 105 public void testClickOnIconOfSelectedItem_RemovesFromSelection() { 106 mInputHandler.onSingleTapConfirmed(mEvent.at(8).build()); 107 mInputHandler.onSingleTapUp(mEvent.at(11).shift().build()); 108 mSelection.assertSelected(8, 9, 10, 11); 109 110 mInputHandler.onSingleTapUp(mEvent.at(9).unshift().build()); 111 mSelection.assertSelected(8, 10, 11); 112 } 113 114 @Test 115 public void testRightClickDown_StartsContextMenu() { 116 mInputHandler.onDown(mEvent.secondary().build()); 117 mContextMenuClickHandler.assertLastArgument(mEvent.secondary().build()); 118 } 119 120 @Test 121 public void testAltClickDown_StartsContextMenu() { 122 mInputHandler.onDown(mEvent.primary().alt().build()); 123 mContextMenuClickHandler.assertLastArgument(mEvent.primary().alt().build()); 124 } 125 126 @Test 127 public void testScroll_shouldTrap() { 128 assertTrue(mInputHandler.onScroll(mEvent.at(0).action(MotionEvent.ACTION_MOVE).primary().build())); 129 } 130 131 @Test 132 public void testScroll_NoTrapForTwoFinger() { 133 assertFalse(mInputHandler.onScroll(mEvent.at(0).action(MotionEvent.ACTION_MOVE).build())); 134 } 135 136 @Test 137 public void testUnconfirmedCtrlClick_AddsToExistingSelection() { 138 mInputHandler.onSingleTapConfirmed(mEvent.at(7).build()); 139 140 mInputHandler.onSingleTapUp(mEvent.at(11).ctrl().build()); 141 mSelection.assertSelection(7, 11); 142 } 143 144 @Test 145 public void testUnconfirmedShiftClick_ExtendsSelection() { 146 mInputHandler.onSingleTapConfirmed(mEvent.at(7).build()); 147 148 mInputHandler.onSingleTapUp(mEvent.at(11).shift().build()); 149 mSelection.assertSelection(7, 8, 9, 10, 11); 150 } 151 152 @Test 153 public void testConfirmedShiftClick_ExtendsSelectionFromOriginFocus() { 154 mFocusHandler.focusPos = 7; 155 mFocusHandler.focusModelId = "7"; 156 // This is a hack-y test, since the real FocusManager would've set range begin itself. 157 mSelectionMgr.setSelectionRangeBegin(7); 158 mSelection.assertNoSelection(); 159 160 mInputHandler.onSingleTapConfirmed(mEvent.at(11).shift().build()); 161 mSelection.assertSelection(7, 8, 9, 10, 11); 162 } 163 164 @Test 165 public void testUnconfirmedShiftClick_RotatesAroundOrigin() { 166 mInputHandler.onSingleTapConfirmed(mEvent.at(7).build()); 167 168 mInputHandler.onSingleTapUp(mEvent.at(11).shift().build()); 169 mSelection.assertSelection(7, 8, 9, 10, 11); 170 171 mInputHandler.onSingleTapUp(mEvent.at(5).shift().build()); 172 mSelection.assertSelection(5, 6, 7); 173 mSelection.assertNotSelected(8, 9, 10, 11); 174 } 175 176 @Test 177 public void testUnconfirmedShiftCtrlClick_Combination() { 178 mInputHandler.onSingleTapConfirmed(mEvent.at(7).build()); 179 180 mInputHandler.onSingleTapUp(mEvent.at(11).shift().build()); 181 mSelection.assertSelection(7, 8, 9, 10, 11); 182 183 mInputHandler.onSingleTapUp(mEvent.at(5).unshift().ctrl().build()); 184 185 mSelection.assertSelection(5, 7, 8, 9, 10, 11); 186 } 187 188 @Test 189 public void testUnconfirmedShiftCtrlClick_ShiftTakesPriority() { 190 mInputHandler.onSingleTapConfirmed(mEvent.at(7).build()); 191 192 mInputHandler.onSingleTapUp(mEvent.at(11).ctrl().shift().build()); 193 mSelection.assertSelection(7, 8, 9, 10, 11); 194 } 195 196 // TODO: Add testSpaceBar_Previews, but we need to set a system property 197 // to have a deterministic state. 198 199 @Test 200 public void testDoubleClick_Opens() { 201 mInputHandler.onDoubleTap(mEvent.at(11).build()); 202 mActionHandler.open.assertLastArgument(mEvent.build().getDocumentDetails()); 203 } 204 205 @Test 206 public void testMiddleClick_DoesNothing() { 207 mInputHandler.onSingleTapConfirmed(mEvent.at(11).tertiary().build()); 208 mSelection.assertNoSelection(); 209 } 210 211 @Test 212 public void testClickOff_ClearsSelection() { 213 mInputHandler.onSingleTapConfirmed(mEvent.at(11).build()); 214 mInputHandler.onSingleTapUp(mEvent.at(RecyclerView.NO_POSITION).build()); 215 mSelection.assertNoSelection(); 216 } 217 218 @Test 219 public void testClick_Focuses() { 220 int id = 11; 221 mInputHandler.onSingleTapConfirmed(mEvent.at(id).notOverDocIcon().build()); 222 assertTrue(mFocusHandler.getFocusModelId().equals(Integer.toString(id))); 223 } 224 225 @Test 226 public void testClickOff_ClearsFocus() { 227 int id = 11; 228 mInputHandler.onSingleTapConfirmed(mEvent.at(id).notOverDocIcon().build()); 229 assertTrue(mFocusHandler.hasFocusedItem()); 230 mInputHandler.onSingleTapUp(mEvent.at(RecyclerView.NO_POSITION).build()); 231 assertFalse(mFocusHandler.hasFocusedItem()); 232 } 233 234 @Test 235 public void testClickOffSelection_RemovesSelectionAndFocuses() { 236 mInputHandler.onSingleTapConfirmed(mEvent.at(1).build()); 237 mInputHandler.onSingleTapUp(mEvent.at(5).shift().build()); 238 mSelection.assertSelection(1, 2, 3, 4, 5); 239 240 int id = 11; 241 mInputHandler.onSingleTapUp(mEvent.at(id).unshift().notOverDocIcon().build()); 242 assertTrue(mFocusHandler.getFocusModelId().equals(Integer.toString(id))); 243 mSelection.assertNoSelection(); 244 } 245} 246