blob: 2dba1d5bc25710855d9d65ca00bc57662a20ecc0 [file] [log] [blame]
Rakesh Iyer1186faa2015-12-07 16:48:46 -08001/*
Brad Stenning8d1a51c2018-11-20 17:34:16 -08002 * Copyright (C) 2018 The Android Open Source Project
Rakesh Iyer1186faa2015-12-07 16:48:46 -08003 *
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.car;
18
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070019import android.app.ActivityTaskManager;
jovanakedba98c2018-09-14 15:46:24 -070020import android.car.drivingstate.CarDrivingStateEvent;
Rakesh Iyer1186faa2015-12-07 16:48:46 -080021import android.graphics.PixelFormat;
Anthony Chene658cc22017-04-27 11:17:35 -070022import android.graphics.drawable.Drawable;
Rakesh Iyer74ebabe2016-03-11 10:10:43 -080023import android.util.Log;
Brad Stenning078235b2017-12-18 08:25:10 -080024import android.view.Gravity;
Rakesh Iyer1186faa2015-12-07 16:48:46 -080025import android.view.View;
Anthony Chen0801a5c2017-03-22 09:54:37 -070026import android.view.ViewGroup;
Rakesh Iyer1186faa2015-12-07 16:48:46 -080027import android.view.ViewGroup.LayoutParams;
28import android.view.WindowManager;
Anthony Chene658cc22017-04-27 11:17:35 -070029
Winson Chung2db35572017-10-09 15:08:30 -070030import com.android.keyguard.KeyguardUpdateMonitor;
Anthony Chenda62fdcd52016-04-06 16:15:14 -070031import com.android.systemui.BatteryMeterView;
Jason Monk27d01a622018-12-10 15:57:09 -050032import com.android.systemui.CarSystemUIFactory;
Jason Monk9c7844c2017-01-18 15:21:53 -050033import com.android.systemui.Dependency;
Winson Chung2db35572017-10-09 15:08:30 -070034import com.android.systemui.Prefs;
Rakesh Iyer1186faa2015-12-07 16:48:46 -080035import com.android.systemui.R;
Jason Monk27d01a622018-12-10 15:57:09 -050036import com.android.systemui.SystemUIFactory;
Winson Chung2db35572017-10-09 15:08:30 -070037import com.android.systemui.classifier.FalsingLog;
38import com.android.systemui.classifier.FalsingManager;
Jason Monkaa573e92017-01-27 17:00:29 -050039import com.android.systemui.fragments.FragmentHostManager;
Brad Stenning19f236a2018-12-11 14:12:30 -080040import com.android.systemui.notifications.NotificationsUI;
Brad Stenning8d1a51c2018-11-20 17:34:16 -080041import com.android.systemui.plugins.qs.QS;
42import com.android.systemui.qs.car.CarQSFragment;
Winson Chungb05b3982017-11-01 18:02:43 -070043import com.android.systemui.shared.system.ActivityManagerWrapper;
Winson Chung67f5c8b2018-09-24 12:09:19 -070044import com.android.systemui.shared.system.TaskStackChangeListener;
Rakesh Iyer2790a372016-01-22 15:33:39 -080045import com.android.systemui.statusbar.StatusBarState;
Brad Stenning38b46f82018-03-27 13:57:29 -070046import com.android.systemui.statusbar.car.hvac.HvacController;
Brad Stenningf084d882018-08-08 13:34:21 -070047import com.android.systemui.statusbar.car.hvac.TemperatureView;
Jason Monkaa573e92017-01-27 17:00:29 -050048import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
Jason Monk2a6ea9c2017-01-26 11:14:51 -050049import com.android.systemui.statusbar.phone.StatusBar;
Anthony Chenda62fdcd52016-04-06 16:15:14 -070050import com.android.systemui.statusbar.policy.BatteryController;
Brad Stenning224b5b32018-03-28 21:26:57 -070051import com.android.systemui.statusbar.policy.DeviceProvisionedController;
Jason Monk9c7844c2017-01-18 15:21:53 -050052import com.android.systemui.statusbar.policy.UserSwitcherController;
Rakesh Iyer1186faa2015-12-07 16:48:46 -080053
Qiming Shib9dfb922017-04-13 16:23:18 +080054import java.io.FileDescriptor;
55import java.io.PrintWriter;
56import java.util.Map;
davidln54739152018-07-02 13:25:44 -070057
Rakesh Iyer1186faa2015-12-07 16:48:46 -080058/**
59 * A status bar (and navigation bar) tailored for the automotive use case.
60 */
Jason Monk2a6ea9c2017-01-26 11:14:51 -050061public class CarStatusBar extends StatusBar implements
Anthony Chenda62fdcd52016-04-06 16:15:14 -070062 CarBatteryController.BatteryViewHandler {
Rakesh Iyer74ebabe2016-03-11 10:10:43 -080063 private static final String TAG = "CarStatusBar";
64
Victor Chan1c6d0582016-01-09 16:26:37 -080065 private TaskStackListenerImpl mTaskStackListener;
Victor Chan1c6d0582016-01-09 16:26:37 -080066
Rakesh Iyer2790a372016-01-22 15:33:39 -080067 private FullscreenUserSwitcher mFullscreenUserSwitcher;
Victor Chan1c6d0582016-01-09 16:26:37 -080068
Anthony Chenda62fdcd52016-04-06 16:15:14 -070069 private CarBatteryController mCarBatteryController;
70 private BatteryMeterView mBatteryMeterView;
Anthony Chene658cc22017-04-27 11:17:35 -070071 private Drawable mNotificationPanelBackground;
Anthony Chenda62fdcd52016-04-06 16:15:14 -070072
Anthony Chen1c59e9f2016-04-11 11:05:48 -070073 private ConnectedDeviceSignalController mConnectedDeviceSignalController;
Scott Randolphf4085822017-06-27 15:23:01 -070074 private ViewGroup mNavigationBarWindow;
Brad Stenning078235b2017-12-18 08:25:10 -080075 private ViewGroup mLeftNavigationBarWindow;
76 private ViewGroup mRightNavigationBarWindow;
Jason Monk49fa0162017-01-11 09:21:56 -050077 private CarNavigationBarView mNavigationBarView;
Brad Stenning078235b2017-12-18 08:25:10 -080078 private CarNavigationBarView mLeftNavigationBarView;
79 private CarNavigationBarView mRightNavigationBarView;
Anthony Chen1c59e9f2016-04-11 11:05:48 -070080
Qiming Shib9dfb922017-04-13 16:23:18 +080081 private final Object mQueueLock = new Object();
Brad Stenning078235b2017-12-18 08:25:10 -080082 private boolean mShowLeft;
83 private boolean mShowRight;
84 private boolean mShowBottom;
85 private CarFacetButtonController mCarFacetButtonController;
Brad Stenning224b5b32018-03-28 21:26:57 -070086 private ActivityManagerWrapper mActivityManagerWrapper;
87 private DeviceProvisionedController mDeviceProvisionedController;
88 private boolean mDeviceIsProvisioned = true;
Brad Stenningf084d882018-08-08 13:34:21 -070089 private HvacController mHvacController;
jovanakedba98c2018-09-14 15:46:24 -070090 private DrivingStateHelper mDrivingStateHelper;
91 private SwitchToGuestTimer mSwitchToGuestTimer;
Brad Stenning078235b2017-12-18 08:25:10 -080092
Victor Chan1c6d0582016-01-09 16:26:37 -080093 @Override
94 public void start() {
95 super.start();
Jaewan Kim938a50b2016-03-14 17:35:43 +090096 mTaskStackListener = new TaskStackListenerImpl();
Brad Stenning224b5b32018-03-28 21:26:57 -070097 mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
98 mActivityManagerWrapper.registerTaskStackListener(mTaskStackListener);
Anthony Chenda62fdcd52016-04-06 16:15:14 -070099
Jason Monke59dc402018-08-16 12:05:01 -0400100 mNotificationPanel.setScrollingEnabled(true);
Anthony Chen3cb3ad92016-12-01 10:58:47 -0800101
Rakesh Iyer545e47d2017-01-23 18:10:21 -0800102 createBatteryController();
Anthony Chenda62fdcd52016-04-06 16:15:14 -0700103 mCarBatteryController.startListening();
Brad Stenning38b46f82018-03-27 13:57:29 -0700104
Brad Stenningf084d882018-08-08 13:34:21 -0700105 mHvacController.connectToCarService();
davidln54739152018-07-02 13:25:44 -0700106
Jason Monk27d01a622018-12-10 15:57:09 -0500107 CarSystemUIFactory factory = SystemUIFactory.getInstance();
Brad Stenning224b5b32018-03-28 21:26:57 -0700108 mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
109 mDeviceIsProvisioned = mDeviceProvisionedController.isDeviceProvisioned();
110 if (!mDeviceIsProvisioned) {
111 mDeviceProvisionedController.addCallback(
112 new DeviceProvisionedController.DeviceProvisionedListener() {
113 @Override
114 public void onDeviceProvisionedChanged() {
Brad Stenninga2d87d82019-01-24 12:33:10 -0800115 mHandler.post(() -> {
116 // on initial boot we are getting a call even though the value
117 // is the same so we are confirming the reset is needed
118 boolean deviceProvisioned =
119 mDeviceProvisionedController.isDeviceProvisioned();
120 if (mDeviceIsProvisioned != deviceProvisioned) {
121 mDeviceIsProvisioned = deviceProvisioned;
122 restartNavBars();
123 }
124 });
Brad Stenning224b5b32018-03-28 21:26:57 -0700125 }
126 });
127 }
jovanakedba98c2018-09-14 15:46:24 -0700128
129 // Register a listener for driving state changes.
130 mDrivingStateHelper = new DrivingStateHelper(mContext, this::onDrivingStateChanged);
131 mDrivingStateHelper.connectToCarService();
132
133 mSwitchToGuestTimer = new SwitchToGuestTimer(mContext);
Anthony Chenda62fdcd52016-04-06 16:15:14 -0700134 }
135
Brad Stenning224b5b32018-03-28 21:26:57 -0700136 /**
137 * Remove all content from navbars and rebuild them. Used to allow for different nav bars
Guobin Zhangeef0e0c2019-02-01 11:54:24 -0800138 * before and after the device is provisioned. . Also for change of density and font size.
Brad Stenning224b5b32018-03-28 21:26:57 -0700139 */
140 private void restartNavBars() {
Brad Stenningf084d882018-08-08 13:34:21 -0700141 // remove and reattach all hvac components such that we don't keep a reference to unused
142 // ui elements
143 mHvacController.removeAllComponents();
144 addTemperatureViewToController(mStatusBarWindow);
Brad Stenning224b5b32018-03-28 21:26:57 -0700145 mCarFacetButtonController.removeAll();
Brad Stenning224b5b32018-03-28 21:26:57 -0700146 if (mNavigationBarWindow != null) {
147 mNavigationBarWindow.removeAllViews();
148 mNavigationBarView = null;
149 }
150
151 if (mLeftNavigationBarWindow != null) {
152 mLeftNavigationBarWindow.removeAllViews();
153 mLeftNavigationBarView = null;
154 }
155
156 if (mRightNavigationBarWindow != null) {
157 mRightNavigationBarWindow.removeAllViews();
158 mRightNavigationBarView = null;
159 }
Brad Stenningf084d882018-08-08 13:34:21 -0700160
Brad Stenning224b5b32018-03-28 21:26:57 -0700161 buildNavBarContent();
162 }
163
Brad Stenningf084d882018-08-08 13:34:21 -0700164 private void addTemperatureViewToController(View v) {
165 if (v instanceof TemperatureView) {
166 Log.d(TAG, "addTemperatureViewToController: found ");
167 mHvacController.addHvacTextView((TemperatureView) v);
168 } else if (v instanceof ViewGroup) {
169 ViewGroup viewGroup = (ViewGroup) v;
170 for (int i = 0; i < viewGroup.getChildCount(); i++) {
171 addTemperatureViewToController(viewGroup.getChildAt(i));
172 }
173 }
174 }
175
Brad Stenning7e411812018-04-13 22:52:39 -0700176 /**
177 * Allows for showing or hiding just the navigation bars. This is indented to be used when
178 * the full screen user selector is shown.
179 */
davidln54739152018-07-02 13:25:44 -0700180 void setNavBarVisibility(@View.Visibility int visibility) {
Brad Stenning7e411812018-04-13 22:52:39 -0700181 if (mNavigationBarWindow != null) {
182 mNavigationBarWindow.setVisibility(visibility);
183 }
184 if (mLeftNavigationBarWindow != null) {
185 mLeftNavigationBarWindow.setVisibility(visibility);
186 }
187 if (mRightNavigationBarWindow != null) {
188 mRightNavigationBarWindow.setVisibility(visibility);
189 }
190 }
191
192
193 @Override
194 public boolean hideKeyguard() {
195 boolean result = super.hideKeyguard();
196 if (mNavigationBarView != null) {
197 mNavigationBarView.hideKeyguardButtons();
198 }
199 if (mLeftNavigationBarView != null) {
200 mLeftNavigationBarView.hideKeyguardButtons();
201 }
202 if (mRightNavigationBarView != null) {
203 mRightNavigationBarView.hideKeyguardButtons();
204 }
205 return result;
206 }
207
208
209 @Override
210 public void showKeyguard() {
211 super.showKeyguard();
Brad Stenningc622f1d2019-01-29 11:24:11 -0800212 getComponent(NotificationsUI.class).closeCarNotifications(0);
Brad Stenning7e411812018-04-13 22:52:39 -0700213 if (mNavigationBarView != null) {
214 mNavigationBarView.showKeyguardButtons();
215 }
216 if (mLeftNavigationBarView != null) {
217 mLeftNavigationBarView.showKeyguardButtons();
218 }
219 if (mRightNavigationBarView != null) {
220 mRightNavigationBarView.showKeyguardButtons();
221 }
222 }
Brad Stenning224b5b32018-03-28 21:26:57 -0700223
Anthony Chenda62fdcd52016-04-06 16:15:14 -0700224 @Override
225 public void destroy() {
226 mCarBatteryController.stopListening();
Anthony Chen1c59e9f2016-04-11 11:05:48 -0700227 mConnectedDeviceSignalController.stopListening();
Brad Stenning224b5b32018-03-28 21:26:57 -0700228 mActivityManagerWrapper.unregisterTaskStackListener(mTaskStackListener);
jovanakedba98c2018-09-14 15:46:24 -0700229 mDrivingStateHelper.disconnectFromCarService();
Anthony Chen1c59e9f2016-04-11 11:05:48 -0700230
Scott Randolphf4085822017-06-27 15:23:01 -0700231 if (mNavigationBarWindow != null) {
232 mWindowManager.removeViewImmediate(mNavigationBarWindow);
233 mNavigationBarView = null;
234 }
235
Brad Stenning078235b2017-12-18 08:25:10 -0800236 if (mLeftNavigationBarWindow != null) {
237 mWindowManager.removeViewImmediate(mLeftNavigationBarWindow);
238 mLeftNavigationBarView = null;
239 }
240
241 if (mRightNavigationBarWindow != null) {
242 mWindowManager.removeViewImmediate(mRightNavigationBarWindow);
243 mRightNavigationBarView = null;
244 }
Anthony Chenda62fdcd52016-04-06 16:15:14 -0700245 super.destroy();
246 }
247
Brad Stenning224b5b32018-03-28 21:26:57 -0700248
Anthony Chenda62fdcd52016-04-06 16:15:14 -0700249 @Override
Jason Monkaa573e92017-01-27 17:00:29 -0500250 protected void makeStatusBarView() {
251 super.makeStatusBarView();
Jason Monk27d01a622018-12-10 15:57:09 -0500252 mHvacController = new HvacController(mContext);
Anthony Chenda62fdcd52016-04-06 16:15:14 -0700253
Guobin Zhangeef0e0c2019-02-01 11:54:24 -0800254 CarSystemUIFactory factory = SystemUIFactory.getInstance();
255 mCarFacetButtonController = factory.getCarDependencyComponent()
256 .getCarFacetButtonController();
Anthony Chene658cc22017-04-27 11:17:35 -0700257 mNotificationPanelBackground = getDefaultWallpaper();
258 mScrimController.setScrimBehindDrawable(mNotificationPanelBackground);
259
Jason Monkaa573e92017-01-27 17:00:29 -0500260 FragmentHostManager manager = FragmentHostManager.get(mStatusBarWindow);
261 manager.addTagListener(CollapsedStatusBarFragment.TAG, (tag, fragment) -> {
Anthony Chene658cc22017-04-27 11:17:35 -0700262 mBatteryMeterView = fragment.getView().findViewById(R.id.battery);
Anthony Chenda62fdcd52016-04-06 16:15:14 -0700263
Jason Monkaa573e92017-01-27 17:00:29 -0500264 // By default, the BatteryMeterView should not be visible. It will be toggled
265 // when a device has connected by bluetooth.
266 mBatteryMeterView.setVisibility(View.GONE);
Jason Monkaa573e92017-01-27 17:00:29 -0500267 });
Brad Stenningf084d882018-08-08 13:34:21 -0700268 addTemperatureViewToController(mStatusBarWindow);
Brad Stenningc622f1d2019-01-29 11:24:11 -0800269 // The following are the ui elements that the user would call the status bar.
270 // This will set the status bar so it they can make call backs.
271 CarNavigationBarView topBar = mStatusBarWindow.findViewById(R.id.car_top_bar);
272 topBar.setStatusBar(this);
273 CarNavigationBarView qsTopBar = mStatusBarWindow.findViewById(R.id.qs_car_top_bar);
274 qsTopBar.setStatusBar(this);
Anthony Chenda62fdcd52016-04-06 16:15:14 -0700275 }
276
Brad Stenning8d1a51c2018-11-20 17:34:16 -0800277 @Override
278 protected QS createDefaultQSFragment() {
279 return new CarQSFragment();
280 }
281
Rakesh Iyer545e47d2017-01-23 18:10:21 -0800282 private BatteryController createBatteryController() {
Anthony Chenda62fdcd52016-04-06 16:15:14 -0700283 mCarBatteryController = new CarBatteryController(mContext);
284 mCarBatteryController.addBatteryViewHandler(this);
285 return mCarBatteryController;
Victor Chan1c6d0582016-01-09 16:26:37 -0800286 }
287
Rakesh Iyer1186faa2015-12-07 16:48:46 -0800288 @Override
Jason Monk49fa0162017-01-11 09:21:56 -0500289 protected void createNavigationBar() {
Brad Stenning078235b2017-12-18 08:25:10 -0800290 mShowBottom = mContext.getResources().getBoolean(R.bool.config_enableBottomNavigationBar);
Brad Stenning078235b2017-12-18 08:25:10 -0800291 mShowLeft = mContext.getResources().getBoolean(R.bool.config_enableLeftNavigationBar);
Brad Stenning078235b2017-12-18 08:25:10 -0800292 mShowRight = mContext.getResources().getBoolean(R.bool.config_enableRightNavigationBar);
293
Brad Stenning224b5b32018-03-28 21:26:57 -0700294 buildNavBarWindows();
295 buildNavBarContent();
296 attachNavBarWindows();
Andrii Kulian3ddd7de2018-10-10 00:33:19 -0700297
Charles Chen10ca70b2018-11-28 00:03:38 +0800298 // There has been a car customized nav bar on the default display, so just create nav bars
299 // on external displays.
300 mNavigationBarController.createNavigationBars(false /* includeDefaultDisplay */);
Brad Stenning224b5b32018-03-28 21:26:57 -0700301 }
302
303 private void buildNavBarContent() {
304 if (mShowBottom) {
305 buildBottomBar((mDeviceIsProvisioned) ? R.layout.car_navigation_bar :
306 R.layout.car_navigation_bar_unprovisioned);
307 }
308
309 if (mShowLeft) {
310 buildLeft((mDeviceIsProvisioned) ? R.layout.car_left_navigation_bar :
311 R.layout.car_left_navigation_bar_unprovisioned);
312 }
313
Brad Stenning078235b2017-12-18 08:25:10 -0800314 if (mShowRight) {
Brad Stenning224b5b32018-03-28 21:26:57 -0700315 buildRight((mDeviceIsProvisioned) ? R.layout.car_right_navigation_bar :
316 R.layout.car_right_navigation_bar_unprovisioned);
317 }
318 }
319
320 private void buildNavBarWindows() {
321 if (mShowBottom) {
davidln54739152018-07-02 13:25:44 -0700322 mNavigationBarWindow = (ViewGroup) View.inflate(mContext,
Brad Stenning224b5b32018-03-28 21:26:57 -0700323 R.layout.navigation_bar_window, null);
324 }
325 if (mShowLeft) {
326 mLeftNavigationBarWindow = (ViewGroup) View.inflate(mContext,
davidln54739152018-07-02 13:25:44 -0700327 R.layout.navigation_bar_window, null);
Brad Stenning224b5b32018-03-28 21:26:57 -0700328 }
329 if (mShowRight) {
330 mRightNavigationBarWindow = (ViewGroup) View.inflate(mContext,
331 R.layout.navigation_bar_window, null);
Brad Stenning078235b2017-12-18 08:25:10 -0800332 }
333
334 }
335
Brad Stenning224b5b32018-03-28 21:26:57 -0700336 private void attachNavBarWindows() {
Brad Stenning078235b2017-12-18 08:25:10 -0800337
Brad Stenning224b5b32018-03-28 21:26:57 -0700338 if (mShowBottom) {
339 WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
340 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
341 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR,
342 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
343 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
344 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
345 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
346 PixelFormat.TRANSLUCENT);
347 lp.setTitle("CarNavigationBar");
348 lp.windowAnimations = 0;
349 mWindowManager.addView(mNavigationBarWindow, lp);
Brad Stenningc622f1d2019-01-29 11:24:11 -0800350 mNavigationBarWindow.setOnTouchListener(getStatusBarWindowTouchListener());
Brad Stenning224b5b32018-03-28 21:26:57 -0700351 }
352 if (mShowLeft) {
353 int width = mContext.getResources().getDimensionPixelSize(
354 R.dimen.car_left_navigation_bar_width);
355 WindowManager.LayoutParams leftlp = new WindowManager.LayoutParams(
356 width, LayoutParams.MATCH_PARENT,
357 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
358 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
359 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
360 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
361 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
362 PixelFormat.TRANSLUCENT);
363 leftlp.setTitle("LeftCarNavigationBar");
364 leftlp.windowAnimations = 0;
365 leftlp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
366 leftlp.gravity = Gravity.LEFT;
367 mWindowManager.addView(mLeftNavigationBarWindow, leftlp);
368 }
369 if (mShowRight) {
370 int width = mContext.getResources().getDimensionPixelSize(
371 R.dimen.car_right_navigation_bar_width);
372 WindowManager.LayoutParams rightlp = new WindowManager.LayoutParams(
373 width, LayoutParams.MATCH_PARENT,
374 WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL,
375 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
376 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
377 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
378 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
379 PixelFormat.TRANSLUCENT);
380 rightlp.setTitle("RightCarNavigationBar");
381 rightlp.windowAnimations = 0;
382 rightlp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;
383 rightlp.gravity = Gravity.RIGHT;
384 mWindowManager.addView(mRightNavigationBarWindow, rightlp);
385 }
386
387 }
388
389 private void buildBottomBar(int layout) {
Anthony Chen0801a5c2017-03-22 09:54:37 -0700390 // SystemUI requires that the navigation bar view have a parent. Since the regular
391 // StatusBar inflates navigation_bar_window as this parent view, use the same view for the
392 // CarNavigationBarView.
Brad Stenning224b5b32018-03-28 21:26:57 -0700393 View.inflate(mContext, layout, mNavigationBarWindow);
Scott Randolphf4085822017-06-27 15:23:01 -0700394 mNavigationBarView = (CarNavigationBarView) mNavigationBarWindow.getChildAt(0);
395 if (mNavigationBarView == null) {
396 Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_navigation_bar");
Brad Stenning078235b2017-12-18 08:25:10 -0800397 throw new RuntimeException("Unable to build botom nav bar due to missing layout");
Scott Randolphf4085822017-06-27 15:23:01 -0700398 }
Brad Stenning078235b2017-12-18 08:25:10 -0800399 mNavigationBarView.setStatusBar(this);
Brad Stenningf084d882018-08-08 13:34:21 -0700400 addTemperatureViewToController(mNavigationBarView);
Rakesh Iyer1186faa2015-12-07 16:48:46 -0800401 }
402
Brad Stenning224b5b32018-03-28 21:26:57 -0700403 private void buildLeft(int layout) {
404 View.inflate(mContext, layout, mLeftNavigationBarWindow);
Brad Stenning078235b2017-12-18 08:25:10 -0800405 mLeftNavigationBarView = (CarNavigationBarView) mLeftNavigationBarWindow.getChildAt(0);
406 if (mLeftNavigationBarView == null) {
407 Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_navigation_bar");
408 throw new RuntimeException("Unable to build left nav bar due to missing layout");
409 }
410 mLeftNavigationBarView.setStatusBar(this);
Brad Stenningf084d882018-08-08 13:34:21 -0700411 addTemperatureViewToController(mLeftNavigationBarView);
Brad Stenning078235b2017-12-18 08:25:10 -0800412 }
413
414
Brad Stenning224b5b32018-03-28 21:26:57 -0700415 private void buildRight(int layout) {
416 View.inflate(mContext, layout, mRightNavigationBarWindow);
Brad Stenning078235b2017-12-18 08:25:10 -0800417 mRightNavigationBarView = (CarNavigationBarView) mRightNavigationBarWindow.getChildAt(0);
418 if (mRightNavigationBarView == null) {
419 Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_navigation_bar");
420 throw new RuntimeException("Unable to build right nav bar due to missing layout");
421 }
Brad Stenningf084d882018-08-08 13:34:21 -0700422 mRightNavigationBarView.setStatusBar(this);
423 addTemperatureViewToController(mRightNavigationBarView);
Brad Stenning078235b2017-12-18 08:25:10 -0800424 }
425
Rakesh Iyer1186faa2015-12-07 16:48:46 -0800426 @Override
Qiming Shib9dfb922017-04-13 16:23:18 +0800427 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
428 //When executing dump() funciton simultaneously, we need to serialize them
429 //to get mStackScroller's position correctly.
430 synchronized (mQueueLock) {
431 pw.println(" mStackScroller: " + viewInfo(mStackScroller));
432 pw.println(" mStackScroller: " + viewInfo(mStackScroller)
433 + " scroll " + mStackScroller.getScrollX()
434 + "," + mStackScroller.getScrollY());
435 }
436
davidln54739152018-07-02 13:25:44 -0700437 pw.print(" mTaskStackListener=");
438 pw.println(mTaskStackListener);
Brad Stenning078235b2017-12-18 08:25:10 -0800439 pw.print(" mCarFacetButtonController=");
440 pw.println(mCarFacetButtonController);
davidln54739152018-07-02 13:25:44 -0700441 pw.print(" mFullscreenUserSwitcher=");
442 pw.println(mFullscreenUserSwitcher);
Qiming Shib9dfb922017-04-13 16:23:18 +0800443 pw.print(" mCarBatteryController=");
444 pw.println(mCarBatteryController);
445 pw.print(" mBatteryMeterView=");
446 pw.println(mBatteryMeterView);
447 pw.print(" mConnectedDeviceSignalController=");
448 pw.println(mConnectedDeviceSignalController);
449 pw.print(" mNavigationBarView=");
450 pw.println(mNavigationBarView);
451
452 if (KeyguardUpdateMonitor.getInstance(mContext) != null) {
453 KeyguardUpdateMonitor.getInstance(mContext).dump(fd, pw, args);
454 }
455
456 FalsingManager.getInstance(mContext).dump(pw);
457 FalsingLog.dump(pw);
458
459 pw.println("SharedPreferences:");
460 for (Map.Entry<String, ?> entry : Prefs.getAll(mContext).entrySet()) {
davidln54739152018-07-02 13:25:44 -0700461 pw.print(" ");
462 pw.print(entry.getKey());
463 pw.print("=");
464 pw.println(entry.getValue());
Qiming Shib9dfb922017-04-13 16:23:18 +0800465 }
466 }
467
Scott Randolphf4085822017-06-27 15:23:01 -0700468 @Override
Anthony Chen3cb3ad92016-12-01 10:58:47 -0800469 protected View.OnTouchListener getStatusBarWindowTouchListener() {
Brad Stenningc622f1d2019-01-29 11:24:11 -0800470 // Gets the car specific notification touch listener
471 return getComponent(NotificationsUI.class).getDragDownListener();
Anthony Chen3cb3ad92016-12-01 10:58:47 -0800472 }
473
Anthony Chen3cb3ad92016-12-01 10:58:47 -0800474 @Override
Anthony Chenda62fdcd52016-04-06 16:15:14 -0700475 public void showBatteryView() {
476 if (Log.isLoggable(TAG, Log.DEBUG)) {
477 Log.d(TAG, "showBatteryView(). mBatteryMeterView: " + mBatteryMeterView);
478 }
479
480 if (mBatteryMeterView != null) {
481 mBatteryMeterView.setVisibility(View.VISIBLE);
482 }
483 }
484
485 @Override
486 public void hideBatteryView() {
487 if (Log.isLoggable(TAG, Log.DEBUG)) {
488 Log.d(TAG, "hideBatteryView(). mBatteryMeterView: " + mBatteryMeterView);
489 }
490
491 if (mBatteryMeterView != null) {
492 mBatteryMeterView.setVisibility(View.GONE);
493 }
494 }
495
Victor Chan1c6d0582016-01-09 16:26:37 -0800496 /**
Winson Chung67f5c8b2018-09-24 12:09:19 -0700497 * An implementation of TaskStackChangeListener, that listens for changes in the system
davidln54739152018-07-02 13:25:44 -0700498 * task stack and notifies the navigation bar.
Victor Chan1c6d0582016-01-09 16:26:37 -0800499 */
Winson Chung67f5c8b2018-09-24 12:09:19 -0700500 private class TaskStackListenerImpl extends TaskStackChangeListener {
Wale Ogunwale480dca02016-02-06 13:58:29 -0800501 @Override
Victor Chan1c6d0582016-01-09 16:26:37 -0800502 public void onTaskStackChanged() {
Brad Stenninga5e714c2018-04-12 19:23:39 -0700503 try {
504 mCarFacetButtonController.taskChanged(
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700505 ActivityTaskManager.getService().getAllStackInfos());
Brad Stenninga5e714c2018-04-12 19:23:39 -0700506 } catch (Exception e) {
507 Log.e(TAG, "Getting StackInfo from activity manager failed", e);
508 }
Victor Chan1c6d0582016-01-09 16:26:37 -0800509 }
Victor Chan1c6d0582016-01-09 16:26:37 -0800510 }
Rakesh Iyer2790a372016-01-22 15:33:39 -0800511
jovanakedba98c2018-09-14 15:46:24 -0700512 private void onDrivingStateChanged(CarDrivingStateEvent notUsed) {
513 // Check if we need to start the timer every time driving state changes.
514 startSwitchToGuestTimerIfDrivingOnKeyguard();
515 }
516
517 private void startSwitchToGuestTimerIfDrivingOnKeyguard() {
518 if (mDrivingStateHelper.isCurrentlyDriving() && mState != StatusBarState.SHADE) {
519 // We're driving while keyguard is up.
520 mSwitchToGuestTimer.start();
521 } else {
522 mSwitchToGuestTimer.cancel();
523 }
524 }
525
Rakesh Iyer2790a372016-01-22 15:33:39 -0800526 @Override
527 protected void createUserSwitcher() {
Jason Monk9c7844c2017-01-18 15:21:53 -0500528 UserSwitcherController userSwitcherController =
529 Dependency.get(UserSwitcherController.class);
530 if (userSwitcherController.useFullscreenUserSwitcher()) {
531 mFullscreenUserSwitcher = new FullscreenUserSwitcher(this,
Aarthi Balachanderd8bf2492018-03-30 11:15:59 -0700532 mStatusBarWindow.findViewById(R.id.fullscreen_user_switcher_stub), mContext);
Rakesh Iyer2790a372016-01-22 15:33:39 -0800533 } else {
534 super.createUserSwitcher();
535 }
536 }
537
538 @Override
Jason Monk1fd3fc32018-08-14 17:20:09 -0400539 public void onStateChanged(int newState) {
540 super.onStateChanged(newState);
jovanakedba98c2018-09-14 15:46:24 -0700541
542 startSwitchToGuestTimerIfDrivingOnKeyguard();
543
jovanak1aa629c2018-08-29 09:58:58 -0700544 if (mFullscreenUserSwitcher == null) {
545 return; // Not using the full screen user switcher.
546 }
547
jovanak604ad512018-08-14 18:41:27 -0700548 if (newState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
549 if (!mFullscreenUserSwitcher.isVisible()) {
550 // Current execution path continues to set state after this, thus we deffer the
551 // dismissal to the next execution cycle.
552 postDismissKeyguard(); // Dismiss the keyguard if switcher is not visible.
553 }
554 } else {
555 mFullscreenUserSwitcher.hide();
Aarthi Balachander0a427ef2018-07-13 15:00:58 -0700556 }
557 }
558
559 public void showUserSwitcher() {
jovanak604ad512018-08-14 18:41:27 -0700560 if (mFullscreenUserSwitcher != null && mState == StatusBarState.FULLSCREEN_USER_SWITCHER) {
561 mFullscreenUserSwitcher.show(); // Makes the switcher visible.
Rakesh Iyer2790a372016-01-22 15:33:39 -0800562 }
563 }
Rakesh Iyer74ebabe2016-03-11 10:10:43 -0800564
jovanak604ad512018-08-14 18:41:27 -0700565 public void postDismissKeyguard() {
566 mHandler.post(this::dismissKeyguard);
567 }
568
569 /**
570 * Dismisses the keyguard and shows bouncer if authentication is necessary.
571 */
572 public void dismissKeyguard() {
573 executeRunnableDismissingKeyguard(null/* runnable */, null /* cancelAction */,
Brad Stenning8d1a51c2018-11-20 17:34:16 -0800574 true /* dismissShade */, true /* afterKeyguardGone */, true /* deferred */);
jovanak604ad512018-08-14 18:41:27 -0700575 }
576
Victor Chanc87554c2016-08-24 14:58:14 -0700577 @Override
Anthony Chene658cc22017-04-27 11:17:35 -0700578 public void animateExpandNotificationsPanel() {
579 // Because space is usually constrained in the auto use-case, there should not be a
580 // pinned notification when the shade has been expanded. Ensure this by removing all heads-
581 // up notifications.
yoshiki iguchi4e30e762018-02-06 12:09:23 +0900582 mHeadsUpManager.releaseAllImmediately();
Anthony Chene658cc22017-04-27 11:17:35 -0700583 super.animateExpandNotificationsPanel();
584 }
585
Anthony Chen3cb3ad92016-12-01 10:58:47 -0800586 /**
587 * Ensures that relevant child views are appropriately recreated when the device's density
588 * changes.
589 */
590 @Override
Jason Monk9cac5ff2017-06-02 11:35:50 -0400591 public void onDensityOrFontScaleChanged() {
Anthony Chen3cb3ad92016-12-01 10:58:47 -0800592 super.onDensityOrFontScaleChanged();
Guobin Zhangeef0e0c2019-02-01 11:54:24 -0800593 restartNavBars();
Anthony Chene658cc22017-04-27 11:17:35 -0700594 // Need to update the background on density changed in case the change was due to night
595 // mode.
596 mNotificationPanelBackground = getDefaultWallpaper();
597 mScrimController.setScrimBehindDrawable(mNotificationPanelBackground);
598 }
599
600 /**
601 * Returns the {@link Drawable} that represents the wallpaper that the user has currently set.
602 */
603 private Drawable getDefaultWallpaper() {
604 return mContext.getDrawable(com.android.internal.R.drawable.default_wallpaper);
Anthony Chen3cb3ad92016-12-01 10:58:47 -0800605 }
Brad Stenning19f236a2018-12-11 14:12:30 -0800606
607 public void toggleCarNotifications() {
608 getComponent(NotificationsUI.class).toggleShowingCarNotifications();
609 }
610
Rakesh Iyer1186faa2015-12-07 16:48:46 -0800611}