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 static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; 20 21 import android.annotation.IntDef; 22 import android.content.res.Resources; 23 import android.graphics.PixelFormat; 24 import android.os.Binder; 25 import android.util.ArrayMap; 26 import android.util.ArraySet; 27 import android.util.Log; 28 import android.view.Gravity; 29 import android.view.InsetsFrameProvider; 30 import android.view.ViewGroup; 31 import android.view.WindowInsets; 32 import android.view.WindowManager; 33 34 import com.android.internal.annotations.VisibleForTesting; 35 import com.android.systemui.R; 36 import com.android.systemui.car.notification.BottomNotificationPanelViewMediator; 37 import com.android.systemui.car.notification.TopNotificationPanelViewMediator; 38 import com.android.systemui.dagger.SysUISingleton; 39 import com.android.systemui.dagger.qualifiers.Main; 40 41 import java.lang.annotation.ElementType; 42 import java.lang.annotation.Target; 43 import java.util.ArrayList; 44 import java.util.Comparator; 45 import java.util.List; 46 import java.util.Map; 47 import java.util.Set; 48 49 import javax.inject.Inject; 50 51 /** 52 * Reads configs for system bars for each side (TOP, BOTTOM, LEFT, and RIGHT) and returns the 53 * corresponding {@link android.view.WindowManager.LayoutParams} per the configuration. 54 */ 55 @SysUISingleton 56 public class SystemBarConfigs { 57 58 private static final String TAG = SystemBarConfigs.class.getSimpleName(); 59 // The z-order from which system bars will start to appear on top of HUN's. 60 private static final int HUN_ZORDER = 10; 61 62 @IntDef(value = {TOP, BOTTOM, LEFT, RIGHT}) 63 @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) 64 private @interface SystemBarSide { 65 } 66 67 public static final int TOP = 0; 68 public static final int BOTTOM = 1; 69 public static final int LEFT = 2; 70 public static final int RIGHT = 3; 71 72 private static final Binder INSETS_OWNER = new Binder(); 73 74 /* 75 NOTE: The elements' order in the map below must be preserved as-is since the correct 76 corresponding values are obtained by the index. 77 */ 78 public static final InsetsFrameProvider[] BAR_PROVIDER_MAP = { 79 new InsetsFrameProvider( 80 INSETS_OWNER, 0 /* index */, WindowInsets.Type.statusBars()), 81 new InsetsFrameProvider( 82 INSETS_OWNER, 0 /* index */, WindowInsets.Type.navigationBars()), 83 new InsetsFrameProvider( 84 INSETS_OWNER, 1 /* index */, WindowInsets.Type.statusBars()), 85 new InsetsFrameProvider( 86 INSETS_OWNER, 1 /* index */, WindowInsets.Type.navigationBars()), 87 }; 88 89 private static final Map<@SystemBarSide Integer, Integer> BAR_GRAVITY_MAP = new ArrayMap<>(); 90 private static final Map<@SystemBarSide Integer, String> BAR_TITLE_MAP = new ArrayMap<>(); 91 private static final Map<@SystemBarSide Integer, InsetsFrameProvider> BAR_GESTURE_MAP = 92 new ArrayMap<>(); 93 94 private final Resources mResources; 95 private final Map<@SystemBarSide Integer, SystemBarConfig> mSystemBarConfigMap = 96 new ArrayMap<>(); 97 private final List<@SystemBarSide Integer> mSystemBarSidesByZOrder = new ArrayList<>(); 98 99 private boolean mTopNavBarEnabled; 100 private boolean mBottomNavBarEnabled; 101 private boolean mLeftNavBarEnabled; 102 private boolean mRightNavBarEnabled; 103 104 @Inject SystemBarConfigs(@ain Resources resources)105 public SystemBarConfigs(@Main Resources resources) { 106 mResources = resources; 107 init(); 108 } 109 init()110 private void init() { 111 populateMaps(); 112 readConfigs(); 113 114 checkEnabledBarsHaveUniqueBarTypes(); 115 checkAllOverlappingBarsHaveDifferentZOrders(); 116 checkSystemBarEnabledForNotificationPanel(); 117 checkHideBottomBarForKeyboardConfigSync(); 118 119 setInsetPaddingsForOverlappingCorners(); 120 sortSystemBarSidesByZOrder(); 121 } 122 123 /** 124 * Invalidate cached resources and fetch from resources config file. 125 * TODO: b/260206944, Can remove this after we have a fix for overlaid resources not applied. 126 * <p> 127 * Since SystemBarConfig is a Scoped(Dagger Singleton Annotation), We will have stale values, of 128 * all the resources after the RRO is applied. 129 * Another way is to remove the Scope(Singleton), but the downside is that it will be re-created 130 * everytime. 131 * </p> 132 */ resetSystemBarConfigs()133 void resetSystemBarConfigs() { 134 init(); 135 } 136 getLayoutParamsBySide(@ystemBarSide int side)137 protected WindowManager.LayoutParams getLayoutParamsBySide(@SystemBarSide int side) { 138 return mSystemBarConfigMap.get(side) != null 139 ? mSystemBarConfigMap.get(side).getLayoutParams() : null; 140 } 141 getEnabledStatusBySide(@ystemBarSide int side)142 protected boolean getEnabledStatusBySide(@SystemBarSide int side) { 143 switch (side) { 144 case TOP: 145 return mTopNavBarEnabled; 146 case BOTTOM: 147 return mBottomNavBarEnabled; 148 case LEFT: 149 return mLeftNavBarEnabled; 150 case RIGHT: 151 return mRightNavBarEnabled; 152 default: 153 return false; 154 } 155 } 156 getHideForKeyboardBySide(@ystemBarSide int side)157 protected boolean getHideForKeyboardBySide(@SystemBarSide int side) { 158 return mSystemBarConfigMap.get(side) != null 159 && mSystemBarConfigMap.get(side).getHideForKeyboard(); 160 } 161 insetSystemBar(@ystemBarSide int side, CarSystemBarView view)162 protected void insetSystemBar(@SystemBarSide int side, CarSystemBarView view) { 163 if (mSystemBarConfigMap.get(side) == null) return; 164 165 int[] paddings = mSystemBarConfigMap.get(side).getPaddings(); 166 view.setPadding(paddings[2], paddings[0], paddings[3], paddings[1]); 167 } 168 getSystemBarSidesByZOrder()169 protected List<Integer> getSystemBarSidesByZOrder() { 170 return mSystemBarSidesByZOrder; 171 } 172 173 @VisibleForTesting updateInsetPaddings(@ystemBarSide int side, Map<@SystemBarSide Integer, Boolean> barVisibilities)174 void updateInsetPaddings(@SystemBarSide int side, 175 Map<@SystemBarSide Integer, Boolean> barVisibilities) { 176 SystemBarConfig currentConfig = mSystemBarConfigMap.get(side); 177 178 if (currentConfig == null) return; 179 180 if (isHorizontalBar(side)) { 181 if (mLeftNavBarEnabled && currentConfig.getZOrder() < mSystemBarConfigMap.get( 182 LEFT).getZOrder()) { 183 currentConfig.setPaddingBySide(LEFT, 184 barVisibilities.get(LEFT) ? mSystemBarConfigMap.get(LEFT).getGirth() : 0); 185 } 186 if (mRightNavBarEnabled && currentConfig.getZOrder() < mSystemBarConfigMap.get( 187 RIGHT).getZOrder()) { 188 currentConfig.setPaddingBySide(RIGHT, 189 barVisibilities.get(RIGHT) ? mSystemBarConfigMap.get(RIGHT).getGirth() : 0); 190 } 191 } 192 if (isVerticalBar(side)) { 193 if (mTopNavBarEnabled && currentConfig.getZOrder() < mSystemBarConfigMap.get( 194 TOP).getZOrder()) { 195 currentConfig.setPaddingBySide(TOP, 196 barVisibilities.get(TOP) ? mSystemBarConfigMap.get(TOP).getGirth() : 0); 197 } 198 if (mBottomNavBarEnabled && currentConfig.getZOrder() < mSystemBarConfigMap.get( 199 BOTTOM).getZOrder()) { 200 currentConfig.setPaddingBySide(BOTTOM, 201 barVisibilities.get(BOTTOM) ? mSystemBarConfigMap.get(BOTTOM).getGirth() 202 : 0); 203 } 204 } 205 } 206 207 @VisibleForTesting getHunZOrder()208 static int getHunZOrder() { 209 return HUN_ZORDER; 210 } 211 populateMaps()212 private static void populateMaps() { 213 BAR_GRAVITY_MAP.put(TOP, Gravity.TOP); 214 BAR_GRAVITY_MAP.put(BOTTOM, Gravity.BOTTOM); 215 BAR_GRAVITY_MAP.put(LEFT, Gravity.LEFT); 216 BAR_GRAVITY_MAP.put(RIGHT, Gravity.RIGHT); 217 218 BAR_TITLE_MAP.put(TOP, "TopCarSystemBar"); 219 BAR_TITLE_MAP.put(BOTTOM, "BottomCarSystemBar"); 220 BAR_TITLE_MAP.put(LEFT, "LeftCarSystemBar"); 221 BAR_TITLE_MAP.put(RIGHT, "RightCarSystemBar"); 222 223 BAR_GESTURE_MAP.put(TOP, new InsetsFrameProvider( 224 INSETS_OWNER, 0 /* index */, WindowInsets.Type.mandatorySystemGestures())); 225 BAR_GESTURE_MAP.put(BOTTOM, new InsetsFrameProvider( 226 INSETS_OWNER, 1 /* index */, WindowInsets.Type.mandatorySystemGestures())); 227 BAR_GESTURE_MAP.put(LEFT, new InsetsFrameProvider( 228 INSETS_OWNER, 2 /* index */, WindowInsets.Type.mandatorySystemGestures())); 229 BAR_GESTURE_MAP.put(RIGHT, new InsetsFrameProvider( 230 INSETS_OWNER, 3 /* index */, WindowInsets.Type.mandatorySystemGestures())); 231 } 232 readConfigs()233 private void readConfigs() { 234 mTopNavBarEnabled = mResources.getBoolean(R.bool.config_enableTopSystemBar); 235 mBottomNavBarEnabled = mResources.getBoolean(R.bool.config_enableBottomSystemBar); 236 mLeftNavBarEnabled = mResources.getBoolean(R.bool.config_enableLeftSystemBar); 237 mRightNavBarEnabled = mResources.getBoolean(R.bool.config_enableRightSystemBar); 238 239 if (mTopNavBarEnabled) { 240 SystemBarConfig topBarConfig = 241 new SystemBarConfigBuilder() 242 .setSide(TOP) 243 .setGirth(mResources.getDimensionPixelSize( 244 R.dimen.car_top_system_bar_height)) 245 .setBarType(mResources.getInteger(R.integer.config_topSystemBarType)) 246 .setZOrder(mResources.getInteger(R.integer.config_topSystemBarZOrder)) 247 .setHideForKeyboard(mResources.getBoolean( 248 R.bool.config_hideTopSystemBarForKeyboard)) 249 .build(); 250 mSystemBarConfigMap.put(TOP, topBarConfig); 251 } 252 253 if (mBottomNavBarEnabled) { 254 SystemBarConfig bottomBarConfig = 255 new SystemBarConfigBuilder() 256 .setSide(BOTTOM) 257 .setGirth(mResources.getDimensionPixelSize( 258 R.dimen.car_bottom_system_bar_height)) 259 .setBarType(mResources.getInteger(R.integer.config_bottomSystemBarType)) 260 .setZOrder( 261 mResources.getInteger(R.integer.config_bottomSystemBarZOrder)) 262 .setHideForKeyboard(mResources.getBoolean( 263 R.bool.config_hideBottomSystemBarForKeyboard)) 264 .build(); 265 mSystemBarConfigMap.put(BOTTOM, bottomBarConfig); 266 } 267 268 if (mLeftNavBarEnabled) { 269 SystemBarConfig leftBarConfig = 270 new SystemBarConfigBuilder() 271 .setSide(LEFT) 272 .setGirth(mResources.getDimensionPixelSize( 273 R.dimen.car_left_system_bar_width)) 274 .setBarType(mResources.getInteger(R.integer.config_leftSystemBarType)) 275 .setZOrder(mResources.getInteger(R.integer.config_leftSystemBarZOrder)) 276 .setHideForKeyboard(mResources.getBoolean( 277 R.bool.config_hideLeftSystemBarForKeyboard)) 278 .build(); 279 mSystemBarConfigMap.put(LEFT, leftBarConfig); 280 } 281 282 if (mRightNavBarEnabled) { 283 SystemBarConfig rightBarConfig = 284 new SystemBarConfigBuilder() 285 .setSide(RIGHT) 286 .setGirth(mResources.getDimensionPixelSize( 287 R.dimen.car_right_system_bar_width)) 288 .setBarType(mResources.getInteger(R.integer.config_rightSystemBarType)) 289 .setZOrder(mResources.getInteger(R.integer.config_rightSystemBarZOrder)) 290 .setHideForKeyboard(mResources.getBoolean( 291 R.bool.config_hideRightSystemBarForKeyboard)) 292 .build(); 293 mSystemBarConfigMap.put(RIGHT, rightBarConfig); 294 } 295 } 296 checkEnabledBarsHaveUniqueBarTypes()297 private void checkEnabledBarsHaveUniqueBarTypes() throws RuntimeException { 298 Set<Integer> barTypesUsed = new ArraySet<>(); 299 int enabledNavBarCount = mSystemBarConfigMap.size(); 300 301 for (SystemBarConfig systemBarConfig : mSystemBarConfigMap.values()) { 302 barTypesUsed.add(systemBarConfig.getBarType()); 303 } 304 305 // The number of bar types used cannot be fewer than that of enabled system bars. 306 if (barTypesUsed.size() < enabledNavBarCount) { 307 throw new RuntimeException("Each enabled system bar must have a unique bar type. Check " 308 + "the configuration in config.xml"); 309 } 310 } 311 checkAllOverlappingBarsHaveDifferentZOrders()312 private void checkAllOverlappingBarsHaveDifferentZOrders() { 313 checkOverlappingBarsHaveDifferentZOrders(TOP, LEFT); 314 checkOverlappingBarsHaveDifferentZOrders(TOP, RIGHT); 315 checkOverlappingBarsHaveDifferentZOrders(BOTTOM, LEFT); 316 checkOverlappingBarsHaveDifferentZOrders(BOTTOM, RIGHT); 317 } 318 checkSystemBarEnabledForNotificationPanel()319 private void checkSystemBarEnabledForNotificationPanel() throws RuntimeException { 320 String notificationPanelMediatorName = 321 mResources.getString(R.string.config_notificationPanelViewMediator); 322 if (notificationPanelMediatorName == null) { 323 return; 324 } 325 326 Class<?> notificationPanelMediatorUsed = null; 327 try { 328 notificationPanelMediatorUsed = Class.forName(notificationPanelMediatorName); 329 } catch (ClassNotFoundException e) { 330 e.printStackTrace(); 331 } 332 333 if (!mTopNavBarEnabled && TopNotificationPanelViewMediator.class.isAssignableFrom( 334 notificationPanelMediatorUsed)) { 335 throw new RuntimeException( 336 "Top System Bar must be enabled to use " + notificationPanelMediatorName); 337 } 338 339 if (!mBottomNavBarEnabled && BottomNotificationPanelViewMediator.class.isAssignableFrom( 340 notificationPanelMediatorUsed)) { 341 throw new RuntimeException("Bottom System Bar must be enabled to use " 342 + notificationPanelMediatorName); 343 } 344 } 345 checkHideBottomBarForKeyboardConfigSync()346 private void checkHideBottomBarForKeyboardConfigSync() throws RuntimeException { 347 if (mBottomNavBarEnabled) { 348 boolean actual = mResources.getBoolean(R.bool.config_hideBottomSystemBarForKeyboard); 349 boolean expected = mResources.getBoolean( 350 com.android.internal.R.bool.config_hideNavBarForKeyboard); 351 352 if (actual != expected) { 353 throw new RuntimeException("config_hideBottomSystemBarForKeyboard must not be " 354 + "overlaid directly and should always refer to" 355 + "config_hideNavBarForKeyboard. However, their values " 356 + "currently do not sync. Set config_hideBottomSystemBarForKeyguard to " 357 + "@*android:bool/config_hideNavBarForKeyboard. To change its " 358 + "value, overlay config_hideNavBarForKeyboard in " 359 + "framework/base/core/res/res."); 360 } 361 } 362 } 363 setInsetPaddingsForOverlappingCorners()364 private void setInsetPaddingsForOverlappingCorners() { 365 Map<@SystemBarSide Integer, Boolean> systemBarVisibilityOnInit = 366 getSystemBarsVisibilityOnInit(); 367 updateInsetPaddings(TOP, systemBarVisibilityOnInit); 368 updateInsetPaddings(BOTTOM, systemBarVisibilityOnInit); 369 updateInsetPaddings(LEFT, systemBarVisibilityOnInit); 370 updateInsetPaddings(RIGHT, systemBarVisibilityOnInit); 371 } 372 sortSystemBarSidesByZOrder()373 private void sortSystemBarSidesByZOrder() { 374 List<SystemBarConfig> systemBarsByZOrder = new ArrayList<>(mSystemBarConfigMap.values()); 375 376 systemBarsByZOrder.sort(new Comparator<SystemBarConfig>() { 377 @Override 378 public int compare(SystemBarConfig o1, SystemBarConfig o2) { 379 return o1.getZOrder() - o2.getZOrder(); 380 } 381 }); 382 383 mSystemBarSidesByZOrder.clear(); 384 systemBarsByZOrder.forEach(systemBarConfig -> { 385 mSystemBarSidesByZOrder.add(systemBarConfig.getSide()); 386 }); 387 } 388 389 // On init, system bars are visible as long as they are enabled. getSystemBarsVisibilityOnInit()390 private Map<@SystemBarSide Integer, Boolean> getSystemBarsVisibilityOnInit() { 391 ArrayMap<@SystemBarSide Integer, Boolean> visibilityMap = new ArrayMap<>(); 392 visibilityMap.put(TOP, mTopNavBarEnabled); 393 visibilityMap.put(BOTTOM, mBottomNavBarEnabled); 394 visibilityMap.put(LEFT, mLeftNavBarEnabled); 395 visibilityMap.put(RIGHT, mRightNavBarEnabled); 396 return visibilityMap; 397 } 398 checkOverlappingBarsHaveDifferentZOrders(@ystemBarSide int horizontalSide, @SystemBarSide int verticalSide)399 private void checkOverlappingBarsHaveDifferentZOrders(@SystemBarSide int horizontalSide, 400 @SystemBarSide int verticalSide) { 401 402 if (isVerticalBar(horizontalSide) || isHorizontalBar(verticalSide)) { 403 Log.w(TAG, "configureBarPaddings: Returning immediately since the horizontal and " 404 + "vertical sides were not provided correctly."); 405 return; 406 } 407 408 SystemBarConfig horizontalBarConfig = mSystemBarConfigMap.get(horizontalSide); 409 SystemBarConfig verticalBarConfig = mSystemBarConfigMap.get(verticalSide); 410 411 if (verticalBarConfig != null && horizontalBarConfig != null) { 412 int horizontalBarZOrder = horizontalBarConfig.getZOrder(); 413 int verticalBarZOrder = verticalBarConfig.getZOrder(); 414 415 if (horizontalBarZOrder == verticalBarZOrder) { 416 throw new RuntimeException( 417 BAR_TITLE_MAP.get(horizontalSide) + " " + BAR_TITLE_MAP.get(verticalSide) 418 + " have the same Z-Order, and so their placing order cannot be " 419 + "determined. Determine which bar should be placed on top of the " 420 + "other bar and change the Z-order in config.xml accordingly." 421 ); 422 } 423 } 424 } 425 isHorizontalBar(@ystemBarSide int side)426 private static boolean isHorizontalBar(@SystemBarSide int side) { 427 return side == TOP || side == BOTTOM; 428 } 429 isVerticalBar(@ystemBarSide int side)430 private static boolean isVerticalBar(@SystemBarSide int side) { 431 return side == LEFT || side == RIGHT; 432 } 433 434 private static final class SystemBarConfig { 435 private final int mSide; 436 private final int mBarType; 437 private final int mGirth; 438 private final int mZOrder; 439 private final boolean mHideForKeyboard; 440 441 private int[] mPaddings = new int[]{0, 0, 0, 0}; 442 SystemBarConfig(@ystemBarSide int side, int barType, int girth, int zOrder, boolean hideForKeyboard)443 private SystemBarConfig(@SystemBarSide int side, int barType, int girth, int zOrder, 444 boolean hideForKeyboard) { 445 mSide = side; 446 mBarType = barType; 447 mGirth = girth; 448 mZOrder = zOrder; 449 mHideForKeyboard = hideForKeyboard; 450 } 451 getSide()452 private int getSide() { 453 return mSide; 454 } 455 getBarType()456 private int getBarType() { 457 return mBarType; 458 } 459 getGirth()460 private int getGirth() { 461 return mGirth; 462 } 463 getZOrder()464 private int getZOrder() { 465 return mZOrder; 466 } 467 getHideForKeyboard()468 private boolean getHideForKeyboard() { 469 return mHideForKeyboard; 470 } 471 getPaddings()472 private int[] getPaddings() { 473 return mPaddings; 474 } 475 getLayoutParams()476 private WindowManager.LayoutParams getLayoutParams() { 477 WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 478 isHorizontalBar(mSide) ? ViewGroup.LayoutParams.MATCH_PARENT : mGirth, 479 isHorizontalBar(mSide) ? mGirth : ViewGroup.LayoutParams.MATCH_PARENT, 480 mapZOrderToBarType(mZOrder), 481 WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE 482 | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL 483 | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH 484 | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, 485 PixelFormat.TRANSLUCENT); 486 lp.setTitle(BAR_TITLE_MAP.get(mSide)); 487 lp.providedInsets = new InsetsFrameProvider[] { 488 BAR_PROVIDER_MAP[mBarType], 489 BAR_GESTURE_MAP.get(mSide) 490 }; 491 lp.setFitInsetsTypes(0); 492 lp.windowAnimations = 0; 493 lp.gravity = BAR_GRAVITY_MAP.get(mSide); 494 lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; 495 return lp; 496 } 497 mapZOrderToBarType(int zOrder)498 private int mapZOrderToBarType(int zOrder) { 499 return zOrder >= HUN_ZORDER ? WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL 500 : WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL; 501 } 502 setPaddingBySide(@ystemBarSide int side, int padding)503 private void setPaddingBySide(@SystemBarSide int side, int padding) { 504 mPaddings[side] = padding; 505 } 506 } 507 508 private static final class SystemBarConfigBuilder { 509 private int mSide; 510 private int mBarType; 511 private int mGirth; 512 private int mZOrder; 513 private boolean mHideForKeyboard; 514 setSide(@ystemBarSide int side)515 private SystemBarConfigBuilder setSide(@SystemBarSide int side) { 516 mSide = side; 517 return this; 518 } 519 setBarType(int type)520 private SystemBarConfigBuilder setBarType(int type) { 521 mBarType = type; 522 return this; 523 } 524 setGirth(int girth)525 private SystemBarConfigBuilder setGirth(int girth) { 526 mGirth = girth; 527 return this; 528 } 529 setZOrder(int zOrder)530 private SystemBarConfigBuilder setZOrder(int zOrder) { 531 mZOrder = zOrder; 532 return this; 533 } 534 setHideForKeyboard(boolean hide)535 private SystemBarConfigBuilder setHideForKeyboard(boolean hide) { 536 mHideForKeyboard = hide; 537 return this; 538 } 539 build()540 private SystemBarConfig build() { 541 return new SystemBarConfig(mSide, mBarType, mGirth, mZOrder, mHideForKeyboard); 542 } 543 } 544 } 545