blob: 6dbe9f89dcdeebf17e87cdc802454696a4e17d22 [file] [log] [blame]
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001/*
2 * Copyright (C) 2008 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
17package com.android.systemui.statusbar.phone;
18
Winson Chungc4e06202018-02-13 10:37:35 -080019import static android.view.MotionEvent.ACTION_DOWN;
20import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_BACK;
21import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_HOME;
22import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_NONE;
23
John Spurlock1bbd49d2012-10-19 11:09:32 -040024import android.animation.LayoutTransition;
John Spurlock56d007b2013-10-28 18:40:56 -040025import android.animation.LayoutTransition.TransitionListener;
26import android.animation.ObjectAnimator;
27import android.animation.TimeInterpolator;
28import android.animation.ValueAnimator;
Jorim Jaggi40db0292016-06-27 17:58:03 -070029import android.annotation.DrawableRes;
Mike Digman1e28a5a2018-02-14 10:49:19 -080030import android.annotation.StyleRes;
Daniel Sandler328310c2011-09-23 15:56:52 -040031import android.app.StatusBarManager;
Daniel Sandler8956dbb2011-04-22 07:55:02 -040032import android.content.Context;
Selim Cinek17a327a2014-08-25 15:03:48 +020033import android.content.res.Configuration;
Matthew Nga8f24262017-12-19 11:54:24 -080034import android.graphics.Canvas;
Jeff Browna8b9def2012-07-23 14:22:49 -070035import android.graphics.Point;
Daniel Sandler48852952011-12-01 14:34:23 -050036import android.graphics.Rect;
Mike Digmana48cf192018-02-12 17:52:48 -080037import android.graphics.drawable.AnimatedVectorDrawable;
Mike Digman1e28a5a2018-02-14 10:49:19 -080038import android.graphics.drawable.Drawable;
Daniel Sandler0b69b592012-01-23 21:08:36 -050039import android.os.Handler;
40import android.os.Message;
Matthew Ng8f25fb962018-01-16 17:17:24 -080041import android.os.SystemProperties;
Mike Digman7d092772018-01-11 12:10:32 -080042import android.support.annotation.ColorInt;
Daniel Sandler8956dbb2011-04-22 07:55:02 -040043import android.util.AttributeSet;
John Spurlockcd686b52013-06-05 10:13:46 -040044import android.util.Log;
Jason Monka2081822016-01-18 14:41:03 -050045import android.util.SparseArray;
Jorim Jaggi40db0292016-06-27 17:58:03 -070046import android.view.ContextThemeWrapper;
Daniel Sandler8956dbb2011-04-22 07:55:02 -040047import android.view.Display;
Daniel Sandler1d4d30a2011-04-28 12:35:29 -040048import android.view.MotionEvent;
Daniel Sandler8956dbb2011-04-22 07:55:02 -040049import android.view.Surface;
John Spurlockde84f0e2013-06-12 12:41:00 -040050import android.view.View;
John Spurlock1bbd49d2012-10-19 11:09:32 -040051import android.view.ViewGroup;
Adrian Roos7e58a082018-03-09 16:40:56 +010052import android.view.WindowInsets;
Daniel Sandler8956dbb2011-04-22 07:55:02 -040053import android.view.WindowManager;
Jason Monkf1ff2092014-04-29 16:50:53 -040054import android.view.inputmethod.InputMethodManager;
Jason Monk86bc3312016-08-16 13:17:56 -040055import android.widget.FrameLayout;
Jason Monk67e6c802016-08-30 14:09:21 -040056
Jason Monk9a376bc2017-05-10 09:52:10 -040057import com.android.settingslib.Utils;
Jason Monkde850bb2017-02-01 19:26:30 -050058import com.android.systemui.Dependency;
Jason Monkf85fc962017-04-19 17:13:41 -040059import com.android.systemui.DockedStackExistsListener;
Matthew Ng7d05e772017-11-09 14:41:07 -080060import com.android.systemui.OverviewProxyService;
Daniel Sandler8956dbb2011-04-22 07:55:02 -040061import com.android.systemui.R;
Jorim Jaggidd98d412015-11-18 15:57:38 -080062import com.android.systemui.RecentsComponent;
Jason Monk67e6c802016-08-30 14:09:21 -040063import com.android.systemui.plugins.PluginListener;
64import com.android.systemui.plugins.PluginManager;
65import com.android.systemui.plugins.statusbar.phone.NavGesture;
66import com.android.systemui.plugins.statusbar.phone.NavGesture.GestureHelper;
Tony Wickham05c1f852018-02-06 12:32:54 -080067import com.android.systemui.recents.RecentsOnboarding;
Matthew Ng87cbf342018-02-15 12:21:18 -080068import com.android.systemui.shared.system.ActivityManagerWrapper;
Winson Chungc4e06202018-02-13 10:37:35 -080069import com.android.systemui.shared.system.NavigationBarCompat;
Matthew Ng84db1612018-04-17 16:48:21 -070070import com.android.systemui.shared.system.WindowManagerWrapper;
Jorim Jaggidd98d412015-11-18 15:57:38 -080071import com.android.systemui.stackdivider.Divider;
Daniel Sandlerc26185b2012-08-29 15:49:53 -040072import com.android.systemui.statusbar.policy.DeadZone;
Jorim Jaggi40db0292016-06-27 17:58:03 -070073import com.android.systemui.statusbar.policy.KeyButtonDrawable;
Tony Wickhamfb63fe82018-01-16 12:14:06 -080074import com.android.systemui.statusbar.policy.TintedKeyButtonDrawable;
Jorim Jaggi2fdeeab2015-04-01 15:13:03 -070075
John Spurlockde84f0e2013-06-12 12:41:00 -040076import java.io.FileDescriptor;
77import java.io.PrintWriter;
Jason Monk32e3bb52017-07-27 12:35:41 -040078import java.util.function.Consumer;
John Spurlockde84f0e2013-06-12 12:41:00 -040079
Matthew Ng8f25fb962018-01-16 17:17:24 -080080import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_DISABLE_QUICK_SCRUB;
Matthew Ng8f25fb962018-01-16 17:17:24 -080081import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_HIDE_BACK_BUTTON;
82import static com.android.systemui.shared.system.NavigationBarCompat.FLAG_SHOW_OVERVIEW_BUTTON;
Matthew Ng8a8c89c2018-03-01 13:21:43 -080083import static com.android.systemui.shared.system.NavigationBarCompat.HIT_TARGET_OVERVIEW;
Matthew Ng8f25fb962018-01-16 17:17:24 -080084
Jason Monk67e6c802016-08-30 14:09:21 -040085public class NavigationBarView extends FrameLayout implements PluginListener<NavGesture> {
Daniel Sandler60ee2562011-07-22 12:34:33 -040086 final static boolean DEBUG = false;
Adrian Roosa98b32c2016-08-11 10:41:08 -070087 final static String TAG = "StatusBar/NavBarView";
Daniel Sandler60ee2562011-07-22 12:34:33 -040088
Daniel Sandlerc3fc3222012-10-25 13:28:33 -040089 // slippery nav bar when everything is disabled, e.g. during setup
John Spurlock7edfbca2013-09-14 11:58:55 -040090 final static boolean SLIPPERY_WHEN_DISABLED = true;
Daniel Sandlerc3fc3222012-10-25 13:28:33 -040091
Justin Paupore01915a12016-09-28 17:41:26 -070092 final static boolean ALTERNATE_CAR_MODE_UI = false;
93
Daniel Sandler8956dbb2011-04-22 07:55:02 -040094 final Display mDisplay;
Daniel Sandler5c8da942011-06-28 00:29:04 -040095 View mCurrentView = null;
Daniel Sandler8956dbb2011-04-22 07:55:02 -040096 View[] mRotatedViews = new View[4];
Daniel Sandler60ee2562011-07-22 12:34:33 -040097
Daniel Sandler60ee2562011-07-22 12:34:33 -040098 boolean mVertical;
Adrian Roos090b7d82016-08-02 18:36:12 -070099 private int mCurrentRotation = -1;
Daniel Sandler60ee2562011-07-22 12:34:33 -0400100
John Spurlock7edfbca2013-09-14 11:58:55 -0400101 boolean mShowMenu;
Casey Burkhardt048c2bc2016-12-08 16:09:20 -0800102 boolean mShowAccessibilityButton;
103 boolean mLongClickableAccessibilityButton;
Mike Digmana48cf192018-02-12 17:52:48 -0800104 boolean mShowRotateButton;
Daniel Sandler6da2b762011-09-14 16:04:59 -0400105 int mDisabledFlags = 0;
Daniel Sandler328310c2011-09-23 15:56:52 -0400106 int mNavigationIconHints = 0;
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400107
Winson Chungc4e06202018-02-13 10:37:35 -0800108 private @NavigationBarCompat.HitTarget int mDownHitTarget = HIT_TARGET_NONE;
109 private Rect mHomeButtonBounds = new Rect();
110 private Rect mBackButtonBounds = new Rect();
Matthew Ng8a8c89c2018-03-01 13:21:43 -0800111 private Rect mRecentsButtonBounds = new Rect();
Winson Chungc4e06202018-02-13 10:37:35 -0800112 private int[] mTmpPosition = new int[2];
113
Jorim Jaggi40db0292016-06-27 17:58:03 -0700114 private KeyButtonDrawable mBackIcon, mBackLandIcon, mBackAltIcon, mBackAltLandIcon;
115 private KeyButtonDrawable mBackCarModeIcon, mBackLandCarModeIcon;
116 private KeyButtonDrawable mBackAltCarModeIcon, mBackAltLandCarModeIcon;
117 private KeyButtonDrawable mHomeDefaultIcon, mHomeCarModeIcon;
118 private KeyButtonDrawable mRecentIcon;
119 private KeyButtonDrawable mDockedIcon;
120 private KeyButtonDrawable mImeIcon;
121 private KeyButtonDrawable mMenuIcon;
Casey Burkhardt048c2bc2016-12-08 16:09:20 -0800122 private KeyButtonDrawable mAccessibilityIcon;
Mike Digmanc8217582018-03-06 13:08:33 -0800123 private TintedKeyButtonDrawable mRotateSuggestionIcon;
Fabrice Di Meglio18d98242013-01-17 10:57:40 -0800124
Jason Monk67e6c802016-08-30 14:09:21 -0400125 private GestureHelper mGestureHelper;
Matthew Ng603b3292018-03-30 17:15:39 -0700126 private final DeadZone mDeadZone;
John Spurlock89835dd2013-08-16 15:06:51 -0400127 private final NavigationBarTransitions mBarTransitions;
Matthew Ngdc79e5c2017-12-14 17:37:35 -0800128 private final OverviewProxyService mOverviewProxyService;
Jim Millere898ac52012-04-06 17:10:57 -0700129
Daniel Sandler0b69b592012-01-23 21:08:36 -0500130 // workaround for LayoutTransitions leaving the nav buttons in a weird state (bug 5549288)
131 final static boolean WORKAROUND_INVALID_LAYOUT = true;
132 final static int MSG_CHECK_INVALID_LAYOUT = 8686;
133
John Spurlock56d007b2013-10-28 18:40:56 -0400134 // performs manual animation in sync with layout transitions
135 private final NavTransitionListener mTransitionListener = new NavTransitionListener();
136
Jorim Jaggif4797922014-08-04 22:49:41 +0200137 private OnVerticalChangedListener mOnVerticalChangedListener;
Jorim Jaggi37c11802015-08-18 20:27:54 -0700138 private boolean mLayoutTransitionsEnabled = true;
139 private boolean mWakeAndUnlocking;
Justin Paupore01915a12016-09-28 17:41:26 -0700140 private boolean mUseCarModeUi = false;
141 private boolean mInCarMode = false;
Jorim Jaggid30d95d2016-02-17 20:27:22 -0800142 private boolean mDockedStackExists;
Jorim Jaggif4797922014-08-04 22:49:41 +0200143
Felipe Leme15f915c2016-10-31 12:47:15 -0700144 private final SparseArray<ButtonDispatcher> mButtonDispatchers = new SparseArray<>();
Winsonfde2e6a2016-03-22 16:03:10 -0700145 private Configuration mConfiguration;
Jason Monka2081822016-01-18 14:41:03 -0500146
Adrian Roosdb12b152016-07-12 15:38:55 -0700147 private NavigationBarInflaterView mNavigationInflaterView;
Jason Monk67e6c802016-08-30 14:09:21 -0400148 private RecentsComponent mRecentsComponent;
149 private Divider mDivider;
Tony Wickham05c1f852018-02-06 12:32:54 -0800150 private RecentsOnboarding mRecentsOnboarding;
Matthew Ng78f88d12018-01-23 12:39:55 -0800151 private NotificationPanelView mPanelView;
Adrian Roosdb12b152016-07-12 15:38:55 -0700152
Mike Digman1e28a5a2018-02-14 10:49:19 -0800153 private int mRotateBtnStyle = R.style.RotateButtonCCWStart90;
Mike Digmana48cf192018-02-12 17:52:48 -0800154
John Spurlock56d007b2013-10-28 18:40:56 -0400155 private class NavTransitionListener implements TransitionListener {
156 private boolean mBackTransitioning;
157 private boolean mHomeAppearing;
158 private long mStartDelay;
159 private long mDuration;
160 private TimeInterpolator mInterpolator;
161
162 @Override
163 public void startTransition(LayoutTransition transition, ViewGroup container,
164 View view, int transitionType) {
165 if (view.getId() == R.id.back) {
166 mBackTransitioning = true;
167 } else if (view.getId() == R.id.home && transitionType == LayoutTransition.APPEARING) {
168 mHomeAppearing = true;
169 mStartDelay = transition.getStartDelay(transitionType);
170 mDuration = transition.getDuration(transitionType);
171 mInterpolator = transition.getInterpolator(transitionType);
172 }
173 }
174
175 @Override
176 public void endTransition(LayoutTransition transition, ViewGroup container,
177 View view, int transitionType) {
178 if (view.getId() == R.id.back) {
179 mBackTransitioning = false;
180 } else if (view.getId() == R.id.home && transitionType == LayoutTransition.APPEARING) {
181 mHomeAppearing = false;
182 }
183 }
184
185 public void onBackAltCleared() {
Jason Monka2081822016-01-18 14:41:03 -0500186 ButtonDispatcher backButton = getBackButton();
Anthony Chenada13042016-01-19 16:57:20 -0800187
John Spurlock56d007b2013-10-28 18:40:56 -0400188 // When dismissing ime during unlock, force the back button to run the same appearance
189 // animation as home (if we catch this condition early enough).
Jason Monka2081822016-01-18 14:41:03 -0500190 if (!mBackTransitioning && backButton.getVisibility() == VISIBLE
191 && mHomeAppearing && getHomeButton().getAlpha() == 0) {
John Spurlock56d007b2013-10-28 18:40:56 -0400192 getBackButton().setAlpha(0);
Anthony Chenada13042016-01-19 16:57:20 -0800193 ValueAnimator a = ObjectAnimator.ofFloat(backButton, "alpha", 0, 1);
John Spurlock56d007b2013-10-28 18:40:56 -0400194 a.setStartDelay(mStartDelay);
195 a.setDuration(mDuration);
196 a.setInterpolator(mInterpolator);
197 a.start();
198 }
199 }
200 }
201
Jason Monkf1ff2092014-04-29 16:50:53 -0400202 private final OnClickListener mImeSwitcherClickListener = new OnClickListener() {
203 @Override
204 public void onClick(View view) {
Yohei Yukawa777ef952015-11-25 20:32:24 -0800205 mContext.getSystemService(InputMethodManager.class)
Seigo Nonaka14e13912015-05-06 21:04:13 -0700206 .showInputMethodPicker(true /* showAuxiliarySubtypes */);
Jason Monkf1ff2092014-04-29 16:50:53 -0400207 }
208 };
209
Daniel Sandler0b69b592012-01-23 21:08:36 -0500210 private class H extends Handler {
211 public void handleMessage(Message m) {
212 switch (m.what) {
213 case MSG_CHECK_INVALID_LAYOUT:
214 final String how = "" + m.obj;
215 final int w = getWidth();
216 final int h = getHeight();
Rakesh Iyer1186faa2015-12-07 16:48:46 -0800217 final int vw = getCurrentView().getWidth();
218 final int vh = getCurrentView().getHeight();
Daniel Sandler0b69b592012-01-23 21:08:36 -0500219
220 if (h != vh || w != vw) {
John Spurlockcd686b52013-06-05 10:13:46 -0400221 Log.w(TAG, String.format(
Daniel Sandler0b69b592012-01-23 21:08:36 -0500222 "*** Invalid layout in navigation bar (%s this=%dx%d cur=%dx%d)",
223 how, w, h, vw, vh));
224 if (WORKAROUND_INVALID_LAYOUT) {
225 requestLayout();
226 }
227 }
228 break;
229 }
230 }
231 }
232
John Spurlocke932e302013-08-12 10:16:29 -0400233 public NavigationBarView(Context context, AttributeSet attrs) {
234 super(context, attrs);
235
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800236 mDisplay = ((WindowManager) context.getSystemService(
John Spurlocke932e302013-08-12 10:16:29 -0400237 Context.WINDOW_SERVICE)).getDefaultDisplay();
John Spurlocke932e302013-08-12 10:16:29 -0400238
John Spurlocke932e302013-08-12 10:16:29 -0400239 mVertical = false;
240 mShowMenu = false;
John Spurlocke932e302013-08-12 10:16:29 -0400241
Casey Burkhardt048c2bc2016-12-08 16:09:20 -0800242 mShowAccessibilityButton = false;
243 mLongClickableAccessibilityButton = false;
244
Matthew Ngf2946542018-02-12 14:13:18 -0800245 mOverviewProxyService = Dependency.get(OverviewProxyService.class);
246 mRecentsOnboarding = new RecentsOnboarding(context, mOverviewProxyService);
247
Winsonfde2e6a2016-03-22 16:03:10 -0700248 mConfiguration = new Configuration();
249 mConfiguration.updateFrom(context.getResources().getConfiguration());
Matthew Ngd0a73e72018-03-02 15:16:03 -0800250 reloadNavIcons();
John Spurlocke932e302013-08-12 10:16:29 -0400251
John Spurlock7edfbca2013-09-14 11:58:55 -0400252 mBarTransitions = new NavigationBarTransitions(this);
Jason Monka2081822016-01-18 14:41:03 -0500253
Felipe Leme15f915c2016-10-31 12:47:15 -0700254 mButtonDispatchers.put(R.id.back, new ButtonDispatcher(R.id.back));
255 mButtonDispatchers.put(R.id.home, new ButtonDispatcher(R.id.home));
256 mButtonDispatchers.put(R.id.recent_apps, new ButtonDispatcher(R.id.recent_apps));
257 mButtonDispatchers.put(R.id.menu, new ButtonDispatcher(R.id.menu));
258 mButtonDispatchers.put(R.id.ime_switcher, new ButtonDispatcher(R.id.ime_switcher));
Casey Burkhardt048c2bc2016-12-08 16:09:20 -0800259 mButtonDispatchers.put(R.id.accessibility_button,
260 new ButtonDispatcher(R.id.accessibility_button));
Mike Digman7d092772018-01-11 12:10:32 -0800261 mButtonDispatchers.put(R.id.rotate_suggestion,
262 new ButtonDispatcher(R.id.rotate_suggestion));
Matthew Ng603b3292018-03-30 17:15:39 -0700263 mDeadZone = new DeadZone(this);
John Spurlocke932e302013-08-12 10:16:29 -0400264 }
265
266 public BarTransitions getBarTransitions() {
267 return mBarTransitions;
268 }
269
Jorim Jaggi40db0292016-06-27 17:58:03 -0700270 public LightBarTransitionsController getLightTransitionsController() {
271 return mBarTransitions.getLightTransitionsController();
272 }
273
Matthew Ng78f88d12018-01-23 12:39:55 -0800274 public void setComponents(RecentsComponent recentsComponent, Divider divider,
275 NotificationPanelView panel) {
Jason Monk67e6c802016-08-30 14:09:21 -0400276 mRecentsComponent = recentsComponent;
277 mDivider = divider;
Matthew Ng78f88d12018-01-23 12:39:55 -0800278 mPanelView = panel;
Jason Monk67e6c802016-08-30 14:09:21 -0400279 if (mGestureHelper instanceof NavigationBarGestureHelper) {
280 ((NavigationBarGestureHelper) mGestureHelper).setComponents(
281 recentsComponent, divider, this);
282 }
Jim Millere898ac52012-04-06 17:10:57 -0700283 }
284
Jorim Jaggif4797922014-08-04 22:49:41 +0200285 public void setOnVerticalChangedListener(OnVerticalChangedListener onVerticalChangedListener) {
286 mOnVerticalChangedListener = onVerticalChangedListener;
Selim Cinek92d892c2014-09-11 15:11:00 +0200287 notifyVerticalChangedListener(mVertical);
Jorim Jaggif4797922014-08-04 22:49:41 +0200288 }
289
Jim Millere898ac52012-04-06 17:10:57 -0700290 @Override
291 public boolean onInterceptTouchEvent(MotionEvent event) {
Matthew Ng603b3292018-03-30 17:15:39 -0700292 if (mDeadZone.onTouchEvent(event)) {
293 // Consumed the touch event
294 return true;
295 }
Winson Chungc4e06202018-02-13 10:37:35 -0800296 switch (event.getActionMasked()) {
297 case ACTION_DOWN:
298 int x = (int) event.getX();
299 int y = (int) event.getY();
300 mDownHitTarget = HIT_TARGET_NONE;
301 if (mBackButtonBounds.contains(x, y)) {
302 mDownHitTarget = HIT_TARGET_BACK;
303 } else if (mHomeButtonBounds.contains(x, y)) {
304 mDownHitTarget = HIT_TARGET_HOME;
Matthew Ng8a8c89c2018-03-01 13:21:43 -0800305 } else if (mRecentsButtonBounds.contains(x, y)) {
306 mDownHitTarget = HIT_TARGET_OVERVIEW;
Winson Chungc4e06202018-02-13 10:37:35 -0800307 }
308 break;
309 }
Winson Chung49658842018-02-08 12:52:21 -0800310 return mGestureHelper.onInterceptTouchEvent(event);
Jim Millere898ac52012-04-06 17:10:57 -0700311 }
312
Winson Chung4faf38a2018-02-06 08:53:37 -0800313 @Override
314 public boolean onTouchEvent(MotionEvent event) {
Matthew Ng603b3292018-03-30 17:15:39 -0700315 if (mDeadZone.onTouchEvent(event)) {
316 // Consumed the touch event
317 return true;
318 }
Winson Chung4faf38a2018-02-06 08:53:37 -0800319 if (mGestureHelper.onTouchEvent(event)) {
320 return true;
321 }
Winson Chung49658842018-02-08 12:52:21 -0800322 return super.onTouchEvent(event);
Winson Chung4faf38a2018-02-06 08:53:37 -0800323 }
324
Winson Chungc4e06202018-02-13 10:37:35 -0800325 public @NavigationBarCompat.HitTarget int getDownHitTarget() {
326 return mDownHitTarget;
327 }
328
Xiyuan Xiaee7dd052015-05-15 09:46:27 -0700329 public void abortCurrentGesture() {
Jason Monka2081822016-01-18 14:41:03 -0500330 getHomeButton().abortCurrentGesture();
Xiyuan Xiaee7dd052015-05-15 09:46:27 -0700331 }
332
Daniel Sandler0b69b592012-01-23 21:08:36 -0500333 private H mHandler = new H();
334
John Spurlock7edfbca2013-09-14 11:58:55 -0400335 public View getCurrentView() {
336 return mCurrentView;
337 }
338
Xiaohui Chen10942302015-12-16 16:38:13 -0800339 public View[] getAllViews() {
340 return mRotatedViews;
341 }
342
Jason Monka2081822016-01-18 14:41:03 -0500343 public ButtonDispatcher getRecentsButton() {
Felipe Leme15f915c2016-10-31 12:47:15 -0700344 return mButtonDispatchers.get(R.id.recent_apps);
Daniel Sandler5c8da942011-06-28 00:29:04 -0400345 }
346
Jason Monka2081822016-01-18 14:41:03 -0500347 public ButtonDispatcher getMenuButton() {
Felipe Leme15f915c2016-10-31 12:47:15 -0700348 return mButtonDispatchers.get(R.id.menu);
Daniel Sandler5c8da942011-06-28 00:29:04 -0400349 }
350
Jason Monka2081822016-01-18 14:41:03 -0500351 public ButtonDispatcher getBackButton() {
Felipe Leme15f915c2016-10-31 12:47:15 -0700352 return mButtonDispatchers.get(R.id.back);
Mike Lockwoode3646dd2011-09-01 12:46:28 -0400353 }
354
Jason Monka2081822016-01-18 14:41:03 -0500355 public ButtonDispatcher getHomeButton() {
Felipe Leme15f915c2016-10-31 12:47:15 -0700356 return mButtonDispatchers.get(R.id.home);
Mike Lockwoode3646dd2011-09-01 12:46:28 -0400357 }
358
Jason Monka2081822016-01-18 14:41:03 -0500359 public ButtonDispatcher getImeSwitchButton() {
Felipe Leme15f915c2016-10-31 12:47:15 -0700360 return mButtonDispatchers.get(R.id.ime_switcher);
Jason Monkf1ff2092014-04-29 16:50:53 -0400361 }
362
Casey Burkhardt048c2bc2016-12-08 16:09:20 -0800363 public ButtonDispatcher getAccessibilityButton() {
364 return mButtonDispatchers.get(R.id.accessibility_button);
365 }
366
Mike Digman7d092772018-01-11 12:10:32 -0800367 public ButtonDispatcher getRotateSuggestionButton() {
368 return mButtonDispatchers.get(R.id.rotate_suggestion);
369 }
370
Jorim Jaggi40db0292016-06-27 17:58:03 -0700371 public SparseArray<ButtonDispatcher> getButtonDispatchers() {
372 return mButtonDispatchers;
373 }
374
Matthew Ng9c3bce52018-02-01 22:00:31 +0000375 public boolean isRecentsButtonVisible() {
376 return getRecentsButton().getVisibility() == View.VISIBLE;
377 }
378
Matthew Ng6ff33b72018-02-27 13:47:38 -0800379 public boolean isOverviewEnabled() {
380 return (mDisabledFlags & View.STATUS_BAR_DISABLE_RECENT) == 0;
381 }
382
Matthew Ng8f25fb962018-01-16 17:17:24 -0800383 public boolean isQuickStepSwipeUpEnabled() {
Matthew Ngc1a97b12018-03-28 14:02:00 -0700384 return mOverviewProxyService.shouldShowSwipeUpUI() && isOverviewEnabled();
Matthew Ng8f25fb962018-01-16 17:17:24 -0800385 }
386
387 public boolean isQuickScrubEnabled() {
388 return SystemProperties.getBoolean("persist.quickstep.scrub.enabled", true)
Winson Chungd95a2252018-04-04 17:02:29 +0000389 && mOverviewProxyService.isEnabled() && isOverviewEnabled()
Matthew Ngc1a97b12018-03-28 14:02:00 -0700390 && ((mOverviewProxyService.getInteractionFlags() & FLAG_DISABLE_QUICK_SCRUB) == 0);
Matthew Ng8f25fb962018-01-16 17:17:24 -0800391 }
392
Winsonfde2e6a2016-03-22 16:03:10 -0700393 private void updateCarModeIcons(Context ctx) {
Jorim Jaggi40db0292016-06-27 17:58:03 -0700394 mBackCarModeIcon = getDrawable(ctx,
395 R.drawable.ic_sysbar_back_carmode, R.drawable.ic_sysbar_back_carmode);
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800396 mBackLandCarModeIcon = mBackCarModeIcon;
Jorim Jaggi40db0292016-06-27 17:58:03 -0700397 mBackAltCarModeIcon = getDrawable(ctx,
398 R.drawable.ic_sysbar_back_ime_carmode, R.drawable.ic_sysbar_back_ime_carmode);
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800399 mBackAltLandCarModeIcon = mBackAltCarModeIcon;
Jorim Jaggi40db0292016-06-27 17:58:03 -0700400 mHomeCarModeIcon = getDrawable(ctx,
401 R.drawable.ic_sysbar_home_carmode, R.drawable.ic_sysbar_home_carmode);
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800402 }
403
Matthew Ngd0a73e72018-03-02 15:16:03 -0800404 private void reloadNavIcons() {
405 updateIcons(mContext, Configuration.EMPTY, mConfiguration);
406 }
407
Winsonfde2e6a2016-03-22 16:03:10 -0700408 private void updateIcons(Context ctx, Configuration oldConfig, Configuration newConfig) {
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700409 if (oldConfig.orientation != newConfig.orientation
410 || oldConfig.densityDpi != newConfig.densityDpi) {
Jorim Jaggi40db0292016-06-27 17:58:03 -0700411 mDockedIcon = getDrawable(ctx,
412 R.drawable.ic_sysbar_docked, R.drawable.ic_sysbar_docked_dark);
Matthew Ng87cbf342018-02-15 12:21:18 -0800413 mHomeDefaultIcon = getHomeDrawable(ctx);
Winsonfde2e6a2016-03-22 16:03:10 -0700414 }
Jason Monk1f785d42017-07-25 15:46:33 -0400415 if (oldConfig.densityDpi != newConfig.densityDpi
416 || oldConfig.getLayoutDirection() != newConfig.getLayoutDirection()) {
Matthew Ng87cbf342018-02-15 12:21:18 -0800417 mBackIcon = getBackDrawable(ctx);
Winsonfde2e6a2016-03-22 16:03:10 -0700418 mBackLandIcon = mBackIcon;
Matthew Ng87cbf342018-02-15 12:21:18 -0800419 mBackAltIcon = getBackImeDrawable(ctx);
Winsonfde2e6a2016-03-22 16:03:10 -0700420 mBackAltLandIcon = mBackAltIcon;
Jorim Jaggi40db0292016-06-27 17:58:03 -0700421 mRecentIcon = getDrawable(ctx,
422 R.drawable.ic_sysbar_recent, R.drawable.ic_sysbar_recent_dark);
423 mMenuIcon = getDrawable(ctx, R.drawable.ic_sysbar_menu, R.drawable.ic_sysbar_menu_dark);
424
Jason Monk9a376bc2017-05-10 09:52:10 -0400425 int dualToneDarkTheme = Utils.getThemeAttr(ctx, R.attr.darkIconTheme);
426 int dualToneLightTheme = Utils.getThemeAttr(ctx, R.attr.lightIconTheme);
427 Context darkContext = new ContextThemeWrapper(ctx, dualToneDarkTheme);
428 Context lightContext = new ContextThemeWrapper(ctx, dualToneLightTheme);
Mike Digmane3909de2018-03-30 11:22:05 -0700429
430 mAccessibilityIcon = getDrawable(darkContext, lightContext,
431 R.drawable.ic_sysbar_accessibility_button,
432 R.drawable.ic_sysbar_accessibility_button);
433
Jorim Jaggi40db0292016-06-27 17:58:03 -0700434 mImeIcon = getDrawable(darkContext, lightContext,
435 R.drawable.ic_ime_switcher_default, R.drawable.ic_ime_switcher_default);
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700436
Mike Digman1e28a5a2018-02-14 10:49:19 -0800437 updateRotateSuggestionButtonStyle(mRotateBtnStyle, false);
Mike Digman7d092772018-01-11 12:10:32 -0800438
Justin Paupore01915a12016-09-28 17:41:26 -0700439 if (ALTERNATE_CAR_MODE_UI) {
440 updateCarModeIcons(ctx);
441 }
Winsonfde2e6a2016-03-22 16:03:10 -0700442 }
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700443 }
444
Matthew Ng87cbf342018-02-15 12:21:18 -0800445 public KeyButtonDrawable getBackDrawable(Context ctx) {
446 return chooseNavigationIconDrawable(ctx, R.drawable.ic_sysbar_back,
447 R.drawable.ic_sysbar_back_dark, R.drawable.ic_sysbar_back_quick_step,
448 R.drawable.ic_sysbar_back_quick_step_dark);
449 }
450
451 public KeyButtonDrawable getBackImeDrawable(Context ctx) {
452 return chooseNavigationIconDrawable(ctx, R.drawable.ic_sysbar_back_ime,
453 R.drawable.ic_sysbar_back_ime_dark, R.drawable.ic_sysbar_back_ime_quick_step,
454 R.drawable.ic_sysbar_back_ime_quick_step_dark);
455 }
456
457 public KeyButtonDrawable getHomeDrawable(Context ctx) {
458 return chooseNavigationIconDrawable(ctx, R.drawable.ic_sysbar_home,
459 R.drawable.ic_sysbar_home_dark, R.drawable.ic_sysbar_home_quick_step,
460 R.drawable.ic_sysbar_home_quick_step_dark);
461 }
462
463 private KeyButtonDrawable chooseNavigationIconDrawable(Context ctx, @DrawableRes int iconLight,
464 @DrawableRes int iconDark, @DrawableRes int quickStepIconLight,
465 @DrawableRes int quickStepIconDark) {
Matthew Ngc1a97b12018-03-28 14:02:00 -0700466 final boolean quickStepEnabled = mOverviewProxyService.shouldShowSwipeUpUI();
Matthew Ng87cbf342018-02-15 12:21:18 -0800467 return quickStepEnabled
468 ? getDrawable(ctx, quickStepIconLight, quickStepIconDark)
469 : getDrawable(ctx, iconLight, iconDark);
470 }
471
Jorim Jaggi40db0292016-06-27 17:58:03 -0700472 private KeyButtonDrawable getDrawable(Context ctx, @DrawableRes int lightIcon,
473 @DrawableRes int darkIcon) {
474 return getDrawable(ctx, ctx, lightIcon, darkIcon);
475 }
476
477 private KeyButtonDrawable getDrawable(Context darkContext, Context lightContext,
478 @DrawableRes int lightIcon, @DrawableRes int darkIcon) {
479 return KeyButtonDrawable.create(lightContext.getDrawable(lightIcon),
480 darkContext.getDrawable(darkIcon));
481 }
482
Mike Digmanc8217582018-03-06 13:08:33 -0800483 private TintedKeyButtonDrawable getDrawable(Context ctx, @DrawableRes int icon,
Mike Digman7d092772018-01-11 12:10:32 -0800484 @ColorInt int lightColor, @ColorInt int darkColor) {
485 return TintedKeyButtonDrawable.create(ctx.getDrawable(icon), lightColor, darkColor);
486 }
487
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700488 @Override
489 public void setLayoutDirection(int layoutDirection) {
Matthew Ngd0a73e72018-03-02 15:16:03 -0800490 reloadNavIcons();
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700491
492 super.setLayoutDirection(layoutDirection);
Daniel Sandler1d4d30a2011-04-28 12:35:29 -0400493 }
494
Jorim Jaggi40db0292016-06-27 17:58:03 -0700495 private KeyButtonDrawable getBackIconWithAlt(boolean carMode, boolean landscape) {
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800496 return landscape
497 ? carMode ? mBackAltLandCarModeIcon : mBackAltLandIcon
498 : carMode ? mBackAltCarModeIcon : mBackAltIcon;
499 }
500
Jorim Jaggi40db0292016-06-27 17:58:03 -0700501 private KeyButtonDrawable getBackIcon(boolean carMode, boolean landscape) {
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800502 return landscape
503 ? carMode ? mBackLandCarModeIcon : mBackLandIcon
504 : carMode ? mBackCarModeIcon : mBackIcon;
505 }
506
Matthew Ngd0a73e72018-03-02 15:16:03 -0800507 public void setNavigationIconHints(int hints) {
508 if (hints == mNavigationIconHints) return;
John Spurlock56d007b2013-10-28 18:40:56 -0400509 final boolean backAlt = (hints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0;
510 if ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0 && !backAlt) {
511 mTransitionListener.onBackAltCleared();
512 }
Daniel Sandler328310c2011-09-23 15:56:52 -0400513 if (DEBUG) {
John Spurlock01534782014-01-13 11:59:22 -0500514 android.widget.Toast.makeText(getContext(),
Daniel Sandler328310c2011-09-23 15:56:52 -0400515 "Navigation icon hints = " + hints,
516 500).show();
517 }
Daniel Sandler328310c2011-09-23 15:56:52 -0400518 mNavigationIconHints = hints;
Matthew Ngd0a73e72018-03-02 15:16:03 -0800519 updateNavButtonIcons();
520 }
Daniel Sandler328310c2011-09-23 15:56:52 -0400521
Matthew Ngd0a73e72018-03-02 15:16:03 -0800522 public void setDisabledFlags(int disabledFlags) {
523 if (mDisabledFlags == disabledFlags) return;
524
525 final boolean overviewEnabledBefore = isOverviewEnabled();
526 mDisabledFlags = disabledFlags;
527
528 // Update icons if overview was just enabled to ensure the correct icons are present
529 if (!overviewEnabledBefore && isOverviewEnabled()) {
530 reloadNavIcons();
531 }
532
533 updateNavButtonIcons();
534 }
535
536 public void updateNavButtonIcons() {
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800537 // We have to replace or restore the back and home button icons when exiting or entering
538 // carmode, respectively. Recents are not available in CarMode in nav bar so change
539 // to recent icon is not required.
Matthew Ngd0a73e72018-03-02 15:16:03 -0800540 KeyButtonDrawable backIcon
541 = ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) != 0)
542 ? getBackIconWithAlt(mUseCarModeUi, mVertical)
543 : getBackIcon(mUseCarModeUi, mVertical);
Jason Monka2081822016-01-18 14:41:03 -0500544 getBackButton().setImageDrawable(backIcon);
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800545
Jorim Jaggid30d95d2016-02-17 20:27:22 -0800546 updateRecentsIcon();
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800547
Justin Paupore01915a12016-09-28 17:41:26 -0700548 if (mUseCarModeUi) {
Jason Monka2081822016-01-18 14:41:03 -0500549 getHomeButton().setImageDrawable(mHomeCarModeIcon);
550 } else {
551 getHomeButton().setImageDrawable(mHomeDefaultIcon);
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800552 }
Fabrice Di Meglio8afcd142012-07-27 18:27:11 -0700553
Mike Digmana48cf192018-02-12 17:52:48 -0800554 // Update IME button visibility, a11y and rotate button always overrides the appearance
Casey Burkhardt2464dc92017-03-28 15:52:12 -0700555 final boolean showImeButton =
Mike Digmana48cf192018-02-12 17:52:48 -0800556 !mShowAccessibilityButton &&
Matthew Ngd0a73e72018-03-02 15:16:03 -0800557 !mShowRotateButton &&
558 ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) != 0);
Jason Monka2081822016-01-18 14:41:03 -0500559 getImeSwitchButton().setVisibility(showImeButton ? View.VISIBLE : View.INVISIBLE);
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700560 getImeSwitchButton().setImageDrawable(mImeIcon);
Anthony Chenada13042016-01-19 16:57:20 -0800561
Mike Digmana48cf192018-02-12 17:52:48 -0800562 // Update menu button, visibility logic in method
Jason Monkf1ff2092014-04-29 16:50:53 -0400563 setMenuVisibility(mShowMenu, true);
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700564 getMenuButton().setImageDrawable(mMenuIcon);
Jason Monkf1ff2092014-04-29 16:50:53 -0400565
Mike Digmana48cf192018-02-12 17:52:48 -0800566 // Update rotate button, visibility altered by a11y button logic
567 getRotateSuggestionButton().setImageDrawable(mRotateSuggestionIcon);
568
569 // Update a11y button, visibility logic in state method
Casey Burkhardt048c2bc2016-12-08 16:09:20 -0800570 setAccessibilityButtonState(mShowAccessibilityButton, mLongClickableAccessibilityButton);
571 getAccessibilityButton().setImageDrawable(mAccessibilityIcon);
572
Jorim Jaggi40db0292016-06-27 17:58:03 -0700573 mBarTransitions.reapplyDarkIntensity();
Daniel Sandler328310c2011-09-23 15:56:52 -0400574
Matthew Ngd0a73e72018-03-02 15:16:03 -0800575 boolean disableHome = ((mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0);
Sriram Viswanathan469caae2016-03-22 13:11:50 -0700576
Justin Paupore01915a12016-09-28 17:41:26 -0700577 // Always disable recents when alternate car mode UI is active.
Matthew Ng6ff33b72018-02-27 13:47:38 -0800578 boolean disableRecent = mUseCarModeUi || !isOverviewEnabled();
Charles Hee57ff812017-10-26 10:01:35 +0100579
Matthew Ngd0a73e72018-03-02 15:16:03 -0800580 boolean disableBack = ((mDisabledFlags & View.STATUS_BAR_DISABLE_BACK) != 0)
John Spurlocka9b46822012-11-02 10:42:39 -0400581 && ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_BACK_ALT) == 0);
Daniel Sandler029d5872011-09-12 00:58:58 -0400582
Matthew Ng87cbf342018-02-15 12:21:18 -0800583 // When screen pinning, don't hide back and home when connected service or back and
584 // recents buttons when disconnected from launcher service in screen pinning mode,
585 // as they are used for exiting.
Matthew Ng6ff33b72018-02-27 13:47:38 -0800586 final boolean pinningActive = ActivityManagerWrapper.getInstance().isScreenPinningActive();
Winson Chungd95a2252018-04-04 17:02:29 +0000587 if (mOverviewProxyService.isEnabled()) {
Matthew Ng87cbf342018-02-15 12:21:18 -0800588 // Use interaction flags to show/hide navigation buttons but will be shown if required
589 // to exit screen pinning.
Matthew Ng8f25fb962018-01-16 17:17:24 -0800590 final int flags = mOverviewProxyService.getInteractionFlags();
591 disableRecent |= (flags & FLAG_SHOW_OVERVIEW_BUTTON) == 0;
Matthew Ng6ff33b72018-02-27 13:47:38 -0800592 if (pinningActive) {
Matthew Ng87cbf342018-02-15 12:21:18 -0800593 disableBack = disableHome = false;
594 } else {
595 disableBack |= (flags & FLAG_HIDE_BACK_BUTTON) != 0;
596 }
Matthew Ng6ff33b72018-02-27 13:47:38 -0800597 } else if (pinningActive) {
Matthew Ng87cbf342018-02-15 12:21:18 -0800598 disableBack = disableRecent = false;
Matthew Ngdc79e5c2017-12-14 17:37:35 -0800599 }
Charles Hee57ff812017-10-26 10:01:35 +0100600
Rakesh Iyer1186faa2015-12-07 16:48:46 -0800601 ViewGroup navButtons = (ViewGroup) getCurrentView().findViewById(R.id.nav_buttons);
John Spurlock56d007b2013-10-28 18:40:56 -0400602 if (navButtons != null) {
603 LayoutTransition lt = navButtons.getLayoutTransition();
John Spurlock1bbd49d2012-10-19 11:09:32 -0400604 if (lt != null) {
John Spurlock56d007b2013-10-28 18:40:56 -0400605 if (!lt.getTransitionListeners().contains(mTransitionListener)) {
606 lt.addTransitionListener(mTransitionListener);
607 }
John Spurlock1bbd49d2012-10-19 11:09:32 -0400608 }
609 }
610
Jason Monka2081822016-01-18 14:41:03 -0500611 getBackButton().setVisibility(disableBack ? View.INVISIBLE : View.VISIBLE);
Jason Monk188908f2016-01-22 10:23:51 -0500612 getHomeButton().setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
Jason Monka2081822016-01-18 14:41:03 -0500613 getRecentsButton().setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
John Spurlock56d007b2013-10-28 18:40:56 -0400614 }
615
Matthew Ng87cbf342018-02-15 12:21:18 -0800616 public boolean inScreenPinning() {
Matthew Ng6ff33b72018-02-27 13:47:38 -0800617 return ActivityManagerWrapper.getInstance().isScreenPinningActive();
Jason Monk17488b92014-11-06 11:26:14 -0500618 }
619
Jorim Jaggi37c11802015-08-18 20:27:54 -0700620 public void setLayoutTransitionsEnabled(boolean enabled) {
621 mLayoutTransitionsEnabled = enabled;
622 updateLayoutTransitionsEnabled();
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700623 }
624
Jorim Jaggi37c11802015-08-18 20:27:54 -0700625 public void setWakeAndUnlocking(boolean wakeAndUnlocking) {
626 setUseFadingAnimations(wakeAndUnlocking);
627 mWakeAndUnlocking = wakeAndUnlocking;
628 updateLayoutTransitionsEnabled();
629 }
630
631 private void updateLayoutTransitionsEnabled() {
632 boolean enabled = !mWakeAndUnlocking && mLayoutTransitionsEnabled;
Rakesh Iyer1186faa2015-12-07 16:48:46 -0800633 ViewGroup navButtons = (ViewGroup) getCurrentView().findViewById(R.id.nav_buttons);
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700634 LayoutTransition lt = navButtons.getLayoutTransition();
Julia Reynolds8478aba2015-07-31 09:17:20 -0400635 if (lt != null) {
636 if (enabled) {
637 lt.enableTransitionType(LayoutTransition.APPEARING);
638 lt.enableTransitionType(LayoutTransition.DISAPPEARING);
639 lt.enableTransitionType(LayoutTransition.CHANGE_APPEARING);
640 lt.enableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
641 } else {
642 lt.disableTransitionType(LayoutTransition.APPEARING);
643 lt.disableTransitionType(LayoutTransition.DISAPPEARING);
644 lt.disableTransitionType(LayoutTransition.CHANGE_APPEARING);
645 lt.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
646 }
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700647 }
648 }
649
650 private void setUseFadingAnimations(boolean useFadingAnimations) {
Jason Monk49fa0162017-01-11 09:21:56 -0500651 WindowManager.LayoutParams lp = (WindowManager.LayoutParams) ((ViewGroup) getParent())
652 .getLayoutParams();
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700653 if (lp != null) {
654 boolean old = lp.windowAnimations != 0;
655 if (!old && useFadingAnimations) {
656 lp.windowAnimations = R.style.Animation_NavigationBarFadeIn;
657 } else if (old && !useFadingAnimations) {
658 lp.windowAnimations = 0;
659 } else {
660 return;
661 }
662 WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
Jason Monk49fa0162017-01-11 09:21:56 -0500663 wm.updateViewLayout((View) getParent(), lp);
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700664 }
665 }
666
Matthew Ng2ea93b72018-03-14 19:43:18 +0000667 public void onNavigationButtonLongPress(View v) {
668 mGestureHelper.onNavigationButtonLongPress(v);
669 }
670
Matthew Ng78f88d12018-01-23 12:39:55 -0800671 public void onPanelExpandedChange(boolean expanded) {
672 updateSlippery();
673 }
674
Matthew Ng8f25fb962018-01-16 17:17:24 -0800675 public void updateStates() {
676 updateSlippery();
Winson Chung770d7e92018-03-20 17:51:39 -0700677 reloadNavIcons();
Matthew Ngd0a73e72018-03-02 15:16:03 -0800678 updateNavButtonIcons();
Winson Chungf9e30272018-03-26 17:25:36 -0700679 setUpSwipeUpOnboarding(isQuickStepSwipeUpEnabled());
Matthew Ng84db1612018-04-17 16:48:21 -0700680 WindowManagerWrapper.getInstance().setNavBarVirtualKeyHapticFeedbackEnabled(
681 !mOverviewProxyService.shouldShowSwipeUpUI());
Matthew Ng8f25fb962018-01-16 17:17:24 -0800682 }
683
Matthew Ng78f88d12018-01-23 12:39:55 -0800684 private void updateSlippery() {
Winson Chung770d7e92018-03-20 17:51:39 -0700685 setSlippery(!isQuickStepSwipeUpEnabled() || mPanelView.isFullyExpanded());
Matthew Ng78f88d12018-01-23 12:39:55 -0800686 }
687
Matthew Ng7d05e772017-11-09 14:41:07 -0800688 private void setSlippery(boolean slippery) {
689 boolean changed = false;
690 final ViewGroup navbarView = ((ViewGroup) getParent());
691 final WindowManager.LayoutParams lp = (WindowManager.LayoutParams) navbarView
692 .getLayoutParams();
Matthew Ng9c3bce52018-02-01 22:00:31 +0000693 if (lp == null) {
694 return;
695 }
Matthew Ng7d05e772017-11-09 14:41:07 -0800696 if (slippery && (lp.flags & WindowManager.LayoutParams.FLAG_SLIPPERY) == 0) {
697 lp.flags |= WindowManager.LayoutParams.FLAG_SLIPPERY;
698 changed = true;
699 } else if (!slippery && (lp.flags & WindowManager.LayoutParams.FLAG_SLIPPERY) != 0) {
700 lp.flags &= ~WindowManager.LayoutParams.FLAG_SLIPPERY;
701 changed = true;
702 }
703 if (changed) {
704 WindowManager wm = (WindowManager)getContext().getSystemService(Context.WINDOW_SERVICE);
705 wm.updateViewLayout(navbarView, lp);
706 }
707 }
708
Daniel Sandler56598cd2011-09-15 16:02:56 -0400709 public void setMenuVisibility(final boolean show) {
710 setMenuVisibility(show, false);
711 }
712
713 public void setMenuVisibility(final boolean show, final boolean force) {
714 if (!force && mShowMenu == show) return;
715
716 mShowMenu = show;
717
Mike Digmana48cf192018-02-12 17:52:48 -0800718 // Only show Menu if IME switcher, rotate and Accessibility buttons are not shown.
719 final boolean shouldShow = mShowMenu &&
720 !mShowAccessibilityButton &&
721 !mShowRotateButton &&
Jason Monkf1ff2092014-04-29 16:50:53 -0400722 ((mNavigationIconHints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) == 0);
Anthony Chenada13042016-01-19 16:57:20 -0800723
Jason Monka2081822016-01-18 14:41:03 -0500724 getMenuButton().setVisibility(shouldShow ? View.VISIBLE : View.INVISIBLE);
Daniel Sandler029d5872011-09-12 00:58:58 -0400725 }
726
Casey Burkhardt048c2bc2016-12-08 16:09:20 -0800727 public void setAccessibilityButtonState(final boolean visible, final boolean longClickable) {
728 mShowAccessibilityButton = visible;
729 mLongClickableAccessibilityButton = longClickable;
730 if (visible) {
Mike Digmana48cf192018-02-12 17:52:48 -0800731 // Accessibility button overrides Menu, IME switcher and rotate buttons.
Casey Burkhardt048c2bc2016-12-08 16:09:20 -0800732 setMenuVisibility(false, true);
Casey Burkhardt2464dc92017-03-28 15:52:12 -0700733 getImeSwitchButton().setVisibility(View.INVISIBLE);
Mike Digman1e28a5a2018-02-14 10:49:19 -0800734 setRotateButtonVisibility(false);
Casey Burkhardt048c2bc2016-12-08 16:09:20 -0800735 }
736
737 getAccessibilityButton().setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
738 getAccessibilityButton().setLongClickable(longClickable);
739 }
740
Mike Digman1e28a5a2018-02-14 10:49:19 -0800741 public void updateRotateSuggestionButtonStyle(@StyleRes int style, boolean setIcon) {
742 mRotateBtnStyle = style;
743 final Context ctx = getContext();
744
745 // Extract the dark and light tints
746 final int dualToneDarkTheme = Utils.getThemeAttr(ctx, R.attr.darkIconTheme);
747 final int dualToneLightTheme = Utils.getThemeAttr(ctx, R.attr.lightIconTheme);
748 Context darkContext = new ContextThemeWrapper(ctx, dualToneDarkTheme);
749 Context lightContext = new ContextThemeWrapper(ctx, dualToneLightTheme);
750 final int lightColor = Utils.getColorAttr(lightContext, R.attr.singleToneColor);
751 final int darkColor = Utils.getColorAttr(darkContext, R.attr.singleToneColor);
752
753 // Use the supplied style to set the icon's rotation parameters
754 Context rotateContext = new ContextThemeWrapper(ctx, style);
755
756 // Recreate the icon and set it if needed
Mike Digmanc8217582018-03-06 13:08:33 -0800757 TintedKeyButtonDrawable priorIcon = mRotateSuggestionIcon;
Mike Digman1e28a5a2018-02-14 10:49:19 -0800758 mRotateSuggestionIcon = getDrawable(rotateContext, R.drawable.ic_sysbar_rotate_button,
759 lightColor, darkColor);
Mike Digmanc8217582018-03-06 13:08:33 -0800760
761 // Apply any prior set dark intensity
762 if (priorIcon != null && priorIcon.isDarkIntensitySet()) {
763 mRotateSuggestionIcon.setDarkIntensity(priorIcon.getDarkIntensity());
764 }
765
Mike Digman1e28a5a2018-02-14 10:49:19 -0800766 if (setIcon) getRotateSuggestionButton().setImageDrawable(mRotateSuggestionIcon);
Mike Digmana48cf192018-02-12 17:52:48 -0800767 }
768
Mike Digman9b50b762018-04-19 10:50:35 -0700769 public int setRotateButtonVisibility(final boolean visible) {
Mike Digmana48cf192018-02-12 17:52:48 -0800770 // Never show if a11y is visible
771 final boolean adjVisible = visible && !mShowAccessibilityButton;
772 final int vis = adjVisible ? View.VISIBLE : View.INVISIBLE;
773
Mike Digman1e28a5a2018-02-14 10:49:19 -0800774 // No need to do anything if the request matches the current state
Mike Digman9b50b762018-04-19 10:50:35 -0700775 if (vis == getRotateSuggestionButton().getVisibility()) return vis;
Mike Digman1e28a5a2018-02-14 10:49:19 -0800776
Mike Digmana48cf192018-02-12 17:52:48 -0800777 getRotateSuggestionButton().setVisibility(vis);
778 mShowRotateButton = visible;
779
Mike Digman1e28a5a2018-02-14 10:49:19 -0800780 // Stop any active animations if hidden
781 if (!visible) {
782 Drawable d = mRotateSuggestionIcon.getDrawable(0);
783 if (d instanceof AnimatedVectorDrawable) {
784 AnimatedVectorDrawable avd = (AnimatedVectorDrawable) d;
785 avd.clearAnimationCallbacks();
786 avd.reset();
787 }
788 }
789
Mike Digmana48cf192018-02-12 17:52:48 -0800790 // Hide/restore other button visibility, if necessary
Matthew Ngd0a73e72018-03-02 15:16:03 -0800791 updateNavButtonIcons();
Mike Digman9b50b762018-04-19 10:50:35 -0700792
793 // Return applied visibility
794 return vis;
Mike Digmana48cf192018-02-12 17:52:48 -0800795 }
796
Mike Digman1e28a5a2018-02-14 10:49:19 -0800797 public boolean isRotateButtonVisible() { return mShowRotateButton; }
798
Jim Miller960892c2012-05-23 15:50:04 -0700799 @Override
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400800 public void onFinishInflate() {
Adrian Roosdb12b152016-07-12 15:38:55 -0700801 mNavigationInflaterView = (NavigationBarInflaterView) findViewById(
802 R.id.navigation_inflater);
Felipe Leme15f915c2016-10-31 12:47:15 -0700803 mNavigationInflaterView.setButtonDispatchers(mButtonDispatchers);
Jason Monka2081822016-01-18 14:41:03 -0500804
805 getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
Selim Cinek17a327a2014-08-25 15:03:48 +0200806
Jason Monk32e3bb52017-07-27 12:35:41 -0400807 DockedStackExistsListener.register(mDockedListener);
Siarhei Vishniakoufdb42772017-06-29 10:32:11 -0700808 updateRotatedViews();
Jorim Jaggia6c934e2015-12-21 13:22:31 +0100809 }
810
Matthew Nga8f24262017-12-19 11:54:24 -0800811 public void onDarkIntensityChange(float intensity) {
812 if (mGestureHelper != null) {
813 mGestureHelper.onDarkIntensityChange(intensity);
814 }
815 }
816
817 @Override
818 protected void onDraw(Canvas canvas) {
819 mGestureHelper.onDraw(canvas);
Matthew Ng603b3292018-03-30 17:15:39 -0700820 mDeadZone.onDraw(canvas);
Matthew Nga8f24262017-12-19 11:54:24 -0800821 super.onDraw(canvas);
822 }
823
824 @Override
825 protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
826 super.onLayout(changed, left, top, right, bottom);
Winson Chungc4e06202018-02-13 10:37:35 -0800827 updateButtonLocationOnScreen(getBackButton(), mBackButtonBounds);
828 updateButtonLocationOnScreen(getHomeButton(), mHomeButtonBounds);
Matthew Ng8a8c89c2018-03-01 13:21:43 -0800829 updateButtonLocationOnScreen(getRecentsButton(), mRecentsButtonBounds);
Matthew Nga8f24262017-12-19 11:54:24 -0800830 mGestureHelper.onLayout(changed, left, top, right, bottom);
Tracy Zhou559d97c2018-04-07 23:54:46 -0700831 mRecentsOnboarding.setNavBarHeight(getMeasuredHeight());
Matthew Nga8f24262017-12-19 11:54:24 -0800832 }
833
Winson Chungc4e06202018-02-13 10:37:35 -0800834 private void updateButtonLocationOnScreen(ButtonDispatcher button, Rect buttonBounds) {
835 View view = button.getCurrentView();
836 if (view == null) {
837 buttonBounds.setEmpty();
838 return;
839 }
Matthew Ng3b7e3902018-03-22 16:06:09 -0700840 // Temporarily reset the translation back to origin to get the position in window
841 final float posX = view.getTranslationX();
842 final float posY = view.getTranslationY();
843 view.setTranslationX(0);
844 view.setTranslationY(0);
Winson Chungc4e06202018-02-13 10:37:35 -0800845 view.getLocationInWindow(mTmpPosition);
846 buttonBounds.set(mTmpPosition[0], mTmpPosition[1],
847 mTmpPosition[0] + view.getMeasuredWidth(),
848 mTmpPosition[1] + view.getMeasuredHeight());
Matthew Ng3b7e3902018-03-22 16:06:09 -0700849 view.setTranslationX(posX);
850 view.setTranslationY(posY);
Winson Chungc4e06202018-02-13 10:37:35 -0800851 }
852
Siarhei Vishniakoufdb42772017-06-29 10:32:11 -0700853 private void updateRotatedViews() {
Jason Monk9a6552d2016-05-20 11:21:59 -0400854 mRotatedViews[Surface.ROTATION_0] =
855 mRotatedViews[Surface.ROTATION_180] = findViewById(R.id.rot0);
856 mRotatedViews[Surface.ROTATION_270] =
857 mRotatedViews[Surface.ROTATION_90] = findViewById(R.id.rot90);
858
Jason Monk199a2d02017-07-28 11:08:27 -0400859 updateCurrentView();
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400860 }
861
Adrian Roosa98b32c2016-08-11 10:41:08 -0700862 public boolean needsReorient(int rotation) {
863 return mCurrentRotation != rotation;
Adrian Roos090b7d82016-08-02 18:36:12 -0700864 }
865
Jason Monk199a2d02017-07-28 11:08:27 -0400866 private void updateCurrentView() {
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400867 final int rot = mDisplay.getRotation();
868 for (int i=0; i<4; i++) {
869 mRotatedViews[i].setVisibility(View.GONE);
870 }
Daniel Sandler5c8da942011-06-28 00:29:04 -0400871 mCurrentView = mRotatedViews[rot];
872 mCurrentView.setVisibility(View.VISIBLE);
Adrian Roosdb12b152016-07-12 15:38:55 -0700873 mNavigationInflaterView.setAlternativeOrder(rot == Surface.ROTATION_90);
Matthew Ng1efc9c32018-04-11 18:13:56 -0700874 mNavigationInflaterView.updateButtonDispatchersCurrentView();
Jorim Jaggi37c11802015-08-18 20:27:54 -0700875 updateLayoutTransitionsEnabled();
Adrian Roos090b7d82016-08-02 18:36:12 -0700876 mCurrentRotation = rot;
Jason Monk9a6552d2016-05-20 11:21:59 -0400877 }
878
879 private void updateRecentsIcon() {
880 getRecentsButton().setImageDrawable(mDockedStackExists ? mDockedIcon : mRecentIcon);
Jorim Jaggi40db0292016-06-27 17:58:03 -0700881 mBarTransitions.reapplyDarkIntensity();
Jason Monk9a6552d2016-05-20 11:21:59 -0400882 }
883
884 public boolean isVertical() {
885 return mVertical;
886 }
887
888 public void reorient() {
Jason Monk199a2d02017-07-28 11:08:27 -0400889 updateCurrentView();
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400890
Siarhei Vishniakoufdb42772017-06-29 10:32:11 -0700891 ((NavigationBarFrame) getRootView()).setDeadZone(mDeadZone);
Matthew Ng603b3292018-03-30 17:15:39 -0700892 mDeadZone.onConfigurationChanged(mCurrentRotation);
Daniel Sandlerc26185b2012-08-29 15:49:53 -0400893
Daniel Sandler6da2b762011-09-14 16:04:59 -0400894 // force the low profile & disabled states into compliance
Adrian Roos8a8ffd42015-05-26 18:30:37 -0700895 mBarTransitions.init();
Daniel Sandler56598cd2011-09-15 16:02:56 -0400896 setMenuVisibility(mShowMenu, true /* force */);
Daniel Sandler6da2b762011-09-14 16:04:59 -0400897
Daniel Sandler60ee2562011-07-22 12:34:33 -0400898 if (DEBUG) {
Adrian Roosa98b32c2016-08-11 10:41:08 -0700899 Log.d(TAG, "reorient(): rot=" + mCurrentRotation);
Daniel Sandler60ee2562011-07-22 12:34:33 -0400900 }
Michael Jurkaa5d0ddb2012-03-09 17:41:41 -0800901
Matthew Ng5fd80412018-02-14 14:40:31 -0800902 // Resolve layout direction if not resolved since components changing layout direction such
903 // as changing languages will recreate this view and the direction will be resolved later
904 if (!isLayoutDirectionResolved()) {
905 resolveLayoutDirection();
906 }
Selim Cinek92d892c2014-09-11 15:11:00 +0200907 updateTaskSwitchHelper();
Matthew Ngd0a73e72018-03-02 15:16:03 -0800908 updateNavButtonIcons();
Xiaohui Chen9efa5de2016-11-22 10:34:38 -0800909
Xiaohui Chen40e978e2016-11-29 15:10:04 -0800910 getHomeButton().setVertical(mVertical);
Daniel Sandler8956dbb2011-04-22 07:55:02 -0400911 }
Daniel Sandler48852952011-12-01 14:34:23 -0500912
Selim Cinek92d892c2014-09-11 15:11:00 +0200913 private void updateTaskSwitchHelper() {
Jason Monkde850bb2017-02-01 19:26:30 -0500914 if (mGestureHelper == null) return;
Selim Cinek92d892c2014-09-11 15:11:00 +0200915 boolean isRtl = (getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
Jorim Jaggidd98d412015-11-18 15:57:38 -0800916 mGestureHelper.setBarState(mVertical, isRtl);
Selim Cinek92d892c2014-09-11 15:11:00 +0200917 }
918
Daniel Sandler0b69b592012-01-23 21:08:36 -0500919 @Override
920 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
John Spurlockcd686b52013-06-05 10:13:46 -0400921 if (DEBUG) Log.d(TAG, String.format(
Daniel Sandler0b69b592012-01-23 21:08:36 -0500922 "onSizeChanged: (%dx%d) old: (%dx%d)", w, h, oldw, oldh));
Daniel Sandlere03bc952012-04-27 16:11:22 -0400923
924 final boolean newVertical = w > 0 && h > w;
925 if (newVertical != mVertical) {
926 mVertical = newVertical;
John Spurlockcd686b52013-06-05 10:13:46 -0400927 //Log.v(TAG, String.format("onSizeChanged: h=%d, w=%d, vert=%s", h, w, mVertical?"y":"n"));
Daniel Sandlere03bc952012-04-27 16:11:22 -0400928 reorient();
Selim Cinek92d892c2014-09-11 15:11:00 +0200929 notifyVerticalChangedListener(newVertical);
Daniel Sandlere03bc952012-04-27 16:11:22 -0400930 }
931
Daniel Sandler0b69b592012-01-23 21:08:36 -0500932 postCheckForInvalidLayout("sizeChanged");
933 super.onSizeChanged(w, h, oldw, oldh);
934 }
935
Selim Cinek92d892c2014-09-11 15:11:00 +0200936 private void notifyVerticalChangedListener(boolean newVertical) {
937 if (mOnVerticalChangedListener != null) {
938 mOnVerticalChangedListener.onVerticalChanged(newVertical);
939 }
940 }
941
Selim Cinek17a327a2014-08-25 15:03:48 +0200942 @Override
943 protected void onConfigurationChanged(Configuration newConfig) {
944 super.onConfigurationChanged(newConfig);
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800945 boolean uiCarModeChanged = updateCarMode(newConfig);
Selim Cinek92d892c2014-09-11 15:11:00 +0200946 updateTaskSwitchHelper();
Winsonfde2e6a2016-03-22 16:03:10 -0700947 updateIcons(getContext(), mConfiguration, newConfig);
948 updateRecentsIcon();
Tony Wickham05c1f852018-02-06 12:32:54 -0800949 mRecentsOnboarding.onConfigurationChanged(newConfig);
Jason Monk1f785d42017-07-25 15:46:33 -0400950 if (uiCarModeChanged || mConfiguration.densityDpi != newConfig.densityDpi
951 || mConfiguration.getLayoutDirection() != newConfig.getLayoutDirection()) {
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700952 // If car mode or density changes, we need to reset the icons.
Matthew Ngd0a73e72018-03-02 15:16:03 -0800953 updateNavButtonIcons();
Jorim Jaggi11c62e12016-04-05 20:41:21 -0700954 }
Winsonfde2e6a2016-03-22 16:03:10 -0700955 mConfiguration.updateFrom(newConfig);
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800956 }
957
958 /**
959 * If the configuration changed, update the carmode and return that it was updated.
960 */
961 private boolean updateCarMode(Configuration newConfig) {
962 boolean uiCarModeChanged = false;
963 if (newConfig != null) {
964 int uiMode = newConfig.uiMode & Configuration.UI_MODE_TYPE_MASK;
Justin Paupore01915a12016-09-28 17:41:26 -0700965 final boolean isCarMode = (uiMode == Configuration.UI_MODE_TYPE_CAR);
966
967 if (isCarMode != mInCarMode) {
968 mInCarMode = isCarMode;
Justin Paupore01915a12016-09-28 17:41:26 -0700969 if (ALTERNATE_CAR_MODE_UI) {
970 mUseCarModeUi = isCarMode;
971 uiCarModeChanged = true;
972 } else {
973 // Don't use car mode behavior if ALTERNATE_CAR_MODE_UI not set.
974 mUseCarModeUi = false;
975 }
Sriram Viswanathan9ebbe6a2015-11-16 17:59:22 -0800976 }
977 }
978 return uiCarModeChanged;
Selim Cinek17a327a2014-08-25 15:03:48 +0200979 }
980
Daniel Sandler0b69b592012-01-23 21:08:36 -0500981 /*
982 @Override
983 protected void onLayout (boolean changed, int left, int top, int right, int bottom) {
John Spurlockcd686b52013-06-05 10:13:46 -0400984 if (DEBUG) Log.d(TAG, String.format(
John Spurlock209bede2013-07-17 12:23:27 -0400985 "onLayout: %s (%d,%d,%d,%d)",
Daniel Sandler0b69b592012-01-23 21:08:36 -0500986 changed?"changed":"notchanged", left, top, right, bottom));
987 super.onLayout(changed, left, top, right, bottom);
988 }
989
990 // uncomment this for extra defensiveness in WORKAROUND_INVALID_LAYOUT situations: if all else
991 // fails, any touch on the display will fix the layout.
992 @Override
993 public boolean onInterceptTouchEvent(MotionEvent ev) {
John Spurlockcd686b52013-06-05 10:13:46 -0400994 if (DEBUG) Log.d(TAG, "onInterceptTouchEvent: " + ev.toString());
Daniel Sandler0b69b592012-01-23 21:08:36 -0500995 if (ev.getAction() == MotionEvent.ACTION_DOWN) {
996 postCheckForInvalidLayout("touch");
997 }
998 return super.onInterceptTouchEvent(ev);
999 }
1000 */
John Spurlock209bede2013-07-17 12:23:27 -04001001
Daniel Sandler0b69b592012-01-23 21:08:36 -05001002
Daniel Sandler48852952011-12-01 14:34:23 -05001003 private String getResourceName(int resId) {
1004 if (resId != 0) {
John Spurlock01534782014-01-13 11:59:22 -05001005 final android.content.res.Resources res = getContext().getResources();
Daniel Sandler48852952011-12-01 14:34:23 -05001006 try {
1007 return res.getResourceName(resId);
1008 } catch (android.content.res.Resources.NotFoundException ex) {
1009 return "(unknown)";
1010 }
1011 } else {
1012 return "(null)";
1013 }
1014 }
1015
Daniel Sandler0b69b592012-01-23 21:08:36 -05001016 private void postCheckForInvalidLayout(final String how) {
1017 mHandler.obtainMessage(MSG_CHECK_INVALID_LAYOUT, 0, 0, how).sendToTarget();
1018 }
1019
Daniel Sandler48852952011-12-01 14:34:23 -05001020 private static String visibilityToString(int vis) {
1021 switch (vis) {
1022 case View.INVISIBLE:
1023 return "INVISIBLE";
1024 case View.GONE:
1025 return "GONE";
1026 default:
1027 return "VISIBLE";
1028 }
1029 }
1030
Jason Monk67e6c802016-08-30 14:09:21 -04001031 @Override
1032 protected void onAttachedToWindow() {
1033 super.onAttachedToWindow();
Adrian Roos7e58a082018-03-09 16:40:56 +01001034 requestApplyInsets();
Siarhei Vishniakoufdb42772017-06-29 10:32:11 -07001035 reorient();
Jason Monkde850bb2017-02-01 19:26:30 -05001036 onPluginDisconnected(null); // Create default gesture helper
Jason Monk5bec68f2017-02-08 20:45:10 -08001037 Dependency.get(PluginManager.class).addPluginListener(this,
1038 NavGesture.class, false /* Only one */);
Winson Chungf9e30272018-03-26 17:25:36 -07001039 setUpSwipeUpOnboarding(isQuickStepSwipeUpEnabled());
Jason Monk67e6c802016-08-30 14:09:21 -04001040 }
1041
1042 @Override
1043 protected void onDetachedFromWindow() {
1044 super.onDetachedFromWindow();
Jason Monkde850bb2017-02-01 19:26:30 -05001045 Dependency.get(PluginManager.class).removePluginListener(this);
1046 if (mGestureHelper != null) {
1047 mGestureHelper.destroy();
1048 }
Tony Wickhamfb63fe82018-01-16 12:14:06 -08001049 setUpSwipeUpOnboarding(false);
1050 }
1051
1052 private void setUpSwipeUpOnboarding(boolean connectedToOverviewProxy) {
1053 if (connectedToOverviewProxy) {
Tony Wickham05c1f852018-02-06 12:32:54 -08001054 mRecentsOnboarding.onConnectedToLauncher();
Tony Wickhamfb63fe82018-01-16 12:14:06 -08001055 } else {
Tony Wickham05c1f852018-02-06 12:32:54 -08001056 mRecentsOnboarding.onDisconnectedFromLauncher();
Tony Wickhamfb63fe82018-01-16 12:14:06 -08001057 }
Jason Monk67e6c802016-08-30 14:09:21 -04001058 }
1059
1060 @Override
Jason Monk20ff3f92017-01-09 15:13:23 -05001061 public void onPluginConnected(NavGesture plugin, Context context) {
Jason Monk67e6c802016-08-30 14:09:21 -04001062 mGestureHelper = plugin.getGestureHelper();
1063 updateTaskSwitchHelper();
1064 }
1065
1066 @Override
1067 public void onPluginDisconnected(NavGesture plugin) {
1068 NavigationBarGestureHelper defaultHelper = new NavigationBarGestureHelper(getContext());
1069 defaultHelper.setComponents(mRecentsComponent, mDivider, this);
Jason Monkde850bb2017-02-01 19:26:30 -05001070 if (mGestureHelper != null) {
1071 mGestureHelper.destroy();
1072 }
Jason Monk67e6c802016-08-30 14:09:21 -04001073 mGestureHelper = defaultHelper;
1074 updateTaskSwitchHelper();
1075 }
1076
Daniel Sandler48852952011-12-01 14:34:23 -05001077 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1078 pw.println("NavigationBarView {");
1079 final Rect r = new Rect();
Jeff Browna8b9def2012-07-23 14:22:49 -07001080 final Point size = new Point();
1081 mDisplay.getRealSize(size);
Daniel Sandler48852952011-12-01 14:34:23 -05001082
Jason Monk2a6ea9c2017-01-26 11:14:51 -05001083 pw.println(String.format(" this: " + StatusBar.viewInfo(this)
Daniel Sandler48852952011-12-01 14:34:23 -05001084 + " " + visibilityToString(getVisibility())));
1085
1086 getWindowVisibleDisplayFrame(r);
Jeff Browna8b9def2012-07-23 14:22:49 -07001087 final boolean offscreen = r.right > size.x || r.bottom > size.y;
John Spurlock209bede2013-07-17 12:23:27 -04001088 pw.println(" window: "
Daniel Sandler48852952011-12-01 14:34:23 -05001089 + r.toShortString()
1090 + " " + visibilityToString(getWindowVisibility())
1091 + (offscreen ? " OFFSCREEN!" : ""));
1092
1093 pw.println(String.format(" mCurrentView: id=%s (%dx%d) %s",
Rakesh Iyerf51fe4e2016-02-09 10:51:50 -08001094 getResourceName(getCurrentView().getId()),
1095 getCurrentView().getWidth(), getCurrentView().getHeight(),
1096 visibilityToString(getCurrentView().getVisibility())));
Daniel Sandler48852952011-12-01 14:34:23 -05001097
John Spurlock41c1e352013-09-16 13:57:13 -04001098 pw.println(String.format(" disabled=0x%08x vertical=%s menu=%s",
Daniel Sandler48852952011-12-01 14:34:23 -05001099 mDisabledFlags,
1100 mVertical ? "true" : "false",
Daniel Sandler48852952011-12-01 14:34:23 -05001101 mShowMenu ? "true" : "false"));
1102
John Spurlock56d007b2013-10-28 18:40:56 -04001103 dumpButton(pw, "back", getBackButton());
1104 dumpButton(pw, "home", getHomeButton());
1105 dumpButton(pw, "rcnt", getRecentsButton());
1106 dumpButton(pw, "menu", getMenuButton());
Casey Burkhardt048c2bc2016-12-08 16:09:20 -08001107 dumpButton(pw, "a11y", getAccessibilityButton());
Daniel Sandler48852952011-12-01 14:34:23 -05001108
Daniel Sandler48852952011-12-01 14:34:23 -05001109 pw.println(" }");
1110 }
Jim Millere898ac52012-04-06 17:10:57 -07001111
Adrian Roos7e58a082018-03-09 16:40:56 +01001112 @Override
1113 public WindowInsets onApplyWindowInsets(WindowInsets insets) {
1114 setPadding(insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
1115 insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
1116 return super.onApplyWindowInsets(insets);
1117 }
1118
Jason Monka2081822016-01-18 14:41:03 -05001119 private static void dumpButton(PrintWriter pw, String caption, ButtonDispatcher button) {
John Spurlock56d007b2013-10-28 18:40:56 -04001120 pw.print(" " + caption + ": ");
1121 if (button == null) {
1122 pw.print("null");
1123 } else {
Jason Monka2081822016-01-18 14:41:03 -05001124 pw.print(visibilityToString(button.getVisibility())
John Spurlock56d007b2013-10-28 18:40:56 -04001125 + " alpha=" + button.getAlpha()
1126 );
John Spurlock56d007b2013-10-28 18:40:56 -04001127 }
1128 pw.println();
1129 }
1130
Jorim Jaggif4797922014-08-04 22:49:41 +02001131 public interface OnVerticalChangedListener {
1132 void onVerticalChanged(boolean isVertical);
1133 }
Jason Monka2081822016-01-18 14:41:03 -05001134
Jason Monk32e3bb52017-07-27 12:35:41 -04001135 private final Consumer<Boolean> mDockedListener = exists -> mHandler.post(() -> {
1136 mDockedStackExists = exists;
1137 updateRecentsIcon();
1138 });
Daniel Sandler8956dbb2011-04-22 07:55:02 -04001139}