Home | History | Annotate | Download | only in documentsui
      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 package com.android.documentsui;
     17 
     18 import static com.android.documentsui.base.SharedMinimal.DEBUG;
     19 
     20 import android.util.Log;
     21 import android.view.KeyEvent;
     22 
     23 import com.android.documentsui.base.Events;
     24 import com.android.documentsui.base.Features;
     25 import com.android.documentsui.base.Procedure;
     26 import com.android.documentsui.dirlist.FocusHandler;
     27 import com.android.documentsui.selection.SelectionHelper;
     28 
     29 public class SharedInputHandler {
     30 
     31     private static final String TAG = "SharedInputHandler";
     32 
     33     private final FocusHandler mFocusManager;
     34     private final Procedure mSearchCanceler;
     35     private final Procedure mDirPopper;
     36     private final Features mFeatures;
     37     private final SelectionHelper mSelectionMgr;
     38 
     39     public SharedInputHandler(
     40             FocusHandler focusHandler,
     41             SelectionHelper selectionMgr,
     42             Procedure searchCanceler,
     43             Procedure dirPopper,
     44             Features features) {
     45         mFocusManager = focusHandler;
     46         mSearchCanceler = searchCanceler;
     47         mSelectionMgr = selectionMgr;
     48         mDirPopper = dirPopper;
     49         mFeatures = features;
     50     }
     51 
     52     public boolean onKeyDown(int keyCode, KeyEvent event) {
     53         switch (keyCode) {
     54             // Unhandled ESC keys end up being rethrown back at us as BACK keys. So by returning
     55             // true, we make sure it always does no-op.
     56             case KeyEvent.KEYCODE_ESCAPE:
     57                 return onEscape();
     58 
     59             case KeyEvent.KEYCODE_DEL:
     60                 return onDelete();
     61 
     62             // This is the Android back button, not backspace.
     63             case KeyEvent.KEYCODE_BACK:
     64                 return onBack();
     65 
     66             case KeyEvent.KEYCODE_TAB:
     67                 return onTab();
     68 
     69             default:
     70                 // Instead of duplicating the switch-case in #isNavigationKeyCode, best just to
     71                 // leave it here.
     72                 if (Events.isNavigationKeyCode(keyCode)) {
     73                     // Forward all unclaimed navigation keystrokes to the directory list.
     74                     // This causes any stray navigation keystrokes to focus the content pane,
     75                     // which is probably what the user is trying to do.
     76                     mFocusManager.focusDirectoryList();
     77                     return true;
     78                 }
     79                 return false;
     80         }
     81     }
     82 
     83     private boolean onTab() {
     84         if (!mFeatures.isSystemKeyboardNavigationEnabled()) {
     85             // Tab toggles focus on the navigation drawer.
     86             // This should only be called in pre-O devices, since O has built-in keyboard
     87             // navigation
     88             // support.
     89             mFocusManager.advanceFocusArea();
     90             return true;
     91         }
     92 
     93         return false;
     94     }
     95 
     96     private boolean onDelete() {
     97         mDirPopper.run();
     98         return true;
     99     }
    100 
    101     private boolean onBack() {
    102         if (mSearchCanceler.run()) {
    103             return true;
    104         }
    105 
    106         if (mSelectionMgr.hasSelection()) {
    107             if (DEBUG) Log.d(TAG, "Back pressed. Clearing existing selection.");
    108             mSelectionMgr.clearSelection();
    109             return true;
    110         }
    111 
    112         return mDirPopper.run();
    113     }
    114 
    115     private boolean onEscape() {
    116         if (mSearchCanceler.run()) {
    117             return true;
    118         }
    119 
    120         if (mSelectionMgr.hasSelection()) {
    121             if (DEBUG) Log.d(TAG, "ESC pressed. Clearing existing selection.");
    122             mSelectionMgr.clearSelection();
    123             return true;
    124         }
    125 
    126         return true;
    127     }
    128 }
    129