Loading packages/SystemUI/res/values/dimens.xml +3 −2 Original line number Diff line number Diff line Loading @@ -23,8 +23,9 @@ <dimen name="navigation_bar_size">@*android:dimen/navigation_bar_height</dimen> <!-- Minimum swipe distance to catch the swipe gestures to invoke assist or switch tasks. --> <dimen name="navigation_bar_min_swipe_distance">48dp</dimen> <!-- The distance from a side of device of the navigation bar to start an edge swipe --> <dimen name="navigation_bar_edge_swipe_threshold">48dp</dimen> <!-- The default distance from a side of the device to start an edge swipe from --> <dimen name="navigation_bar_default_edge_width">48dp</dimen> <dimen name="navigation_bar_default_edge_height">500dp</dimen> <!-- thickness (height) of the dead zone at the top of the navigation bar, reducing false presses on navbar buttons; approx 2mm --> Loading packages/SystemUI/res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -1829,6 +1829,9 @@ <!-- SysUI Tuner: Button that leads to the navigation bar customization screen [CHAR LIMIT=60] --> <string name="nav_bar">Navigation bar</string> <!-- Label for navigation edge panel for gestures [CHAR LIMIT=60] --> <string name="nav_bar_edge_panel" translatable="false">Navigation bar Edge Panel</string> <!-- SysUI Tuner: Button that controls layout of navigation bar [CHAR LIMIT=60] --> <string name="nav_bar_layout">Layout</string> Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java 0 → 100644 +78 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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 android.annotation.NonNull; import android.content.Context; import android.graphics.PixelFormat; import android.view.View; import android.view.WindowManager; import com.android.systemui.R; public class NavigationBarEdgePanel extends View { private static final String TAG = "NavigationBarEdgePanel"; public static NavigationBarEdgePanel create(@NonNull Context context, int width, int height, int gravity) { final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, height, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, PixelFormat.TRANSLUCENT); lp.gravity = gravity; lp.setTitle(TAG + context.getDisplayId()); lp.accessibilityTitle = context.getString(R.string.nav_bar_edge_panel); lp.windowAnimations = 0; NavigationBarEdgePanel panel = new NavigationBarEdgePanel(context); panel.setLayoutParams(lp); return panel; } private NavigationBarEdgePanel(Context context) { super(context); } public void setWindowFlag(int flags, boolean enable) { WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams(); if (lp == null || enable == ((lp.flags & flags) != 0)) { return; } if (enable) { lp.flags |= flags; } else { lp.flags &= ~flags; } updateLayout(lp); } public void setDimensions(int width, int height) { final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams(); if (lp.width != width || lp.height != height) { lp.width = width; lp.height = height; updateLayout(lp); } } private void updateLayout(WindowManager.LayoutParams lp) { WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); wm.updateViewLayout(this, lp); } } packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +104 −14 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.systemui.statusbar.phone; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.WindowManagerPolicyConstants.NAV_BAR_INVALID; import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT; import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT; import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_QUICK_SCRUB; import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON; Loading @@ -35,6 +37,8 @@ import android.animation.PropertyValuesHolder; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.annotation.DrawableRes; import android.annotation.IntDef; import android.annotation.SuppressLint; import android.app.StatusBarManager; import android.content.Context; import android.content.res.Configuration; Loading @@ -51,6 +55,7 @@ import android.util.Log; import android.util.Slog; import android.util.SparseArray; import android.view.Display; import android.view.Gravity; import android.view.MotionEvent; import android.view.Surface; import android.view.View; Loading Loading @@ -87,12 +92,21 @@ import com.android.systemui.statusbar.policy.KeyButtonDrawable; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.function.Consumer; public class NavigationBarView extends FrameLayout implements PluginListener<NavGesture> { final static boolean DEBUG = false; final static String TAG = "StatusBar/NavBarView"; @Retention(RetentionPolicy.SOURCE) @IntDef({WINDOW_TARGET_BOTTOM, WINDOW_TARGET_LEFT, WINDOW_TARGET_RIGHT}) public @interface WindowTarget{} public static final int WINDOW_TARGET_BOTTOM = 0; public static final int WINDOW_TARGET_LEFT = 1; public static final int WINDOW_TARGET_RIGHT = 2; // slippery nav bar when everything is disabled, e.g. during setup final static boolean SLIPPERY_WHEN_DISABLED = true; Loading @@ -109,6 +123,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav int mNavigationIconHints = 0; private @NavigationBarCompat.HitTarget int mDownHitTarget = HIT_TARGET_NONE; private @WindowTarget int mWindowHitTarget = WINDOW_TARGET_BOTTOM; private Rect mHomeButtonBounds = new Rect(); private Rect mBackButtonBounds = new Rect(); private Rect mRecentsButtonBounds = new Rect(); Loading Loading @@ -160,6 +175,9 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav private NavigationAssistantAction mAssistantAction; private NavigationNotificationPanelAction mNotificationPanelAction; private NavigationBarEdgePanel mLeftEdgePanel; private NavigationBarEdgePanel mRightEdgePanel; /** * Helper that is responsible for showing the right toast when a disallowed activity operation * occurred. In pinned mode, we show instructions on how to break out of this mode, whilst in Loading Loading @@ -222,6 +240,18 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } }; private final OnTouchListener mEdgePanelTouchListener = new OnTouchListener() { @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouch(View v, MotionEvent event) { if (event.getActionMasked() == ACTION_DOWN) { mWindowHitTarget = v == mLeftEdgePanel ? WINDOW_TARGET_LEFT : WINDOW_TARGET_RIGHT; mDownHitTarget = HIT_TARGET_NONE; } return mGestureHelper.onTouchEvent(event); } }; private class H extends Handler { public void handleMessage(Message m) { switch (m.what) { Loading Loading @@ -297,6 +327,16 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav mColorAdaptionController.end(); } } @Override public void onEdgeSensitivityChanged(int width, int height) { if (mLeftEdgePanel != null) { mLeftEdgePanel.setDimensions(width, height); } if (mRightEdgePanel != null) { mRightEdgePanel.setDimensions(width, height); } } }; public NavigationBarView(Context context, AttributeSet attrs) { Loading Loading @@ -433,6 +473,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav int x = (int) event.getX(); int y = (int) event.getY(); mDownHitTarget = HIT_TARGET_NONE; mWindowHitTarget = WINDOW_TARGET_BOTTOM; if (deadZoneConsumed) { mDownHitTarget = HIT_TARGET_DEAD_ZONE; } else if (getBackButton().isVisible() && mBackButtonBounds.contains(x, y)) { Loading Loading @@ -483,6 +524,10 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav return mDownHitTarget; } public @WindowTarget int getWindowTarget() { return mWindowHitTarget; } public void abortCurrentGesture() { getHomeButton().abortCurrentGesture(); } Loading Loading @@ -837,25 +882,33 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } private void setSlippery(boolean slippery) { boolean changed = false; setWindowFlag(WindowManager.LayoutParams.FLAG_SLIPPERY, slippery); } public void setWindowTouchable(boolean flag) { setWindowFlag(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, !flag); if (mLeftEdgePanel != null) { mLeftEdgePanel.setWindowFlag(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, !flag); } if (mRightEdgePanel != null) { mRightEdgePanel.setWindowFlag(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, !flag); } } private void setWindowFlag(int flags, boolean enable) { final ViewGroup navbarView = ((ViewGroup) getParent()); final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) navbarView .getLayoutParams(); if (lp == null) { WindowManager.LayoutParams lp = (WindowManager.LayoutParams) navbarView.getLayoutParams(); if (lp == null || enable == ((lp.flags & flags) != 0)) { return; } if (slippery && (lp.flags & WindowManager.LayoutParams.FLAG_SLIPPERY) == 0) { lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY; changed = true; } else if (!slippery && (lp.flags & WindowManager.LayoutParams.FLAG_SLIPPERY) != 0) { lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY; changed = true; if (enable) { lp.flags |= flags; } else { lp.flags &= ~flags; } if (changed) { WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); wm.updateViewLayout(navbarView, lp); } } public void setMenuVisibility(final boolean show) { mContextualButtonGroup.setButtonVisiblity(R.id.menu, show); Loading Loading @@ -1016,6 +1069,17 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } catch (RemoteException e) { Slog.e(TAG, "Failed to get nav bar position.", e); } // For landscape, hide the panel that would interfere with navigation bar layout if (mLeftEdgePanel != null && mRightEdgePanel != null) { mLeftEdgePanel.setVisibility(VISIBLE); mRightEdgePanel.setVisibility(VISIBLE); if (navBarPos == NAV_BAR_LEFT) { mLeftEdgePanel.setVisibility(GONE); } else if (navBarPos == NAV_BAR_RIGHT) { mRightEdgePanel.setVisibility(GONE); } } mGestureHelper.setBarState(isRtl, navBarPos); } Loading Loading @@ -1142,6 +1206,21 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav NavGesture.class, false /* Only one */); setUpSwipeUpOnboarding(isQuickStepSwipeUpEnabled()); mColorAdaptionController.start(); if (mPrototypeController.isEnabled()) { WindowManager wm = (WindowManager) getContext() .getSystemService(Context.WINDOW_SERVICE); int width = mPrototypeController.getEdgeSensitivityWidth(); int height = mPrototypeController.getEdgeSensitivityHeight(); mLeftEdgePanel = NavigationBarEdgePanel.create(getContext(), width, height, Gravity.START | Gravity.BOTTOM); mRightEdgePanel = NavigationBarEdgePanel.create(getContext(), width, height, Gravity.END | Gravity.BOTTOM); mLeftEdgePanel.setOnTouchListener(mEdgePanelTouchListener); mRightEdgePanel.setOnTouchListener(mEdgePanelTouchListener); wm.addView(mLeftEdgePanel, mLeftEdgePanel.getLayoutParams()); wm.addView(mRightEdgePanel, mRightEdgePanel.getLayoutParams()); } } @Override Loading @@ -1157,6 +1236,17 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav for (int i = 0; i < mButtonDispatchers.size(); ++i) { mButtonDispatchers.valueAt(i).onDestroy(); } if (mPrototypeController.isEnabled()) { WindowManager wm = (WindowManager) getContext() .getSystemService(Context.WINDOW_SERVICE); if (mLeftEdgePanel != null) { wm.removeView(mLeftEdgePanel); } if (mRightEdgePanel != null) { wm.removeView(mRightEdgePanel); } } } private void setUpSwipeUpOnboarding(boolean connectedToOverviewProxy) { Loading packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java +33 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone; import android.annotation.IntDef; import android.content.Context; import android.content.res.Resources; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; Loading @@ -34,7 +35,12 @@ import java.lang.annotation.RetentionPolicy; public class NavigationPrototypeController extends ContentObserver { private static final String HIDE_BACK_BUTTON_SETTING = "quickstepcontroller_hideback"; private static final String HIDE_HOME_BUTTON_SETTING = "quickstepcontroller_hidehome"; private static final String PROTOTYPE_ENABLED = "prototype_enabled"; private static final String EDGE_SENSITIVITY_HEIGHT_SETTING = "quickstepcontroller_edge_height_sensitivity"; public static final String EDGE_SENSITIVITY_WIDTH_SETTING = "quickstepcontroller_edge_width_sensitivity"; private final String GESTURE_MATCH_SETTING = "quickstepcontroller_gesture_match_map"; public static final String NAV_COLOR_ADAPT_ENABLE_SETTING = "navbar_color_adapt_enable"; Loading Loading @@ -79,6 +85,8 @@ public class NavigationPrototypeController extends ContentObserver { registerObserver(HIDE_HOME_BUTTON_SETTING); registerObserver(GESTURE_MATCH_SETTING); registerObserver(NAV_COLOR_ADAPT_ENABLE_SETTING); registerObserver(EDGE_SENSITIVITY_WIDTH_SETTING); registerObserver(EDGE_SENSITIVITY_HEIGHT_SETTING); } /** Loading Loading @@ -106,10 +114,26 @@ public class NavigationPrototypeController extends ContentObserver { } else if (path.endsWith(NAV_COLOR_ADAPT_ENABLE_SETTING)) { mListener.onColorAdaptChanged( NavBarTintController.isEnabled(mContext)); } else if (path.endsWith(EDGE_SENSITIVITY_WIDTH_SETTING) || path.endsWith(EDGE_SENSITIVITY_HEIGHT_SETTING)) { mListener.onEdgeSensitivityChanged(getEdgeSensitivityWidth(), getEdgeSensitivityHeight()); } } } public int getEdgeSensitivityWidth() { return convertDpToPixel(getGlobalInt(EDGE_SENSITIVITY_WIDTH_SETTING, 0)); } public int getEdgeSensitivityHeight() { return convertDpToPixel(getGlobalInt(EDGE_SENSITIVITY_HEIGHT_SETTING, 0)); } public boolean isEnabled() { return getGlobalBool(PROTOTYPE_ENABLED, false); } /** * Retrieve the action map to apply to the quick step controller * @return an action map Loading Loading @@ -144,15 +168,24 @@ public class NavigationPrototypeController extends ContentObserver { return Settings.Global.getInt(mContext.getContentResolver(), name, defaultVal ? 1 : 0) == 1; } private int getGlobalInt(String name, int defaultVal) { return Settings.Global.getInt(mContext.getContentResolver(), name, defaultVal); } private void registerObserver(String name) { mContext.getContentResolver() .registerContentObserver(Settings.Global.getUriFor(name), false, this); } private static int convertDpToPixel(float dp) { return (int) (dp * Resources.getSystem().getDisplayMetrics().density); } public interface OnPrototypeChangedListener { void onGestureRemap(@GestureAction int[] actions); void onBackButtonVisibilityChanged(boolean visible); void onHomeButtonVisibilityChanged(boolean visible); void onColorAdaptChanged(boolean enabled); void onEdgeSensitivityChanged(int width, int height); } } Loading
packages/SystemUI/res/values/dimens.xml +3 −2 Original line number Diff line number Diff line Loading @@ -23,8 +23,9 @@ <dimen name="navigation_bar_size">@*android:dimen/navigation_bar_height</dimen> <!-- Minimum swipe distance to catch the swipe gestures to invoke assist or switch tasks. --> <dimen name="navigation_bar_min_swipe_distance">48dp</dimen> <!-- The distance from a side of device of the navigation bar to start an edge swipe --> <dimen name="navigation_bar_edge_swipe_threshold">48dp</dimen> <!-- The default distance from a side of the device to start an edge swipe from --> <dimen name="navigation_bar_default_edge_width">48dp</dimen> <dimen name="navigation_bar_default_edge_height">500dp</dimen> <!-- thickness (height) of the dead zone at the top of the navigation bar, reducing false presses on navbar buttons; approx 2mm --> Loading
packages/SystemUI/res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -1829,6 +1829,9 @@ <!-- SysUI Tuner: Button that leads to the navigation bar customization screen [CHAR LIMIT=60] --> <string name="nav_bar">Navigation bar</string> <!-- Label for navigation edge panel for gestures [CHAR LIMIT=60] --> <string name="nav_bar_edge_panel" translatable="false">Navigation bar Edge Panel</string> <!-- SysUI Tuner: Button that controls layout of navigation bar [CHAR LIMIT=60] --> <string name="nav_bar_layout">Layout</string> Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarEdgePanel.java 0 → 100644 +78 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 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 android.annotation.NonNull; import android.content.Context; import android.graphics.PixelFormat; import android.view.View; import android.view.WindowManager; import com.android.systemui.R; public class NavigationBarEdgePanel extends View { private static final String TAG = "NavigationBarEdgePanel"; public static NavigationBarEdgePanel create(@NonNull Context context, int width, int height, int gravity) { final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, height, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, PixelFormat.TRANSLUCENT); lp.gravity = gravity; lp.setTitle(TAG + context.getDisplayId()); lp.accessibilityTitle = context.getString(R.string.nav_bar_edge_panel); lp.windowAnimations = 0; NavigationBarEdgePanel panel = new NavigationBarEdgePanel(context); panel.setLayoutParams(lp); return panel; } private NavigationBarEdgePanel(Context context) { super(context); } public void setWindowFlag(int flags, boolean enable) { WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams(); if (lp == null || enable == ((lp.flags & flags) != 0)) { return; } if (enable) { lp.flags |= flags; } else { lp.flags &= ~flags; } updateLayout(lp); } public void setDimensions(int width, int height) { final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) getLayoutParams(); if (lp.width != width || lp.height != height) { lp.width = width; lp.height = height; updateLayout(lp); } } private void updateLayout(WindowManager.LayoutParams lp) { WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); wm.updateViewLayout(this, lp); } }
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +104 −14 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.systemui.statusbar.phone; import static android.view.MotionEvent.ACTION_DOWN; import static android.view.WindowManagerPolicyConstants.NAV_BAR_INVALID; import static android.view.WindowManagerPolicyConstants.NAV_BAR_LEFT; import static android.view.WindowManagerPolicyConstants.NAV_BAR_RIGHT; import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_QUICK_SCRUB; import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON; Loading @@ -35,6 +37,8 @@ import android.animation.PropertyValuesHolder; import android.animation.TimeInterpolator; import android.animation.ValueAnimator; import android.annotation.DrawableRes; import android.annotation.IntDef; import android.annotation.SuppressLint; import android.app.StatusBarManager; import android.content.Context; import android.content.res.Configuration; Loading @@ -51,6 +55,7 @@ import android.util.Log; import android.util.Slog; import android.util.SparseArray; import android.view.Display; import android.view.Gravity; import android.view.MotionEvent; import android.view.Surface; import android.view.View; Loading Loading @@ -87,12 +92,21 @@ import com.android.systemui.statusbar.policy.KeyButtonDrawable; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.function.Consumer; public class NavigationBarView extends FrameLayout implements PluginListener<NavGesture> { final static boolean DEBUG = false; final static String TAG = "StatusBar/NavBarView"; @Retention(RetentionPolicy.SOURCE) @IntDef({WINDOW_TARGET_BOTTOM, WINDOW_TARGET_LEFT, WINDOW_TARGET_RIGHT}) public @interface WindowTarget{} public static final int WINDOW_TARGET_BOTTOM = 0; public static final int WINDOW_TARGET_LEFT = 1; public static final int WINDOW_TARGET_RIGHT = 2; // slippery nav bar when everything is disabled, e.g. during setup final static boolean SLIPPERY_WHEN_DISABLED = true; Loading @@ -109,6 +123,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav int mNavigationIconHints = 0; private @NavigationBarCompat.HitTarget int mDownHitTarget = HIT_TARGET_NONE; private @WindowTarget int mWindowHitTarget = WINDOW_TARGET_BOTTOM; private Rect mHomeButtonBounds = new Rect(); private Rect mBackButtonBounds = new Rect(); private Rect mRecentsButtonBounds = new Rect(); Loading Loading @@ -160,6 +175,9 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav private NavigationAssistantAction mAssistantAction; private NavigationNotificationPanelAction mNotificationPanelAction; private NavigationBarEdgePanel mLeftEdgePanel; private NavigationBarEdgePanel mRightEdgePanel; /** * Helper that is responsible for showing the right toast when a disallowed activity operation * occurred. In pinned mode, we show instructions on how to break out of this mode, whilst in Loading Loading @@ -222,6 +240,18 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } }; private final OnTouchListener mEdgePanelTouchListener = new OnTouchListener() { @SuppressLint("ClickableViewAccessibility") @Override public boolean onTouch(View v, MotionEvent event) { if (event.getActionMasked() == ACTION_DOWN) { mWindowHitTarget = v == mLeftEdgePanel ? WINDOW_TARGET_LEFT : WINDOW_TARGET_RIGHT; mDownHitTarget = HIT_TARGET_NONE; } return mGestureHelper.onTouchEvent(event); } }; private class H extends Handler { public void handleMessage(Message m) { switch (m.what) { Loading Loading @@ -297,6 +327,16 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav mColorAdaptionController.end(); } } @Override public void onEdgeSensitivityChanged(int width, int height) { if (mLeftEdgePanel != null) { mLeftEdgePanel.setDimensions(width, height); } if (mRightEdgePanel != null) { mRightEdgePanel.setDimensions(width, height); } } }; public NavigationBarView(Context context, AttributeSet attrs) { Loading Loading @@ -433,6 +473,7 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav int x = (int) event.getX(); int y = (int) event.getY(); mDownHitTarget = HIT_TARGET_NONE; mWindowHitTarget = WINDOW_TARGET_BOTTOM; if (deadZoneConsumed) { mDownHitTarget = HIT_TARGET_DEAD_ZONE; } else if (getBackButton().isVisible() && mBackButtonBounds.contains(x, y)) { Loading Loading @@ -483,6 +524,10 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav return mDownHitTarget; } public @WindowTarget int getWindowTarget() { return mWindowHitTarget; } public void abortCurrentGesture() { getHomeButton().abortCurrentGesture(); } Loading Loading @@ -837,25 +882,33 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } private void setSlippery(boolean slippery) { boolean changed = false; setWindowFlag(WindowManager.LayoutParams.FLAG_SLIPPERY, slippery); } public void setWindowTouchable(boolean flag) { setWindowFlag(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, !flag); if (mLeftEdgePanel != null) { mLeftEdgePanel.setWindowFlag(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, !flag); } if (mRightEdgePanel != null) { mRightEdgePanel.setWindowFlag(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, !flag); } } private void setWindowFlag(int flags, boolean enable) { final ViewGroup navbarView = ((ViewGroup) getParent()); final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) navbarView .getLayoutParams(); if (lp == null) { WindowManager.LayoutParams lp = (WindowManager.LayoutParams) navbarView.getLayoutParams(); if (lp == null || enable == ((lp.flags & flags) != 0)) { return; } if (slippery && (lp.flags & WindowManager.LayoutParams.FLAG_SLIPPERY) == 0) { lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY; changed = true; } else if (!slippery && (lp.flags & WindowManager.LayoutParams.FLAG_SLIPPERY) != 0) { lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY; changed = true; if (enable) { lp.flags |= flags; } else { lp.flags &= ~flags; } if (changed) { WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE); wm.updateViewLayout(navbarView, lp); } } public void setMenuVisibility(final boolean show) { mContextualButtonGroup.setButtonVisiblity(R.id.menu, show); Loading Loading @@ -1016,6 +1069,17 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav } catch (RemoteException e) { Slog.e(TAG, "Failed to get nav bar position.", e); } // For landscape, hide the panel that would interfere with navigation bar layout if (mLeftEdgePanel != null && mRightEdgePanel != null) { mLeftEdgePanel.setVisibility(VISIBLE); mRightEdgePanel.setVisibility(VISIBLE); if (navBarPos == NAV_BAR_LEFT) { mLeftEdgePanel.setVisibility(GONE); } else if (navBarPos == NAV_BAR_RIGHT) { mRightEdgePanel.setVisibility(GONE); } } mGestureHelper.setBarState(isRtl, navBarPos); } Loading Loading @@ -1142,6 +1206,21 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav NavGesture.class, false /* Only one */); setUpSwipeUpOnboarding(isQuickStepSwipeUpEnabled()); mColorAdaptionController.start(); if (mPrototypeController.isEnabled()) { WindowManager wm = (WindowManager) getContext() .getSystemService(Context.WINDOW_SERVICE); int width = mPrototypeController.getEdgeSensitivityWidth(); int height = mPrototypeController.getEdgeSensitivityHeight(); mLeftEdgePanel = NavigationBarEdgePanel.create(getContext(), width, height, Gravity.START | Gravity.BOTTOM); mRightEdgePanel = NavigationBarEdgePanel.create(getContext(), width, height, Gravity.END | Gravity.BOTTOM); mLeftEdgePanel.setOnTouchListener(mEdgePanelTouchListener); mRightEdgePanel.setOnTouchListener(mEdgePanelTouchListener); wm.addView(mLeftEdgePanel, mLeftEdgePanel.getLayoutParams()); wm.addView(mRightEdgePanel, mRightEdgePanel.getLayoutParams()); } } @Override Loading @@ -1157,6 +1236,17 @@ public class NavigationBarView extends FrameLayout implements PluginListener<Nav for (int i = 0; i < mButtonDispatchers.size(); ++i) { mButtonDispatchers.valueAt(i).onDestroy(); } if (mPrototypeController.isEnabled()) { WindowManager wm = (WindowManager) getContext() .getSystemService(Context.WINDOW_SERVICE); if (mLeftEdgePanel != null) { wm.removeView(mLeftEdgePanel); } if (mRightEdgePanel != null) { wm.removeView(mRightEdgePanel); } } } private void setUpSwipeUpOnboarding(boolean connectedToOverviewProxy) { Loading
packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationPrototypeController.java +33 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone; import android.annotation.IntDef; import android.content.Context; import android.content.res.Resources; import android.database.ContentObserver; import android.net.Uri; import android.os.Handler; Loading @@ -34,7 +35,12 @@ import java.lang.annotation.RetentionPolicy; public class NavigationPrototypeController extends ContentObserver { private static final String HIDE_BACK_BUTTON_SETTING = "quickstepcontroller_hideback"; private static final String HIDE_HOME_BUTTON_SETTING = "quickstepcontroller_hidehome"; private static final String PROTOTYPE_ENABLED = "prototype_enabled"; private static final String EDGE_SENSITIVITY_HEIGHT_SETTING = "quickstepcontroller_edge_height_sensitivity"; public static final String EDGE_SENSITIVITY_WIDTH_SETTING = "quickstepcontroller_edge_width_sensitivity"; private final String GESTURE_MATCH_SETTING = "quickstepcontroller_gesture_match_map"; public static final String NAV_COLOR_ADAPT_ENABLE_SETTING = "navbar_color_adapt_enable"; Loading Loading @@ -79,6 +85,8 @@ public class NavigationPrototypeController extends ContentObserver { registerObserver(HIDE_HOME_BUTTON_SETTING); registerObserver(GESTURE_MATCH_SETTING); registerObserver(NAV_COLOR_ADAPT_ENABLE_SETTING); registerObserver(EDGE_SENSITIVITY_WIDTH_SETTING); registerObserver(EDGE_SENSITIVITY_HEIGHT_SETTING); } /** Loading Loading @@ -106,10 +114,26 @@ public class NavigationPrototypeController extends ContentObserver { } else if (path.endsWith(NAV_COLOR_ADAPT_ENABLE_SETTING)) { mListener.onColorAdaptChanged( NavBarTintController.isEnabled(mContext)); } else if (path.endsWith(EDGE_SENSITIVITY_WIDTH_SETTING) || path.endsWith(EDGE_SENSITIVITY_HEIGHT_SETTING)) { mListener.onEdgeSensitivityChanged(getEdgeSensitivityWidth(), getEdgeSensitivityHeight()); } } } public int getEdgeSensitivityWidth() { return convertDpToPixel(getGlobalInt(EDGE_SENSITIVITY_WIDTH_SETTING, 0)); } public int getEdgeSensitivityHeight() { return convertDpToPixel(getGlobalInt(EDGE_SENSITIVITY_HEIGHT_SETTING, 0)); } public boolean isEnabled() { return getGlobalBool(PROTOTYPE_ENABLED, false); } /** * Retrieve the action map to apply to the quick step controller * @return an action map Loading Loading @@ -144,15 +168,24 @@ public class NavigationPrototypeController extends ContentObserver { return Settings.Global.getInt(mContext.getContentResolver(), name, defaultVal ? 1 : 0) == 1; } private int getGlobalInt(String name, int defaultVal) { return Settings.Global.getInt(mContext.getContentResolver(), name, defaultVal); } private void registerObserver(String name) { mContext.getContentResolver() .registerContentObserver(Settings.Global.getUriFor(name), false, this); } private static int convertDpToPixel(float dp) { return (int) (dp * Resources.getSystem().getDisplayMetrics().density); } public interface OnPrototypeChangedListener { void onGestureRemap(@GestureAction int[] actions); void onBackButtonVisibilityChanged(boolean visible); void onHomeButtonVisibilityChanged(boolean visible); void onColorAdaptChanged(boolean enabled); void onEdgeSensitivityChanged(int width, int height); } }