Merge "Add multi-user and user-switch support to VMS publisher binding."
diff --git a/car-lib/api/system-current.txt b/car-lib/api/system-current.txt
index 9ab0716..5709b9c 100644
--- a/car-lib/api/system-current.txt
+++ b/car-lib/api/system-current.txt
@@ -707,17 +707,9 @@
 package android.car.hardware.power {
 
   public class CarPowerManager {
-    field public static final int BOOT_REASON_DOOR_OPEN = 4; // 0x4
-    field public static final int BOOT_REASON_DOOR_UNLOCK = 2; // 0x2
-    field public static final int BOOT_REASON_REMOTE_START = 5; // 0x5
-    field public static final int BOOT_REASON_TIMER = 3; // 0x3
-    field public static final int BOOT_REASON_USER_POWER_ON = 1; // 0x1
   }
 
   public static interface CarPowerManager.CarPowerStateListener {
-    method public void onStateChanged(int);
-    field public static final int SHUTDOWN_CANCELLED = 0; // 0x0
-    field public static final int SHUTDOWN_ENTER = 1; // 0x1
   }
 
 }
diff --git a/car-lib/native/include/CarPowerManager.h b/car-lib/native/include/CarPowerManager.h
index 90e77f7..22c2240 100644
--- a/car-lib/native/include/CarPowerManager.h
+++ b/car-lib/native/include/CarPowerManager.h
@@ -38,13 +38,14 @@
     //  NOTE:  The entries in this enum must match the ones in CarPowerStateListener located in
     //      packages/services/Car/car-lib/src/android/car/hardware/power/CarPowerManager.java
     enum class State {
-        kShutdownCancelled = 0,
-        kShutdownEnter = 1,
-        kWaitForVhal = 2,
-        kSuspendEnter = 3,
-        kSuspendExit = 4,
-        kOn = 5,
-        kShutdownPrepare = 6,
+        kWaitForVhal = 1,
+        kSuspendEnter = 2,
+        kSuspendExit = 3,
+        kShutdownEnter = 5,
+        kOn = 6,
+        kShutdownPrepare = 7,
+        kShutdownCancelled = 8,
+
 
         kFirst = kWaitForVhal,
         kLast = kShutdownCancelled,
diff --git a/car-lib/src/android/car/hardware/power/CarPowerManager.java b/car-lib/src/android/car/hardware/power/CarPowerManager.java
index e61a817..459b575 100644
--- a/car-lib/src/android/car/hardware/power/CarPowerManager.java
+++ b/car-lib/src/android/car/hardware/power/CarPowerManager.java
@@ -38,35 +38,15 @@
 public class CarPowerManager implements CarManagerBase {
     private final static boolean DBG = false;
     private final static String TAG = "CarPowerManager";
-    private CarPowerStateListener mListener;
-    private final ICarPower mService;
-    private CompletableFuture<Void> mFuture;
 
+    private final Object mLock = new Object();
+    private final ICarPower mService;
+
+    private CarPowerStateListener mListener;
+    private CompletableFuture<Void> mFuture;
     @GuardedBy("mLock")
     private ICarPowerStateListener mListenerToService;
 
-    private final Object mLock = new Object();
-
-    /**
-     * Deleted! Don't use.
-     */
-    public static final int BOOT_REASON_USER_POWER_ON = 1;
-    /**
-     * Deleted! Don't use.
-     */
-    public static final int BOOT_REASON_DOOR_UNLOCK = 2;
-    /**
-     * Deleted! Don't use.
-     */
-    public static final int BOOT_REASON_TIMER = 3;
-    /**
-     * Deleted! Don't use.
-     */
-    public static final int BOOT_REASON_DOOR_OPEN = 4;
-    /**
-     * Deleted! Don't use.
-     */
-    public static final int BOOT_REASON_REMOTE_START = 5;
 
     /**
      *  Applications set a {@link CarPowerStateListener} for power state event updates.
@@ -78,44 +58,41 @@
          */
 
         /**
-         * Shutdown is cancelled, return to normal state.
-         */
-        int SHUTDOWN_CANCELLED = 0;
-        /**
-         * Enter shutdown state.  CPMS is switching to WAIT_FOR_FINISHED state.
-         */
-        int SHUTDOWN_ENTER = 1;
-        /**
          * Android is up, but vendor is controlling the audio / display
          * @hide
          */
-        int WAIT_FOR_VHAL = 2;
+        int WAIT_FOR_VHAL = 1;
         /**
          * Enter suspend state.  CPMS is switching to WAIT_FOR_FINISHED state.
          * @hide
          */
-        int SUSPEND_ENTER = 3;
+        int SUSPEND_ENTER = 2;
         /**
          * Wake up from suspend.
          * @hide
          */
-        int SUSPEND_EXIT = 4;
+        int SUSPEND_EXIT = 3;
+        /**
+         * Enter shutdown state.  CPMS is switching to WAIT_FOR_FINISHED state.
+         * @hide
+         */
+        int SHUTDOWN_ENTER = 5;
         /**
          * On state
          * @hide
          */
-        int ON = 5;
+        int ON = 6;
         /**
          * State where system is getting ready for shutdown or suspend.  Application is expected to
          * cleanup and be ready to suspend
          * @hide
          */
-        int SHUTDOWN_PREPARE = 6;
-        
+        int SHUTDOWN_PREPARE = 7;
         /**
-         * Deleted! Don't use.
+         * Shutdown is cancelled, return to normal state.
+         * @hide
          */
-        void onStateChanged(int state);
+        int SHUTDOWN_CANCELLED = 8;
 
         /**
          *  Called when power state changes
@@ -184,6 +161,12 @@
     public void setListener(CarPowerStateListener listener) throws
             CarNotConnectedException, IllegalStateException {
         synchronized(mLock) {
+            if (mListener == null) {
+                // Update listener
+                mListener = listener;
+            } else {
+                throw new IllegalStateException("Listener must be cleared first");
+            }
             if (mListenerToService == null) {
                 ICarPowerStateListener listenerToService = new ICarPowerStateListener.Stub() {
                     @Override
@@ -201,12 +184,6 @@
                     Car.checkCarNotConnectedExceptionFromCarService(ex);
                 }
             }
-            if (mListener == null) {
-                // Update listener
-                mListener = listener;
-            } else {
-                throw new IllegalStateException("Listener must be cleared first");
-            }
         }
     }
 
diff --git a/car_product/overlay/frameworks/base/core/res/res/layout/resolver_different_item_header.xml b/car_product/overlay/frameworks/base/core/res/res/layout/resolver_different_item_header.xml
new file mode 100644
index 0000000..0874dde
--- /dev/null
+++ b/car_product/overlay/frameworks/base/core/res/res/layout/resolver_different_item_header.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_alwaysShow="true"
+    android:text="@string/use_a_different_app"
+    android:minHeight="56dp"
+    android:textAppearance="?attr/textAppearanceLarge"
+    android:gravity="start|center_vertical"
+    android:paddingStart="16dp"
+    android:paddingEnd="16dp"
+    android:paddingTop="8dp"
+    android:paddingBottom="8dp"
+    android:elevation="8dp"
+/>
\ No newline at end of file
diff --git a/car_product/overlay/frameworks/base/core/res/res/layout/resolver_list.xml b/car_product/overlay/frameworks/base/core/res/res/layout/resolver_list.xml
index 9d64d65..d4cf11e 100644
--- a/car_product/overlay/frameworks/base/core/res/res/layout/resolver_list.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/layout/resolver_list.xml
@@ -20,7 +20,6 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:theme="@android:style/Theme.DeviceDefault.NoActionBar"
     android:id="@id/contentPanel">
 
     <LinearLayout
diff --git a/car_product/overlay/frameworks/base/core/res/res/layout/resolver_list_with_default.xml b/car_product/overlay/frameworks/base/core/res/res/layout/resolver_list_with_default.xml
index 62d4d69..6155465 100644
--- a/car_product/overlay/frameworks/base/core/res/res/layout/resolver_list_with_default.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/layout/resolver_list_with_default.xml
@@ -20,7 +20,6 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:theme="@android:style/Theme.DeviceDefault"
     android:maxCollapsedHeight="200dp"
     android:id="@id/contentPanel">
 
@@ -146,7 +145,6 @@
             android:layout_height="1dp"
             android:background="?attr/dividerVertical"/>
 
-
         <ListView
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
diff --git a/car_product/overlay/frameworks/base/core/res/res/values/themes_device_defaults.xml b/car_product/overlay/frameworks/base/core/res/res/values/themes_device_defaults.xml
index 4f2e0fe..89d5716 100644
--- a/car_product/overlay/frameworks/base/core/res/res/values/themes_device_defaults.xml
+++ b/car_product/overlay/frameworks/base/core/res/res/values/themes_device_defaults.xml
@@ -131,4 +131,56 @@
     <style name="Theme.DeviceDefault.Light.DarkActionBar"  parent="Theme.DeviceDefault"/>
       <!-- DeviceDefault theme for the default system theme.  -->
     <style name="Theme.DeviceDefault.System" parent="Theme.DeviceDefault.Light.DarkActionBar" />
+
+    <!-- Theme used for the intent picker activity. -->
+    <style name="Theme.DeviceDefault.Resolver" parent="Theme.DeviceDefault">
+        <item name="windowEnterTransition">@empty</item>
+        <item name="windowExitTransition">@empty</item>
+        <item name="windowIsTranslucent">true</item>
+        <item name="windowNoTitle">true</item>
+        <item name="windowBackground">@color/transparent</item>
+        <item name="backgroundDimEnabled">true</item>
+        <item name="statusBarColor">@color/transparent</item>
+        <item name="windowContentOverlay">@null</item>
+        <item name="colorControlActivated">?attr/colorControlHighlight</item>
+        <item name="listPreferredItemPaddingStart">?attr/dialogPreferredPadding</item>
+        <item name="listPreferredItemPaddingEnd">?attr/dialogPreferredPadding</item>
+
+        <!-- Dialog attributes -->
+        <item name="dialogCornerRadius">@dimen/config_dialogCornerRadius</item>
+        <item name="alertDialogTheme">@style/Theme.DeviceDefault.Light.Dialog.Alert</item>
+
+        <!-- Button styles -->
+        <item name="buttonCornerRadius">@dimen/config_buttonCornerRadius</item>
+        <item name="buttonBarButtonStyle">@style/Widget.DeviceDefault.Button.ButtonBar.AlertDialog</item>
+        <item name="borderlessButtonStyle">@style/Widget.DeviceDefault.Button.Borderless.Colored</item>
+        <item name="buttonStyle">@style/Widget.DeviceDefault.Button</item>
+
+        <!-- Color palette -->
+        <item name="colorPrimary">@color/primary_device_default_light</item>
+        <item name="colorPrimaryDark">@color/primary_device_default_dark</item>
+        <item name="colorAccent">@color/accent_device_default_light</item>
+        <item name="colorError">@color/error_color_device_default_light</item>
+        <item name="colorBackgroundFloating">@color/background_floating_device_default_light</item>
+        <item name="colorButtonNormal">@color/car_highlight</item>
+        <item name="colorControlHighlight">@color/car_card_ripple_background</item>
+        <item name="colorControlNormal">@color/car_body2</item>
+        <item name="colorForeground">@color/car_card_light</item>
+        <item name="editTextColor">@color/car_body1</item>
+        <item name="textColorHint">@color/car_body2</item>
+        <item name="textColorPrimary">@color/car_body1</item>
+        <item name="textColorSecondary">@color/car_body2</item>
+
+        <!-- Progress bar attributes -->
+        <item name="colorProgressBackgroundNormal">@color/config_progress_background_tint</item>
+        <item name="progressBarCornerRadius">@dimen/config_progressBarCornerRadius</item>
+
+        <!-- Toolbar attributes -->
+        <item name="toolbarStyle">@style/Widget.DeviceDefault.Toolbar</item>
+
+        <item name="toastFrameBackground">@drawable/toast_frame</item>
+        <item name="textAppearanceListItem">@style/TextAppearance.DeviceDefault.Large</item>
+        <item name="textAppearanceListItemSmall">@style/TextAppearance.DeviceDefault.Large</item>
+        <item name="textAppearanceListItemSecondary">@style/TextAppearance.DeviceDefault.Small</item>
+    </style>
 </resources>
diff --git a/service/src/com/android/car/CarLocationService.java b/service/src/com/android/car/CarLocationService.java
index c8543fa..a16c3e3 100644
--- a/service/src/com/android/car/CarLocationService.java
+++ b/service/src/com/android/car/CarLocationService.java
@@ -160,12 +160,6 @@
     }
 
     @Override
-    public void onStateChanged(int state) {
-        throw new UnsupportedOperationException(
-                "Should not be here. This API obsolete and is not used.");
-    }
-
-    @Override
     public void onStateChanged(int state, CompletableFuture<Void> future) {
         logd("onStateChanged: " + state);
         switch (state) {
diff --git a/service/src/com/android/car/CarPowerManagementService.java b/service/src/com/android/car/CarPowerManagementService.java
index 5c744eb..0bec14c 100644
--- a/service/src/com/android/car/CarPowerManagementService.java
+++ b/service/src/com/android/car/CarPowerManagementService.java
@@ -70,6 +70,8 @@
     private HandlerThread mHandlerThread;
     @GuardedBy("this")
     private PowerHandler mHandler;
+    @GuardedBy("this")
+    private boolean mTimerActive;
     private int mNextWakeupSec = 0;
     private int mTokenValue = 1;
     private boolean mShutdownOnFinish = false;
@@ -244,7 +246,7 @@
 
     private void handleWaitForVhal(CpmsState state) {
         int carPowerStateListenerState = state.mCarPowerStateListenerState;
-        sendPowerManagerEvent(carPowerStateListenerState, false);
+        sendPowerManagerEvent(carPowerStateListenerState);
         // Inspect CarPowerStateListenerState to decide which message to send via VHAL
         switch (carPowerStateListenerState) {
             case CarPowerStateListener.WAIT_FOR_VHAL:
@@ -261,7 +263,7 @@
 
     private void handleOn() {
         mSystemInterface.setDisplayState(true);
-        sendPowerManagerEvent(CarPowerStateListener.ON, false);
+        sendPowerManagerEvent(CarPowerStateListener.ON);
         mHal.sendOn();
     }
 
@@ -273,7 +275,7 @@
                 || !newState.mCanSleep;
         if (newState.mCanPostpone) {
             Log.i(CarLog.TAG_POWER, "starting shutdown postpone");
-            sendPowerManagerEvent(CarPowerStateListener.SHUTDOWN_PREPARE, true);
+            sendPowerManagerEvent(CarPowerStateListener.SHUTDOWN_PREPARE);
             mHal.sendShutdownPrepare();
             doHandlePreprocessing();
         } else {
@@ -290,7 +292,7 @@
     }
 
     private void handleWaitForFinish(CpmsState state) {
-        sendPowerManagerEvent(state.mCarPowerStateListenerState, false);
+        sendPowerManagerEvent(state.mCarPowerStateListenerState);
         switch (state.mCarPowerStateListenerState) {
             case CarPowerStateListener.SUSPEND_ENTER:
                 mHal.sendSleepEntry(mNextWakeupSec);
@@ -312,10 +314,13 @@
 
     @GuardedBy("this")
     private void releaseTimerLocked() {
-        if (mTimer != null) {
-            mTimer.cancel();
+        synchronized (this) {
+            if (mTimer != null) {
+                mTimer.cancel();
+            }
+            mTimer = null;
+            mTimerActive = false;
         }
-        mTimer = null;
     }
 
     private void doHandlePreprocessing() {
@@ -326,6 +331,7 @@
             mProcessingStartTime = SystemClock.elapsedRealtime();
             releaseTimerLocked();
             mTimer = new Timer();
+            mTimerActive = true;
             mTimer.scheduleAtFixedRate(
                     new ShutdownProcessingTimerTask(pollingCount),
                     0 /*delay*/,
@@ -333,26 +339,46 @@
         }
     }
 
-    private void sendPowerManagerEvent(int newState, boolean useTokens) {
+    private void sendPowerManagerEvent(int newState) {
+        // Based on new state, do we need to use tokens? In current design, SHUTDOWN_PREPARE
+        // is the only state where we need to maintain callback from listener components.
+        boolean useTokens = (newState == CarPowerStateListener.SHUTDOWN_PREPARE);
+
+        // First lets generate the tokens
+        generateTokensList(useTokens);
+
+        // Now lets notify listeners that we are making a state transition
+        sendBroadcasts(newState, useTokens);
+    }
+
+    private void generateTokensList(boolean useTokens) {
         synchronized (mPowerManagerListenerTokens) {
             if (useTokens) {
                 mPowerManagerListenerTokens.clear();
             }
             int i = mPowerManagerListeners.beginBroadcast();
             while (i-- > 0) {
+                ICarPowerStateListener listener = mPowerManagerListeners.getBroadcastItem(i);
+                if (useTokens) {
+                    mPowerManagerListenerTokens.put(listener.asBinder(), mTokenValue);
+                    mTokenValue++;
+                }
+            }
+            mPowerManagerListeners.finishBroadcast();
+        }
+    }
+
+    private void sendBroadcasts(int newState, boolean useTokens) {
+        synchronized (mPowerManagerListenerTokens) {
+            int i = mPowerManagerListeners.beginBroadcast();
+            while (i-- > 0) {
+                ICarPowerStateListener listener = mPowerManagerListeners.getBroadcastItem(i);
+                int token = useTokens ? mPowerManagerListenerTokens.get(listener.asBinder()) : 0;
                 try {
-                    int token = 0;
-                    ICarPowerStateListener listener = mPowerManagerListeners.getBroadcastItem(i);
-                    if (useTokens) {
-                        mPowerManagerListenerTokens.put(listener.asBinder(), mTokenValue);
-                        listener.onStateChanged(newState, mTokenValue);
-                        mTokenValue++;
-                    } else {
-                        listener.onStateChanged(newState, 0);
-                    }
+                    listener.onStateChanged(newState, token);
                 } catch (RemoteException e) {
                     // Its likely the connection snapped. Let binder death handle the situation.
-                    Log.e(CarLog.TAG_POWER, "onStateChanged calling failed: " + e);
+                    Log.e(CarLog.TAG_POWER, "onStateChanged() call failed: " + e, e);
                 }
             }
             mPowerManagerListeners.finishBroadcast();
@@ -472,7 +498,7 @@
     public void registerListener(ICarPowerStateListener listener) {
         ICarImpl.assertPermission(mContext, Car.PERMISSION_CAR_POWER);
         mPowerManagerListeners.register(listener);
-        // TODO:  Need to send current state to newly registered listener?  If so, need to handle
+        // TODO: Need to send current state to newly registered listener?  If so, need to handle
         //          token for SHUTDOWN_PREPARE state
     }
 
@@ -630,16 +656,20 @@
 
         @Override
         public void run() {
-            mCurrentCount++;
-            if (mCurrentCount > mExpirationCount) {
-                PowerHandler handler;
-                synchronized (CarPowerManagementService.this) {
+            synchronized (this) {
+                if (!mTimerActive) {
+                    // Ignore timer expiration since we got cancelled
+                    return;
+                }
+                mCurrentCount++;
+                if (mCurrentCount > mExpirationCount) {
+                    PowerHandler handler;
                     releaseTimerLocked();
                     handler = mHandler;
+                    handler.handleProcessingComplete();
+                } else {
+                    mHal.sendShutdownPostpone(SHUTDOWN_EXTEND_MAX_MS);
                 }
-                handler.handleProcessingComplete();
-            } else {
-                mHal.sendShutdownPostpone(SHUTDOWN_EXTEND_MAX_MS);
             }
         }
     }
diff --git a/service/src/com/android/car/garagemode/Controller.java b/service/src/com/android/car/garagemode/Controller.java
index 33c10bc..e08ad2f 100644
--- a/service/src/com/android/car/garagemode/Controller.java
+++ b/service/src/com/android/car/garagemode/Controller.java
@@ -93,12 +93,6 @@
     }
 
     @Override
-    public void onStateChanged(int state) {
-        throw new UnsupportedOperationException(
-                "Should not be here. This API obsolete and is not used.");
-    }
-
-    @Override
     public void onStateChanged(int state, CompletableFuture<Void> future) {
         switch (state) {
             case CarPowerStateListener.SHUTDOWN_CANCELLED:
diff --git a/tests/EmbeddedKitchenSinkApp/res/layout/hvac_test.xml b/tests/EmbeddedKitchenSinkApp/res/layout/hvac_test.xml
index d525be8..e28f273 100644
--- a/tests/EmbeddedKitchenSinkApp/res/layout/hvac_test.xml
+++ b/tests/EmbeddedKitchenSinkApp/res/layout/hvac_test.xml
@@ -47,7 +47,8 @@
                 android:layout_weight="1"
                 android:textSize="@dimen/hvacTextSize"/>
         </LinearLayout>
-            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+
+        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:orientation="vertical"
             android:gravity="center"
             android:layout_height="match_parent"
@@ -59,7 +60,7 @@
                 android:id="@+id/btnDTempUp"
                 android:layout_height="@dimen/hvacBtnHeight"
                 android:layout_width ="250dp"
-                android:text="@string/hvac_tempUp"
+                android:text="@string/hvac_dTempUp"
                 android:textSize="@dimen/hvacTextSize"/>
 
             <TextView
@@ -74,7 +75,38 @@
                 android:id="@+id/btnDTempDn"
                 android:layout_height="@dimen/hvacBtnHeight"
                 android:layout_width ="250dp"
-                android:text="@string/hvac_tempDn"
+                android:text="@string/hvac_dTempDn"
+                android:textSize="@dimen/hvacTextSize"/>
+        </LinearLayout>
+
+        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                      android:gravity="center"
+                      android:layout_height="match_parent"
+                      android:layout_weight="1"
+                      android:layout_width = "wrap_content"
+                      android:orientation="vertical">
+
+            <Button
+                android:clickable="false"
+                android:id="@+id/btnATempUp"
+                android:layout_height="@dimen/hvacBtnHeight"
+                android:layout_width ="250dp"
+                android:text="@string/hvac_aTempUp"
+                android:textSize="@dimen/hvacTextSize"/>
+
+            <TextView
+                android:gravity="center"
+                android:id="@+id/tvATemp"
+                android:layout_height="50dp"
+                android:layout_width ="250dp"
+                android:textSize="@dimen/hvacTextSize"/>
+
+            <Button
+                android:clickable="false"
+                android:id="@+id/btnATempDn"
+                android:layout_height="@dimen/hvacBtnHeight"
+                android:layout_width ="250dp"
+                android:text="@string/hvac_aTempDn"
                 android:textSize="@dimen/hvacTextSize"/>
         </LinearLayout>
 
@@ -87,6 +119,37 @@
 
             <Button
                 android:clickable="false"
+                android:id="@+id/btnPTempUp"
+                android:layout_height="@dimen/hvacBtnHeight"
+                android:layout_width ="250dp"
+                android:text="@string/hvac_pTempUp"
+                android:textSize="@dimen/hvacTextSize"/>
+
+            <TextView
+                android:gravity="center"
+                android:id="@+id/tvPTemp"
+                android:layout_height="50dp"
+                android:layout_width ="250dp"
+                android:textSize="@dimen/hvacTextSize"/>
+
+            <Button
+                android:clickable="false"
+                android:id="@+id/btnPTempDn"
+                android:layout_height="@dimen/hvacBtnHeight"
+                android:layout_width ="250dp"
+                android:text="@string/hvac_pTempDn"
+                android:textSize="@dimen/hvacTextSize"/>
+        </LinearLayout>
+
+        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                      android:gravity="center"
+                      android:layout_height="match_parent"
+                      android:layout_weight="1"
+                      android:layout_width = "wrap_content"
+                      android:orientation="vertical">
+
+            <Button
+                android:clickable="false"
                 android:id="@+id/btnFanSpeedUp"
                 android:layout_height="@dimen/hvacBtnHeight"
                 android:layout_width ="250dp"
@@ -108,37 +171,6 @@
                 android:text="@string/hvac_fanSpeedDn"
                 android:textSize="@dimen/hvacTextSize"/>
         </LinearLayout>
-
-        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-            android:gravity="center"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            android:layout_width = "wrap_content"
-            android:orientation="vertical">
-
-            <Button
-                android:clickable="false"
-                android:id="@+id/btnPTempUp"
-                android:layout_height="@dimen/hvacBtnHeight"
-                android:layout_width ="250dp"
-                android:text="@string/hvac_tempUp"
-                android:textSize="@dimen/hvacTextSize"/>
-
-            <TextView
-                android:gravity="center"
-                android:id="@+id/tvPTemp"
-                android:layout_height="50dp"
-                android:layout_width ="250dp"
-                android:textSize="@dimen/hvacTextSize"/>
-
-            <Button
-                android:clickable="false"
-                android:id="@+id/btnPTempDn"
-                android:layout_height="@dimen/hvacBtnHeight"
-                android:layout_width ="250dp"
-                android:text="@string/hvac_tempDn"
-                android:textSize="@dimen/hvacTextSize"/>
-        </LinearLayout>
     </LinearLayout>
     <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_height="match_parent"
@@ -192,6 +224,16 @@
 
                 <ToggleButton
                     android:clickable="false"
+                    android:id="@+id/tbPower"
+                    android:layout_height="@dimen/hvacBtnHeight"
+                    android:layout_weight="1"
+                    android:layout_width ="0dp"
+                    android:textOff="@string/hvac_powerOff"
+                    android:textOn="@string/hvac_powerOn"
+                    android:textSize="@dimen/hvacTextSize"/>
+
+                <ToggleButton
+                    android:clickable="false"
                     android:id="@+id/tbDefrostFront"
                     android:layout_height="@dimen/hvacBtnHeight"
                     android:layout_weight="1"
@@ -202,26 +244,6 @@
 
                 <ToggleButton
                     android:clickable="false"
-                    android:id="@+id/tbMaxAc"
-                    android:layout_height="@dimen/hvacBtnHeight"
-                    android:layout_weight="1"
-                    android:layout_width ="0dp"
-                    android:textOff="@string/hvac_maxAcOff"
-                    android:textOn="@string/hvac_maxAcOn"
-                    android:textSize="@dimen/hvacTextSize"/>
-
-                <ToggleButton
-                    android:clickable="false"
-                    android:id="@+id/tbMaxDefrost"
-                    android:layout_height="@dimen/hvacBtnHeight"
-                    android:layout_weight="1"
-                    android:layout_width ="0dp"
-                    android:textOff="@string/hvac_maxDefrostOff"
-                    android:textOn="@string/hvac_maxDefrostOn"
-                    android:textSize="@dimen/hvacTextSize"/>
-
-                <ToggleButton
-                    android:clickable="false"
                     android:id="@+id/tbDefrostRear"
                     android:layout_height="@dimen/hvacBtnHeight"
                     android:layout_weight="1"
@@ -229,6 +251,16 @@
                     android:textOff="@string/hvac_defrostRearOff"
                     android:textOn="@string/hvac_defrostRearOn"
                     android:textSize="@dimen/hvacTextSize"/>
+
+                <ToggleButton
+                    android:clickable="false"
+                    android:id="@+id/tbMaxDefrost"
+                    android:layout_height="@dimen/hvacBtnHeight"
+                    android:layout_weight="1"
+                    android:layout_width ="0dp"
+                    android:textOff="@string/hvac_maxDefrostOff"
+                    android:textOn="@string/hvac_maxDefrostOn"
+                    android:textSize="@dimen/hvacTextSize"/>
             </LinearLayout>
             <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                 android:layout_height="wrap_content"
@@ -238,16 +270,6 @@
 
                 <ToggleButton
                     android:clickable="false"
-                    android:id="@+id/tbAuto"
-                    android:layout_height="@dimen/hvacBtnHeight"
-                    android:layout_weight="1"
-                    android:layout_width ="0dp"
-                    android:textOff="@string/hvac_autoOff"
-                    android:textOn="@string/hvac_autoOn"
-                    android:textSize="@dimen/hvacTextSize"/>
-
-                <ToggleButton
-                    android:clickable="false"
                     android:id="@+id/tbAc"
                     android:layout_height="@dimen/hvacBtnHeight"
                     android:layout_weight="1"
@@ -258,6 +280,16 @@
 
                 <ToggleButton
                     android:clickable="false"
+                    android:id="@+id/tbMaxAc"
+                    android:layout_height="@dimen/hvacBtnHeight"
+                    android:layout_weight="1"
+                    android:layout_width ="0dp"
+                    android:textOff="@string/hvac_maxAcOff"
+                    android:textOn="@string/hvac_maxAcOn"
+                    android:textSize="@dimen/hvacTextSize"/>
+
+                <ToggleButton
+                    android:clickable="false"
                     android:id="@+id/tbDual"
                     android:layout_height="@dimen/hvacBtnHeight"
                     android:layout_weight="1"
@@ -276,6 +308,51 @@
                     android:textOn="@string/hvac_recircOn"
                     android:textSize="@dimen/hvacTextSize"/>
             </LinearLayout>
+            <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                          android:layout_height="wrap_content"
+                          android:layout_width="match_parent"
+                          android:layout_marginTop="@dimen/hvacBtnMargin"
+                          android:orientation="horizontal">
+
+                <Button
+                    android:clickable="false"
+                    android:id="@+id/tbPowerAndAc"
+                    android:layout_height="@dimen/hvacBtnHeight"
+                    android:layout_weight="1"
+                    android:layout_width ="0dp"
+                    android:text="@string/hvac_powerAndAcOn"
+                    android:textSize="@dimen/hvacTextSize"/>
+
+                <ToggleButton
+                    android:clickable="false"
+                    android:id="@+id/tbAuto"
+                    android:layout_height="@dimen/hvacBtnHeight"
+                    android:layout_weight="1"
+                    android:layout_width ="0dp"
+                    android:textOff="@string/hvac_autoOff"
+                    android:textOn="@string/hvac_autoOn"
+                    android:textSize="@dimen/hvacTextSize"/>
+
+                <ToggleButton
+                    android:clickable="false"
+                    android:id="@+id/tbAutoRecirc"
+                    android:layout_height="@dimen/hvacBtnHeight"
+                    android:layout_weight="1"
+                    android:layout_width ="0dp"
+                    android:textOff="@string/hvac_autoRecircOff"
+                    android:textOn="@string/hvac_autoRecircOn"
+                    android:textSize="@dimen/hvacTextSize"/>
+
+                <ToggleButton
+                    android:clickable="false"
+                    android:id="@+id/tbTempDisplayUnit"
+                    android:layout_height="@dimen/hvacBtnHeight"
+                    android:layout_weight="1"
+                    android:layout_width ="0dp"
+                    android:textOff="@string/hvac_tempDisplayCelsius"
+                    android:textOn="@string/hvac_tempDisplayFahrenheit"
+                    android:textSize="@dimen/hvacTextSize"/>
+            </LinearLayout>
         </LinearLayout>
     </LinearLayout>
 </LinearLayout>
diff --git a/tests/EmbeddedKitchenSinkApp/res/values/strings.xml b/tests/EmbeddedKitchenSinkApp/res/values/strings.xml
index f1a645e..b0efa9d 100644
--- a/tests/EmbeddedKitchenSinkApp/res/values/strings.xml
+++ b/tests/EmbeddedKitchenSinkApp/res/values/strings.xml
@@ -53,6 +53,8 @@
     <string name="hvac_acOn" translatable="false">AC ON</string>
     <string name="hvac_autoOff" translatable="false">Auto OFF</string>
     <string name="hvac_autoOn" translatable="false">Auto ON</string>
+    <string name="hvac_autoRecircOff" translatable="false">Auto Recirc OFF</string>
+    <string name="hvac_autoRecircOn" translatable="false">Auto Recirc ON</string>
     <string name="hvac_defrostFrontOff" translatable="false">Front Defrost OFF</string>
     <string name="hvac_defrostFrontOn" translatable="false">Front Defrost ON</string>
     <string name="hvac_defrostRearOff" translatable="false">Rear Defrost OFF</string>
@@ -69,12 +71,21 @@
     <string name="hvac_positionFaceAndFloor" translatable="false">Face+Floor</string>
     <string name="hvac_positionDefrost" translatable="false">Defrost</string>
     <string name="hvac_positionDefrostAndFloor" translatable="false">Def+Floor</string>
+    <string name="hvac_powerOff" translatable="false">Power OFF</string>
+    <string name="hvac_powerOn" translatable="false">Power ON</string>
+    <string name="hvac_powerAndAcOn" translatable="false">Turn Power And AC ON</string>
     <string name="hvac_fanSpeedDn" translatable="false">Fan Speed Down</string>
     <string name="hvac_fanSpeedUp" translatable="false">Fan Speed Up</string>
     <string name="hvac_recircOff" translatable="false">Recirc OFF</string>
     <string name="hvac_recircOn" translatable="false">Recirc ON</string>
-    <string name="hvac_tempDn" translatable="false">Temp Down</string>
-    <string name="hvac_tempUp" translatable="false">Temp Up</string>
+    <string name="hvac_tempDisplayCelsius" translatable="false">Temp CELSIUS</string>
+    <string name="hvac_tempDisplayFahrenheit" translatable="false">Temp FAHRENHEIT</string>
+    <string name="hvac_aTempDn" translatable="false">All Temp Down</string>
+    <string name="hvac_aTempUp" translatable="false">All Temp Up</string>
+    <string name="hvac_dTempDn" translatable="false">Driver Temp Down</string>
+    <string name="hvac_dTempUp" translatable="false">Driver Temp Up</string>
+    <string name="hvac_pTempDn" translatable="false">Passenger Temp Down</string>
+    <string name="hvac_pTempUp" translatable="false">Passenger Temp Up</string>
     <!-- camera -->
     <string name="rvc_getCapabilities" translatable="false">Get Capabilities</string>
     <string name="rvc_getRvcCrop" translatable="false">Get RVC Crop</string>
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/hvac/HvacTestFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/hvac/HvacTestFragment.java
index f56b487..7c212e9 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/hvac/HvacTestFragment.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/hvac/HvacTestFragment.java
@@ -24,6 +24,7 @@
 import android.car.hardware.hvac.CarHvacManager;
 import android.hardware.automotive.vehicle.V2_0.VehicleAreaSeat;
 import android.hardware.automotive.vehicle.V2_0.VehicleAreaWindow;
+import android.hardware.automotive.vehicle.V2_0.VehicleUnit;
 import android.os.Bundle;
 import android.os.Handler;
 import android.util.Log;
@@ -34,6 +35,7 @@
 import android.widget.RadioButton;
 import android.widget.RadioGroup;
 import android.widget.TextView;
+import android.widget.Toast;
 import android.widget.ToggleButton;
 
 import androidx.fragment.app.Fragment;
@@ -60,6 +62,10 @@
     private ToggleButton mTbMaxAc;
     private ToggleButton mTbMaxDefrost;
     private ToggleButton mTbRecirc;
+    private ToggleButton mTbAutoRecirc;
+    private ToggleButton mTbTempDisplayUnit;
+    private ToggleButton mTbPower;
+    private Button mTbPowerAndAc;
     private TextView mTvFanSpeed;
     private TextView mTvDTemp;
     private TextView mTvPTemp;
@@ -82,25 +88,25 @@
     private View mHvacView;
 
     private final CarHvacManager.CarHvacEventCallback mHvacCallback =
-            new CarHvacManager.CarHvacEventCallback () {
+            new CarHvacManager.CarHvacEventCallback() {
                 @Override
                 public void onChangeEvent(final CarPropertyValue value) {
                     int zones = value.getAreaId();
-                    switch(value.getPropertyId()) {
+                    switch (value.getPropertyId()) {
                         case CarHvacManager.ID_OUTSIDE_AIR_TEMP:
                             mTvOutsideTemp.setText(String.valueOf(value.getValue()));
                             break;
                         case CarHvacManager.ID_ZONED_DUAL_ZONE_ON:
-                            mTbDual.setChecked((boolean)value.getValue());
+                            mTbDual.setChecked((boolean) value.getValue());
                             break;
                         case CarHvacManager.ID_ZONED_AC_ON:
-                            mTbAc.setChecked((boolean)value.getValue());
+                            mTbAc.setChecked((boolean) value.getValue());
                             break;
                         case CarHvacManager.ID_ZONED_AUTOMATIC_MODE_ON:
-                            mTbAuto.setChecked((boolean)value.getValue());
+                            mTbAuto.setChecked((boolean) value.getValue());
                             break;
                         case CarHvacManager.ID_ZONED_FAN_DIRECTION:
-                            switch((int)value.getValue()) {
+                            switch ((int) value.getValue()) {
                                 case CarHvacManager.FAN_DIRECTION_FACE:
                                     mRbFanPositionFace.setChecked(true);
                                     break;
@@ -108,14 +114,14 @@
                                     mRbFanPositionFloor.setChecked(true);
                                     break;
                                 case (CarHvacManager.FAN_DIRECTION_FACE |
-                                      CarHvacManager.FAN_DIRECTION_FLOOR):
+                                        CarHvacManager.FAN_DIRECTION_FLOOR):
                                     mRbFanPositionFaceAndFloor.setChecked(true);
                                     break;
                                 case CarHvacManager.FAN_DIRECTION_DEFROST:
                                     mRbFanPositionDefrost.setChecked(true);
                                     break;
                                 case (CarHvacManager.FAN_DIRECTION_DEFROST |
-                                      CarHvacManager.FAN_DIRECTION_FLOOR):
+                                        CarHvacManager.FAN_DIRECTION_FLOOR):
                                     mRbFanPositionDefrostAndFloor.setChecked(true);
                                     break;
                                 default:
@@ -126,40 +132,50 @@
                             }
                             break;
                         case CarHvacManager.ID_ZONED_MAX_AC_ON:
-                            mTbMaxAc.setChecked((boolean)value.getValue());
+                            mTbMaxAc.setChecked((boolean) value.getValue());
                             break;
                         case CarHvacManager.ID_ZONED_AIR_RECIRCULATION_ON:
-                            mTbRecirc.setChecked((boolean)value.getValue());
+                            mTbRecirc.setChecked((boolean) value.getValue());
                             break;
                         case CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT:
                             if ((zones & mZoneForFanSpeed) == mZoneForFanSpeed) {
-                                mCurFanSpeed = (int)value.getValue();
+                                mCurFanSpeed = (int) value.getValue();
                                 mTvFanSpeed.setText(String.valueOf(mCurFanSpeed));
                             }
                             break;
                         case CarHvacManager.ID_ZONED_TEMP_SETPOINT:
                             if ((zones & mZoneForSetTempD) == mZoneForSetTempD) {
-                                mCurDTemp = (float)value.getValue();
+                                mCurDTemp = (float) value.getValue();
                                 mTvDTemp.setText(String.valueOf(mCurDTemp));
                             }
                             if ((zones & mZoneForSetTempP) == mZoneForSetTempP) {
-                                mCurPTemp = (float)value.getValue();
+                                mCurPTemp = (float) value.getValue();
                                 mTvPTemp.setText(String.valueOf(mCurPTemp));
                             }
                             break;
                         case CarHvacManager.ID_ZONED_MAX_DEFROST_ON:
-                            mTbMaxDefrost.setChecked((boolean)value.getValue());
+                            mTbMaxDefrost.setChecked((boolean) value.getValue());
                             break;
                         case CarHvacManager.ID_WINDOW_DEFROSTER_ON:
-                            if((zones & VehicleAreaWindow.FRONT_WINDSHIELD) ==
-                                    VehicleAreaWindow.FRONT_WINDSHIELD) {
-                                mTbDefrostFront.setChecked((boolean)value.getValue());
+                            if ((zones & VehicleAreaWindow.FRONT_WINDSHIELD)
+                                    == VehicleAreaWindow.FRONT_WINDSHIELD) {
+                                mTbDefrostFront.setChecked((boolean) value.getValue());
                             }
-                            if((zones & VehicleAreaWindow.REAR_WINDSHIELD) ==
-                                    VehicleAreaWindow.REAR_WINDSHIELD) {
-                                mTbDefrostRear.setChecked((boolean)value.getValue());
+                            if ((zones & VehicleAreaWindow.REAR_WINDSHIELD)
+                                    == VehicleAreaWindow.REAR_WINDSHIELD) {
+                                mTbDefrostRear.setChecked((boolean) value.getValue());
                             }
                             break;
+                        case CarHvacManager.ID_ZONED_HVAC_AUTO_RECIRC_ON:
+                            mTbAutoRecirc.setChecked((boolean) value.getValue());
+                            break;
+                        case CarHvacManager.ID_TEMPERATURE_DISPLAY_UNITS:
+                            mTbTempDisplayUnit.setChecked(
+                                    ((Integer) value.getValue()).equals(VehicleUnit.FAHRENHEIT));
+                            break;
+                        case CarHvacManager.ID_ZONED_HVAC_POWER_ON:
+                            mTbPower.setChecked((boolean) value.getValue());
+                            break;
                         default:
                             Log.d(TAG, "onChangeEvent(): unknown property id = " + value
                                     .getPropertyId());
@@ -209,7 +225,7 @@
                     Log.d(TAG, prop.toString());
                 }
 
-                switch(propId) {
+                switch (propId) {
                     case CarHvacManager.ID_OUTSIDE_AIR_TEMP:
                         configureOutsideTemp(mHvacView, prop);
                         break;
@@ -243,6 +259,16 @@
                     case CarHvacManager.ID_WINDOW_DEFROSTER_ON:
                         configureDefrosterOn(mHvacView, prop);
                         break;
+                    case CarHvacManager.ID_ZONED_HVAC_AUTO_RECIRC_ON:
+                        configureAutoRecircOn(mHvacView, prop);
+                        break;
+                    case CarHvacManager.ID_TEMPERATURE_DISPLAY_UNITS:
+                        configureTempDisplayUnit(mHvacView, prop);
+                        break;
+                    case CarHvacManager.ID_ZONED_HVAC_POWER_ON:
+                        configurePowerOn(mHvacView, prop);
+                        configurePowerAndAcOn(mHvacView, prop);
+                        break;
                     default:
                         Log.w(TAG, "propertyId " + propId + " is not handled");
                         break;
@@ -262,7 +288,7 @@
         ((KitchenSinkActivity) getActivity()).requestRefreshManager(r,
                 new Handler(getContext().getMainLooper()));
 
-        if(DBG) {
+        if (DBG) {
             Log.d(TAG, "Starting HvacTestFragment");
         }
 
@@ -275,13 +301,13 @@
 
     private void configureDualOn(View v, CarPropertyConfig prop) {
         int temp = prop.getFirstAndOnlyAreaId();
-        mTbDual = (ToggleButton)v.findViewById(R.id.tbDual);
+        mTbDual = (ToggleButton) v.findViewById(R.id.tbDual);
         mTbDual.setEnabled(true);
 
         mTbDual.setOnClickListener(view -> {
             // TODO handle zone properly
             try {
-                mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_DUAL_ZONE_ON,temp,
+                mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_DUAL_ZONE_ON, temp,
                         mTbDual.isChecked());
             } catch (CarNotConnectedException e) {
                 Log.e(TAG, "Failed to set HVAC boolean property", e);
@@ -291,7 +317,7 @@
 
     private void configureAcOn(View v, CarPropertyConfig prop) {
         mZoneForAcOn = prop.getFirstAndOnlyAreaId();
-        mTbAc = (ToggleButton)v.findViewById(R.id.tbAc);
+        mTbAc = (ToggleButton) v.findViewById(R.id.tbAc);
         mTbAc.setEnabled(true);
 
         mTbAc.setOnClickListener(view -> {
@@ -307,13 +333,13 @@
 
     private void configureAutoModeOn(View v, CarPropertyConfig prop) {
         int temp = prop.getFirstAndOnlyAreaId();
-        mTbAuto = (ToggleButton)v.findViewById(R.id.tbAuto);
+        mTbAuto = (ToggleButton) v.findViewById(R.id.tbAuto);
         mTbAuto.setEnabled(true);
 
         mTbAuto.setOnClickListener(view -> {
             // TODO handle zone properly
             try {
-                mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_AUTOMATIC_MODE_ON,temp,
+                mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_AUTOMATIC_MODE_ON, temp,
                         mTbAuto.isChecked());
             } catch (CarNotConnectedException e) {
                 Log.e(TAG, "Failed to set HVAC boolean property", e);
@@ -323,10 +349,10 @@
 
     private void configureFanPosition(View v, CarPropertyConfig prop) {
         mZoneForFanPosition = prop.getFirstAndOnlyAreaId();
-        RadioGroup rg = (RadioGroup)v.findViewById(R.id.rgFanPosition);
+        RadioGroup rg = (RadioGroup) v.findViewById(R.id.rgFanPosition);
         rg.setOnCheckedChangeListener((group, checkedId) -> {
             int position;
-            switch(checkedId) {
+            switch (checkedId) {
                 case R.id.rbPositionFace:
                     position = CarHvacManager.FAN_DIRECTION_FACE;
                     break;
@@ -335,42 +361,47 @@
                     break;
                 case R.id.rbPositionFaceAndFloor:
                     position = (CarHvacManager.FAN_DIRECTION_FACE |
-                                CarHvacManager.FAN_DIRECTION_FLOOR);
+                            CarHvacManager.FAN_DIRECTION_FLOOR);
                     break;
                 case R.id.rbPositionDefrost:
                     position = CarHvacManager.FAN_DIRECTION_DEFROST;
                     break;
                 case R.id.rbPositionDefrostAndFloor:
                     position = (CarHvacManager.FAN_DIRECTION_DEFROST |
-                                CarHvacManager.FAN_DIRECTION_FLOOR);
+                            CarHvacManager.FAN_DIRECTION_FLOOR);
                     break;
                 default:
                     throw new IllegalStateException("Unexpected fan position: " + checkedId);
             }
             try {
-                mCarHvacManager.setIntProperty(CarHvacManager.ID_ZONED_FAN_DIRECTION,
-                        mZoneForFanPosition,
-                        position);
-            } catch (CarNotConnectedException e) {
+                if (mCarHvacManager.isPropertyAvailable(CarHvacManager.ID_ZONED_FAN_DIRECTION,
+                        mZoneForFanSpeed)) {
+                    mCarHvacManager.setIntProperty(CarHvacManager.ID_ZONED_FAN_DIRECTION,
+                            mZoneForFanPosition,
+                            position);
+                }
+            } catch (CarNotConnectedException | IllegalStateException e) {
                 Log.e(TAG, "Failed to set HVAC integer property", e);
+                Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
             }
         });
 
-        mRbFanPositionFace = (RadioButton)v.findViewById(R.id.rbPositionFace);
+        mRbFanPositionFace = (RadioButton) v.findViewById(R.id.rbPositionFace);
         mRbFanPositionFace.setClickable(true);
-        mRbFanPositionFloor = (RadioButton)v.findViewById(R.id.rbPositionFloor);
+        mRbFanPositionFloor = (RadioButton) v.findViewById(R.id.rbPositionFloor);
         mRbFanPositionFloor.setClickable(true);
-        mRbFanPositionFaceAndFloor = (RadioButton)v.findViewById(R.id.rbPositionFaceAndFloor);
+        mRbFanPositionFaceAndFloor = (RadioButton) v.findViewById(R.id.rbPositionFaceAndFloor);
         mRbFanPositionFaceAndFloor.setClickable(true);
-        mRbFanPositionDefrost = (RadioButton)v.findViewById(R.id.rbPositionDefrost);
+        mRbFanPositionDefrost = (RadioButton) v.findViewById(R.id.rbPositionDefrost);
         mRbFanPositionDefrost.setClickable(true);
-        mRbFanPositionDefrostAndFloor = (RadioButton)v.findViewById(R.id.rbPositionDefrostAndFloor);
+        mRbFanPositionDefrostAndFloor = (RadioButton) v.findViewById(
+                R.id.rbPositionDefrostAndFloor);
         mRbFanPositionDefrostAndFloor.setClickable(true);
     }
 
     private void configureFanSpeed(View v, CarPropertyConfig prop) {
-        mMinFanSpeed = ((Integer)prop.getMinValue()).intValue();
-        mMaxFanSpeed = ((Integer)prop.getMaxValue()).intValue();
+        mMinFanSpeed = ((Integer) prop.getMinValue()).intValue();
+        mMaxFanSpeed = ((Integer) prop.getMaxValue()).intValue();
         mZoneForFanSpeed = prop.getFirstAndOnlyAreaId();
         try {
             mCurFanSpeed = mCarHvacManager.getIntProperty(
@@ -382,38 +413,34 @@
 
         Button btnFanSpeedUp = (Button) v.findViewById(R.id.btnFanSpeedUp);
         btnFanSpeedUp.setEnabled(true);
-        btnFanSpeedUp.setOnClickListener(view -> {
-            if (mCurFanSpeed < mMaxFanSpeed) {
-                mCurFanSpeed++;
-                mTvFanSpeed.setText(String.valueOf(mCurFanSpeed));
-                try {
-                    mCarHvacManager.setIntProperty(CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT,
-                            mZoneForFanSpeed, mCurFanSpeed);
-                } catch (CarNotConnectedException e) {
-                    Log.e(TAG, "Failed to set HVAC int property", e);
-                }
-            }
-        });
+        btnFanSpeedUp.setOnClickListener(view -> changeFanSpeed(1));
 
         Button btnFanSpeedDn = (Button) v.findViewById(R.id.btnFanSpeedDn);
         btnFanSpeedDn.setEnabled(true);
-        btnFanSpeedDn.setOnClickListener(view -> {
-            if (mCurFanSpeed > mMinFanSpeed) {
-                mCurFanSpeed--;
-                mTvFanSpeed.setText(String.valueOf(mCurFanSpeed));
-                try {
+        btnFanSpeedDn.setOnClickListener(view -> changeFanSpeed(-1));
+    }
+
+    private void changeFanSpeed(int change) {
+        int targetSpeed = mCurFanSpeed + change;
+        if (mMinFanSpeed < targetSpeed && targetSpeed < mMaxFanSpeed) {
+            mCurFanSpeed = targetSpeed;
+            mTvFanSpeed.setText(String.valueOf(mCurFanSpeed));
+            try {
+                if (mCarHvacManager.isPropertyAvailable(
+                        CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT, mZoneForFanSpeed)) {
                     mCarHvacManager.setIntProperty(CarHvacManager.ID_ZONED_FAN_SPEED_SETPOINT,
                             mZoneForFanSpeed, mCurFanSpeed);
-                } catch (CarNotConnectedException e) {
-                    Log.e(TAG, "Failed to set HVAC fan speed property", e);
                 }
+            } catch (CarNotConnectedException | IllegalStateException e) {
+                Log.e(TAG, "Failed to set HVAC int property", e);
+                Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
             }
-        });
+        }
     }
 
     private void configureTempSetpoint(View v, CarPropertyConfig prop) {
-        mMinTemp = ((Float)prop.getMinValue()).floatValue();
-        mMaxTemp = ((Float)prop.getMaxValue()).floatValue();
+        mMinTemp = ((Float) prop.getMinValue()).floatValue();
+        mMaxTemp = ((Float) prop.getMaxValue()).floatValue();
 
         if (mMaxTemp > 50) {
             // Assume it's Fahrenheit
@@ -424,7 +451,7 @@
         }
         mZoneForSetTempD = 0;
         if (prop.hasArea(VehicleAreaSeat.ROW_1_LEFT | VehicleAreaSeat.ROW_2_LEFT
-                         | VehicleAreaSeat.ROW_2_CENTER)) {
+                | VehicleAreaSeat.ROW_2_CENTER)) {
             mZoneForSetTempD = VehicleAreaSeat.ROW_1_LEFT | VehicleAreaSeat.ROW_2_LEFT
                     | VehicleAreaSeat.ROW_2_CENTER;
         }
@@ -454,41 +481,17 @@
                 Log.e(TAG, "Failed to get HVAC zoned temp property", e);
             }
             btnDTempUp.setEnabled(true);
-            btnDTempUp.setOnClickListener(view -> {
-                if(mCurDTemp < mMaxTemp) {
-                    mCurDTemp += mTempStep;
-                    mTvDTemp.setText(String.valueOf(mCurDTemp));
-                    try {
-                        mCarHvacManager.setFloatProperty(
-                                CarHvacManager.ID_ZONED_TEMP_SETPOINT,
-                                mZoneForSetTempD, mCurDTemp);
-                    } catch (CarNotConnectedException e) {
-                        Log.e(TAG, "Failed to set HVAC zoned temp property", e);
-                    }
-                }
-            });
+            btnDTempUp.setOnClickListener(view -> changeDriverTemperature(mTempStep));
 
             Button btnDTempDn = (Button) v.findViewById(R.id.btnDTempDn);
             btnDTempDn.setEnabled(true);
-            btnDTempDn.setOnClickListener(view -> {
-                if(mCurDTemp > mMinTemp) {
-                    mCurDTemp -= mTempStep;
-                    mTvDTemp.setText(String.valueOf(mCurDTemp));
-                    try {
-                        mCarHvacManager.setFloatProperty(
-                                CarHvacManager.ID_ZONED_TEMP_SETPOINT,
-                                mZoneForSetTempD, mCurDTemp);
-                    } catch (CarNotConnectedException e) {
-                        Log.e(TAG, "Failed to set HVAC zoned temp property", e);
-                    }
-                }
-            });
+            btnDTempDn.setOnClickListener(view -> changeDriverTemperature(-mTempStep));
         } else {
             btnDTempUp.setEnabled(false);
         }
 
         Button btnPTempUp = (Button) v.findViewById(R.id.btnPTempUp);
-        if (mZoneForSetTempP !=0 ) {
+        if (mZoneForSetTempP != 0) {
             try {
                 mCurPTemp = mCarHvacManager.getFloatProperty(
                         CarHvacManager.ID_ZONED_TEMP_SETPOINT,
@@ -502,38 +505,60 @@
                 Log.e(TAG, "Failed to get HVAC zoned temp property", e);
             }
             btnPTempUp.setEnabled(true);
-            btnPTempUp.setOnClickListener(view -> {
-                if (mCurPTemp < mMaxTemp) {
-                    mCurPTemp += mTempStep;
-                    mTvPTemp.setText(String.valueOf(mCurPTemp));
-                    try {
-                        mCarHvacManager.setFloatProperty(
-                                CarHvacManager.ID_ZONED_TEMP_SETPOINT,
-                                mZoneForSetTempP, mCurPTemp);
-                    } catch (CarNotConnectedException e) {
-                        Log.e(TAG, "Failed to set HVAC zoned temp property", e);
-                    }
-                }
-            });
+            btnPTempUp.setOnClickListener(view -> changePassengerTemperature(mTempStep));
 
             Button btnPTempDn = (Button) v.findViewById(R.id.btnPTempDn);
             btnPTempDn.setEnabled(true);
-            btnPTempDn.setOnClickListener(view -> {
-                if (mCurPTemp > mMinTemp) {
-                    mCurPTemp -= mTempStep;
-                    mTvPTemp.setText(String.valueOf(mCurPTemp));
-                    try {
-                        mCarHvacManager.setFloatProperty(
-                                CarHvacManager.ID_ZONED_TEMP_SETPOINT,
-                                mZoneForSetTempP, mCurPTemp);
-                    } catch (CarNotConnectedException e) {
-                        Log.e(TAG, "Failed to set HVAC zoned temp property", e);
-                    }
-                }
-            });
+            btnPTempDn.setOnClickListener(view -> changePassengerTemperature(-mTempStep));
         } else {
             btnPTempUp.setEnabled(false);
         }
+
+        Button btnATempUp = (Button) v.findViewById(R.id.btnATempUp);
+        if (mZoneForSetTempD != 0 && mZoneForSetTempP != 0) {
+            btnATempUp.setEnabled(true);
+            btnATempUp.setOnClickListener(view -> {
+                changeDriverTemperature(mTempStep);
+                changePassengerTemperature(mTempStep);
+            });
+
+            Button btnATempDn = (Button) v.findViewById(R.id.btnATempDn);
+            btnATempDn.setEnabled(true);
+            btnATempDn.setOnClickListener(view -> {
+                changeDriverTemperature(-mTempStep);
+                changePassengerTemperature(-mTempStep);
+            });
+        } else {
+            btnATempUp.setEnabled(false);
+        }
+    }
+
+    private void changeDriverTemperature(float tempStep) {
+        float targetTemp = mCurDTemp + tempStep;
+        if (mMinTemp < targetTemp && targetTemp < mMaxTemp) {
+            mCurDTemp = targetTemp;
+            mTvDTemp.setText(String.valueOf(mCurDTemp));
+            try {
+                mCarHvacManager.setFloatProperty(CarHvacManager.ID_ZONED_TEMP_SETPOINT,
+                        mZoneForSetTempD, mCurDTemp);
+            } catch (CarNotConnectedException e) {
+                Log.e(TAG, "Failed to set HVAC zoned temp property", e);
+            }
+        }
+    }
+
+    private void changePassengerTemperature(float tempStep) {
+        float targetTemp = mCurPTemp + tempStep;
+        if (mMinTemp < targetTemp && targetTemp < mMaxTemp) {
+            mCurPTemp = targetTemp;
+            mTvPTemp.setText(String.valueOf(mCurPTemp));
+            try {
+                mCarHvacManager.setFloatProperty(CarHvacManager.ID_ZONED_TEMP_SETPOINT,
+                        mZoneForSetTempP, mCurPTemp);
+            } catch (CarNotConnectedException e) {
+                Log.e(TAG, "Failed to set HVAC zoned temp property", e);
+            }
+        }
     }
 
     private void configureDefrosterOn(View v, CarPropertyConfig prop1) {
@@ -567,7 +592,7 @@
 
     private void configureRecircOn(View v, CarPropertyConfig prop) {
         int temp = prop.getFirstAndOnlyAreaId();
-        mTbRecirc = (ToggleButton)v.findViewById(R.id.tbRecirc);
+        mTbRecirc = (ToggleButton) v.findViewById(R.id.tbRecirc);
         mTbRecirc.setEnabled(true);
 
         mTbRecirc.setOnClickListener(view -> {
@@ -583,13 +608,13 @@
 
     private void configureMaxAcOn(View v, CarPropertyConfig prop) {
         int temp = prop.getFirstAndOnlyAreaId();
-        mTbMaxAc = (ToggleButton)v.findViewById(R.id.tbMaxAc);
+        mTbMaxAc = (ToggleButton) v.findViewById(R.id.tbMaxAc);
         mTbMaxAc.setEnabled(true);
 
         mTbMaxAc.setOnClickListener(view -> {
             // TODO handle zone properly
             try {
-                mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_MAX_AC_ON,temp,
+                mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_MAX_AC_ON, temp,
                         mTbMaxAc.isChecked());
             } catch (CarNotConnectedException e) {
                 Log.e(TAG, "Failed to set HVAC boolean property", e);
@@ -599,17 +624,83 @@
 
     private void configureMaxDefrostOn(View v, CarPropertyConfig prop) {
         int temp = prop.getFirstAndOnlyAreaId();
-        mTbMaxDefrost = (ToggleButton)v.findViewById(R.id.tbMaxDefrost);
+        mTbMaxDefrost = (ToggleButton) v.findViewById(R.id.tbMaxDefrost);
         mTbMaxDefrost.setEnabled(true);
 
         mTbMaxDefrost.setOnClickListener(view -> {
             // TODO handle zone properly
             try {
-                mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_MAX_DEFROST_ON,temp,
+                mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_MAX_DEFROST_ON, temp,
                         mTbMaxDefrost.isChecked());
             } catch (CarNotConnectedException e) {
                 Log.e(TAG, "Failed to set HVAC boolean property", e);
             }
         });
     }
+
+    private void configureAutoRecircOn(View v, CarPropertyConfig prop) {
+        // TODO handle areaId properly
+        int areaId = prop.getFirstAndOnlyAreaId();
+        mTbAutoRecirc = (ToggleButton) v.findViewById(R.id.tbAutoRecirc);
+        mTbAutoRecirc.setEnabled(true);
+
+        mTbAutoRecirc.setOnClickListener(view -> {
+            try {
+                mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_HVAC_AUTO_RECIRC_ON,
+                        areaId, mTbAutoRecirc.isChecked());
+            } catch (CarNotConnectedException e) {
+                Log.e(TAG, "Failed to set HVAC boolean property", e);
+            }
+        });
+    }
+
+    private void configureTempDisplayUnit(View v, CarPropertyConfig prop) {
+        int areaId = prop.getFirstAndOnlyAreaId();
+        mTbTempDisplayUnit = (ToggleButton) v.findViewById(R.id.tbTempDisplayUnit);
+        mTbTempDisplayUnit.setEnabled(true);
+
+        mTbTempDisplayUnit.setOnClickListener(view -> {
+            try {
+                int unit = (mTbTempDisplayUnit.isChecked() ? VehicleUnit.FAHRENHEIT
+                        : VehicleUnit.CELSIUS);
+                mCarHvacManager.setIntProperty(CarHvacManager.ID_TEMPERATURE_DISPLAY_UNITS, areaId,
+                        unit);
+            } catch (CarNotConnectedException e) {
+                Log.e(TAG, "Failed to set HVAC temperature display unit property", e);
+            }
+        });
+    }
+
+    private void configurePowerOn(View v, CarPropertyConfig prop) {
+        // TODO handle areaId properly
+        int areaId = prop.getFirstAndOnlyAreaId();
+        mTbPower = (ToggleButton) v.findViewById(R.id.tbPower);
+        mTbPower.setEnabled(true);
+
+        mTbPower.setOnClickListener(view -> {
+            try {
+                mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_HVAC_POWER_ON, areaId,
+                        mTbPower.isChecked());
+            } catch (CarNotConnectedException e) {
+                Log.e(TAG, "Failed to set HVAC boolean property", e);
+            }
+        });
+    }
+
+    private void configurePowerAndAcOn(View v, CarPropertyConfig prop) {
+        // TODO handle areaId properly
+        int areaId = prop.getFirstAndOnlyAreaId();
+        mTbPowerAndAc = (Button) v.findViewById(R.id.tbPowerAndAc);
+        mTbPowerAndAc.setEnabled(true);
+
+        mTbPowerAndAc.setOnClickListener(view -> {
+            try {
+                mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_HVAC_POWER_ON, areaId,
+                        true);
+                mCarHvacManager.setBooleanProperty(CarHvacManager.ID_ZONED_AC_ON, areaId, true);
+            } catch (CarNotConnectedException e) {
+                Log.e(TAG, "Failed to set HVAC boolean property", e);
+            }
+        });
+    }
 }
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/power/PowerTestFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/power/PowerTestFragment.java
index 2dea5d8..bf1548c 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/power/PowerTestFragment.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/power/PowerTestFragment.java
@@ -34,28 +34,17 @@
 import com.google.android.car.kitchensink.KitchenSinkActivity;
 import com.google.android.car.kitchensink.R;
 
-import java.util.concurrent.CompletableFuture;
-
 public class PowerTestFragment extends Fragment {
     private final boolean DBG = false;
     private final String TAG = "PowerTestFragment";
     private CarPowerManager mCarPowerManager;
 
     private final CarPowerManager.CarPowerStateListener mPowerListener =
-            new CarPowerManager.CarPowerStateListener() {
-                @Override
-                public void onStateChanged(int state) {
-                    throw new UnsupportedOperationException(
-                            "Should not be here. This API obsolete and is not used.");
+            (state, future) -> {
+                if (future != null) {
+                    future.complete(null);
                 }
-
-                @Override
-                public void onStateChanged(int state, CompletableFuture<Void> future) {
-                    if (future != null) {
-                        future.complete(null);
-                    }
-                    Log.i(TAG, "onStateChanged() state = " + state);
-                }
+                Log.i(TAG, "onStateChanged() state = " + state);
             };
 
     @Override
diff --git a/tests/ThemePlayground/res/values/strings.xml b/tests/ThemePlayground/res/values/strings.xml
index b1a7544..e263fd0 100644
--- a/tests/ThemePlayground/res/values/strings.xml
+++ b/tests/ThemePlayground/res/values/strings.xml
@@ -15,21 +15,21 @@
   ~ limitations under the License
   -->
 <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="app_name" translable="false">AAE Theme Playground</string>
-    <string name="text_elements" translable="false">Text Elements</string>
-    <string name="panel_elements" translable="false">Color Panels</string>
-    <string name="dialog_elements" translable="false">Dialogs</string>
-    <string name="toggle_theme" translable="false">Change configuration(Day/Night)</string>
-    <string name="apply" translable="false">Apply</string>
-    <string name="widgets" translable="false">Widgets</string>
-    <string name="paged_list_view" translable="false">Paged List View</string>
-    <string name="widget_checkbox" translable="false">Checkbox</string>
-    <string name="toggle_switch" translable="false">Toggle Switch</string>
-    <string name="reset" translable="false">Reset</string>
-    <string name="progress_bar" translable="false">Progress Bar</string>
-    <string name="background_name" translable="false">Set background color :</string>
-    <string name="default_themes" translable="false">Apply Themes</string>
-    <string name="theme_name" translable="false">Theme Name:</string>
-    <string name="multiple_intent" translable="false">Chooser Activity</string>
-    <string name="default_background_color" translable="false">#90CAF9</string>
+    <string name="app_name" translatable="false">AAE Theme Playground</string>
+    <string name="text_elements" translatable="false">Text Elements</string>
+    <string name="panel_elements" translatable="false">Color Panels</string>
+    <string name="dialog_elements" translatable="false">Dialogs</string>
+    <string name="toggle_theme" translatable="false">Change configuration(Day/Night)</string>
+    <string name="apply" translatable="false">Apply</string>
+    <string name="widgets" translatable="false">Widgets</string>
+    <string name="paged_list_view" translatable="false">Paged List View</string>
+    <string name="widget_checkbox" translatable="false">Checkbox</string>
+    <string name="toggle_switch" translatable="false">Toggle Switch</string>
+    <string name="reset" translatable="false">Reset</string>
+    <string name="progress_bar" translatable="false">Progress Bar</string>
+    <string name="background_name" translatable="false">Set background color :</string>
+    <string name="default_themes" translatable="false">Apply Themes</string>
+    <string name="theme_name" translatable="false">Theme Name:</string>
+    <string name="multiple_intent" translatable="false">Chooser Activity</string>
+    <string name="default_background_color" translatable="false">#90CAF9</string>
 </resources>