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>