Loading src/com/android/documentsui/base/Events.java +17 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,10 @@ public final class Events { return (metaState & KeyEvent.META_CTRL_ON) != 0; } public static boolean hasAltBit(int metaState) { return (metaState & KeyEvent.META_ALT_ON) != 0; } /** * A facade over MotionEvent primarily designed to permit for unit testing * of related code. Loading @@ -119,6 +123,8 @@ public final class Events { boolean isMouseEvent(); boolean isPrimaryButtonPressed(); boolean isSecondaryButtonPressed(); boolean isTertiaryButtonPressed(); boolean isAltKeyDown(); boolean isShiftKeyDown(); boolean isCtrlKeyDown(); Loading Loading @@ -231,6 +237,16 @@ public final class Events { return mEvent.isButtonPressed(MotionEvent.BUTTON_SECONDARY); } @Override public boolean isTertiaryButtonPressed() { return mEvent.isButtonPressed(MotionEvent.BUTTON_TERTIARY); } @Override public boolean isAltKeyDown() { return Events.hasAltBit(mEvent.getMetaState()); } @Override public boolean isShiftKeyDown() { return Events.hasShiftBit(mEvent.getMetaState()); Loading Loading @@ -334,6 +350,7 @@ public final class Events { .append(" isPrimaryButtonPressed=").append(isPrimaryButtonPressed()) .append(" isSecondaryButtonPressed=").append(isSecondaryButtonPressed()) .append(" isShiftKeyDown=").append(isShiftKeyDown()) .append(" isAltKeyDown=").append(isAltKeyDown()) .append(" action(decoded)=").append( MotionEvent.actionToString(mEvent.getActionMasked())) .append(" getOrigin=").append(getOrigin()) Loading src/com/android/documentsui/dirlist/DirectoryFragment.java +2 −4 Original line number Diff line number Diff line Loading @@ -347,7 +347,7 @@ public class DirectoryFragment extends Fragment mSelectionMgr, (MotionEvent t) -> MotionInputEvent.obtain(t, mRecView), this::canSelect, this::onRightClick, this::onContextMenuClick, mDragStartListener::onTouchDragEvent, gestureHandler); Loading Loading @@ -459,7 +459,7 @@ public class DirectoryFragment extends Fragment FileOperations.start(mActivity, operation, mDialogs::showFileOperationFailures); } protected boolean onRightClick(InputEvent e) { protected boolean onContextMenuClick(InputEvent e) { final View v; final float x, y; if (e.isOverModelItem()) { Loading Loading @@ -558,8 +558,6 @@ public class DirectoryFragment extends Fragment case R.id.menu_share: mActions.shareSelectedDocuments(); // TODO: Only finish selection if share action is completed. mActionModeController.finishActionMode(); return true; case R.id.menu_delete: Loading src/com/android/documentsui/dirlist/UserInputHandler.java +21 −15 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ public final class UserInputHandler<T extends InputEvent> private final Function<MotionEvent, T> mEventConverter; private final Predicate<DocumentDetails> mSelectable; private final EventHandler<InputEvent> mRightClickHandler; private final EventHandler<InputEvent> mContextMenuClickHandler; private final EventHandler<InputEvent> mTouchDragListener; private final EventHandler<InputEvent> mGestureSelectHandler; Loading @@ -66,7 +66,7 @@ public final class UserInputHandler<T extends InputEvent> SelectionManager selectionMgr, Function<MotionEvent, T> eventConverter, Predicate<DocumentDetails> selectable, EventHandler<InputEvent> rightClickHandler, EventHandler<InputEvent> contextMenuClickHandler, EventHandler<InputEvent> touchDragListener, EventHandler<InputEvent> gestureSelectHandler) { Loading @@ -75,7 +75,7 @@ public final class UserInputHandler<T extends InputEvent> mSelectionMgr = selectionMgr; mEventConverter = eventConverter; mSelectable = selectable; mRightClickHandler = rightClickHandler; mContextMenuClickHandler = contextMenuClickHandler; mTouchDragListener = touchDragListener; mGestureSelectHandler = gestureSelectHandler; Loading Loading @@ -292,7 +292,8 @@ public final class UserInputHandler<T extends InputEvent> boolean onDown(T event) { if (DEBUG) Log.v(MTAG, "Delegated onDown event."); if (event.isSecondaryButtonPressed()) { if (event.isSecondaryButtonPressed() || (event.isAltKeyDown() && event.isPrimaryButtonPressed())) { mHandledOnDown = true; return onRightClick(event); } Loading Loading @@ -324,6 +325,11 @@ public final class UserInputHandler<T extends InputEvent> return false; } if (event.isTertiaryButtonPressed()) { if (DEBUG) Log.d(MTAG, "Ignoring middle click"); return false; } DocumentDetails doc = event.getDocumentDetails(); if (mSelectionMgr.hasSelection()) { if (isRangeExtension(event)) { Loading Loading @@ -358,6 +364,11 @@ public final class UserInputHandler<T extends InputEvent> return false; } if (event.isTertiaryButtonPressed()) { if (DEBUG) Log.d(MTAG, "Ignoring middle click"); return false; } @Nullable DocumentDetails doc = event.getDocumentDetails(); if (doc == null || !doc.hasModelId()) { Log.w(MTAG, "Ignoring Confirmed Tap. No document details associated w/ event."); Loading @@ -376,6 +387,11 @@ public final class UserInputHandler<T extends InputEvent> return false; } if (event.isTertiaryButtonPressed()) { if (DEBUG) Log.d(MTAG, "Ignoring middle click"); return false; } DocumentDetails doc = event.getDocumentDetails(); return mActions.viewDocument(doc); } Loading @@ -398,7 +414,7 @@ public final class UserInputHandler<T extends InputEvent> // We always delegate final handling of the event, // since the handler might want to show a context menu // in an empty area or some other weirdo view. return mRightClickHandler.accept(event); return mContextMenuClickHandler.accept(event); } } Loading Loading @@ -447,16 +463,6 @@ public final class UserInputHandler<T extends InputEvent> return mActions.viewDocument(doc); case KeyEvent.KEYCODE_SPACE: return mActions.previewDocument(doc); case KeyEvent.KEYCODE_FORWARD_DEL: // This has to be handled here instead of in a keyboard shortcut, because // keyboard shortcuts all have to be modified with the 'Ctrl' key. if (mSelectionMgr.hasSelection()) { mActions.deleteSelectedDocuments(); } // Always handle the key, even if there was nothing to delete. This is a // precaution to prevent other handlers from potentially picking up the event // and triggering extra behaviors. return true; } return false; Loading src/com/android/documentsui/files/FilesActivity.java +16 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.content.ClipData; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.support.annotation.CallSuper; import android.util.Log; import android.view.KeyEvent; import android.view.KeyboardShortcutGroup; Loading Loading @@ -284,6 +285,21 @@ public class FilesActivity mActions.openContainerDocument(doc); } @CallSuper @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_DEL && event.isAltPressed()) || keyCode == KeyEvent.KEYCODE_FORWARD_DEL) { if (mSelectionMgr.hasSelection()) { mActions.deleteSelectedDocuments(); return true; } else { return false; } } return super.onKeyDown(keyCode, event); } @Override public boolean onKeyShortcut(int keyCode, KeyEvent event) { DirectoryFragment dir; Loading tests/common/com/android/documentsui/testing/TestEvent.java +24 −0 Original line number Diff line number Diff line Loading @@ -140,6 +140,11 @@ public class TestEvent implements InputEvent { return mButtons.contains(MotionEvent.BUTTON_SECONDARY); } @Override public boolean isTertiaryButtonPressed() { return mButtons.contains(MotionEvent.BUTTON_TERTIARY); } @Override public boolean isShiftKeyDown() { return mKeys.contains(KeyEvent.META_SHIFT_ON); Loading @@ -150,6 +155,11 @@ public class TestEvent implements InputEvent { return mKeys.contains(KeyEvent.META_CTRL_ON); } @Override public boolean isAltKeyDown() { return mKeys.contains(KeyEvent.META_ALT_ON); } @Override public boolean isActionDown() { return mAction == MotionEvent.ACTION_DOWN; Loading Loading @@ -427,15 +437,29 @@ public class TestEvent implements InputEvent { return this; } public Builder alt() { pressKey(KeyEvent.META_ALT_ON); return this; } public Builder primary() { pressButton(MotionEvent.BUTTON_PRIMARY); releaseButton(MotionEvent.BUTTON_SECONDARY); releaseButton(MotionEvent.BUTTON_TERTIARY); return this; } public Builder secondary() { pressButton(MotionEvent.BUTTON_SECONDARY); releaseButton(MotionEvent.BUTTON_PRIMARY); releaseButton(MotionEvent.BUTTON_TERTIARY); return this; } public Builder tertiary() { pressButton(MotionEvent.BUTTON_TERTIARY); releaseButton(MotionEvent.BUTTON_PRIMARY); releaseButton(MotionEvent.BUTTON_SECONDARY); return this; } Loading Loading
src/com/android/documentsui/base/Events.java +17 −0 Original line number Diff line number Diff line Loading @@ -111,6 +111,10 @@ public final class Events { return (metaState & KeyEvent.META_CTRL_ON) != 0; } public static boolean hasAltBit(int metaState) { return (metaState & KeyEvent.META_ALT_ON) != 0; } /** * A facade over MotionEvent primarily designed to permit for unit testing * of related code. Loading @@ -119,6 +123,8 @@ public final class Events { boolean isMouseEvent(); boolean isPrimaryButtonPressed(); boolean isSecondaryButtonPressed(); boolean isTertiaryButtonPressed(); boolean isAltKeyDown(); boolean isShiftKeyDown(); boolean isCtrlKeyDown(); Loading Loading @@ -231,6 +237,16 @@ public final class Events { return mEvent.isButtonPressed(MotionEvent.BUTTON_SECONDARY); } @Override public boolean isTertiaryButtonPressed() { return mEvent.isButtonPressed(MotionEvent.BUTTON_TERTIARY); } @Override public boolean isAltKeyDown() { return Events.hasAltBit(mEvent.getMetaState()); } @Override public boolean isShiftKeyDown() { return Events.hasShiftBit(mEvent.getMetaState()); Loading Loading @@ -334,6 +350,7 @@ public final class Events { .append(" isPrimaryButtonPressed=").append(isPrimaryButtonPressed()) .append(" isSecondaryButtonPressed=").append(isSecondaryButtonPressed()) .append(" isShiftKeyDown=").append(isShiftKeyDown()) .append(" isAltKeyDown=").append(isAltKeyDown()) .append(" action(decoded)=").append( MotionEvent.actionToString(mEvent.getActionMasked())) .append(" getOrigin=").append(getOrigin()) Loading
src/com/android/documentsui/dirlist/DirectoryFragment.java +2 −4 Original line number Diff line number Diff line Loading @@ -347,7 +347,7 @@ public class DirectoryFragment extends Fragment mSelectionMgr, (MotionEvent t) -> MotionInputEvent.obtain(t, mRecView), this::canSelect, this::onRightClick, this::onContextMenuClick, mDragStartListener::onTouchDragEvent, gestureHandler); Loading Loading @@ -459,7 +459,7 @@ public class DirectoryFragment extends Fragment FileOperations.start(mActivity, operation, mDialogs::showFileOperationFailures); } protected boolean onRightClick(InputEvent e) { protected boolean onContextMenuClick(InputEvent e) { final View v; final float x, y; if (e.isOverModelItem()) { Loading Loading @@ -558,8 +558,6 @@ public class DirectoryFragment extends Fragment case R.id.menu_share: mActions.shareSelectedDocuments(); // TODO: Only finish selection if share action is completed. mActionModeController.finishActionMode(); return true; case R.id.menu_delete: Loading
src/com/android/documentsui/dirlist/UserInputHandler.java +21 −15 Original line number Diff line number Diff line Loading @@ -51,7 +51,7 @@ public final class UserInputHandler<T extends InputEvent> private final Function<MotionEvent, T> mEventConverter; private final Predicate<DocumentDetails> mSelectable; private final EventHandler<InputEvent> mRightClickHandler; private final EventHandler<InputEvent> mContextMenuClickHandler; private final EventHandler<InputEvent> mTouchDragListener; private final EventHandler<InputEvent> mGestureSelectHandler; Loading @@ -66,7 +66,7 @@ public final class UserInputHandler<T extends InputEvent> SelectionManager selectionMgr, Function<MotionEvent, T> eventConverter, Predicate<DocumentDetails> selectable, EventHandler<InputEvent> rightClickHandler, EventHandler<InputEvent> contextMenuClickHandler, EventHandler<InputEvent> touchDragListener, EventHandler<InputEvent> gestureSelectHandler) { Loading @@ -75,7 +75,7 @@ public final class UserInputHandler<T extends InputEvent> mSelectionMgr = selectionMgr; mEventConverter = eventConverter; mSelectable = selectable; mRightClickHandler = rightClickHandler; mContextMenuClickHandler = contextMenuClickHandler; mTouchDragListener = touchDragListener; mGestureSelectHandler = gestureSelectHandler; Loading Loading @@ -292,7 +292,8 @@ public final class UserInputHandler<T extends InputEvent> boolean onDown(T event) { if (DEBUG) Log.v(MTAG, "Delegated onDown event."); if (event.isSecondaryButtonPressed()) { if (event.isSecondaryButtonPressed() || (event.isAltKeyDown() && event.isPrimaryButtonPressed())) { mHandledOnDown = true; return onRightClick(event); } Loading Loading @@ -324,6 +325,11 @@ public final class UserInputHandler<T extends InputEvent> return false; } if (event.isTertiaryButtonPressed()) { if (DEBUG) Log.d(MTAG, "Ignoring middle click"); return false; } DocumentDetails doc = event.getDocumentDetails(); if (mSelectionMgr.hasSelection()) { if (isRangeExtension(event)) { Loading Loading @@ -358,6 +364,11 @@ public final class UserInputHandler<T extends InputEvent> return false; } if (event.isTertiaryButtonPressed()) { if (DEBUG) Log.d(MTAG, "Ignoring middle click"); return false; } @Nullable DocumentDetails doc = event.getDocumentDetails(); if (doc == null || !doc.hasModelId()) { Log.w(MTAG, "Ignoring Confirmed Tap. No document details associated w/ event."); Loading @@ -376,6 +387,11 @@ public final class UserInputHandler<T extends InputEvent> return false; } if (event.isTertiaryButtonPressed()) { if (DEBUG) Log.d(MTAG, "Ignoring middle click"); return false; } DocumentDetails doc = event.getDocumentDetails(); return mActions.viewDocument(doc); } Loading @@ -398,7 +414,7 @@ public final class UserInputHandler<T extends InputEvent> // We always delegate final handling of the event, // since the handler might want to show a context menu // in an empty area or some other weirdo view. return mRightClickHandler.accept(event); return mContextMenuClickHandler.accept(event); } } Loading Loading @@ -447,16 +463,6 @@ public final class UserInputHandler<T extends InputEvent> return mActions.viewDocument(doc); case KeyEvent.KEYCODE_SPACE: return mActions.previewDocument(doc); case KeyEvent.KEYCODE_FORWARD_DEL: // This has to be handled here instead of in a keyboard shortcut, because // keyboard shortcuts all have to be modified with the 'Ctrl' key. if (mSelectionMgr.hasSelection()) { mActions.deleteSelectedDocuments(); } // Always handle the key, even if there was nothing to delete. This is a // precaution to prevent other handlers from potentially picking up the event // and triggering extra behaviors. return true; } return false; Loading
src/com/android/documentsui/files/FilesActivity.java +16 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import android.content.ClipData; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.support.annotation.CallSuper; import android.util.Log; import android.view.KeyEvent; import android.view.KeyboardShortcutGroup; Loading Loading @@ -284,6 +285,21 @@ public class FilesActivity mActions.openContainerDocument(doc); } @CallSuper @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_DEL && event.isAltPressed()) || keyCode == KeyEvent.KEYCODE_FORWARD_DEL) { if (mSelectionMgr.hasSelection()) { mActions.deleteSelectedDocuments(); return true; } else { return false; } } return super.onKeyDown(keyCode, event); } @Override public boolean onKeyShortcut(int keyCode, KeyEvent event) { DirectoryFragment dir; Loading
tests/common/com/android/documentsui/testing/TestEvent.java +24 −0 Original line number Diff line number Diff line Loading @@ -140,6 +140,11 @@ public class TestEvent implements InputEvent { return mButtons.contains(MotionEvent.BUTTON_SECONDARY); } @Override public boolean isTertiaryButtonPressed() { return mButtons.contains(MotionEvent.BUTTON_TERTIARY); } @Override public boolean isShiftKeyDown() { return mKeys.contains(KeyEvent.META_SHIFT_ON); Loading @@ -150,6 +155,11 @@ public class TestEvent implements InputEvent { return mKeys.contains(KeyEvent.META_CTRL_ON); } @Override public boolean isAltKeyDown() { return mKeys.contains(KeyEvent.META_ALT_ON); } @Override public boolean isActionDown() { return mAction == MotionEvent.ACTION_DOWN; Loading Loading @@ -427,15 +437,29 @@ public class TestEvent implements InputEvent { return this; } public Builder alt() { pressKey(KeyEvent.META_ALT_ON); return this; } public Builder primary() { pressButton(MotionEvent.BUTTON_PRIMARY); releaseButton(MotionEvent.BUTTON_SECONDARY); releaseButton(MotionEvent.BUTTON_TERTIARY); return this; } public Builder secondary() { pressButton(MotionEvent.BUTTON_SECONDARY); releaseButton(MotionEvent.BUTTON_PRIMARY); releaseButton(MotionEvent.BUTTON_TERTIARY); return this; } public Builder tertiary() { pressButton(MotionEvent.BUTTON_TERTIARY); releaseButton(MotionEvent.BUTTON_PRIMARY); releaseButton(MotionEvent.BUTTON_SECONDARY); return this; } Loading