Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1a13af51 authored by Heemin Seog's avatar Heemin Seog
Browse files

DO NOT MERGE Add support for unprovisioned top nav bar

Also listen for changes to user setup rather than device provisioned

Bug: 140748928
Test: manual with custom SUW apk
Change-Id: Iabab489269d3dbfafd150a919020ac7921e45768
parent c60e0323
Loading
Loading
Loading
Loading
+147 −0
Original line number Diff line number Diff line
<?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>
+3 −3
Original line number Diff line number Diff line
@@ -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"/>
+72 −45
Original line number Diff line number Diff line
@@ -109,9 +109,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;
@@ -123,7 +125,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;
@@ -144,6 +146,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;
@@ -193,7 +198,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(
@@ -205,6 +210,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();
@@ -223,25 +232,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();
                    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);
@@ -253,6 +255,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.
@@ -261,8 +271,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;
@@ -356,7 +366,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()
@@ -381,7 +390,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
@@ -414,9 +424,11 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
        GestureDetector handleBarCloseNotificationGestureDetector = new GestureDetector(mContext,
                new HandleBarCloseNotificationGestureListener());

        mNavBarNotificationTouchListener =
                (v, event) -> {
                    boolean consumed = navBarCloseNotificationGestureDetector.onTouchEvent(event);
        mTopNavBarNotificationTouchListener = (v, event) -> {
            if (!mDeviceIsSetUpForUser) {
                return true;
            }
            boolean consumed = openGestureDetector.onTouchEvent(event);
            if (consumed) {
                return true;
            }
@@ -424,20 +436,15 @@ 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);
        mNavBarNotificationTouchListener =
                (v, event) -> {
                    boolean consumed = navBarCloseNotificationGestureDetector.onTouchEvent(event);
                    if (consumed) {
                        return true;
                    }
                    maybeCompleteAnimation(event1);
                    maybeCompleteAnimation(event);
                    return true;
                }
        );
                };

        mNotificationClickHandlerFactory = new NotificationClickHandlerFactory(
                mBarService,
@@ -745,23 +752,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);
@@ -883,6 +897,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
@@ -891,7 +918,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);
@@ -902,7 +929,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);
@@ -915,7 +942,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);