From 86a436efb8ab9898740c3594950eb332d8dd095d Mon Sep 17 00:00:00 2001 From: Matthew Ng Date: Fri, 26 Oct 2018 16:00:53 -0700 Subject: [PATCH] Refactor QuickStepController into Gestures The refactor allows adding new gestures easier and provides a way to reassign triggers to the gestures. go/navbar-prototypes-doc Test: atest QuickStepControllerTest Bug: 112934365 Change-Id: I5334947e2ff3f39af890e1f026089b933ff48a3c --- .../plugins/statusbar/phone/NavGesture.java | 2 +- .../statusbar/phone/ButtonDispatcher.java | 15 + .../statusbar/phone/NavigationBackAction.java | 131 ++++ .../statusbar/phone/NavigationBarView.java | 47 +- .../phone/NavigationGestureAction.java | 181 +++++ .../statusbar/phone/QuickScrubAction.java | 329 ++++++++ .../statusbar/phone/QuickStepAction.java | 62 ++ .../statusbar/phone/QuickStepController.java | 735 +++++++----------- .../phone/QuickStepControllerTest.java | 618 +++++++++++++++ 9 files changed, 1626 insertions(+), 494 deletions(-) create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationGestureAction.java create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickScrubAction.java create mode 100644 packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepAction.java create mode 100644 packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/QuickStepControllerTest.java diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java index 814324e63d198..99cc3a37d7394 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/phone/NavGesture.java @@ -36,7 +36,7 @@ public interface NavGesture extends Plugin { public boolean onInterceptTouchEvent(MotionEvent event); - public void setBarState(boolean vertical, boolean isRtl); + public void setBarState(boolean isRtl, int navBarPosition); public void onDraw(Canvas canvas); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java index 4eca6bb4c3e77..119f01adddf82 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java @@ -263,6 +263,16 @@ public class ButtonDispatcher { } } + public void setTranslation(int x, int y, int z) { + final int N = mViews.size(); + for (int i = 0; i < N; i++) { + final View view = mViews.get(i); + view.setTranslationX(x); + view.setTranslationY(y); + view.setTranslationZ(z); + } + } + public ArrayList getViews() { return mViews; } @@ -276,6 +286,11 @@ public class ButtonDispatcher { if (mImageDrawable != null) { mImageDrawable.setCallback(mCurrentView); } + if (mCurrentView != null) { + mCurrentView.setTranslationX(0); + mCurrentView.setTranslationY(0); + mCurrentView.setTranslationZ(0); + } } public void setVertical(boolean vertical) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java new file mode 100644 index 0000000000000..1002f9e45b3c2 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBackAction.java @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.statusbar.phone; + +import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME; + +import android.annotation.NonNull; +import android.hardware.input.InputManager; +import android.os.Handler; +import android.os.SystemClock; +import android.view.HapticFeedbackConstants; +import android.view.InputDevice; +import android.view.KeyCharacterMap; +import android.view.KeyEvent; +import android.view.MotionEvent; + +import com.android.systemui.recents.OverviewProxyService; + +/** + * A back action when triggered will execute a back command + */ +public class NavigationBackAction extends NavigationGestureAction { + + private static final String PULL_HOME_GO_BACK_PROP = "quickstepcontroller_homegoesback"; + private static final String BACK_AFTER_END_PROP = + "quickstepcontroller_homegoesbackwhenend"; + private static final String NAVBAR_EXPERIMENTS_DISABLED = "navbarexperiments_disabled"; + private static final long BACK_BUTTON_FADE_OUT_ALPHA = 60; + private static final long BACK_GESTURE_POLL_TIMEOUT = 1000; + + private final Handler mHandler = new Handler(); + + private final Runnable mExecuteBackRunnable = new Runnable() { + @Override + public void run() { + if (isEnabled() && canPerformAction()) { + performBack(); + mHandler.postDelayed(this, BACK_GESTURE_POLL_TIMEOUT); + } + } + }; + + public NavigationBackAction(@NonNull NavigationBarView navigationBarView, + @NonNull OverviewProxyService service) { + super(navigationBarView, service); + } + + @Override + public int requiresTouchDownHitTarget() { + return HIT_TARGET_HOME; + } + + @Override + public boolean requiresDragWithHitTarget() { + return true; + } + + @Override + public boolean canPerformAction() { + return mProxySender.getBackButtonAlpha() > 0; + } + + @Override + public boolean isEnabled() { + return swipeHomeGoBackGestureEnabled(); + } + + @Override + protected void onGestureStart(MotionEvent event) { + if (!QuickStepController.shouldhideBackButton(getContext())) { + mNavigationBarView.getBackButton().setAlpha(0 /* alpha */, true /* animate */, + BACK_BUTTON_FADE_OUT_ALPHA); + } + mHandler.removeCallbacks(mExecuteBackRunnable); + if (!shouldExecuteBackOnUp()) { + performBack(); + mHandler.postDelayed(mExecuteBackRunnable, BACK_GESTURE_POLL_TIMEOUT); + } + } + + @Override + protected void onGestureEnd() { + mHandler.removeCallbacks(mExecuteBackRunnable); + if (!QuickStepController.shouldhideBackButton(getContext())) { + mNavigationBarView.getBackButton().setAlpha( + mProxySender.getBackButtonAlpha(), true /* animate */); + } + if (shouldExecuteBackOnUp()) { + performBack(); + } + } + + private void performBack() { + sendEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK); + sendEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK); + mNavigationBarView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY); + } + + private boolean swipeHomeGoBackGestureEnabled() { + return !getGlobalBoolean(NAVBAR_EXPERIMENTS_DISABLED) + && getGlobalBoolean(PULL_HOME_GO_BACK_PROP); + } + + private boolean shouldExecuteBackOnUp() { + return !getGlobalBoolean(NAVBAR_EXPERIMENTS_DISABLED) + && getGlobalBoolean(BACK_AFTER_END_PROP); + } + + private void sendEvent(int action, int code) { + long when = SystemClock.uptimeMillis(); + final KeyEvent ev = new KeyEvent(when, when, action, code, 0 /* repeat */, + 0 /* metaState */, KeyCharacterMap.VIRTUAL_KEYBOARD, 0 /* scancode */, + KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, + InputDevice.SOURCE_KEYBOARD); + InputManager.getInstance().injectInputEvent(ev, InputManager.INJECT_INPUT_EVENT_MODE_ASYNC); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 6728f08581ec9..2c3c27fe50391 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -38,9 +38,11 @@ import android.graphics.Rect; import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.os.RemoteException; import android.os.SystemProperties; import android.util.AttributeSet; import android.util.Log; +import android.util.Slog; import android.util.SparseArray; import android.view.Display; import android.view.MotionEvent; @@ -49,6 +51,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.WindowInsets; import android.view.WindowManager; +import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.view.inputmethod.InputMethodManager; @@ -143,6 +146,10 @@ public class NavigationBarView extends FrameLayout implements PluginListener