blob: 893efdc0991c6a37f03c85b9ba2ef1d2d7bf35b2 [file] [log] [blame]
Heemin Seog1a39dea2019-10-16 15:58:21 -07001/*
Heemin Seog9b078d32020-04-21 15:07:32 -07002 * Copyright (C) 2020 The Android Open Source Project
Heemin Seog1a39dea2019-10-16 15:58:21 -07003 *
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
Heemin Seog9b078d32020-04-21 15:07:32 -070017package com.android.systemui.car.navigationbar;
Heemin Seog1a39dea2019-10-16 15:58:21 -070018
Heemin Seoge67cefea2020-01-28 12:02:50 -080019import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
Heemin Seog29ecf612020-04-14 22:47:01 -070020import static android.view.InsetsState.ITYPE_STATUS_BAR;
Heemin Seoge67cefea2020-01-28 12:02:50 -080021import static android.view.InsetsState.containsType;
22
23import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
24import static com.android.systemui.statusbar.phone.BarTransitions.MODE_TRANSPARENT;
25
Heemin Seog1a39dea2019-10-16 15:58:21 -070026import android.content.Context;
Heemin Seog29ecf612020-04-14 22:47:01 -070027import android.content.res.Resources;
Heemin Seog1a39dea2019-10-16 15:58:21 -070028import android.graphics.PixelFormat;
29import android.inputmethodservice.InputMethodService;
30import android.os.Handler;
31import android.os.IBinder;
32import android.os.RemoteException;
Heemin Seog1a39dea2019-10-16 15:58:21 -070033import android.view.Display;
34import android.view.Gravity;
Heemin Seog8d6ec6a72019-10-25 14:34:11 -070035import android.view.View;
Heemin Seog1a39dea2019-10-16 15:58:21 -070036import android.view.ViewGroup;
37import android.view.WindowManager;
38
Heemin Seog29ecf612020-04-14 22:47:01 -070039import androidx.annotation.VisibleForTesting;
40
Heemin Seog1a39dea2019-10-16 15:58:21 -070041import com.android.internal.statusbar.IStatusBarService;
42import com.android.internal.statusbar.RegisterStatusBarResult;
43import com.android.systemui.R;
44import com.android.systemui.SystemUI;
Abhijoy Sahaee513692019-12-10 13:52:26 -080045import com.android.systemui.car.CarDeviceProvisionedController;
46import com.android.systemui.car.CarDeviceProvisionedListener;
Dave Mankoff00e8a2f2019-12-18 16:59:49 -050047import com.android.systemui.dagger.qualifiers.Main;
Heemin Seog4860f802020-05-05 00:22:42 -070048import com.android.systemui.dagger.qualifiers.UiBackground;
Heemin Seog1a39dea2019-10-16 15:58:21 -070049import com.android.systemui.shared.system.ActivityManagerWrapper;
Heemin Seoge67cefea2020-01-28 12:02:50 -080050import com.android.systemui.statusbar.AutoHideUiElement;
Heemin Seog1a39dea2019-10-16 15:58:21 -070051import com.android.systemui.statusbar.CommandQueue;
Heemin Seoge67cefea2020-01-28 12:02:50 -080052import com.android.systemui.statusbar.phone.AutoHideController;
53import com.android.systemui.statusbar.phone.BarTransitions;
Heemin Seog29ecf612020-04-14 22:47:01 -070054import com.android.systemui.statusbar.phone.PhoneStatusBarPolicy;
55import com.android.systemui.statusbar.phone.StatusBarIconController;
56import com.android.systemui.statusbar.phone.StatusBarSignalPolicy;
Heemin Seog1a39dea2019-10-16 15:58:21 -070057import com.android.systemui.statusbar.policy.KeyguardStateController;
58
59import java.io.FileDescriptor;
60import java.io.PrintWriter;
Heemin Seog4860f802020-05-05 00:22:42 -070061import java.util.concurrent.Executor;
Heemin Seog1a39dea2019-10-16 15:58:21 -070062
63import javax.inject.Inject;
Heemin Seog1a39dea2019-10-16 15:58:21 -070064
65import dagger.Lazy;
66
67/** Navigation bars customized for the automotive use case. */
68public class CarNavigationBar extends SystemUI implements CommandQueue.Callbacks {
69
Heemin Seog29ecf612020-04-14 22:47:01 -070070 private final Resources mResources;
Heemin Seogfcccab72019-10-22 08:30:23 -070071 private final CarNavigationBarController mCarNavigationBarController;
Heemin Seog1a39dea2019-10-16 15:58:21 -070072 private final WindowManager mWindowManager;
Abhijoy Sahaee513692019-12-10 13:52:26 -080073 private final CarDeviceProvisionedController mCarDeviceProvisionedController;
Heemin Seog4a689482019-11-04 10:37:43 -080074 private final CommandQueue mCommandQueue;
Heemin Seoge67cefea2020-01-28 12:02:50 -080075 private final AutoHideController mAutoHideController;
kwaky77d81dc2019-12-12 16:23:59 -080076 private final ButtonSelectionStateListener mButtonSelectionStateListener;
Heemin Seog1a39dea2019-10-16 15:58:21 -070077 private final Handler mMainHandler;
Heemin Seog4860f802020-05-05 00:22:42 -070078 private final Executor mUiBgExecutor;
Heemin Seog23f18d02020-04-24 17:53:22 -070079 private final IStatusBarService mBarService;
Heemin Seogd59786b2019-11-08 09:20:26 -080080 private final Lazy<KeyguardStateController> mKeyguardStateControllerLazy;
kwaky77d81dc2019-12-12 16:23:59 -080081 private final ButtonSelectionStateController mButtonSelectionStateController;
Heemin Seoga3d358f2020-04-28 22:31:03 -070082 private final Lazy<PhoneStatusBarPolicy> mIconPolicyLazy;
83 private final Lazy<StatusBarIconController> mIconControllerLazy;
Heemin Seog1a39dea2019-10-16 15:58:21 -070084
Heemin Seoge67cefea2020-01-28 12:02:50 -080085 private final int mDisplayId;
86
Heemin Seog29ecf612020-04-14 22:47:01 -070087 private StatusBarSignalPolicy mSignalPolicy;
Heemin Seog1a39dea2019-10-16 15:58:21 -070088 private ActivityManagerWrapper mActivityManagerWrapper;
89
90 // If the nav bar should be hidden when the soft keyboard is visible.
91 private boolean mHideNavBarForKeyboard;
92 private boolean mBottomNavBarVisible;
93
94 // Nav bar views.
Heemin Seogd59786b2019-11-08 09:20:26 -080095 private ViewGroup mTopNavigationBarWindow;
96 private ViewGroup mBottomNavigationBarWindow;
Heemin Seog1a39dea2019-10-16 15:58:21 -070097 private ViewGroup mLeftNavigationBarWindow;
98 private ViewGroup mRightNavigationBarWindow;
Heemin Seogd59786b2019-11-08 09:20:26 -080099 private CarNavigationBarView mTopNavigationBarView;
100 private CarNavigationBarView mBottomNavigationBarView;
Heemin Seog1a39dea2019-10-16 15:58:21 -0700101 private CarNavigationBarView mLeftNavigationBarView;
102 private CarNavigationBarView mRightNavigationBarView;
103
104 // To be attached to the navigation bars such that they can close the notification panel if
105 // it's open.
106 private boolean mDeviceIsSetUpForUser = true;
Abhijoy Sahaee513692019-12-10 13:52:26 -0800107 private boolean mIsUserSetupInProgress = false;
Heemin Seog1a39dea2019-10-16 15:58:21 -0700108
Heemin Seog4860f802020-05-05 00:22:42 -0700109 @BarTransitions.TransitionMode
110 private int mStatusBarMode;
111 @BarTransitions.TransitionMode
112 private int mNavigationBarMode;
Heemin Seog29ecf612020-04-14 22:47:01 -0700113 private boolean mStatusBarTransientShown;
114 private boolean mNavBarTransientShown;
Heemin Seoge67cefea2020-01-28 12:02:50 -0800115
Heemin Seog1a39dea2019-10-16 15:58:21 -0700116 @Inject
117 public CarNavigationBar(Context context,
Heemin Seog29ecf612020-04-14 22:47:01 -0700118 @Main Resources resources,
Heemin Seogfcccab72019-10-22 08:30:23 -0700119 CarNavigationBarController carNavigationBarController,
Heemin Seog1a39dea2019-10-16 15:58:21 -0700120 WindowManager windowManager,
Eric Berglund89edc872020-01-21 15:28:35 -0800121 CarDeviceProvisionedController deviceProvisionedController,
Heemin Seog4a689482019-11-04 10:37:43 -0800122 CommandQueue commandQueue,
Heemin Seoge67cefea2020-01-28 12:02:50 -0800123 AutoHideController autoHideController,
kwaky77d81dc2019-12-12 16:23:59 -0800124 ButtonSelectionStateListener buttonSelectionStateListener,
Dave Mankoff00e8a2f2019-12-18 16:59:49 -0500125 @Main Handler mainHandler,
Heemin Seog4860f802020-05-05 00:22:42 -0700126 @UiBackground Executor uiBgExecutor,
Heemin Seog23f18d02020-04-24 17:53:22 -0700127 IStatusBarService barService,
Heemin Seogd59786b2019-11-08 09:20:26 -0800128 Lazy<KeyguardStateController> keyguardStateControllerLazy,
Heemin Seog29ecf612020-04-14 22:47:01 -0700129 ButtonSelectionStateController buttonSelectionStateController,
Heemin Seoga3d358f2020-04-28 22:31:03 -0700130 Lazy<PhoneStatusBarPolicy> iconPolicyLazy,
131 Lazy<StatusBarIconController> iconControllerLazy
Heemin Seog29ecf612020-04-14 22:47:01 -0700132 ) {
Heemin Seog1a39dea2019-10-16 15:58:21 -0700133 super(context);
Heemin Seog29ecf612020-04-14 22:47:01 -0700134 mResources = resources;
Heemin Seogfcccab72019-10-22 08:30:23 -0700135 mCarNavigationBarController = carNavigationBarController;
Heemin Seog1a39dea2019-10-16 15:58:21 -0700136 mWindowManager = windowManager;
Eric Berglund89edc872020-01-21 15:28:35 -0800137 mCarDeviceProvisionedController = deviceProvisionedController;
Heemin Seog4a689482019-11-04 10:37:43 -0800138 mCommandQueue = commandQueue;
Heemin Seoge67cefea2020-01-28 12:02:50 -0800139 mAutoHideController = autoHideController;
kwaky77d81dc2019-12-12 16:23:59 -0800140 mButtonSelectionStateListener = buttonSelectionStateListener;
Heemin Seog1a39dea2019-10-16 15:58:21 -0700141 mMainHandler = mainHandler;
Heemin Seog4860f802020-05-05 00:22:42 -0700142 mUiBgExecutor = uiBgExecutor;
Heemin Seog23f18d02020-04-24 17:53:22 -0700143 mBarService = barService;
Heemin Seogd59786b2019-11-08 09:20:26 -0800144 mKeyguardStateControllerLazy = keyguardStateControllerLazy;
kwaky77d81dc2019-12-12 16:23:59 -0800145 mButtonSelectionStateController = buttonSelectionStateController;
Heemin Seoga3d358f2020-04-28 22:31:03 -0700146 mIconPolicyLazy = iconPolicyLazy;
147 mIconControllerLazy = iconControllerLazy;
Heemin Seoge67cefea2020-01-28 12:02:50 -0800148
Heemin Seog29ecf612020-04-14 22:47:01 -0700149 mDisplayId = context.getDisplayId();
Heemin Seog1a39dea2019-10-16 15:58:21 -0700150 }
151
152 @Override
153 public void start() {
154 // Set initial state.
Heemin Seog29ecf612020-04-14 22:47:01 -0700155 mHideNavBarForKeyboard = mResources.getBoolean(
Heemin Seog1a39dea2019-10-16 15:58:21 -0700156 com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard);
157 mBottomNavBarVisible = false;
158
Heemin Seog1a39dea2019-10-16 15:58:21 -0700159 // Connect into the status bar manager service
Heemin Seog1a39dea2019-10-16 15:58:21 -0700160 mCommandQueue.addCallback(this);
161
162 RegisterStatusBarResult result = null;
163 try {
164 result = mBarService.registerStatusBar(mCommandQueue);
165 } catch (RemoteException ex) {
166 ex.rethrowFromSystemServer();
167 }
168
Heemin Seog29ecf612020-04-14 22:47:01 -0700169 // StatusBarManagerService has a back up of IME token and it's restored here.
170 setImeWindowStatus(mDisplayId, result.mImeToken, result.mImeWindowVis,
171 result.mImeBackDisposition, result.mShowImeSwitcher);
172
173 // Set up the initial icon state
174 int numIcons = result.mIcons.size();
175 for (int i = 0; i < numIcons; i++) {
176 mCommandQueue.setIcon(result.mIcons.keyAt(i), result.mIcons.valueAt(i));
177 }
178
179 mAutoHideController.setStatusBar(new AutoHideUiElement() {
180 @Override
181 public void synchronizeState() {
182 // No op.
183 }
184
185 @Override
186 public boolean isVisible() {
187 return mStatusBarTransientShown;
188 }
189
190 @Override
191 public void hide() {
192 clearTransient();
193 }
194 });
195
Heemin Seoga8983af2020-03-31 13:16:48 -0700196 mAutoHideController.setNavigationBar(new AutoHideUiElement() {
Heemin Seoge67cefea2020-01-28 12:02:50 -0800197 @Override
198 public void synchronizeState() {
199 // No op.
200 }
201
202 @Override
203 public boolean isVisible() {
Heemin Seog29ecf612020-04-14 22:47:01 -0700204 return mNavBarTransientShown;
Heemin Seoge67cefea2020-01-28 12:02:50 -0800205 }
206
207 @Override
208 public void hide() {
209 clearTransient();
210 }
211 });
212
Abhijoy Sahaee513692019-12-10 13:52:26 -0800213 mDeviceIsSetUpForUser = mCarDeviceProvisionedController.isCurrentUserSetup();
214 mIsUserSetupInProgress = mCarDeviceProvisionedController.isCurrentUserSetupInProgress();
215 mCarDeviceProvisionedController.addCallback(
216 new CarDeviceProvisionedListener() {
217 @Override
218 public void onUserSetupInProgressChanged() {
219 mMainHandler.post(() -> restartNavBarsIfNecessary());
220 }
221
Heemin Seog1a39dea2019-10-16 15:58:21 -0700222 @Override
223 public void onUserSetupChanged() {
224 mMainHandler.post(() -> restartNavBarsIfNecessary());
225 }
226
227 @Override
228 public void onUserSwitched() {
229 mMainHandler.post(() -> restartNavBarsIfNecessary());
230 }
231 });
232
233 createNavigationBar(result);
234
235 mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
kwaky77d81dc2019-12-12 16:23:59 -0800236 mActivityManagerWrapper.registerTaskStackListener(mButtonSelectionStateListener);
Heemin Seog1a39dea2019-10-16 15:58:21 -0700237
Heemin Seog4860f802020-05-05 00:22:42 -0700238 mUiBgExecutor.execute(mCarNavigationBarController::connectToHvac);
Heemin Seog29ecf612020-04-14 22:47:01 -0700239
240 // Lastly, call to the icon policy to install/update all the icons.
Heemin Seog23f18d02020-04-24 17:53:22 -0700241 // Must be called on the main thread due to the use of observeForever() in
242 // mIconPolicy.init().
243 mMainHandler.post(() -> {
Heemin Seoga3d358f2020-04-28 22:31:03 -0700244 mIconPolicyLazy.get().init();
245 mSignalPolicy = new StatusBarSignalPolicy(mContext, mIconControllerLazy.get());
Heemin Seog23f18d02020-04-24 17:53:22 -0700246 });
Heemin Seog1a39dea2019-10-16 15:58:21 -0700247 }
248
249 private void restartNavBarsIfNecessary() {
Abhijoy Sahaee513692019-12-10 13:52:26 -0800250 boolean currentUserSetup = mCarDeviceProvisionedController.isCurrentUserSetup();
251 boolean currentUserSetupInProgress = mCarDeviceProvisionedController
252 .isCurrentUserSetupInProgress();
253 if (mIsUserSetupInProgress != currentUserSetupInProgress
254 || mDeviceIsSetUpForUser != currentUserSetup) {
Heemin Seog1a39dea2019-10-16 15:58:21 -0700255 mDeviceIsSetUpForUser = currentUserSetup;
Abhijoy Sahaee513692019-12-10 13:52:26 -0800256 mIsUserSetupInProgress = currentUserSetupInProgress;
Heemin Seog1a39dea2019-10-16 15:58:21 -0700257 restartNavBars();
258 }
259 }
260
261 /**
262 * Remove all content from navbars and rebuild them. Used to allow for different nav bars
263 * before and after the device is provisioned. . Also for change of density and font size.
264 */
265 private void restartNavBars() {
266 // remove and reattach all hvac components such that we don't keep a reference to unused
267 // ui elements
Heemin Seogfcccab72019-10-22 08:30:23 -0700268 mCarNavigationBarController.removeAllFromHvac();
kwaky77d81dc2019-12-12 16:23:59 -0800269 mButtonSelectionStateController.removeAll();
Heemin Seog1a39dea2019-10-16 15:58:21 -0700270
Heemin Seogd59786b2019-11-08 09:20:26 -0800271 if (mTopNavigationBarWindow != null) {
272 mTopNavigationBarWindow.removeAllViews();
273 mTopNavigationBarView = null;
274 }
275
276 if (mBottomNavigationBarWindow != null) {
277 mBottomNavigationBarWindow.removeAllViews();
278 mBottomNavigationBarView = null;
Heemin Seog1a39dea2019-10-16 15:58:21 -0700279 }
280
281 if (mLeftNavigationBarWindow != null) {
282 mLeftNavigationBarWindow.removeAllViews();
283 mLeftNavigationBarView = null;
284 }
285
286 if (mRightNavigationBarWindow != null) {
287 mRightNavigationBarWindow.removeAllViews();
288 mRightNavigationBarView = null;
289 }
290
291 buildNavBarContent();
JianYang Liu4fbd9812020-03-09 13:39:58 -0700292 // If the UI was rebuilt (day/night change or user change) while the keyguard was up we need
293 // to correctly respect that state.
Heemin Seogd59786b2019-11-08 09:20:26 -0800294 if (mKeyguardStateControllerLazy.get().isShowing()) {
Abhijoy Sahaee513692019-12-10 13:52:26 -0800295 mCarNavigationBarController.showAllKeyguardButtons(isDeviceSetupForUser());
JianYang Liu4fbd9812020-03-09 13:39:58 -0700296 } else {
297 mCarNavigationBarController.hideAllKeyguardButtons(isDeviceSetupForUser());
Heemin Seog1a39dea2019-10-16 15:58:21 -0700298 }
kwaky371e6212020-02-19 13:45:22 -0800299
300 // Upon restarting the Navigation Bar, CarFacetButtonController should immediately apply the
301 // selection state that reflects the current task stack.
302 mButtonSelectionStateListener.onTaskStackChanged();
Heemin Seog1a39dea2019-10-16 15:58:21 -0700303 }
304
Abhijoy Sahaee513692019-12-10 13:52:26 -0800305 private boolean isDeviceSetupForUser() {
306 return mDeviceIsSetUpForUser && !mIsUserSetupInProgress;
307 }
308
Heemin Seog1a39dea2019-10-16 15:58:21 -0700309 private void createNavigationBar(RegisterStatusBarResult result) {
310 buildNavBarWindows();
311 buildNavBarContent();
312 attachNavBarWindows();
313
314 // Try setting up the initial state of the nav bar if applicable.
315 if (result != null) {
316 setImeWindowStatus(Display.DEFAULT_DISPLAY, result.mImeToken,
317 result.mImeWindowVis, result.mImeBackDisposition,
318 result.mShowImeSwitcher);
319 }
Heemin Seog1a39dea2019-10-16 15:58:21 -0700320 }
321
322 private void buildNavBarWindows() {
Heemin Seog29ecf612020-04-14 22:47:01 -0700323 mTopNavigationBarWindow = mCarNavigationBarController.getTopWindow();
Heemin Seogd59786b2019-11-08 09:20:26 -0800324 mBottomNavigationBarWindow = mCarNavigationBarController.getBottomWindow();
Heemin Seogfcccab72019-10-22 08:30:23 -0700325 mLeftNavigationBarWindow = mCarNavigationBarController.getLeftWindow();
326 mRightNavigationBarWindow = mCarNavigationBarController.getRightWindow();
Heemin Seog1a39dea2019-10-16 15:58:21 -0700327 }
328
329 private void buildNavBarContent() {
Abhijoy Sahaee513692019-12-10 13:52:26 -0800330 mTopNavigationBarView = mCarNavigationBarController.getTopBar(isDeviceSetupForUser());
Heemin Seogd59786b2019-11-08 09:20:26 -0800331 if (mTopNavigationBarView != null) {
332 mTopNavigationBarWindow.addView(mTopNavigationBarView);
333 }
334
Abhijoy Sahaee513692019-12-10 13:52:26 -0800335 mBottomNavigationBarView = mCarNavigationBarController.getBottomBar(isDeviceSetupForUser());
Heemin Seogd59786b2019-11-08 09:20:26 -0800336 if (mBottomNavigationBarView != null) {
337 mBottomNavigationBarWindow.addView(mBottomNavigationBarView);
Heemin Seog1a39dea2019-10-16 15:58:21 -0700338 }
339
Abhijoy Sahaee513692019-12-10 13:52:26 -0800340 mLeftNavigationBarView = mCarNavigationBarController.getLeftBar(isDeviceSetupForUser());
Heemin Seogfcccab72019-10-22 08:30:23 -0700341 if (mLeftNavigationBarView != null) {
Heemin Seog1a39dea2019-10-16 15:58:21 -0700342 mLeftNavigationBarWindow.addView(mLeftNavigationBarView);
Heemin Seog1a39dea2019-10-16 15:58:21 -0700343 }
344
Abhijoy Sahaee513692019-12-10 13:52:26 -0800345 mRightNavigationBarView = mCarNavigationBarController.getRightBar(isDeviceSetupForUser());
Heemin Seogfcccab72019-10-22 08:30:23 -0700346 if (mRightNavigationBarView != null) {
Heemin Seog1a39dea2019-10-16 15:58:21 -0700347 mRightNavigationBarWindow.addView(mRightNavigationBarView);
Heemin Seog1a39dea2019-10-16 15:58:21 -0700348 }
349 }
350
351 private void attachNavBarWindows() {
Heemin Seog29ecf612020-04-14 22:47:01 -0700352 if (mTopNavigationBarWindow != null) {
353 int height = mResources.getDimensionPixelSize(
354 com.android.internal.R.dimen.status_bar_height);
355 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
356 ViewGroup.LayoutParams.MATCH_PARENT,
357 height,
Heemin Seog991711a2020-04-24 00:38:39 -0700358 WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL,
Heemin Seog29ecf612020-04-14 22:47:01 -0700359 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
Heemin Seog991711a2020-04-24 00:38:39 -0700360 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
361 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
362 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
Heemin Seog29ecf612020-04-14 22:47:01 -0700363 PixelFormat.TRANSLUCENT);
Heemin Seog29ecf612020-04-14 22:47:01 -0700364 lp.setTitle("TopCarNavigationBar");
Heemin Seog991711a2020-04-24 00:38:39 -0700365 lp.providesInsetsTypes = new int[]{ITYPE_STATUS_BAR};
366 lp.setFitInsetsTypes(0);
367 lp.windowAnimations = 0;
368 lp.gravity = Gravity.TOP;
Heemin Seog29ecf612020-04-14 22:47:01 -0700369 mWindowManager.addView(mTopNavigationBarWindow, lp);
370 }
371
Heemin Seogd59786b2019-11-08 09:20:26 -0800372 if (mBottomNavigationBarWindow != null && !mBottomNavBarVisible) {
Heemin Seog1a39dea2019-10-16 15:58:21 -0700373 mBottomNavBarVisible = true;
Heemin Seog991711a2020-04-24 00:38:39 -0700374 int height = mResources.getDimensionPixelSize(
375 com.android.internal.R.dimen.navigation_bar_height);
Heemin Seog1a39dea2019-10-16 15:58:21 -0700376
377 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
Heemin Seog991711a2020-04-24 00:38:39 -0700378 ViewGroup.LayoutParams.MATCH_PARENT,
379 height,
380 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
Heemin Seog1a39dea2019-10-16 15:58:21 -0700381 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
382 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
383 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
384 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
385 PixelFormat.TRANSLUCENT);
Heemin Seog29ecf612020-04-14 22:47:01 -0700386 lp.setTitle("BottomCarNavigationBar");
Heemin Seog991711a2020-04-24 00:38:39 -0700387 lp.providesInsetsTypes = new int[]{ITYPE_NAVIGATION_BAR};
Heemin Seog1a39dea2019-10-16 15:58:21 -0700388 lp.windowAnimations = 0;
Heemin Seog991711a2020-04-24 00:38:39 -0700389 lp.gravity = Gravity.BOTTOM;
Heemin Seogd59786b2019-11-08 09:20:26 -0800390 mWindowManager.addView(mBottomNavigationBarWindow, lp);
Heemin Seog1a39dea2019-10-16 15:58:21 -0700391 }
392
Heemin Seogfcccab72019-10-22 08:30:23 -0700393 if (mLeftNavigationBarWindow != null) {
Heemin Seog29ecf612020-04-14 22:47:01 -0700394 int width = mResources.getDimensionPixelSize(
Heemin Seog1a39dea2019-10-16 15:58:21 -0700395 R.dimen.car_left_navigation_bar_width);
396 WindowManager.LayoutParams leftlp = new WindowManager.LayoutParams(
397 width, ViewGroup.LayoutParams.MATCH_PARENT,
398 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
399 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
400 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
401 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
402 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
403 PixelFormat.TRANSLUCENT);
404 leftlp.setTitle("LeftCarNavigationBar");
405 leftlp.windowAnimations = 0;
Heemin Seog1a39dea2019-10-16 15:58:21 -0700406 leftlp.gravity = Gravity.LEFT;
407 mWindowManager.addView(mLeftNavigationBarWindow, leftlp);
408 }
Heemin Seog991711a2020-04-24 00:38:39 -0700409
Heemin Seogfcccab72019-10-22 08:30:23 -0700410 if (mRightNavigationBarWindow != null) {
Heemin Seog29ecf612020-04-14 22:47:01 -0700411 int width = mResources.getDimensionPixelSize(
Heemin Seog1a39dea2019-10-16 15:58:21 -0700412 R.dimen.car_right_navigation_bar_width);
413 WindowManager.LayoutParams rightlp = new WindowManager.LayoutParams(
414 width, ViewGroup.LayoutParams.MATCH_PARENT,
415 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
416 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
417 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
418 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
419 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
420 PixelFormat.TRANSLUCENT);
421 rightlp.setTitle("RightCarNavigationBar");
422 rightlp.windowAnimations = 0;
Heemin Seog1a39dea2019-10-16 15:58:21 -0700423 rightlp.gravity = Gravity.RIGHT;
424 mWindowManager.addView(mRightNavigationBarWindow, rightlp);
425 }
426 }
427
428 /**
429 * We register for soft keyboard visibility events such that we can hide the navigation bar
430 * giving more screen space to the IME. Note: this is optional and controlled by
431 * {@code com.android.internal.R.bool.config_automotiveHideNavBarForKeyboard}.
432 */
433 @Override
434 public void setImeWindowStatus(int displayId, IBinder token, int vis, int backDisposition,
435 boolean showImeSwitcher) {
436 if (!mHideNavBarForKeyboard) {
437 return;
438 }
439
Heemin Seog29ecf612020-04-14 22:47:01 -0700440 if (mContext.getDisplayId() != displayId) {
Heemin Seog1a39dea2019-10-16 15:58:21 -0700441 return;
442 }
443
444 boolean isKeyboardVisible = (vis & InputMethodService.IME_VISIBLE) != 0;
Heemin Seog8d6ec6a72019-10-25 14:34:11 -0700445 mCarNavigationBarController.setBottomWindowVisibility(
446 isKeyboardVisible ? View.GONE : View.VISIBLE);
Heemin Seog1a39dea2019-10-16 15:58:21 -0700447 }
448
Heemin Seog1a39dea2019-10-16 15:58:21 -0700449 @Override
Heemin Seoge67cefea2020-01-28 12:02:50 -0800450 public void showTransient(int displayId, int[] types) {
451 if (displayId != mDisplayId) {
452 return;
453 }
Heemin Seog29ecf612020-04-14 22:47:01 -0700454 if (containsType(types, ITYPE_STATUS_BAR)) {
455 if (!mStatusBarTransientShown) {
456 mStatusBarTransientShown = true;
457 handleTransientChanged();
458 }
Heemin Seoge67cefea2020-01-28 12:02:50 -0800459 }
Heemin Seog29ecf612020-04-14 22:47:01 -0700460 if (containsType(types, ITYPE_NAVIGATION_BAR)) {
461 if (!mNavBarTransientShown) {
462 mNavBarTransientShown = true;
463 handleTransientChanged();
464 }
Heemin Seoge67cefea2020-01-28 12:02:50 -0800465 }
466 }
467
468 @Override
469 public void abortTransient(int displayId, int[] types) {
470 if (displayId != mDisplayId) {
471 return;
472 }
Heemin Seog29ecf612020-04-14 22:47:01 -0700473 if (!containsType(types, ITYPE_STATUS_BAR) && !containsType(types, ITYPE_NAVIGATION_BAR)) {
Heemin Seoge67cefea2020-01-28 12:02:50 -0800474 return;
475 }
476 clearTransient();
477 }
478
479 private void clearTransient() {
Heemin Seog29ecf612020-04-14 22:47:01 -0700480 if (mStatusBarTransientShown) {
481 mStatusBarTransientShown = false;
Heemin Seoge67cefea2020-01-28 12:02:50 -0800482 handleTransientChanged();
483 }
Heemin Seog29ecf612020-04-14 22:47:01 -0700484 if (mNavBarTransientShown) {
485 mNavBarTransientShown = false;
486 handleTransientChanged();
487 }
488 }
489
490 @VisibleForTesting
491 boolean isStatusBarTransientShown() {
492 return mStatusBarTransientShown;
493 }
494
495 @VisibleForTesting
496 boolean isNavBarTransientShown() {
497 return mNavBarTransientShown;
Heemin Seoge67cefea2020-01-28 12:02:50 -0800498 }
499
500 @Override
Heemin Seog1a39dea2019-10-16 15:58:21 -0700501 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
502 pw.print(" mTaskStackListener=");
kwaky77d81dc2019-12-12 16:23:59 -0800503 pw.println(mButtonSelectionStateListener);
Heemin Seogd59786b2019-11-08 09:20:26 -0800504 pw.print(" mBottomNavigationBarView=");
505 pw.println(mBottomNavigationBarView);
Heemin Seog1a39dea2019-10-16 15:58:21 -0700506 }
Heemin Seoge67cefea2020-01-28 12:02:50 -0800507
508 private void handleTransientChanged() {
Heemin Seog29ecf612020-04-14 22:47:01 -0700509 updateStatusBarMode(mStatusBarTransientShown ? MODE_SEMI_TRANSPARENT : MODE_TRANSPARENT);
510 updateNavBarMode(mNavBarTransientShown ? MODE_SEMI_TRANSPARENT : MODE_TRANSPARENT);
Heemin Seoge67cefea2020-01-28 12:02:50 -0800511 }
512
Heemin Seog29ecf612020-04-14 22:47:01 -0700513 // Returns true if the status bar mode has changed.
514 private boolean updateStatusBarMode(int barMode) {
515 if (mStatusBarMode != barMode) {
516 mStatusBarMode = barMode;
517 mAutoHideController.touchAutoHide();
518 return true;
519 }
520 return false;
521 }
522
523 // Returns true if the nav bar mode has changed.
524 private boolean updateNavBarMode(int barMode) {
Heemin Seoge67cefea2020-01-28 12:02:50 -0800525 if (mNavigationBarMode != barMode) {
526 mNavigationBarMode = barMode;
527 mAutoHideController.touchAutoHide();
528 return true;
529 }
530 return false;
531 }
Heemin Seog1a39dea2019-10-16 15:58:21 -0700532}