Merge "Add support for unprovisioned top nav bar"

This commit is contained in:
Heemin Seog
2019-10-15 15:55:13 +00:00
committed by Android (Google) Code Review
3 changed files with 222 additions and 48 deletions

View File

@@ -0,0 +1,147 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2019 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
~ You may obtain a copy of the License at
~
~ http://www.apache.org/licenses/LICENSE-2.0
~
~ Unless required by applicable law or agreed to in writing, software
~ distributed under the License is distributed on an "AS IS" BASIS,
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
<com.android.systemui.statusbar.car.CarNavigationBarView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res-auto"
android:id="@+id/car_top_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/system_bar_background"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1">
<FrameLayout
android:id="@+id/left_hvac_container"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
>
<com.android.systemui.statusbar.car.CarNavigationButton
android:id="@+id/hvacleft"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"
systemui:broadcast="true"
systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
/>
<com.android.systemui.statusbar.hvac.AnimatedTemperatureView
android:id="@+id/lefttext"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingStart="@*android:dimen/car_padding_4"
android:paddingEnd="16dp"
android:gravity="center_vertical|start"
android:minEms="4"
android:textAppearance="@style/TextAppearance.CarStatus"
systemui:hvacAreaId="49"
systemui:hvacMaxText="@string/hvac_max_text"
systemui:hvacMaxValue="@dimen/hvac_max_value"
systemui:hvacMinText="@string/hvac_min_text"
systemui:hvacMinValue="@dimen/hvac_min_value"
systemui:hvacPivotOffset="60dp"
systemui:hvacPropertyId="358614275"
systemui:hvacTempFormat="%.0f\u00B0"
/>
</FrameLayout>
<FrameLayout
android:id="@+id/clock_container"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerInParent="true">
<com.android.systemui.statusbar.car.CarNavigationButton
android:id="@+id/qs"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"/>
<com.android.systemui.statusbar.policy.Clock
android:id="@+id/clock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:elevation="5dp"
android:singleLine="true"
android:textAppearance="@style/TextAppearance.StatusBar.Clock"/>
</FrameLayout>
<LinearLayout
android:id="@+id/system_icon_area"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:layout_toEndOf="@+id/clock_container"
android:paddingStart="@*android:dimen/car_padding_1"
android:gravity="center_vertical"
android:orientation="horizontal"
>
<include
layout="@layout/system_icons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingStart="4dp"
android:gravity="center_vertical"
/>
</LinearLayout>
<FrameLayout
android:id="@+id/right_hvac_container"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentEnd="true"
>
<com.android.systemui.statusbar.car.CarNavigationButton
android:id="@+id/hvacright"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@null"
systemui:broadcast="true"
systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"
/>
<com.android.systemui.statusbar.hvac.AnimatedTemperatureView
android:id="@+id/righttext"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingStart="16dp"
android:paddingEnd="@*android:dimen/car_padding_4"
android:gravity="center_vertical|end"
android:minEms="4"
android:textAppearance="@style/TextAppearance.CarStatus"
systemui:hvacAreaId="68"
systemui:hvacMaxText="@string/hvac_max_text"
systemui:hvacMaxValue="@dimen/hvac_max_value"
systemui:hvacMinText="@string/hvac_min_text"
systemui:hvacMinValue="@dimen/hvac_min_value"
systemui:hvacPivotOffset="60dp"
systemui:hvacPropertyId="358614275"
systemui:hvacTempFormat="%.0f\u00B0"
/>
</FrameLayout>
</RelativeLayout>
</com.android.systemui.statusbar.car.CarNavigationBarView>

View File

@@ -69,10 +69,10 @@
android:visibility="gone"
/>
<include layout="@layout/car_top_navigation_bar"
<FrameLayout
android:id="@+id/car_top_navigation_bar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
android:layout_height="wrap_content"/>
</LinearLayout>
<include layout="@layout/brightness_mirror"/>

View File

@@ -162,9 +162,11 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
private BatteryMeterView mBatteryMeterView;
private Drawable mNotificationPanelBackground;
private ViewGroup mTopNavigationBarContainer;
private ViewGroup mNavigationBarWindow;
private ViewGroup mLeftNavigationBarWindow;
private ViewGroup mRightNavigationBarWindow;
private CarNavigationBarView mTopNavigationBarView;
private CarNavigationBarView mNavigationBarView;
private CarNavigationBarView mLeftNavigationBarView;
private CarNavigationBarView mRightNavigationBarView;
@@ -176,7 +178,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
private CarFacetButtonController mCarFacetButtonController;
private ActivityManagerWrapper mActivityManagerWrapper;
private DeviceProvisionedController mDeviceProvisionedController;
private boolean mDeviceIsProvisioned = true;
private boolean mDeviceIsSetUpForUser = true;
private HvacController mHvacController;
private DrivingStateHelper mDrivingStateHelper;
private PowerManagerHelper mPowerManagerHelper;
@@ -197,6 +199,9 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
private boolean mNotificationListAtBottom;
// Was the notification list at the bottom when the user first touched the screen
private boolean mNotificationListAtBottomAtTimeOfTouch;
// To be attached to the top navigation bar (i.e. status bar) to pull down the notification
// panel.
private View.OnTouchListener mTopNavBarNotificationTouchListener;
// To be attached to the navigation bars such that they can close the notification panel if
// it's open.
private View.OnTouchListener mNavBarNotificationTouchListener;
@@ -364,7 +369,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
// get the provisioned state before calling the parent class since it's that flow that
// builds the nav bar
mDeviceProvisionedController = Dependency.get(DeviceProvisionedController.class);
mDeviceIsProvisioned = mDeviceProvisionedController.isDeviceProvisioned();
mDeviceIsSetUpForUser = mDeviceProvisionedController.isCurrentUserSetup();
// Keyboard related setup, before nav bars are created.
mHideNavBarForKeyboard = mContext.getResources().getBoolean(
@@ -376,6 +381,10 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
mScreenLifecycle = Dependency.get(ScreenLifecycle.class);
mScreenLifecycle.addObserver(mScreenObserver);
// Need to initialize HVAC controller before calling super.start - before system bars are
// created.
mHvacController = new HvacController(mContext);
super.start();
mTaskStackListener = new TaskStackListenerImpl();
mActivityManagerWrapper = ActivityManagerWrapper.getInstance();
@@ -394,25 +403,18 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
mHvacController.connectToCarService();
CarSystemUIFactory factory = SystemUIFactory.getInstance();
if (!mDeviceIsProvisioned) {
mDeviceProvisionedController.addCallback(
new DeviceProvisionedController.DeviceProvisionedListener() {
@Override
public void onDeviceProvisionedChanged() {
mHandler.post(() -> {
// on initial boot we are getting a call even though the value
// is the same so we are confirming the reset is needed
boolean deviceProvisioned =
mDeviceProvisionedController.isDeviceProvisioned();
if (mDeviceIsProvisioned != deviceProvisioned) {
mDeviceIsProvisioned = deviceProvisioned;
restartNavBars();
}
});
}
});
}
mDeviceProvisionedController.addCallback(
new DeviceProvisionedController.DeviceProvisionedListener() {
@Override
public void onUserSetupChanged() {
mHandler.post(() -> restartNavBarsIfNecessary());
}
@Override
public void onUserSwitched() {
mHandler.post(() -> restartNavBarsIfNecessary());
}
});
// Register a listener for driving state changes.
mDrivingStateHelper = new DrivingStateHelper(mContext, this::onDrivingStateChanged);
@@ -424,6 +426,14 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
mSwitchToGuestTimer = new SwitchToGuestTimer(mContext);
}
private void restartNavBarsIfNecessary() {
boolean currentUserSetup = mDeviceProvisionedController.isCurrentUserSetup();
if (mDeviceIsSetUpForUser != currentUserSetup) {
mDeviceIsSetUpForUser = currentUserSetup;
restartNavBars();
}
}
/**
* Remove all content from navbars and rebuild them. Used to allow for different nav bars
* before and after the device is provisioned. . Also for change of density and font size.
@@ -432,8 +442,8 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
// remove and reattach all hvac components such that we don't keep a reference to unused
// ui elements
mHvacController.removeAllComponents();
addTemperatureViewToController(mStatusBarWindow);
mCarFacetButtonController.removeAll();
if (mNavigationBarWindow != null) {
mNavigationBarWindow.removeAllViews();
mNavigationBarView = null;
@@ -527,7 +537,6 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
@Override
protected void makeStatusBarView(@Nullable RegisterStatusBarResult result) {
super.makeStatusBarView(result);
mHvacController = new HvacController(mContext);
CarSystemUIFactory factory = SystemUIFactory.getInstance();
mCarFacetButtonController = factory.getCarDependencyComponent()
@@ -552,7 +561,8 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
* touch listeners needed for opening and closing the notification panel
*/
private void connectNotificationsUI() {
// Attached to the status bar to detect pull down of the notification shade.
// Attached to the top navigation bar (i.e. status bar) to detect pull down of the
// notification shade.
GestureDetector openGestureDetector = new GestureDetector(mContext,
new OpenNotificationGestureListener() {
@Override
@@ -585,6 +595,18 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
GestureDetector handleBarCloseNotificationGestureDetector = new GestureDetector(mContext,
new HandleBarCloseNotificationGestureListener());
mTopNavBarNotificationTouchListener = (v, event) -> {
if (!mDeviceIsSetUpForUser) {
return true;
}
boolean consumed = openGestureDetector.onTouchEvent(event);
if (consumed) {
return true;
}
maybeCompleteAnimation(event);
return true;
};
mNavBarNotificationTouchListener =
(v, event) -> {
boolean consumed = navBarCloseNotificationGestureDetector.onTouchEvent(event);
@@ -595,21 +617,6 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
return true;
};
// The following are the ui elements that the user would call the status bar.
// This will set the status bar so it they can make call backs.
CarNavigationBarView topBar = mStatusBarWindow.findViewById(R.id.car_top_bar);
topBar.setStatusBar(this);
topBar.setStatusBarWindowTouchListener((v1, event1) -> {
boolean consumed = openGestureDetector.onTouchEvent(event1);
if (consumed) {
return true;
}
maybeCompleteAnimation(event1);
return true;
}
);
mNotificationClickHandlerFactory = new NotificationClickHandlerFactory(mBarService);
mNotificationClickHandlerFactory.registerClickListener((launchResult, alertEntry) -> {
if (launchResult == ActivityManager.START_TASK_TO_FRONT
@@ -916,23 +923,30 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
}
private void buildNavBarContent() {
// Always build top bar.
buildTopBar((mDeviceIsSetUpForUser) ? R.layout.car_top_navigation_bar :
R.layout.car_top_navigation_bar_unprovisioned);
if (mShowBottom) {
buildBottomBar((mDeviceIsProvisioned) ? R.layout.car_navigation_bar :
buildBottomBar((mDeviceIsSetUpForUser) ? R.layout.car_navigation_bar :
R.layout.car_navigation_bar_unprovisioned);
}
if (mShowLeft) {
buildLeft((mDeviceIsProvisioned) ? R.layout.car_left_navigation_bar :
buildLeft((mDeviceIsSetUpForUser) ? R.layout.car_left_navigation_bar :
R.layout.car_left_navigation_bar_unprovisioned);
}
if (mShowRight) {
buildRight((mDeviceIsProvisioned) ? R.layout.car_right_navigation_bar :
buildRight((mDeviceIsSetUpForUser) ? R.layout.car_right_navigation_bar :
R.layout.car_right_navigation_bar_unprovisioned);
}
}
private void buildNavBarWindows() {
mTopNavigationBarContainer = mStatusBarWindow
.findViewById(R.id.car_top_navigation_bar_container);
if (mShowBottom) {
mNavigationBarWindow = (ViewGroup) View.inflate(mContext,
R.layout.navigation_bar_window, null);
@@ -1054,6 +1068,19 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
mWindowManager.removeView(mNavigationBarWindow);
}
private void buildTopBar(int layout) {
mTopNavigationBarContainer.removeAllViews();
View.inflate(mContext, layout, mTopNavigationBarContainer);
mTopNavigationBarView = (CarNavigationBarView) mTopNavigationBarContainer.getChildAt(0);
if (mTopNavigationBarView == null) {
Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_top_navigation_bar");
throw new RuntimeException("Unable to build top nav bar due to missing layout");
}
mTopNavigationBarView.setStatusBar(this);
addTemperatureViewToController(mTopNavigationBarView);
mTopNavigationBarView.setStatusBarWindowTouchListener(mTopNavBarNotificationTouchListener);
}
private void buildBottomBar(int layout) {
// SystemUI requires that the navigation bar view have a parent. Since the regular
// StatusBar inflates navigation_bar_window as this parent view, use the same view for the
@@ -1062,7 +1089,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
mNavigationBarView = (CarNavigationBarView) mNavigationBarWindow.getChildAt(0);
if (mNavigationBarView == null) {
Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_navigation_bar");
throw new RuntimeException("Unable to build botom nav bar due to missing layout");
throw new RuntimeException("Unable to build bottom nav bar due to missing layout");
}
mNavigationBarView.setStatusBar(this);
addTemperatureViewToController(mNavigationBarView);
@@ -1073,7 +1100,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
View.inflate(mContext, layout, mLeftNavigationBarWindow);
mLeftNavigationBarView = (CarNavigationBarView) mLeftNavigationBarWindow.getChildAt(0);
if (mLeftNavigationBarView == null) {
Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_navigation_bar");
Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_left_navigation_bar");
throw new RuntimeException("Unable to build left nav bar due to missing layout");
}
mLeftNavigationBarView.setStatusBar(this);
@@ -1086,7 +1113,7 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
View.inflate(mContext, layout, mRightNavigationBarWindow);
mRightNavigationBarView = (CarNavigationBarView) mRightNavigationBarWindow.getChildAt(0);
if (mRightNavigationBarView == null) {
Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_navigation_bar");
Log.e(TAG, "CarStatusBar failed inflate for R.layout.car_right_navigation_bar");
throw new RuntimeException("Unable to build right nav bar due to missing layout");
}
mRightNavigationBarView.setStatusBar(this);