From a212999f245032f033e6a0993fd2be9832a9b9cc Mon Sep 17 00:00:00 2001 From: Muyuan Li Date: Thu, 3 Mar 2016 18:30:39 -0800 Subject: [PATCH] Added shortcut key to dock windows Meta + [ / ] will dock top window to left / right or cycle between 1/3 1/2 2/3 of screen if it's already in docking mode Change-Id: I546418235a9b9699d406b04f52914c85bd950532 (cherry picked from commit 63635675b56564a17e3897a221d73a19cfbc77f7) --- .../internal/policy/DividerSnapAlgorithm.java | 20 ++++++ .../com/android/systemui/recents/Recents.java | 9 +++ .../shortcut/ShortcutKeyDispatcher.java | 63 +++++++++++++++++-- .../statusbar/phone/PhoneStatusBar.java | 7 +-- proto/src/metrics_constants.proto | 3 + 5 files changed, 92 insertions(+), 10 deletions(-) diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java index 84d0fc70b1ca6..9907ea92670b2 100644 --- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java +++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java @@ -278,6 +278,26 @@ public class DividerSnapAlgorithm { return snapTarget; } + /** + * Cycles through all non-dismiss targets with a stepping of {@param increment}. It moves left + * if {@param increment} is negative and moves right otherwise. + */ + public SnapTarget cycleNonDismissTarget(SnapTarget snapTarget, int increment) { + int index = mTargets.indexOf(snapTarget); + if (index != -1) { + SnapTarget newTarget = mTargets.get((index + mTargets.size() + increment) + % mTargets.size()); + if (newTarget == mDismissStartTarget) { + return mLastSplitTarget; + } else if (newTarget == mDismissEndTarget) { + return mFirstSplitTarget; + } else { + return newTarget; + } + } + return snapTarget; + } + /** * Represents a snap target for the divider. */ diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index da77dfd8d539c..73ce26fecf29f 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -23,7 +23,9 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.res.Configuration; +import android.graphics.Point; import android.graphics.Rect; +import android.hardware.display.DisplayManager; import android.os.Build; import android.os.Handler; import android.os.IBinder; @@ -389,6 +391,13 @@ public class Recents extends SystemUI return false; } + Point realSize = new Point(); + if (initialBounds == null) { + mContext.getSystemService(DisplayManager.class).getDisplay(Display.DEFAULT_DISPLAY) + .getRealSize(realSize); + initialBounds = new Rect(0, 0, realSize.x, realSize.y); + } + int currentUser = sSystemServicesProxy.getCurrentUser(); SystemServicesProxy ssp = Recents.getSystemServices(); ActivityManager.RunningTaskInfo topTask = ssp.getTopMostTask(); diff --git a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java index 8f8683b4ea239..69dcabea28b89 100644 --- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java +++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java @@ -17,18 +17,31 @@ package com.android.systemui.shortcut; import android.accessibilityservice.AccessibilityServiceInfo; +import android.app.ActivityManager; +import android.app.ActivityManagerNative; +import android.app.IActivityManager; import android.content.ComponentName; import android.content.Context; import android.content.pm.ServiceInfo; +import android.content.res.Configuration; import android.os.RemoteException; +import android.util.DisplayMetrics; import android.util.Log; import android.view.IWindowManager; import android.view.KeyEvent; +import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityManager; +import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.policy.DividerSnapAlgorithm; import com.android.settingslib.accessibility.AccessibilityUtils; import com.android.systemui.R; import com.android.systemui.SystemUI; +import com.android.systemui.recents.Recents; +import com.android.systemui.stackdivider.Divider; +import com.android.systemui.stackdivider.DividerView; +import com.android.systemui.statusbar.phone.NavigationBarGestureHelper; import java.util.List; import java.util.Set; @@ -42,28 +55,70 @@ public class ShortcutKeyDispatcher extends SystemUI private static final String TAG = "ShortcutKeyDispatcher"; private ShortcutKeyServiceProxy mShortcutKeyServiceProxy = new ShortcutKeyServiceProxy(this); - private IWindowManager windowManagerService = WindowManagerGlobal.getWindowManagerService(); + private IWindowManager mWindowManagerService = WindowManagerGlobal.getWindowManagerService(); + private IActivityManager mActivityManager = ActivityManagerNative.getDefault(); protected final long META_MASK = ((long) KeyEvent.META_META_ON) << Integer.SIZE; protected final long ALT_MASK = ((long) KeyEvent.META_ALT_ON) << Integer.SIZE; protected final long CTRL_MASK = ((long) KeyEvent.META_CTRL_ON) << Integer.SIZE; protected final long SHIFT_MASK = ((long) KeyEvent.META_SHIFT_ON) << Integer.SIZE; + protected final long SC_DOCK_LEFT = META_MASK | KeyEvent.KEYCODE_LEFT_BRACKET; + protected final long SC_DOCK_RIGHT = META_MASK | KeyEvent.KEYCODE_RIGHT_BRACKET; + /** * Registers a shortcut key to window manager. * @param shortcutCode packed representation of shortcut key code and meta information */ public void registerShortcutKey(long shortcutCode) { try { - windowManagerService.registerShortcutKey(shortcutCode, mShortcutKeyServiceProxy); + mWindowManagerService.registerShortcutKey(shortcutCode, mShortcutKeyServiceProxy); } catch (RemoteException e) { // Do nothing } } @Override - public void onShortcutKeyPressed(long shortcutCode) {} + public void onShortcutKeyPressed(long shortcutCode) { + int orientation = mContext.getResources().getConfiguration().orientation; + if ((shortcutCode == SC_DOCK_LEFT || shortcutCode == SC_DOCK_RIGHT) + && orientation == Configuration.ORIENTATION_LANDSCAPE) { + handleDockKey(shortcutCode); + } + } @Override - public void start() {} + public void start() { + registerShortcutKey(SC_DOCK_LEFT); + registerShortcutKey(SC_DOCK_RIGHT); + } + + private void handleDockKey(long shortcutCode) { + try { + int dockSide = mWindowManagerService.getDockedStackSide(); + if (dockSide == WindowManager.DOCKED_INVALID) { + // If there is no window docked, we dock the top-most window. + Recents recents = getComponent(Recents.class); + int dockMode = (shortcutCode == SC_DOCK_LEFT) + ? ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT + : ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT; + recents.dockTopTask(NavigationBarGestureHelper.DRAG_MODE_NONE, dockMode, null); + MetricsLogger.action(mContext, MetricsEvent.WINDOW_DOCK_SHORTCUTS); + } else { + // If there is already a docked window, we respond by resizing the docking pane. + DividerView dividerView = getComponent(Divider.class).getView(); + DividerSnapAlgorithm snapAlgorithm = dividerView.getSnapAlgorithm(); + int dividerPosition = dividerView.getCurrentPosition(); + DividerSnapAlgorithm.SnapTarget currentTarget = + snapAlgorithm.calculateNonDismissingSnapTarget(dividerPosition); + int increment = (shortcutCode == SC_DOCK_LEFT) ? -1 : 1; + DividerSnapAlgorithm.SnapTarget target = snapAlgorithm.cycleNonDismissTarget( + currentTarget, increment); + dividerView.startDragging(true /* animate */, false /* touching */); + dividerView.stopDragging(target.position, 0f, true /* avoidDismissStart */); + } + } catch (RemoteException e) { + Log.e(TAG, "handleDockKey() failed."); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 6ad7aadc09722..4b8b6c131a68f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -1172,13 +1172,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } int dockSide = WindowManagerProxy.getInstance().getDockSide(); if (dockSide == WindowManager.DOCKED_INVALID) { - Point realSize = new Point(); - mContext.getSystemService(DisplayManager.class).getDisplay(Display.DEFAULT_DISPLAY) - .getRealSize(realSize); - Rect initialBounds= new Rect(0, 0, realSize.x, realSize.y); return mRecents.dockTopTask(NavigationBarGestureHelper.DRAG_MODE_NONE, - ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, - initialBounds); + ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, null); } else { EventBus.getDefault().send(new UndockingTaskEvent()); return false; diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index fb50df9fe791b..d36a1d7027010 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -1993,6 +1993,9 @@ message MetricsEvent { // Settings -> Apps -> Gear -> Special access SPECIAL_ACCESS = 351; + // Logs that the user docks window via shortcut key. + WINDOW_DOCK_SHORTCUTS = 352; + // Add new aosp constants above this line. // END OF AOSP CONSTANTS }