1 /* 2 * Copyright (C) 2020 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 17 package com.android.systemui.car.systembar; 18 19 import android.app.ActivityManager; 20 import android.app.StatusBarManager; 21 import android.content.Context; 22 import android.os.Build; 23 import android.util.Log; 24 import android.view.Gravity; 25 import android.view.View; 26 import android.view.ViewGroup; 27 import android.widget.Toast; 28 29 import androidx.annotation.Nullable; 30 31 import com.android.internal.annotations.VisibleForTesting; 32 import com.android.systemui.R; 33 import com.android.systemui.broadcast.BroadcastDispatcher; 34 import com.android.systemui.car.CarServiceProvider; 35 import com.android.systemui.car.hvac.HvacPanelOverlayViewController; 36 import com.android.systemui.car.privacy.MicQcPanel; 37 import com.android.systemui.car.statusbar.UserNameViewController; 38 import com.android.systemui.car.statusicon.StatusIconPanelController; 39 import com.android.systemui.dagger.SysUISingleton; 40 import com.android.systemui.statusbar.policy.ConfigurationController; 41 42 import java.util.ArrayList; 43 import java.util.List; 44 45 import javax.inject.Inject; 46 47 import dagger.Lazy; 48 49 /** A single class which controls the navigation bar views. */ 50 @SysUISingleton 51 public class CarSystemBarController { 52 private static final boolean DEBUG = Build.IS_ENG || Build.IS_USERDEBUG; 53 54 private static final String TAG = CarSystemBarController.class.getSimpleName(); 55 56 private final Context mContext; 57 private final CarSystemBarViewFactory mCarSystemBarViewFactory; 58 private final CarServiceProvider mCarServiceProvider; 59 private final BroadcastDispatcher mBroadcastDispatcher; 60 private final ConfigurationController mConfigurationController; 61 private final ButtonSelectionStateController mButtonSelectionStateController; 62 private final ButtonRoleHolderController mButtonRoleHolderController; 63 private final Lazy<UserNameViewController> mUserNameViewControllerLazy; 64 private final Lazy<PrivacyChipViewController> mPrivacyChipViewControllerLazy; 65 private final Lazy<MicQcPanel.MicPrivacyElementsProvider> mMicPrivacyElementsProviderLazy; 66 67 private final boolean mShowTop; 68 private final boolean mShowBottom; 69 private final boolean mShowLeft; 70 private final boolean mShowRight; 71 private final int mPrivacyChipXOffset; 72 73 private View.OnTouchListener mTopBarTouchListener; 74 private View.OnTouchListener mBottomBarTouchListener; 75 private View.OnTouchListener mLeftBarTouchListener; 76 private View.OnTouchListener mRightBarTouchListener; 77 private NotificationsShadeController mNotificationsShadeController; 78 private HvacPanelController mHvacPanelController; 79 private StatusIconPanelController mMicPanelController; 80 private StatusIconPanelController mProfilePanelController; 81 private HvacPanelOverlayViewController mHvacPanelOverlayViewController; 82 83 private CarSystemBarView mTopView; 84 private CarSystemBarView mBottomView; 85 private CarSystemBarView mLeftView; 86 private CarSystemBarView mRightView; 87 88 private int mStatusBarState; 89 90 @Inject CarSystemBarController(Context context, CarSystemBarViewFactory carSystemBarViewFactory, CarServiceProvider carServiceProvider, BroadcastDispatcher broadcastDispatcher, ConfigurationController configurationController, ButtonSelectionStateController buttonSelectionStateController, Lazy<UserNameViewController> userNameViewControllerLazy, Lazy<PrivacyChipViewController> privacyChipViewControllerLazy, ButtonRoleHolderController buttonRoleHolderController, SystemBarConfigs systemBarConfigs, Lazy<MicQcPanel.MicPrivacyElementsProvider> micPrivacyElementsProvider)91 public CarSystemBarController(Context context, 92 CarSystemBarViewFactory carSystemBarViewFactory, 93 CarServiceProvider carServiceProvider, 94 BroadcastDispatcher broadcastDispatcher, 95 ConfigurationController configurationController, 96 ButtonSelectionStateController buttonSelectionStateController, 97 Lazy<UserNameViewController> userNameViewControllerLazy, 98 Lazy<PrivacyChipViewController> privacyChipViewControllerLazy, 99 ButtonRoleHolderController buttonRoleHolderController, 100 SystemBarConfigs systemBarConfigs, 101 Lazy<MicQcPanel.MicPrivacyElementsProvider> micPrivacyElementsProvider) { 102 mContext = context; 103 mCarSystemBarViewFactory = carSystemBarViewFactory; 104 mCarServiceProvider = carServiceProvider; 105 mBroadcastDispatcher = broadcastDispatcher; 106 mConfigurationController = configurationController; 107 mButtonSelectionStateController = buttonSelectionStateController; 108 mUserNameViewControllerLazy = userNameViewControllerLazy; 109 mPrivacyChipViewControllerLazy = privacyChipViewControllerLazy; 110 mButtonRoleHolderController = buttonRoleHolderController; 111 mMicPrivacyElementsProviderLazy = micPrivacyElementsProvider; 112 113 // Read configuration. 114 mShowTop = systemBarConfigs.getEnabledStatusBySide(SystemBarConfigs.TOP); 115 mShowBottom = systemBarConfigs.getEnabledStatusBySide(SystemBarConfigs.BOTTOM); 116 mShowLeft = systemBarConfigs.getEnabledStatusBySide(SystemBarConfigs.LEFT); 117 mShowRight = systemBarConfigs.getEnabledStatusBySide(SystemBarConfigs.RIGHT); 118 119 mPrivacyChipXOffset = -context.getResources() 120 .getDimensionPixelOffset(R.dimen.privacy_chip_horizontal_padding); 121 } 122 123 /** 124 * Hides all system bars. 125 */ hideBars()126 public void hideBars() { 127 setTopWindowVisibility(View.GONE); 128 setBottomWindowVisibility(View.GONE); 129 setLeftWindowVisibility(View.GONE); 130 setRightWindowVisibility(View.GONE); 131 } 132 133 /** 134 * Shows all system bars. 135 */ showBars()136 public void showBars() { 137 setTopWindowVisibility(View.VISIBLE); 138 setBottomWindowVisibility(View.VISIBLE); 139 setLeftWindowVisibility(View.VISIBLE); 140 setRightWindowVisibility(View.VISIBLE); 141 } 142 143 /** Clean up */ removeAll()144 public void removeAll() { 145 mButtonSelectionStateController.removeAll(); 146 mButtonRoleHolderController.removeAll(); 147 mUserNameViewControllerLazy.get().removeAll(); 148 mPrivacyChipViewControllerLazy.get().removeAll(); 149 mMicPanelController = null; 150 mProfilePanelController = null; 151 } 152 153 /** Gets the top window if configured to do so. */ 154 @Nullable getTopWindow()155 public ViewGroup getTopWindow() { 156 return mShowTop ? mCarSystemBarViewFactory.getTopWindow() : null; 157 } 158 159 /** Gets the bottom window if configured to do so. */ 160 @Nullable getBottomWindow()161 public ViewGroup getBottomWindow() { 162 return mShowBottom ? mCarSystemBarViewFactory.getBottomWindow() : null; 163 } 164 165 /** Gets the left window if configured to do so. */ 166 @Nullable getLeftWindow()167 public ViewGroup getLeftWindow() { 168 return mShowLeft ? mCarSystemBarViewFactory.getLeftWindow() : null; 169 } 170 171 /** Gets the right window if configured to do so. */ 172 @Nullable getRightWindow()173 public ViewGroup getRightWindow() { 174 return mShowRight ? mCarSystemBarViewFactory.getRightWindow() : null; 175 } 176 177 /** Toggles the top nav bar visibility. */ setTopWindowVisibility(@iew.Visibility int visibility)178 public boolean setTopWindowVisibility(@View.Visibility int visibility) { 179 return setWindowVisibility(getTopWindow(), visibility); 180 } 181 182 /** Toggles the bottom nav bar visibility. */ setBottomWindowVisibility(@iew.Visibility int visibility)183 public boolean setBottomWindowVisibility(@View.Visibility int visibility) { 184 return setWindowVisibility(getBottomWindow(), visibility); 185 } 186 187 /** Toggles the left nav bar visibility. */ setLeftWindowVisibility(@iew.Visibility int visibility)188 public boolean setLeftWindowVisibility(@View.Visibility int visibility) { 189 return setWindowVisibility(getLeftWindow(), visibility); 190 } 191 192 /** Toggles the right nav bar visibility. */ setRightWindowVisibility(@iew.Visibility int visibility)193 public boolean setRightWindowVisibility(@View.Visibility int visibility) { 194 return setWindowVisibility(getRightWindow(), visibility); 195 } 196 setWindowVisibility(ViewGroup window, @View.Visibility int visibility)197 private boolean setWindowVisibility(ViewGroup window, @View.Visibility int visibility) { 198 if (window == null) { 199 return false; 200 } 201 202 if (window.getVisibility() == visibility) { 203 return false; 204 } 205 206 window.setVisibility(visibility); 207 return true; 208 } 209 210 /** 211 * Sets the status bar state and refreshes the system bar when the state was changed. 212 */ setStatusBarState(int state)213 public void setStatusBarState(int state) { 214 int diff = state ^ mStatusBarState; 215 if (diff == 0) { 216 if (DEBUG) { 217 Log.d(TAG, "setStatusBarState(): status bar states unchanged: " 218 + state); 219 } 220 return; 221 } 222 mStatusBarState = state; 223 refreshSystemBarByLockTaskFeatures(); 224 } 225 226 @VisibleForTesting getStatusBarState()227 protected int getStatusBarState() { 228 return mStatusBarState; 229 } 230 231 /** 232 * Refreshes certain system bar views when lock task mode feature is changed based on 233 * {@link StatusBarManager} flags. 234 */ refreshSystemBarByLockTaskFeatures()235 public void refreshSystemBarByLockTaskFeatures() { 236 boolean locked = isLockTaskModeLocked(); 237 int lockTaskModeVisibility = locked ? View.GONE : View.VISIBLE; 238 boolean homeDisabled = ((mStatusBarState & StatusBarManager.DISABLE_HOME) > 0); 239 boolean notificationDisabled = 240 ((mStatusBarState & StatusBarManager.DISABLE_NOTIFICATION_ICONS) > 0); 241 if (DEBUG) { 242 Log.d(TAG, "refreshSystemBarByLockTaskFeatures: locked?: " + locked 243 + " homeDisabled: " + homeDisabled 244 + " notificationDisabled: " + notificationDisabled); 245 } 246 247 setLockTaskDisabledContainer(R.id.qc_entry_points_container, lockTaskModeVisibility); 248 setLockTaskDisabledContainer(R.id.user_name_container, lockTaskModeVisibility); 249 250 // Check navigation icons 251 setLockTaskDisabledButton(R.id.home, homeDisabled); 252 setLockTaskDisabledButton(R.id.phone_nav, locked); 253 setLockTaskDisabledButton(R.id.grid_nav, homeDisabled); 254 setLockTaskDisabledButton(R.id.notifications, notificationDisabled); 255 } 256 isLockTaskModeLocked()257 private boolean isLockTaskModeLocked() { 258 return mContext.getSystemService(ActivityManager.class).getLockTaskModeState() 259 == ActivityManager.LOCK_TASK_MODE_LOCKED; 260 } 261 setLockTaskDisabledButton(int viewId, boolean disabled)262 private void setLockTaskDisabledButton(int viewId, boolean disabled) { 263 for (CarSystemBarView barView : getAllAvailableSystemBarViews()) { 264 barView.setLockTaskDisabledButton(viewId, disabled, () -> 265 showAdminSupportDetailsDialog()); 266 } 267 } 268 setLockTaskDisabledContainer(int viewId, @View.Visibility int visibility)269 private void setLockTaskDisabledContainer(int viewId, @View.Visibility int visibility) { 270 for (CarSystemBarView barView : getAllAvailableSystemBarViews()) { 271 barView.setLockTaskDisabledContainer(viewId, visibility); 272 } 273 } 274 showAdminSupportDetailsDialog()275 private void showAdminSupportDetailsDialog() { 276 // TODO(b/205891123): launch AdminSupportDetailsDialog after moving 277 // AdminSupportDetailsDialog out of CarSettings since CarSettings is not and should not 278 // be allowlisted for lock task mode. 279 Toast.makeText(mContext, "This action is unavailable for your profile", 280 Toast.LENGTH_LONG).show(); 281 } 282 283 /** Gets the top navigation bar with the appropriate listeners set. */ 284 @Nullable getTopBar(boolean isSetUp)285 public CarSystemBarView getTopBar(boolean isSetUp) { 286 if (!mShowTop) { 287 return null; 288 } 289 290 mTopView = mCarSystemBarViewFactory.getTopBar(isSetUp); 291 setupBar(mTopView, mTopBarTouchListener, mNotificationsShadeController, 292 mHvacPanelController, mHvacPanelOverlayViewController); 293 294 if (isSetUp) { 295 // We do not want the mic privacy chip or the profile picker to be clickable in 296 // unprovisioned mode. 297 setupMicQcPanel(); 298 setupProfilePanel(); 299 } 300 301 return mTopView; 302 } 303 304 /** Gets the bottom navigation bar with the appropriate listeners set. */ 305 @Nullable getBottomBar(boolean isSetUp)306 public CarSystemBarView getBottomBar(boolean isSetUp) { 307 if (!mShowBottom) { 308 return null; 309 } 310 311 mBottomView = mCarSystemBarViewFactory.getBottomBar(isSetUp); 312 setupBar(mBottomView, mBottomBarTouchListener, mNotificationsShadeController, 313 mHvacPanelController, mHvacPanelOverlayViewController); 314 return mBottomView; 315 } 316 317 /** Gets the left navigation bar with the appropriate listeners set. */ 318 @Nullable getLeftBar(boolean isSetUp)319 public CarSystemBarView getLeftBar(boolean isSetUp) { 320 if (!mShowLeft) { 321 return null; 322 } 323 324 mLeftView = mCarSystemBarViewFactory.getLeftBar(isSetUp); 325 setupBar(mLeftView, mLeftBarTouchListener, mNotificationsShadeController, 326 mHvacPanelController, mHvacPanelOverlayViewController); 327 return mLeftView; 328 } 329 330 /** Gets the right navigation bar with the appropriate listeners set. */ 331 @Nullable getRightBar(boolean isSetUp)332 public CarSystemBarView getRightBar(boolean isSetUp) { 333 if (!mShowRight) { 334 return null; 335 } 336 337 mRightView = mCarSystemBarViewFactory.getRightBar(isSetUp); 338 setupBar(mRightView, mRightBarTouchListener, mNotificationsShadeController, 339 mHvacPanelController, mHvacPanelOverlayViewController); 340 return mRightView; 341 } 342 setupBar(CarSystemBarView view, View.OnTouchListener statusBarTouchListener, NotificationsShadeController notifShadeController, HvacPanelController hvacPanelController, HvacPanelOverlayViewController hvacPanelOverlayViewController)343 private void setupBar(CarSystemBarView view, View.OnTouchListener statusBarTouchListener, 344 NotificationsShadeController notifShadeController, 345 HvacPanelController hvacPanelController, 346 HvacPanelOverlayViewController hvacPanelOverlayViewController) { 347 view.setStatusBarWindowTouchListener(statusBarTouchListener); 348 view.setNotificationsPanelController(notifShadeController); 349 view.setHvacPanelController(hvacPanelController); 350 view.registerHvacPanelOverlayViewController(hvacPanelOverlayViewController); 351 mButtonSelectionStateController.addAllButtonsWithSelectionState(view); 352 mButtonRoleHolderController.addAllButtonsWithRoleName(view); 353 mUserNameViewControllerLazy.get().addUserNameView(view); 354 mPrivacyChipViewControllerLazy.get().addPrivacyChipView(view); 355 } 356 setupMicQcPanel()357 private void setupMicQcPanel() { 358 if (mMicPanelController == null) { 359 mMicPanelController = new StatusIconPanelController(mContext, mCarServiceProvider, 360 mBroadcastDispatcher, mConfigurationController); 361 } 362 363 mMicPanelController.setOnQcViewsFoundListener(qcViews -> qcViews.forEach(qcView -> { 364 if (qcView.getLocalQCProvider() instanceof MicQcPanel) { 365 MicQcPanel micQcPanel = (MicQcPanel) qcView.getLocalQCProvider(); 366 micQcPanel.setControllers(mPrivacyChipViewControllerLazy.get(), 367 mMicPrivacyElementsProviderLazy.get()); 368 } 369 })); 370 371 mMicPanelController.attachPanel(mTopView.requireViewById(R.id.privacy_chip), 372 R.layout.qc_mic_panel, R.dimen.car_mic_qc_panel_width, mPrivacyChipXOffset, 373 mMicPanelController.getDefaultYOffset(), Gravity.TOP | Gravity.END); 374 } 375 setupProfilePanel()376 private void setupProfilePanel() { 377 View profilePickerView = mTopView.findViewById(R.id.user_name); 378 if (mProfilePanelController == null && profilePickerView != null) { 379 boolean profilePanelDisabledWhileDriving = mContext.getResources().getBoolean( 380 R.bool.config_profile_panel_disabled_while_driving); 381 mProfilePanelController = new StatusIconPanelController(mContext, mCarServiceProvider, 382 mBroadcastDispatcher, mConfigurationController, 383 profilePanelDisabledWhileDriving); 384 mProfilePanelController.attachPanel(profilePickerView, R.layout.qc_profile_switcher, 385 R.dimen.car_profile_quick_controls_panel_width, Gravity.TOP | Gravity.END); 386 } 387 } 388 389 /** Sets a touch listener for the top navigation bar. */ registerTopBarTouchListener(View.OnTouchListener listener)390 public void registerTopBarTouchListener(View.OnTouchListener listener) { 391 mTopBarTouchListener = listener; 392 if (mTopView != null) { 393 mTopView.setStatusBarWindowTouchListener(mTopBarTouchListener); 394 } 395 } 396 397 /** Sets a touch listener for the bottom navigation bar. */ registerBottomBarTouchListener(View.OnTouchListener listener)398 public void registerBottomBarTouchListener(View.OnTouchListener listener) { 399 mBottomBarTouchListener = listener; 400 if (mBottomView != null) { 401 mBottomView.setStatusBarWindowTouchListener(mBottomBarTouchListener); 402 } 403 } 404 405 /** Sets a touch listener for the left navigation bar. */ registerLeftBarTouchListener(View.OnTouchListener listener)406 public void registerLeftBarTouchListener(View.OnTouchListener listener) { 407 mLeftBarTouchListener = listener; 408 if (mLeftView != null) { 409 mLeftView.setStatusBarWindowTouchListener(mLeftBarTouchListener); 410 } 411 } 412 413 /** Sets a touch listener for the right navigation bar. */ registerRightBarTouchListener(View.OnTouchListener listener)414 public void registerRightBarTouchListener(View.OnTouchListener listener) { 415 mRightBarTouchListener = listener; 416 if (mRightView != null) { 417 mRightView.setStatusBarWindowTouchListener(mRightBarTouchListener); 418 } 419 } 420 421 /** Sets a notification controller which toggles the notification panel. */ registerNotificationController( NotificationsShadeController notificationsShadeController)422 public void registerNotificationController( 423 NotificationsShadeController notificationsShadeController) { 424 mNotificationsShadeController = notificationsShadeController; 425 if (mTopView != null) { 426 mTopView.setNotificationsPanelController(mNotificationsShadeController); 427 } 428 if (mBottomView != null) { 429 mBottomView.setNotificationsPanelController(mNotificationsShadeController); 430 } 431 if (mLeftView != null) { 432 mLeftView.setNotificationsPanelController(mNotificationsShadeController); 433 } 434 if (mRightView != null) { 435 mRightView.setNotificationsPanelController(mNotificationsShadeController); 436 } 437 } 438 439 /** Sets an HVAC controller which toggles the HVAC panel. */ registerHvacPanelController(HvacPanelController hvacPanelController)440 public void registerHvacPanelController(HvacPanelController hvacPanelController) { 441 mHvacPanelController = hvacPanelController; 442 if (mTopView != null) { 443 mTopView.setHvacPanelController(mHvacPanelController); 444 } 445 if (mBottomView != null) { 446 mBottomView.setHvacPanelController(mHvacPanelController); 447 } 448 if (mLeftView != null) { 449 mLeftView.setHvacPanelController(mHvacPanelController); 450 } 451 if (mRightView != null) { 452 mRightView.setHvacPanelController(mHvacPanelController); 453 } 454 } 455 456 /** Sets the HVACPanelOverlayViewController for views to listen to the panel's state. */ registerHvacPanelOverlayViewController( HvacPanelOverlayViewController hvacPanelOverlayViewController)457 public void registerHvacPanelOverlayViewController( 458 HvacPanelOverlayViewController hvacPanelOverlayViewController) { 459 mHvacPanelOverlayViewController = hvacPanelOverlayViewController; 460 if (mTopView != null) { 461 mTopView.registerHvacPanelOverlayViewController(mHvacPanelOverlayViewController); 462 } 463 if (mBottomView != null) { 464 mBottomView.registerHvacPanelOverlayViewController(mHvacPanelOverlayViewController); 465 } 466 if (mLeftView != null) { 467 mLeftView.registerHvacPanelOverlayViewController(mHvacPanelOverlayViewController); 468 } 469 if (mRightView != null) { 470 mRightView.registerHvacPanelOverlayViewController(mHvacPanelOverlayViewController); 471 } 472 } 473 474 /** 475 * Shows all of the navigation buttons on the valid instances of {@link CarSystemBarView}. 476 */ showAllNavigationButtons(boolean isSetUp)477 public void showAllNavigationButtons(boolean isSetUp) { 478 checkAllBars(isSetUp); 479 if (mTopView != null) { 480 mTopView.showButtonsOfType(CarSystemBarView.BUTTON_TYPE_NAVIGATION); 481 } 482 if (mBottomView != null) { 483 mBottomView.showButtonsOfType(CarSystemBarView.BUTTON_TYPE_NAVIGATION); 484 } 485 if (mLeftView != null) { 486 mLeftView.showButtonsOfType(CarSystemBarView.BUTTON_TYPE_NAVIGATION); 487 } 488 if (mRightView != null) { 489 mRightView.showButtonsOfType(CarSystemBarView.BUTTON_TYPE_NAVIGATION); 490 } 491 } 492 493 /** 494 * Shows all of the keyguard specific buttons on the valid instances of 495 * {@link CarSystemBarView}. 496 */ showAllKeyguardButtons(boolean isSetUp)497 public void showAllKeyguardButtons(boolean isSetUp) { 498 checkAllBars(isSetUp); 499 if (mTopView != null) { 500 mTopView.showButtonsOfType(CarSystemBarView.BUTTON_TYPE_KEYGUARD); 501 } 502 if (mBottomView != null) { 503 mBottomView.showButtonsOfType(CarSystemBarView.BUTTON_TYPE_KEYGUARD); 504 } 505 if (mLeftView != null) { 506 mLeftView.showButtonsOfType(CarSystemBarView.BUTTON_TYPE_KEYGUARD); 507 } 508 if (mRightView != null) { 509 mRightView.showButtonsOfType(CarSystemBarView.BUTTON_TYPE_KEYGUARD); 510 } 511 } 512 513 /** 514 * Shows all of the occlusion state buttons on the valid instances of 515 * {@link CarSystemBarView}. 516 */ showAllOcclusionButtons(boolean isSetUp)517 public void showAllOcclusionButtons(boolean isSetUp) { 518 checkAllBars(isSetUp); 519 if (mTopView != null) { 520 mTopView.showButtonsOfType(CarSystemBarView.BUTTON_TYPE_OCCLUSION); 521 } 522 if (mBottomView != null) { 523 mBottomView.showButtonsOfType(CarSystemBarView.BUTTON_TYPE_OCCLUSION); 524 } 525 if (mLeftView != null) { 526 mLeftView.showButtonsOfType(CarSystemBarView.BUTTON_TYPE_OCCLUSION); 527 } 528 if (mRightView != null) { 529 mRightView.showButtonsOfType(CarSystemBarView.BUTTON_TYPE_OCCLUSION); 530 } 531 } 532 533 /** Toggles whether the notifications icon has an unseen indicator or not. */ toggleAllNotificationsUnseenIndicator(boolean isSetUp, boolean hasUnseen)534 public void toggleAllNotificationsUnseenIndicator(boolean isSetUp, boolean hasUnseen) { 535 checkAllBars(isSetUp); 536 if (mTopView != null) { 537 mTopView.toggleNotificationUnseenIndicator(hasUnseen); 538 } 539 if (mBottomView != null) { 540 mBottomView.toggleNotificationUnseenIndicator(hasUnseen); 541 } 542 if (mLeftView != null) { 543 mLeftView.toggleNotificationUnseenIndicator(hasUnseen); 544 } 545 if (mRightView != null) { 546 mRightView.toggleNotificationUnseenIndicator(hasUnseen); 547 } 548 } 549 550 /** Interface for controlling the notifications shade. */ 551 public interface NotificationsShadeController { 552 /** Toggles the visibility of the notifications shade. */ togglePanel()553 void togglePanel(); 554 555 /** Returns {@code true} if the panel is open. */ isNotificationPanelOpen()556 boolean isNotificationPanelOpen(); 557 } 558 559 /** Interface for controlling the HVAC panel. */ 560 public interface HvacPanelController { 561 /** Toggles the visibility of the HVAC shade. */ togglePanel()562 void togglePanel(); 563 564 /** Returns {@code true} if the panel is open. */ isHvacPanelOpen()565 boolean isHvacPanelOpen(); 566 } 567 checkAllBars(boolean isSetUp)568 private void checkAllBars(boolean isSetUp) { 569 mTopView = getTopBar(isSetUp); 570 mBottomView = getBottomBar(isSetUp); 571 mLeftView = getLeftBar(isSetUp); 572 mRightView = getRightBar(isSetUp); 573 } 574 getAllAvailableSystemBarViews()575 private List<CarSystemBarView> getAllAvailableSystemBarViews() { 576 List<CarSystemBarView> barViews = new ArrayList<>(); 577 if (mTopView != null) { 578 barViews.add(mTopView); 579 } 580 if (mBottomView != null) { 581 barViews.add(mBottomView); 582 } 583 if (mLeftView != null) { 584 barViews.add(mLeftView); 585 } 586 if (mRightView != null) { 587 barViews.add(mRightView); 588 } 589 return barViews; 590 } 591 } 592