1 /*
2  * Copyright (C) 2017 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.documentsui.dirlist;
17 
18 import static androidx.core.util.Preconditions.checkArgument;
19 
20 import android.view.KeyEvent;
21 
22 import androidx.recyclerview.selection.SelectionTracker;
23 import androidx.recyclerview.selection.SelectionTracker.SelectionPredicate;
24 import androidx.recyclerview.widget.RecyclerView;
25 import androidx.recyclerview.widget.RecyclerView.ViewHolder;
26 
27 import com.android.documentsui.ActionHandler;
28 
29 /**
30  * Helper class dedicated to building gesture input handlers. The construction
31  * of the various input handlers is non trivial. To keep logic clear,
32  * code flexible, and DirectoryFragment small(er), the construction has been
33  * isolated here in a separate class.
34  */
35 final class InputHandlers {
36 
37     private ActionHandler mActions;
38     private SelectionTracker<String> mSelectionHelper;
39     private SelectionPredicate<String> mSelectionPredicate;
40     private FocusHandler mFocusHandler;
41     private RecyclerView mRecView;
42 
InputHandlers( ActionHandler actions, SelectionTracker<String> selectionHelper, SelectionPredicate<String> selectionPredicate, FocusHandler focusHandler, RecyclerView recView)43     InputHandlers(
44             ActionHandler actions,
45             SelectionTracker<String> selectionHelper,
46             SelectionPredicate<String> selectionPredicate,
47             FocusHandler focusHandler,
48             RecyclerView recView) {
49 
50         checkArgument(actions != null);
51         checkArgument(selectionHelper != null);
52         checkArgument(selectionPredicate != null);
53         checkArgument(focusHandler != null);
54         checkArgument(recView != null);
55 
56         mActions = actions;
57         mSelectionHelper = selectionHelper;
58         mSelectionPredicate = selectionPredicate;
59         mFocusHandler = focusHandler;
60         mRecView = recView;
61     }
62 
createKeyHandler()63     KeyInputHandler createKeyHandler() {
64         KeyInputHandler.Callbacks<DocumentItemDetails> callbacks =
65                 new KeyInputHandler.Callbacks<DocumentItemDetails>() {
66             @Override
67             public boolean isInteractiveItem(DocumentItemDetails item, KeyEvent e) {
68                 switch (item.getItemViewType()) {
69                     case DocumentsAdapter.ITEM_TYPE_HEADER_MESSAGE:
70                     case DocumentsAdapter.ITEM_TYPE_INFLATED_MESSAGE:
71                     case DocumentsAdapter.ITEM_TYPE_SECTION_BREAK:
72                         return false;
73                     case DocumentsAdapter.ITEM_TYPE_DOCUMENT:
74                     case DocumentsAdapter.ITEM_TYPE_DIRECTORY:
75                         return true;
76                     default:
77                         throw new RuntimeException(
78                                 "Unsupported item type: " + item.getItemViewType());
79                 }
80             }
81 
82             @Override
83             public boolean onItemActivated(DocumentItemDetails item, KeyEvent e) {
84                 // Handle enter key events
85                 switch (e.getKeyCode()) {
86                     case KeyEvent.KEYCODE_ENTER:
87                     case KeyEvent.KEYCODE_DPAD_CENTER:
88                     case KeyEvent.KEYCODE_BUTTON_A:
89                         return mActions.openItem(
90                                 item,
91                                 ActionHandler.VIEW_TYPE_REGULAR,
92                                 ActionHandler.VIEW_TYPE_PREVIEW);
93                     case KeyEvent.KEYCODE_SPACE:
94                         return mActions.openItem(
95                                 item,
96                                 ActionHandler.VIEW_TYPE_PREVIEW,
97                                 ActionHandler.VIEW_TYPE_NONE);
98                 }
99 
100                 return false;
101             }
102 
103             @Override
104             public boolean onFocusItem(DocumentItemDetails details, int keyCode, KeyEvent event) {
105                 ViewHolder holder =
106                         mRecView.findViewHolderForAdapterPosition(details.getPosition());
107                 if (holder instanceof DocumentHolder) {
108                     return mFocusHandler.handleKey((DocumentHolder) holder, keyCode, event);
109                 }
110                 return false;
111             }
112         };
113 
114         return new KeyInputHandler(mSelectionHelper, mSelectionPredicate, callbacks);
115     }
116 }
117