blob: 28eba70c98a63695ba94ce5aabe9706b0eb23daf [file] [log] [blame]
Steve McKay04718262016-11-08 11:01:35 -08001/*
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 */
16package com.android.documentsui;
17
Felipe Leme9de58072018-01-19 16:40:04 -080018import static com.android.documentsui.base.SharedMinimal.DEBUG;
Ben Lin0902f072017-03-13 18:25:29 -070019
20import android.util.Log;
Steve McKay04718262016-11-08 11:01:35 -080021import android.view.KeyEvent;
22
Riddle Hsu0c375982018-06-21 22:06:43 +080023import androidx.recyclerview.selection.SelectionTracker;
24
Steve McKay04718262016-11-08 11:01:35 -080025import com.android.documentsui.base.Events;
Steve McKay98f8c5f2017-03-03 13:52:14 -080026import com.android.documentsui.base.Features;
Steve McKay04718262016-11-08 11:01:35 -080027import com.android.documentsui.base.Procedure;
Ben Lin0902f072017-03-13 18:25:29 -070028import com.android.documentsui.dirlist.FocusHandler;
Steve McKay04718262016-11-08 11:01:35 -080029
Riddle Hsu0c375982018-06-21 22:06:43 +080030/**
31 * Handle common input events.
32 */
Steve McKay04718262016-11-08 11:01:35 -080033public class SharedInputHandler {
34
Ben Lin0902f072017-03-13 18:25:29 -070035 private static final String TAG = "SharedInputHandler";
36
37 private final FocusHandler mFocusManager;
38 private final Procedure mSearchCanceler;
Steve McKay98f8c5f2017-03-03 13:52:14 -080039 private final Procedure mDirPopper;
40 private final Features mFeatures;
Riddle Hsu0c375982018-06-21 22:06:43 +080041 private final SelectionTracker<String> mSelectionMgr;
Rhed Jao76a9d712018-05-16 15:32:59 +080042 private final DrawerController mDrawer;
Steve McKay04718262016-11-08 11:01:35 -080043
Ben Lin0902f072017-03-13 18:25:29 -070044 public SharedInputHandler(
45 FocusHandler focusHandler,
Riddle Hsu0c375982018-06-21 22:06:43 +080046 SelectionTracker<String> selectionMgr,
Ben Lin0902f072017-03-13 18:25:29 -070047 Procedure searchCanceler,
48 Procedure dirPopper,
Rhed Jao76a9d712018-05-16 15:32:59 +080049 Features features,
50 DrawerController drawer) {
Ben Lin0902f072017-03-13 18:25:29 -070051 mFocusManager = focusHandler;
52 mSearchCanceler = searchCanceler;
53 mSelectionMgr = selectionMgr;
Steve McKay04718262016-11-08 11:01:35 -080054 mDirPopper = dirPopper;
Steve McKay98f8c5f2017-03-03 13:52:14 -080055 mFeatures = features;
Rhed Jao76a9d712018-05-16 15:32:59 +080056 mDrawer = drawer;
Steve McKay04718262016-11-08 11:01:35 -080057 }
58
59 public boolean onKeyDown(int keyCode, KeyEvent event) {
Ben Lin0902f072017-03-13 18:25:29 -070060 switch (keyCode) {
61 // Unhandled ESC keys end up being rethrown back at us as BACK keys. So by returning
62 // true, we make sure it always does no-op.
63 case KeyEvent.KEYCODE_ESCAPE:
64 return onEscape();
65
66 case KeyEvent.KEYCODE_DEL:
67 return onDelete();
68
69 // This is the Android back button, not backspace.
70 case KeyEvent.KEYCODE_BACK:
71 return onBack();
72
73 case KeyEvent.KEYCODE_TAB:
74 return onTab();
75
76 default:
77 // Instead of duplicating the switch-case in #isNavigationKeyCode, best just to
78 // leave it here.
79 if (Events.isNavigationKeyCode(keyCode)) {
80 // Forward all unclaimed navigation keystrokes to the directory list.
81 // This causes any stray navigation keystrokes to focus the content pane,
82 // which is probably what the user is trying to do.
83 mFocusManager.focusDirectoryList();
84 return true;
85 }
86 return false;
87 }
88 }
89
90 private boolean onTab() {
91 if (!mFeatures.isSystemKeyboardNavigationEnabled()) {
Steve McKay04718262016-11-08 11:01:35 -080092 // Tab toggles focus on the navigation drawer.
Ben Lin0902f072017-03-13 18:25:29 -070093 // This should only be called in pre-O devices, since O has built-in keyboard
94 // navigation
Ben Lin340ab172017-01-27 11:41:26 -080095 // support.
Steve McKay04718262016-11-08 11:01:35 -080096 mFocusManager.advanceFocusArea();
97 return true;
Steve McKay04718262016-11-08 11:01:35 -080098 }
99
100 return false;
101 }
Ben Lin0902f072017-03-13 18:25:29 -0700102
103 private boolean onDelete() {
104 mDirPopper.run();
105 return true;
106 }
107
108 private boolean onBack() {
Rhed Jao76a9d712018-05-16 15:32:59 +0800109 if (mDrawer.isPresent() && mDrawer.isOpen()) {
110 mDrawer.setOpen(false);
111 return true;
112 }
113
Ben Lin0902f072017-03-13 18:25:29 -0700114 if (mSearchCanceler.run()) {
115 return true;
116 }
117
118 if (mSelectionMgr.hasSelection()) {
Jason Chang96f886b2019-03-29 17:59:02 +0800119 if (DEBUG) {
120 Log.d(TAG, "Back pressed. Clearing existing selection.");
121 }
Ben Lin0902f072017-03-13 18:25:29 -0700122 mSelectionMgr.clearSelection();
123 return true;
124 }
125
126 return mDirPopper.run();
127 }
128
129 private boolean onEscape() {
130 if (mSearchCanceler.run()) {
131 return true;
132 }
133
134 if (mSelectionMgr.hasSelection()) {
Jason Chang96f886b2019-03-29 17:59:02 +0800135 if (DEBUG) {
136 Log.d(TAG, "ESC pressed. Clearing existing selection.");
137 }
Ben Lin0902f072017-03-13 18:25:29 -0700138 mSelectionMgr.clearSelection();
139 return true;
140 }
141
142 return true;
143 }
Steve McKay04718262016-11-08 11:01:35 -0800144}