Add addition toolbar features needed by settings

This includes:
- Support for custom views for MenuItems
- A performClick() on MenuItems for testing
- A NavButtonStyle for changing the back button to a close button
- Reversing the order MenuItems are displayed in
- More getters for properties of MenuItems

Bug: 140301293
Test: Manually, and Settings' unit tests
Change-Id: Ie5d8323e63a2c7fbb7bbe7f30a388f0379753720
diff --git a/car-chassis-lib/res/color/car_ui_toolbar_menu_item_icon_color.xml b/car-chassis-lib/res/color/car_ui_toolbar_menu_item_icon_color.xml
new file mode 100644
index 0000000..d6c7657
--- /dev/null
+++ b/car-chassis-lib/res/color/car_ui_toolbar_menu_item_icon_color.xml
@@ -0,0 +1,21 @@
+<?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.
+  -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="@color/car_ui_tab_selected_color" android:state_enabled="true"/>
+    <item android:color="@color/car_ui_tab_unselected_color"/>
+</selector>
diff --git a/car-chassis-lib/res/drawable/car_ui_toolbar_menu_item_divider.xml b/car-chassis-lib/res/drawable/car_ui_toolbar_menu_item_divider.xml
new file mode 100644
index 0000000..70f32c5
--- /dev/null
+++ b/car-chassis-lib/res/drawable/car_ui_toolbar_menu_item_divider.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~
+  ~ Copyright (C) 2019 Google Inc.
+  ~
+  ~ 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.
+  ~
+ -->
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+    <size
+        android:width="@dimen/car_ui_toolbar_menu_item_margin"/>
+</shape>
diff --git a/car-chassis-lib/res/layout-port/car_ui_toolbar.xml b/car-chassis-lib/res/layout-port/car_ui_toolbar.xml
index a0f0f5c..aedecc8 100644
--- a/car-chassis-lib/res/layout-port/car_ui_toolbar.xml
+++ b/car-chassis-lib/res/layout-port/car_ui_toolbar.xml
@@ -49,7 +49,8 @@
             android:layout_width="@dimen/car_ui_toolbar_icon_size"
             android:layout_height="@dimen/car_ui_toolbar_icon_size"
             android:layout_gravity="center"
-            android:scaleType="fitXY"/>
+            android:scaleType="fitXY"
+            style="@style/Widget.CarUi.Toolbar.NavIcon"/>
         <ImageView
             android:id="@+id/logo"
             android:layout_width="@dimen/car_ui_toolbar_icon_size"
@@ -94,6 +95,8 @@
         android:layout_width="wrap_content"
         android:layout_height="0dp"
         android:orientation="horizontal"
+        android:divider="@drawable/car_ui_toolbar_menu_item_divider"
+        android:showDividers="beginning|middle|end"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintBottom_toTopOf="@id/row_separator"
         app:layout_constraintEnd_toStartOf="@id/car_ui_toolbar_overflow_button"/>
@@ -114,7 +117,7 @@
             android:layout_height="@dimen/car_ui_primary_icon_size"
             android:layout_gravity="center"
             android:background="@drawable/car_ui_toolbar_icon_background"
-            android:tint="@color/car_ui_toolbar_icon_tint"
+            android:tint="@color/car_ui_toolbar_menu_item_icon_color"
             android:tintMode="src_in"/>
     </FrameLayout>
 
diff --git a/car-chassis-lib/res/layout/car_ui_search_view.xml b/car-chassis-lib/res/layout/car_ui_search_view.xml
index e9edb95..cdfa4b9 100644
--- a/car-chassis-lib/res/layout/car_ui_search_view.xml
+++ b/car-chassis-lib/res/layout/car_ui_search_view.xml
@@ -19,15 +19,20 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:app="http://schemas.android.com/apk/res-auto">
 
-    <ImageView
-        android:id="@+id/icon"
+    <FrameLayout
         android:layout_width="@dimen/car_ui_touch_target_width"
-        android:layout_height="@dimen/car_ui_touch_target_height"
-        android:src="@drawable/car_ui_icon_search"
-        android:scaleType="center"
+        android:layout_height="@dimen/car_ui_touch_target_width"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toStartOf="parent"/>
+        app:layout_constraintStart_toStartOf="parent">
+        <ImageView
+            android:id="@+id/icon"
+            android:layout_width="@dimen/car_ui_primary_icon_size"
+            android:layout_height="@dimen/car_ui_primary_icon_size"
+            android:layout_gravity="center"
+            android:src="@drawable/car_ui_icon_search"
+            android:scaleType="fitCenter"/>
+    </FrameLayout>
 
     <EditText
         android:id="@+id/search_bar"
@@ -44,14 +49,19 @@
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintEnd_toEndOf="parent"/>
 
-    <ImageView
+    <FrameLayout
         android:id="@+id/search_close"
-        android:layout_width="@dimen/car_ui_touch_target_width"
+        android:layout_width="@dimen/car_ui_touch_target_height"
         android:layout_height="@dimen/car_ui_touch_target_height"
-        android:background="@drawable/car_ui_toolbar_icon_background"
-        android:src="@drawable/car_ui_icon_close"
-        android:scaleType="center"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toEndOf="parent"/>
+        app:layout_constraintEnd_toEndOf="parent">
+        <ImageView
+            android:layout_width="@dimen/car_ui_primary_icon_size"
+            android:layout_height="@dimen/car_ui_primary_icon_size"
+            android:layout_gravity="center"
+            android:background="@drawable/car_ui_toolbar_icon_background"
+            android:src="@drawable/car_ui_icon_close"
+            android:scaleType="fitCenter"/>
+    </FrameLayout>
 </merge>
diff --git a/car-chassis-lib/res/layout/car_ui_tab_item.xml b/car-chassis-lib/res/layout/car_ui_tab_item.xml
index 62f4ac7..b387ae3 100644
--- a/car-chassis-lib/res/layout/car_ui_tab_item.xml
+++ b/car-chassis-lib/res/layout/car_ui_tab_item.xml
@@ -22,7 +22,8 @@
         android:layout_width="@dimen/car_ui_tab_icon_width"
         android:layout_height="@dimen/car_ui_tab_icon_height"
         android:scaleType="fitCenter"
-        android:tint="@color/car_ui_tab_item_selector"/>
+        android:tint="@color/car_ui_tab_item_selector"
+        android:tintMode="src_in"/>
     <TextView
         android:id="@+id/car_ui_tab_item_text"
         android:layout_width="@dimen/car_ui_tab_text_width"
diff --git a/car-chassis-lib/res/layout/car_ui_toolbar.xml b/car-chassis-lib/res/layout/car_ui_toolbar.xml
index 2e21b2d..e3bcb73 100644
--- a/car-chassis-lib/res/layout/car_ui_toolbar.xml
+++ b/car-chassis-lib/res/layout/car_ui_toolbar.xml
@@ -80,6 +80,8 @@
         android:layout_width="wrap_content"
         android:layout_height="0dp"
         android:orientation="horizontal"
+        android:divider="@drawable/car_ui_toolbar_menu_item_divider"
+        android:showDividers="beginning|middle|end"
         app:layout_constraintTop_toTopOf="parent"
         app:layout_constraintBottom_toTopOf="@+id/bottom_styleable"
         app:layout_constraintEnd_toStartOf="@+id/car_ui_toolbar_overflow_button"/>
diff --git a/car-chassis-lib/res/layout/car_ui_toolbar_menu_item_icon.xml b/car-chassis-lib/res/layout/car_ui_toolbar_menu_item_icon.xml
index 4285b89..522acd7 100644
--- a/car-chassis-lib/res/layout/car_ui_toolbar_menu_item_icon.xml
+++ b/car-chassis-lib/res/layout/car_ui_toolbar_menu_item_icon.xml
@@ -18,8 +18,6 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="@dimen/car_ui_touch_target_width"
     android:layout_height="@dimen/car_ui_touch_target_height"
-    android:layout_marginLeft="@dimen/car_ui_toolbar_menu_item_margin"
-    android:layout_marginRight="@dimen/car_ui_toolbar_menu_item_margin"
     android:layout_gravity="center_vertical">
     <ImageView
         android:id="@+id/car_ui_toolbar_menu_item_icon"
@@ -27,6 +25,6 @@
         android:layout_height="@dimen/car_ui_primary_icon_size"
         android:layout_gravity="center"
         android:background="@drawable/car_ui_toolbar_icon_background"
-        android:tint="@color/car_ui_toolbar_icon_tint"
+        android:tint="@color/car_ui_toolbar_menu_item_icon_color"
         android:tintMode="src_in"/>
 </FrameLayout>
diff --git a/car-chassis-lib/res/layout/car_ui_toolbar_menu_item_switch.xml b/car-chassis-lib/res/layout/car_ui_toolbar_menu_item_switch.xml
index 6725252..cfa3e1d 100644
--- a/car-chassis-lib/res/layout/car_ui_toolbar_menu_item_switch.xml
+++ b/car-chassis-lib/res/layout/car_ui_toolbar_menu_item_switch.xml
@@ -18,8 +18,6 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="@dimen/car_ui_touch_target_width"
     android:layout_height="@dimen/car_ui_touch_target_height"
-    android:layout_marginLeft="@dimen/car_ui_toolbar_menu_item_margin"
-    android:layout_marginRight="@dimen/car_ui_toolbar_menu_item_margin"
     android:layout_gravity="center_vertical">
     <Switch
         android:id="@+id/car_ui_toolbar_menu_item_switch"
diff --git a/car-chassis-lib/res/layout/car_ui_toolbar_menu_item_text.xml b/car-chassis-lib/res/layout/car_ui_toolbar_menu_item_text.xml
index bfe93ec..aaee10a 100644
--- a/car-chassis-lib/res/layout/car_ui_toolbar_menu_item_text.xml
+++ b/car-chassis-lib/res/layout/car_ui_toolbar_menu_item_text.xml
@@ -20,6 +20,4 @@
     style="@style/Widget.CarUi.Toolbar.TextButton"
     android:layout_width="wrap_content"
     android:layout_height="match_parent"
-    android:layout_marginLeft="@dimen/car_ui_toolbar_menu_item_margin"
-    android:layout_marginRight="@dimen/car_ui_toolbar_menu_item_margin"
     android:layout_gravity="center_vertical"/>
diff --git a/car-chassis-lib/res/values/attrs.xml b/car-chassis-lib/res/values/attrs.xml
index 6dc11a8..a770947 100644
--- a/car-chassis-lib/res/values/attrs.xml
+++ b/car-chassis-lib/res/values/attrs.xml
@@ -32,6 +32,11 @@
         </attr>
         <!-- Whether or not the toolbar should have a background. Default true. -->
         <attr name="showBackground" format="boolean"/>
+        <!-- Mode of the navigation button See the Toolbar.NavButtonMode enum for more information -->
+        <attr name="navButtonMode" format="enum">
+            <enum name="back" value="0"/>
+            <enum name="close" value="1"/>
+        </attr>
     </declare-styleable>
 
     <!-- Theme attribute to specifying a default style for all CarUiToolbars -->
diff --git a/car-chassis-lib/res/values/styles.xml b/car-chassis-lib/res/values/styles.xml
index 6e9a643..cf49c05 100644
--- a/car-chassis-lib/res/values/styles.xml
+++ b/car-chassis-lib/res/values/styles.xml
@@ -19,6 +19,8 @@
 
     <style name="Widget.CarUi" parent="android:Widget.DeviceDefault"/>
 
+    <style name="Widget.CarUi.Button.Borderless.Colored" parent="android:Widget.DeviceDefault.Button.Borderless.Colored"/>
+
     <style name="Widget.CarUi.Toolbar"/>
 
     <style name="Widget.CarUi.Toolbar.NavIcon">
@@ -26,11 +28,7 @@
         <item name="android:src">@drawable/car_ui_icon_arrow_back</item>
     </style>
 
-    <style name="Widget.CarUi.Toolbar.TextButton">
-        <item name="android:background">?android:attr/selectableItemBackground</item>
-        <item name="android:textColor">?android:attr/colorAccent</item>
-        <item name="android:textAppearance">@style/TextAppearance.CarUi.Widget.Toolbar.Tab</item>
-    </style>
+    <style name="Widget.CarUi.Toolbar.TextButton" parent="Widget.CarUi.Button.Borderless.Colored"/>
 
     <style name="Widget.CarUi.PagedRecyclerView"/>
     <style name="Widget.CarUi.PagedRecyclerView.NestedRecyclerView"/>
@@ -129,7 +127,7 @@
         <item name="android:textSize">@dimen/car_ui_preference_edit_text_dialog_message_text_size</item>
     </style>
 
-    <style name="TextAppearance.CarUi.Widget"/>
+    <style name="TextAppearance.CarUi.Widget" parent="android:TextAppearance.DeviceDefault.Widget"/>
 
     <style name="TextAppearance.CarUi.Widget.Toolbar"/>
 
@@ -142,6 +140,7 @@
     <style name="TextAppearance.CarUi.Widget.Toolbar.Tab">
         <item name="android:textSize">24sp</item>
         <item name="android:letterSpacing">@dimen/car_ui_letter_spacing_body3</item>
+        <item name="android:textColor">@color/car_ui_tab_item_selector</item>
     </style>
 
 </resources>
diff --git a/car-chassis-lib/src/com/android/car/ui/toolbar/MenuItem.java b/car-chassis-lib/src/com/android/car/ui/toolbar/MenuItem.java
index f084320..7a57e36 100644
--- a/car-chassis-lib/src/com/android/car/ui/toolbar/MenuItem.java
+++ b/car-chassis-lib/src/com/android/car/ui/toolbar/MenuItem.java
@@ -46,26 +46,39 @@
  */
 public class MenuItem {
 
-    private Context mContext;
+    private final Context mContext;
+    private final boolean mIsCheckable;
+    private final int mCustomLayoutId;
+    private final int mId;
+    private final View.OnClickListener mViewOnClickListener = v -> {
+        if (isCheckable()) {
+            setChecked(!isChecked());
+        }
+
+        if (getOnClickListener() != null) {
+            getOnClickListener().onClick(this);
+        }
+    };
+
     private Listener mListener;
     private CharSequence mTitle;
     private Drawable mIcon;
     private OnClickListener mOnClickListener;
     private DisplayBehavior mDisplayBehavior;
     private boolean mIsEnabled;
-    private boolean mIsCheckable;
     private boolean mIsChecked;
-    private int mId;
     private View mView;
 
+
     private MenuItem(Builder builder) {
         mContext = builder.mContext;
+        mIsCheckable = builder.mIsCheckable;
+        mCustomLayoutId = builder.mCustomLayoutId;
         mTitle = builder.mTitle;
         mIcon = builder.mIcon;
         mOnClickListener = builder.mOnClickListener;
         mDisplayBehavior = builder.mDisplayBehavior;
         mIsEnabled = builder.mIsEnabled;
-        mIsCheckable = builder.mIsCheckable;
         mIsChecked = builder.mIsChecked;
         mId = builder.mId;
     }
@@ -109,12 +122,10 @@
         mIsChecked = checked;
 
         if (mView != null) {
-            Switch s = mView.requireViewById(R.id.car_ui_toolbar_menu_item_switch);
-            s.setChecked(mIsChecked);
-        }
-
-        if (isEnabled() && getOnClickListener() != null) {
-            getOnClickListener().onClick(this);
+            Switch s = mView.findViewById(R.id.car_ui_toolbar_menu_item_switch);
+            if (s != null) {
+                s.setChecked(mIsChecked);
+            }
         }
     }
 
@@ -154,6 +165,11 @@
         mOnClickListener = listener;
     }
 
+    /** Calls the {@link OnClickListener}. */
+    public void performClick() {
+        mViewOnClickListener.onClick(null);
+    }
+
     /** Gets the current {@link DisplayBehavior} */
     public DisplayBehavior getDisplayBehavior() {
         return mDisplayBehavior;
@@ -164,6 +180,16 @@
         return mIcon;
     }
 
+    /**
+     * Gets the custom view specified by {@link Builder#setCustomLayout(int)}
+     *
+     * @return null if {@link Builder#setCustomLayout(int)} was not used when
+     * building this MenuItem.
+     */
+    public View getView() {
+        return mView;
+    }
+
     int getId() {
         return mId;
     }
@@ -185,6 +211,7 @@
         private boolean mIsEnabled = true;
         private boolean mIsCheckable = false;
         private boolean mIsChecked = false;
+        private int mCustomLayoutId;
         private int mId;
 
         public Builder(Context c) {
@@ -214,6 +241,21 @@
             return this;
         }
 
+        /**
+         * Sets a custom layout to use for this MenuItem.
+         *
+         * <p>Should not be used in non-system (GAS) apps, as the OEM will not be able to
+         * customize the layout.
+         */
+        public Builder setCustomLayout(int resId) {
+            if (mIsCheckable) {
+                throw new IllegalStateException("Cannot have a checkable custom layout MenuItem");
+            }
+
+            mCustomLayoutId = resId;
+            return this;
+        }
+
         /** Sets the {@link OnClickListener} */
         public Builder setOnClickListener(OnClickListener listener) {
             mOnClickListener = listener;
@@ -252,6 +294,11 @@
                 throw new IllegalStateException(
                         "Currently we don't support a checkable overflow item");
             }
+
+            if (mCustomLayoutId != 0) {
+                throw new IllegalStateException("Cannot have a checkable custom layout MenuItem");
+            }
+
             mIsCheckable = true;
             return this;
         }
@@ -332,11 +379,11 @@
         LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
 
-        if (isCheckable()) {
+        if (mCustomLayoutId != 0) {
+            mView = inflater.inflate(mCustomLayoutId, parent, false);
+        } else if (isCheckable()) {
             mView = inflater.inflate(
                     R.layout.car_ui_toolbar_menu_item_switch, parent, false);
-            Switch s = mView.requireViewById(R.id.car_ui_toolbar_menu_item_switch);
-            s.setChecked(isChecked());
         } else if (getIcon() != null) {
             mView = inflater.inflate(
                     R.layout.car_ui_toolbar_menu_item_icon, parent, false);
@@ -345,8 +392,12 @@
         } else {
             mView = (Button) inflater.inflate(
                     R.layout.car_ui_toolbar_menu_item_text, parent, false);
-            Button button = mView.requireViewById(R.id.car_ui_toolbar_menu_item_text);
-            button.setText(getTitle());
+            setTitle(getTitle());
+        }
+
+        // Both custom and switch layouts can be checkable
+        if (isCheckable()) {
+            setChecked(isChecked());
         }
 
         if (getId() != 0) {
@@ -354,18 +405,7 @@
         }
 
         recursiveSetEnabled(mView, isEnabled());
-        mView.setOnClickListener(v -> {
-            Switch s = v.findViewById(R.id.car_ui_toolbar_menu_item_switch);
-            if (s != null) {
-                s.toggle();
-                setChecked(s.isChecked());
-            }
-
-            if (getOnClickListener() != null) {
-                getOnClickListener().onClick(this);
-            }
-        });
-
+        mView.setOnClickListener(mViewOnClickListener);
         return mView;
     }
 
diff --git a/car-chassis-lib/src/com/android/car/ui/toolbar/TabLayout.java b/car-chassis-lib/src/com/android/car/ui/toolbar/TabLayout.java
index 16360a6..066da0f 100644
--- a/car-chassis-lib/src/com/android/car/ui/toolbar/TabLayout.java
+++ b/car-chassis-lib/src/com/android/car/ui/toolbar/TabLayout.java
@@ -197,13 +197,10 @@
     }
 
     private static class TabAdapter extends BaseAdapter {
-        private static final int MEDIUM_WEIGHT = 500;
         private final Context mContext;
         private final TabLayout mTabLayout;
         @LayoutRes
         private final int mTabItemLayoutRes;
-        private final Typeface mUnselectedTypeface;
-        private final Typeface mSelectedTypeface;
         private final List<Tab> mTabList;
 
         private TabAdapter(Context context, @LayoutRes int res, TabLayout tabLayout) {
@@ -211,9 +208,6 @@
             mContext = context;
             mTabItemLayoutRes = res;
             mTabLayout = tabLayout;
-            mUnselectedTypeface = Typeface.defaultFromStyle(Typeface.NORMAL);
-            // TODO: add indirection to allow customization.
-            mSelectedTypeface = Typeface.create(mUnselectedTypeface, MEDIUM_WEIGHT, false);
         }
 
         private void add(@NonNull Tab tab) {
@@ -305,7 +299,8 @@
             tabItemView.setSelected(tab.mIsSelected);
             iconView.setSelected(tab.mIsSelected);
             textView.setSelected(tab.mIsSelected);
-            textView.setTypeface(tab.mIsSelected ? mSelectedTypeface : mUnselectedTypeface);
+            // TODO(b/141109269): add indirection to allow customization.
+            textView.setTypeface(null, tab.mIsSelected ? Typeface.BOLD : Typeface.NORMAL);
         }
     }
 
diff --git a/car-chassis-lib/src/com/android/car/ui/toolbar/Toolbar.java b/car-chassis-lib/src/com/android/car/ui/toolbar/Toolbar.java
index 5a33eaa..0125b4f 100644
--- a/car-chassis-lib/src/com/android/car/ui/toolbar/Toolbar.java
+++ b/car-chassis-lib/src/com/android/car/ui/toolbar/Toolbar.java
@@ -78,13 +78,6 @@
         SEARCH,
     }
 
-    /**
-     * {@link java.util.function.Consumer} is not available for non-java8 enabled Android targets.
-     */
-    private interface Consumer<T> {
-        void accept(T value);
-    }
-
     private ImageView mNavIcon;
     private ImageView mLogo;
     private ViewGroup mNavIconContainer;
@@ -99,6 +92,7 @@
     private boolean mShowMenuItemsWhileSearching;
     private View mSearchButton;
     private State mState = State.HOME;
+    private NavButtonMode mNavButtonMode = NavButtonMode.BACK;
     @NonNull
     private List<MenuItem> mMenuItems = Collections.emptyList();
     private List<MenuItem> mOverflowItems = new ArrayList<>();
@@ -171,6 +165,20 @@
                     }
                     break;
             }
+
+            switch (a.getInt(R.styleable.CarUiToolbar_navButtonMode, 0)) {
+                case 0:
+                    setNavButtonMode(NavButtonMode.BACK);
+                    break;
+                case 1:
+                    setNavButtonMode(NavButtonMode.CLOSE);
+                    break;
+                default:
+                    if (Log.isLoggable(TAG, Log.WARN)) {
+                        Log.w(TAG, "Unknown navigation button style");
+                    }
+                    break;
+            }
         } finally {
             a.recycle();
         }
@@ -271,6 +279,30 @@
     }
 
     /**
+     * An enum of possible styles the nav button could be in. All styles will still call
+     * {@link Listener#onBack()}.
+     */
+    public enum NavButtonMode {
+        /** Display the nav button as a back button */
+        BACK,
+        /** Display the nav button as a close button */
+        CLOSE
+    }
+
+    /** Sets the {@link NavButtonMode} */
+    public void setNavButtonMode(NavButtonMode style) {
+        if (style != mNavButtonMode) {
+            mNavButtonMode = style;
+            setState(mState);
+        }
+    }
+
+    /**  Gets the {@link NavButtonMode} */
+    public NavButtonMode getNavButtonMode() {
+        return mNavButtonMode;
+    }
+
+    /**
      * setBackground is disallowed, to prevent apps from deviating from the intended style too much.
      */
     @Override
@@ -314,7 +346,9 @@
                 mOverflowItems.add(item);
             } else {
                 View menuItemView = item.createView(mMenuItemsContainer);
-                mMenuItemsContainer.addView(menuItemView);
+
+                // Add views with index 0 so that they are added right-to-left
+                mMenuItemsContainer.addView(menuItemView, 0);
             }
         }
 
@@ -325,6 +359,12 @@
         setState(mState);
     }
 
+    /** Gets the {@link MenuItem MenuItems} currently displayed */
+    @NonNull
+    public List<MenuItem> getMenuItems() {
+        return mMenuItems;
+    }
+
     private void createOverflowDialog() {
         // TODO(b/140564530) Use a carui alert with a (paged)recyclerview here
         // TODO(b/140563930) Support enabled/disabled overflow items
@@ -388,7 +428,9 @@
 
         View.OnClickListener backClickListener = (v) -> forEachListener(Listener::onBack);
         mNavIcon.setVisibility(state != State.HOME ? VISIBLE : INVISIBLE);
-        mNavIcon.setImageResource(state != State.HOME ? R.drawable.car_ui_icon_arrow_back : 0);
+        mNavIcon.setImageResource(mNavButtonMode == NavButtonMode.BACK
+                ? R.drawable.car_ui_icon_arrow_back
+                : R.drawable.car_ui_icon_close);
         mLogo.setVisibility(state == State.HOME && mHasLogo ? VISIBLE : INVISIBLE);
         mNavIconContainer.setVisibility(state != State.HOME || mHasLogo ? VISIBLE : GONE);
         mNavIconContainer.setOnClickListener(state != State.HOME ? backClickListener : null);
@@ -408,6 +450,11 @@
         }
     }
 
+    /** Gets the current {@link State} of the toolbar. */
+    public State getState() {
+        return mState;
+    }
+
     /**
      * Toolbar listener.
      */
@@ -444,6 +491,13 @@
         return mListeners.remove(listener);
     }
 
+    /**
+     * {@link java.util.function.Consumer} is not available for non-java8 enabled Android targets.
+     */
+    private interface Consumer<T> {
+        void accept(T value);
+    }
+
     private void forEachListener(Consumer<Listener> callback) {
         List<Listener> listenersCopy = new ArrayList<>(mListeners);
         for (Listener listener : listenersCopy) {