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;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertTrue;
22 
23 import android.view.KeyEvent;
24 import android.view.MotionEvent;
25 
26 import androidx.recyclerview.selection.SelectionTracker;
27 import androidx.test.filters.SmallTest;
28 import androidx.test.runner.AndroidJUnit4;
29 
30 import com.android.documentsui.base.Procedure;
31 import com.android.documentsui.dirlist.TestFocusHandler;
32 import com.android.documentsui.testing.TestDrawerController;
33 import com.android.documentsui.testing.TestFeatures;
34 
35 import org.junit.Before;
36 import org.junit.Test;
37 import org.junit.runner.RunWith;
38 
39 @RunWith(AndroidJUnit4.class)
40 @SmallTest
41 public class SharedInputHandlerTest {
42 
43     private SharedInputHandler mSharedInputHandler;
44     private SelectionTracker<String> mSelectionMgr = SelectionHelpers.createTestInstance();
45     private TestFeatures mFeatures = new TestFeatures();
46     private TestFocusHandler mFocusHandler = new TestFocusHandler();
47     private TestDrawerController mDrawer = TestDrawerController.create();
48     private boolean mDirPopHappened;
49     private boolean mCanceledSearch;
50     private boolean mSearchExecuted;
51     private Procedure mDirPopper = new Procedure() {
52         @Override
53         public boolean run() {
54             mDirPopHappened = true;
55             return true;
56         }
57     };
58     private Runnable mSearchExecutor = new Runnable() {
59         @Override
60         public void run() {
61             mSearchExecuted = true;
62         }
63     };
64 
65     @Before
setUp()66     public void setUp() {
67         mDirPopHappened = false;
68         mSharedInputHandler = new SharedInputHandler(
69                 mFocusHandler,
70                 mSelectionMgr,
71                 () -> false,
72                 mDirPopper,
73                 mFeatures,
74                 mDrawer,
75                 mSearchExecutor);
76     }
77 
78     @Test
testUnrelatedButton_DoesNothing()79     public void testUnrelatedButton_DoesNothing() {
80         KeyEvent event =
81                 new KeyEvent(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_A, 0, 0);
82         assertFalse(mSharedInputHandler.onKeyDown(event.getKeyCode(), event));
83     }
84 
85     @Test
testBackButton_CancelsSearch()86     public void testBackButton_CancelsSearch() {
87         mSelectionMgr.select("1");
88         mSharedInputHandler = new SharedInputHandler(
89                 new TestFocusHandler(),
90                 SelectionHelpers.createTestInstance(),
91                 () -> {
92                         mCanceledSearch = true;
93                         return true;
94                 },
95                 mDirPopper,
96                 new TestFeatures(),
97                 mDrawer,
98                 mSearchExecutor);
99         KeyEvent backEvent =
100                 new KeyEvent(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK, 0, 0);
101         assertTrue(mSharedInputHandler.onKeyDown(backEvent.getKeyCode(), backEvent));
102 
103         assertTrue(mCanceledSearch);
104         assertEquals(mSelectionMgr.getSelection().size(), 1);
105         assertFalse(mDirPopHappened);
106         mDrawer.assertWasClosed();
107     }
108 
109     @Test
testBackButton_ClearsSelection()110     public void testBackButton_ClearsSelection() {
111         mSelectionMgr.select("1");
112         assertEquals(mSelectionMgr.getSelection().size(), 1);
113         KeyEvent backEvent =
114                 new KeyEvent(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK, 0, 0);
115         assertTrue(mSharedInputHandler.onKeyDown(backEvent.getKeyCode(), backEvent));
116 
117         assertFalse(mCanceledSearch);
118         assertEquals(mSelectionMgr.getSelection().size(), 0);
119         assertFalse(mDirPopHappened);
120         mDrawer.assertWasClosed();
121     }
122 
123     @Test
testBackButton_PopsDirectory()124     public void testBackButton_PopsDirectory() {
125         KeyEvent backEvent =
126                 new KeyEvent(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK, 0, 0);
127         assertTrue(mSharedInputHandler.onKeyDown(backEvent.getKeyCode(), backEvent));
128 
129         assertFalse(mCanceledSearch);
130         assertEquals(mSelectionMgr.getSelection().size(), 0);
131         assertTrue(mDirPopHappened);
132         mDrawer.assertWasClosed();
133     }
134 
135     @Test
testBackButton_CloseDrawer()136     public void testBackButton_CloseDrawer() {
137         KeyEvent backEvent =
138                 new KeyEvent(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK, 0, 0);
139         mDrawer.openDrawer(true);
140         assertTrue(mSharedInputHandler.onKeyDown(backEvent.getKeyCode(), backEvent));
141         mDrawer.assertWasOpened();
142     }
143 
144     @Test
testEscButton_CancelsSearch()145     public void testEscButton_CancelsSearch() {
146         mSelectionMgr.select("1");
147         mSharedInputHandler = new SharedInputHandler(
148                 new TestFocusHandler(),
149                 SelectionHelpers.createTestInstance(),
150                 () -> {
151                         mCanceledSearch = true;
152                         return true;
153                 },
154                 mDirPopper,
155                 new TestFeatures(),
156                 mDrawer,
157                 mSearchExecutor);
158         KeyEvent escapeEvent =
159                 new KeyEvent(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_ESCAPE, 0, 0);
160         assertTrue(mSharedInputHandler.onKeyDown(escapeEvent.getKeyCode(), escapeEvent));
161 
162         assertTrue(mCanceledSearch);
163         assertEquals(mSelectionMgr.getSelection().size(), 1);
164         assertFalse(mDirPopHappened);
165     }
166 
167     @Test
testEscButton_ClearsSelection()168     public void testEscButton_ClearsSelection() {
169         mSelectionMgr.select("1");
170         assertEquals(mSelectionMgr.getSelection().size(), 1);
171         KeyEvent escapeEvent =
172                 new KeyEvent(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_ESCAPE, 0, 0);
173         assertTrue(mSharedInputHandler.onKeyDown(escapeEvent.getKeyCode(), escapeEvent));
174 
175         assertFalse(mCanceledSearch);
176         assertEquals(mSelectionMgr.getSelection().size(), 0);
177         assertFalse(mDirPopHappened);
178     }
179 
180     @Test
testEscButton_DoesNotPopDirectory()181     public void testEscButton_DoesNotPopDirectory() {
182         KeyEvent escapeEvent =
183                 new KeyEvent(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_ESCAPE, 0, 0);
184         assertTrue(mSharedInputHandler.onKeyDown(escapeEvent.getKeyCode(), escapeEvent));
185 
186         assertFalse(mCanceledSearch);
187         assertEquals(mSelectionMgr.getSelection().size(), 0);
188         assertFalse(mDirPopHappened);
189     }
190 
191     @Test
testDeleteButton_PopsDirectory()192     public void testDeleteButton_PopsDirectory() {
193         KeyEvent delEvent =
194                 new KeyEvent(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL, 0, 0);
195         assertTrue(mSharedInputHandler.onKeyDown(delEvent.getKeyCode(), delEvent));
196 
197         assertTrue(mDirPopHappened);
198     }
199 
200     @Test
testTab_AdvancesFocusArea()201     public void testTab_AdvancesFocusArea() {
202         mFeatures.systemKeyboardNavigation = false;
203         KeyEvent tabEvent =
204                 new KeyEvent(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_TAB, 0, 0);
205         assertTrue(mSharedInputHandler.onKeyDown(tabEvent.getKeyCode(), tabEvent));
206 
207         assertTrue(mFocusHandler.advanceFocusAreaCalled);
208     }
209 
210     @Test
testNavKey_FocusesDirectory()211     public void testNavKey_FocusesDirectory() {
212         mFeatures.systemKeyboardNavigation = false;
213         KeyEvent navEvent =
214                 new KeyEvent(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_DPAD_UP, 0, 0);
215         assertTrue(mSharedInputHandler.onKeyDown(navEvent.getKeyCode(), navEvent));
216 
217         assertTrue(mFocusHandler.focusDirectoryCalled);
218     }
219 
220     @Test
testSearchKey_LaunchSearchView()221     public void testSearchKey_LaunchSearchView() {
222         KeyEvent searchEvent =
223                 new KeyEvent(0, 0, MotionEvent.ACTION_DOWN, KeyEvent.KEYCODE_SEARCH, 0, 0);
224         assertTrue(mSharedInputHandler.onKeyDown(searchEvent.getKeyCode(), searchEvent));
225 
226         assertTrue(mSearchExecuted);
227     }
228 }
229