diff --git a/packages/CarSystemUI/res/drawable/car_ic_apps.xml b/packages/CarSystemUI/res/drawable/car_ic_apps.xml index a8d8a2f241f6c..e028a0ed45c94 100644 --- a/packages/CarSystemUI/res/drawable/car_ic_apps.xml +++ b/packages/CarSystemUI/res/drawable/car_ic_apps.xml @@ -15,11 +15,11 @@ ~ limitations under the License --> - + android:viewportHeight="44"> + \ No newline at end of file diff --git a/packages/CarSystemUI/res/drawable/car_ic_apps_selected.xml b/packages/CarSystemUI/res/drawable/car_ic_apps_selected.xml index 2a4e91aa3cd9e..9504e61e53e42 100644 --- a/packages/CarSystemUI/res/drawable/car_ic_apps_selected.xml +++ b/packages/CarSystemUI/res/drawable/car_ic_apps_selected.xml @@ -15,10 +15,10 @@ ~ limitations under the License --> + android:viewportHeight="44"> diff --git a/packages/CarSystemUI/res/drawable/car_ic_home.xml b/packages/CarSystemUI/res/drawable/car_ic_home.xml new file mode 100644 index 0000000000000..c78f0edd5594c --- /dev/null +++ b/packages/CarSystemUI/res/drawable/car_ic_home.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/packages/CarSystemUI/res/drawable/car_ic_home_selected.xml b/packages/CarSystemUI/res/drawable/car_ic_home_selected.xml new file mode 100644 index 0000000000000..16192df866760 --- /dev/null +++ b/packages/CarSystemUI/res/drawable/car_ic_home_selected.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/packages/CarSystemUI/res/drawable/car_ic_hvac.xml b/packages/CarSystemUI/res/drawable/car_ic_hvac.xml index bdc44b38a1762..55c968eacc4d2 100644 --- a/packages/CarSystemUI/res/drawable/car_ic_hvac.xml +++ b/packages/CarSystemUI/res/drawable/car_ic_hvac.xml @@ -1,3 +1,4 @@ + - - - - - - - - - \ No newline at end of file + android:width="@dimen/system_bar_icon_drawing_size" + android:height="@dimen/system_bar_icon_drawing_size" + android:viewportWidth="24" + android:viewportHeight="24"> + + diff --git a/packages/CarSystemUI/res/drawable/car_ic_hvac_selected.xml b/packages/CarSystemUI/res/drawable/car_ic_hvac_selected.xml new file mode 100644 index 0000000000000..817b7148ecdd9 --- /dev/null +++ b/packages/CarSystemUI/res/drawable/car_ic_hvac_selected.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/packages/CarSystemUI/res/drawable/car_ic_notification.xml b/packages/CarSystemUI/res/drawable/car_ic_notification.xml index 9d9ad0fdf9c59..aabf9161c11fe 100644 --- a/packages/CarSystemUI/res/drawable/car_ic_notification.xml +++ b/packages/CarSystemUI/res/drawable/car_ic_notification.xml @@ -15,10 +15,10 @@ ~ limitations under the License --> + android:width="@dimen/system_bar_icon_drawing_size" + android:height="@dimen/system_bar_icon_drawing_size" + android:viewportWidth="44" + android:viewportHeight="44"> diff --git a/packages/CarSystemUI/res/drawable/hvac_decrease_button.xml b/packages/CarSystemUI/res/drawable/hvac_decrease_button.xml new file mode 100644 index 0000000000000..469ac91073f99 --- /dev/null +++ b/packages/CarSystemUI/res/drawable/hvac_decrease_button.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/CarSystemUI/res/drawable/hvac_increase_button.xml b/packages/CarSystemUI/res/drawable/hvac_increase_button.xml new file mode 100644 index 0000000000000..a3fca2233dddd --- /dev/null +++ b/packages/CarSystemUI/res/drawable/hvac_increase_button.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/packages/CarSystemUI/res/drawable/ic_mic_white.xml b/packages/CarSystemUI/res/drawable/ic_mic_white.xml index 546b1a894e6ad..71fcc5302d75c 100644 --- a/packages/CarSystemUI/res/drawable/ic_mic_white.xml +++ b/packages/CarSystemUI/res/drawable/ic_mic_white.xml @@ -15,11 +15,11 @@ ~ limitations under the License --> - + \ No newline at end of file diff --git a/packages/CarSystemUI/res/layout/adjustable_temperature_view.xml b/packages/CarSystemUI/res/layout/adjustable_temperature_view.xml new file mode 100644 index 0000000000000..d19740932aa43 --- /dev/null +++ b/packages/CarSystemUI/res/layout/adjustable_temperature_view.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/packages/CarSystemUI/res/layout/car_navigation_bar.xml b/packages/CarSystemUI/res/layout/car_navigation_bar.xml index a49a6373a252b..b07dde582e5f6 100644 --- a/packages/CarSystemUI/res/layout/car_navigation_bar.xml +++ b/packages/CarSystemUI/res/layout/car_navigation_bar.xml @@ -1,6 +1,6 @@ - - + + + android:layoutDirection="ltr"> - - + android:layout_alignParentStart="true" + android:background="@null" + systemui:broadcast="true" + systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"> + + + + + + + + + + + + + + + + + + + + + + - - + android:layout_alignParentEnd="true" + android:background="@null" + systemui:broadcast="true" + systemui:intent="intent:#Intent;action=android.car.intent.action.TOGGLE_HVAC_CONTROLS;end"> - - - - - - - - - - - - - - - - - - - + + + - \ No newline at end of file diff --git a/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml b/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml index 9634950e47488..d9c149106451a 100644 --- a/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml +++ b/packages/CarSystemUI/res/layout/car_top_navigation_bar_unprovisioned.xml @@ -55,10 +55,6 @@ android:minEms="4" android:textAppearance="@style/TextAppearance.CarStatus" systemui:hvacAreaId="49" - systemui:hvacMaxText="@string/hvac_max_text" - systemui:hvacMaxValue="@dimen/hvac_max_value" - systemui:hvacMinText="@string/hvac_min_text" - systemui:hvacMinValue="@dimen/hvac_min_value" systemui:hvacPivotOffset="60dp" systemui:hvacPropertyId="358614275" systemui:hvacTempFormat="%.0f\u00B0" @@ -133,10 +129,6 @@ android:minEms="4" android:textAppearance="@style/TextAppearance.CarStatus" systemui:hvacAreaId="68" - systemui:hvacMaxText="@string/hvac_max_text" - systemui:hvacMaxValue="@dimen/hvac_max_value" - systemui:hvacMinText="@string/hvac_min_text" - systemui:hvacMinValue="@dimen/hvac_min_value" systemui:hvacPivotOffset="60dp" systemui:hvacPropertyId="358614275" systemui:hvacTempFormat="%.0f\u00B0" diff --git a/packages/CarSystemUI/res/values/colors.xml b/packages/CarSystemUI/res/values/colors.xml index 98e31b31551ee..1e15affcbf489 100644 --- a/packages/CarSystemUI/res/values/colors.xml +++ b/packages/CarSystemUI/res/values/colors.xml @@ -33,6 +33,7 @@ #ffffff + #ffffff #33000000 @color/status_bar_background_color diff --git a/packages/CarSystemUI/res/values/dimens.xml b/packages/CarSystemUI/res/values/dimens.xml index 5fb32aff27e82..f02a8e7648c0f 100644 --- a/packages/CarSystemUI/res/values/dimens.xml +++ b/packages/CarSystemUI/res/values/dimens.xml @@ -47,16 +47,22 @@ set here. See car_product overlay for car specific defaults--> 16dp - 36dp - 36dp + 36dp + 64dp + 44dp + 1.75 @*android:dimen/car_primary_icon_size + 16dp + 56sp + 8dp + 76dp - 0 - 126 + 0 + 126 diff --git a/packages/CarSystemUI/res/values/strings.xml b/packages/CarSystemUI/res/values/strings.xml index 67fd5bb685211..fbdb5167fadee 100644 --- a/packages/CarSystemUI/res/values/strings.xml +++ b/packages/CarSystemUI/res/values/strings.xml @@ -16,6 +16,8 @@ --> + + %.0f\u00B0 Min diff --git a/packages/CarSystemUI/res/values/styles.xml b/packages/CarSystemUI/res/values/styles.xml index 5b042a4b83ec6..0db17ac42a779 100644 --- a/packages/CarSystemUI/res/values/styles.xml +++ b/packages/CarSystemUI/res/values/styles.xml @@ -34,17 +34,20 @@ \ No newline at end of file diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/AdjustableTemperatureView.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/AdjustableTemperatureView.java new file mode 100644 index 0000000000000..4cac4456789d7 --- /dev/null +++ b/packages/CarSystemUI/src/com/android/systemui/car/hvac/AdjustableTemperatureView.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2020 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. + */ + +package com.android.systemui.car.hvac; + +import static com.android.systemui.car.hvac.HvacController.convertToCelsius; +import static com.android.systemui.car.hvac.HvacController.convertToFahrenheit; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.view.LayoutInflater; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.android.systemui.R; + +/** + * Displays temperature with a button to decrease and a button to increase on either side. + * Properties configured in the XML: + * hvacAreaId - Example: VehicleSeat.SEAT_ROW_1_LEFT (1) + */ +public class AdjustableTemperatureView extends LinearLayout implements TemperatureView { + + private HvacController mHvacController; + private float mCurrentTempC; + private TextView mTempTextView; + private boolean mDisplayInFahrenheit = false; + + private final float mMinTempC; + private final float mMaxTempC; + private final int mAreaId; + private final String mTempFormat; + + public AdjustableTemperatureView(Context context, AttributeSet attrs) { + super(context, attrs); + TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TemperatureView); + mAreaId = typedArray.getInt(R.styleable.TemperatureView_hvacAreaId, -1); + + LayoutInflater.from(context).inflate(R.layout.adjustable_temperature_view, /* root= */this); + mTempFormat = getResources().getString(R.string.hvac_temperature_format); + mMinTempC = getResources().getFloat(R.dimen.hvac_min_value_celsius); + mMaxTempC = getResources().getFloat(R.dimen.hvac_max_value_celsius); + initializeButtons(); + } + + @Override + public void setHvacController(HvacController controller) { + mHvacController = controller; + } + + @Override + public void setTemperatureView(float tempC) { + if (tempC > mMaxTempC || tempC < mMinTempC) { + return; + } + if (mTempTextView == null) { + mTempTextView = findViewById(R.id.hvac_temperature_text); + } + mTempTextView.setText(String.format(mTempFormat, + mDisplayInFahrenheit ? convertToFahrenheit(tempC) : tempC)); + mCurrentTempC = tempC; + } + + @Override + public void setDisplayInFahrenheit(boolean displayFahrenheit) { + mDisplayInFahrenheit = displayFahrenheit; + setTemperatureView(mCurrentTempC); + } + + @Override + public int getAreaId() { + return mAreaId; + } + + private void initializeButtons() { + findViewById(R.id.hvac_decrease_button).setOnClickListener(v -> { + float newTemp = mDisplayInFahrenheit ? convertToCelsius( + convertToFahrenheit(mCurrentTempC) - 1) : (mCurrentTempC - 1); + setTemperature(newTemp, mAreaId); + }); + + findViewById(R.id.hvac_increase_button).setOnClickListener(v -> { + float newTemp = mDisplayInFahrenheit ? convertToCelsius( + convertToFahrenheit(mCurrentTempC) + 1) : (mCurrentTempC + 1); + setTemperature(newTemp, mAreaId); + }); + } + + private void setTemperature(float tempC, int zone) { + if (tempC < mMaxTempC && tempC > mMinTempC && mHvacController != null) { + mHvacController.setTemperature(tempC, zone); + } + } +} diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/AnimatedTemperatureView.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/AnimatedTemperatureView.java index a7294317f46c3..567baa91cb59b 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/hvac/AnimatedTemperatureView.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/hvac/AnimatedTemperatureView.java @@ -16,6 +16,8 @@ package com.android.systemui.car.hvac; +import static com.android.systemui.car.hvac.HvacController.convertToFahrenheit; + import android.animation.ObjectAnimator; import android.annotation.SuppressLint; import android.content.Context; @@ -40,9 +42,7 @@ import com.android.systemui.R; * Simple text display of HVAC properties, It is designed to show mTemperature and is configured in * the XML. * XML properties: - * hvacPropertyId - Example: CarHvacManager.ID_ZONED_TEMP_SETPOINT (16385) - * hvacAreaId - Example: VehicleSeat.SEAT_ROW_1_LEFT (1) - * hvacTempFormat - Example: "%.1f\u00B0" (1 decimal and the degree symbol) + * hvacAreaId - Example: VehicleAreaSeat.SEAT_ROW_1_LEFT (1) * hvacOrientaion = Example: left */ public class AnimatedTemperatureView extends FrameLayout implements TemperatureView { @@ -84,7 +84,6 @@ public class AnimatedTemperatureView extends FrameLayout implements TemperatureV } private final int mAreaId; - private final int mPropertyId; private final int mPivotOffset; private final int mGravity; private final int mTextAppearanceRes; @@ -100,12 +99,13 @@ public class AnimatedTemperatureView extends FrameLayout implements TemperatureV private final TemperatureTextAnimator mTextAnimator; boolean mDisplayInFahrenheit = false; + private HvacController mHvacController; + public AnimatedTemperatureView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AnimatedTemperatureView); mAreaId = typedArray.getInt(R.styleable.AnimatedTemperatureView_hvacAreaId, -1); - mPropertyId = typedArray.getInt(R.styleable.AnimatedTemperatureView_hvacPropertyId, -1); mPivotOffset = typedArray.getDimensionPixelOffset( R.styleable.AnimatedTemperatureView_hvacPivotOffset, 0); @@ -115,11 +115,8 @@ public class AnimatedTemperatureView extends FrameLayout implements TemperatureV typedArray.getResourceId(R.styleable.AnimatedTemperatureView_android_textAppearance, 0); mMinEms = typedArray.getInteger(R.styleable.AnimatedTemperatureView_android_minEms, 0); - mMinValue = typedArray.getFloat(R.styleable.AnimatedTemperatureView_hvacMinValue, - Float.NaN); - mMaxValue = typedArray.getFloat(R.styleable.AnimatedTemperatureView_hvacMaxValue, - Float.NaN); - + mMinValue = getResources().getFloat(R.dimen.hvac_min_value_celsius); + mMaxValue = getResources().getFloat(R.dimen.hvac_max_value_celsius); mPaddingRect = new Rect(getPaddingLeft(), getPaddingTop(), getPaddingRight(), getPaddingBottom()); @@ -138,15 +135,10 @@ public class AnimatedTemperatureView extends FrameLayout implements TemperatureV mBackgroundAnimator = new TemperatureBackgroundAnimator(this, background); - - String format = typedArray.getString(R.styleable.AnimatedTemperatureView_hvacTempFormat); - format = (format == null) ? "%.1f\u00B0" : format; - CharSequence minText = typedArray.getString( - R.styleable.AnimatedTemperatureView_hvacMinText); - CharSequence maxText = typedArray.getString( - R.styleable.AnimatedTemperatureView_hvacMaxText); - mTextAnimator = new TemperatureTextAnimator(this, textSwitcher, format, mPivotOffset, - minText, maxText); + mTextAnimator = new TemperatureTextAnimator(this, textSwitcher, + getResources().getString(R.string.hvac_temperature_format), mPivotOffset, + getResources().getString(R.string.hvac_min_text), + getResources().getString(R.string.hvac_max_text)); addView(background, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); @@ -186,13 +178,18 @@ public class AnimatedTemperatureView extends FrameLayout implements TemperatureV return textView; } + @Override + public void setHvacController(HvacController controller) { + mHvacController = controller; + } + /** * Formats the float for display * * @param temp - The current temp or NaN */ @Override - public void setTemp(float temp) { + public void setTemperatureView(float temp) { if (mDisplayInFahrenheit) { temp = convertToFahrenheit(temp); } @@ -252,15 +249,7 @@ public class AnimatedTemperatureView extends FrameLayout implements TemperatureV } /** - * @return propertiyId Example: CarHvacManager.ID_ZONED_TEMP_SETPOINT (358614275) - */ - @Override - public int getPropertyId() { - return mPropertyId; - } - - /** - * @return hvac AreaId - Example: VehicleSeat.SEAT_ROW_1_LEFT (1) + * @return hvac AreaId - Example: VehicleAreaSeat.SEAT_ROW_1_LEFT (1) */ @Override public int getAreaId() { @@ -272,6 +261,5 @@ public class AnimatedTemperatureView extends FrameLayout implements TemperatureV super.onDetachedFromWindow(); mBackgroundAnimator.stopAnimations(); } - } diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/HvacController.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/HvacController.java index a4b6bfc58d3c3..f7451dc6fdee7 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/hvac/HvacController.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/hvac/HvacController.java @@ -18,12 +18,12 @@ package com.android.systemui.car.hvac; import static android.car.VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL; import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS; +import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_SET; import android.car.Car; import android.car.VehicleUnit; import android.car.hardware.CarPropertyValue; -import android.car.hardware.hvac.CarHvacManager; -import android.car.hardware.hvac.CarHvacManager.CarHvacEventCallback; +import android.car.hardware.property.CarPropertyManager; import android.util.Log; import android.view.View; import android.view.ViewGroup; @@ -34,10 +34,8 @@ import com.android.systemui.dagger.SysUISingleton; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Set; import javax.inject.Inject; @@ -54,49 +52,64 @@ public class HvacController { private final CarServiceProvider mCarServiceProvider; private final Set mRegisteredViews = new HashSet<>(); - private CarHvacManager mHvacManager; - private HashMap> mTempComponents = new HashMap<>(); + private CarPropertyManager mCarPropertyManager; + private HashMap> mTempComponents = new HashMap<>(); - /** - * Callback for getting changes from {@link CarHvacManager} and setting the UI elements to - * match. - */ - private final CarHvacEventCallback mHardwareCallback = new CarHvacEventCallback() { - @Override - public void onChangeEvent(final CarPropertyValue val) { - try { - int areaId = val.getAreaId(); - int propertyId = val.getPropertyId(); - List temperatureViews = mTempComponents.get( - new HvacKey(propertyId, areaId)); - if (temperatureViews != null && !temperatureViews.isEmpty()) { - float value = (float) val.getValue(); - if (DEBUG) { - Log.d(TAG, "onChangeEvent: " + areaId + ":" + propertyId + ":" + value); + private final CarPropertyManager.CarPropertyEventCallback mHvacTemperatureSetCallback = + new CarPropertyManager.CarPropertyEventCallback() { + @Override + public void onChangeEvent(CarPropertyValue value) { + try { + int areaId = value.getAreaId(); + List temperatureViews = mTempComponents.get(areaId); + if (temperatureViews != null && !temperatureViews.isEmpty()) { + float newTemp = (float) value.getValue(); + if (DEBUG) { + Log.d(TAG, "onChangeEvent: " + areaId + ":" + value); + } + for (TemperatureView view : temperatureViews) { + view.setTemperatureView(newTemp); + } + } + } catch (Exception e) { + Log.e(TAG, "Failed handling hvac change event", e); } - for (TemperatureView tempView : temperatureViews) { - tempView.setTemp(value); - } - } // else the data is not of interest - } catch (Exception e) { - // catch all so we don't take down the sysui if a new data type is - // introduced. - Log.e(TAG, "Failed handling hvac change event", e); - } - } + } - @Override - public void onErrorEvent(final int propertyId, final int zone) { - Log.d(TAG, "HVAC error event, propertyId: " + propertyId - + " zone: " + zone); - } - }; + @Override + public void onErrorEvent(int propId, int zone) { + Log.d(TAG, "HVAC error event, propertyId: " + propId + " zone: " + zone); + } + }; + + private final CarPropertyManager.CarPropertyEventCallback mTemperatureUnitChangeCallback = + new CarPropertyManager.CarPropertyEventCallback() { + @Override + public void onChangeEvent(CarPropertyValue value) { + if (!mRegisteredViews.isEmpty()) { + for (TemperatureView view : mRegisteredViews) { + view.setDisplayInFahrenheit( + value.getValue().equals(VehicleUnit.FAHRENHEIT)); + } + } + } + + @Override + public void onErrorEvent(int propId, int zone) { + Log.d(TAG, "HVAC error event, propertyId: " + propId + " zone: " + zone); + } + }; private final CarServiceProvider.CarServiceOnConnectedListener mCarServiceLifecycleListener = car -> { try { - mHvacManager = (CarHvacManager) car.getCarManager(Car.HVAC_SERVICE); - mHvacManager.registerCallback(mHardwareCallback); + mCarPropertyManager = (CarPropertyManager) car.getCarManager( + Car.PROPERTY_SERVICE); + mCarPropertyManager.registerCallback(mHvacTemperatureSetCallback, + HVAC_TEMPERATURE_SET, CarPropertyManager.SENSOR_RATE_ONCHANGE); + mCarPropertyManager.registerCallback(mTemperatureUnitChangeCallback, + HVAC_TEMPERATURE_DISPLAY_UNITS, + CarPropertyManager.SENSOR_RATE_ONCHANGE); initComponents(); } catch (Exception e) { Log.e(TAG, "Failed to correctly connect to HVAC", e); @@ -109,8 +122,7 @@ public class HvacController { } /** - * Create connection to the Car service. Note: call backs from the Car service - * ({@link CarHvacManager}) will happen on the same thread this method was called from. + * Create connection to the Car service. */ public void connectToCarService() { mCarServiceProvider.addListener(mCarServiceLifecycleListener); @@ -124,21 +136,18 @@ public class HvacController { return; } - HvacKey hvacKey = new HvacKey(temperatureView.getPropertyId(), temperatureView.getAreaId()); - if (!mTempComponents.containsKey(hvacKey)) { - mTempComponents.put(hvacKey, new ArrayList<>()); + int areaId = temperatureView.getAreaId(); + if (!mTempComponents.containsKey(areaId)) { + mTempComponents.put(areaId, new ArrayList<>()); } - mTempComponents.get(hvacKey).add(temperatureView); + mTempComponents.get(areaId).add(temperatureView); initComponent(temperatureView); mRegisteredViews.add(temperatureView); } private void initComponents() { - Iterator>> iterator = - mTempComponents.entrySet().iterator(); - while (iterator.hasNext()) { - Map.Entry> next = iterator.next(); + for (Map.Entry> next : mTempComponents.entrySet()) { List temperatureViews = next.getValue(); for (TemperatureView view : temperatureViews) { initComponent(view); @@ -147,29 +156,29 @@ public class HvacController { } private void initComponent(TemperatureView view) { - int id = view.getPropertyId(); int zone = view.getAreaId(); if (DEBUG) { - Log.d(TAG, "initComponent: " + zone + ":" + id); + Log.d(TAG, "initComponent: " + zone); } try { - if (mHvacManager != null - && mHvacManager.isPropertyAvailable(HVAC_TEMPERATURE_DISPLAY_UNITS, - VEHICLE_AREA_TYPE_GLOBAL)) { - if (mHvacManager.getIntProperty(HVAC_TEMPERATURE_DISPLAY_UNITS, + if (mCarPropertyManager != null && mCarPropertyManager.isPropertyAvailable( + HVAC_TEMPERATURE_DISPLAY_UNITS, VEHICLE_AREA_TYPE_GLOBAL)) { + if (mCarPropertyManager.getIntProperty(HVAC_TEMPERATURE_DISPLAY_UNITS, VEHICLE_AREA_TYPE_GLOBAL) == VehicleUnit.FAHRENHEIT) { view.setDisplayInFahrenheit(true); } - } - if (mHvacManager == null || !mHvacManager.isPropertyAvailable(id, zone)) { - view.setTemp(Float.NaN); + if (mCarPropertyManager == null || !mCarPropertyManager.isPropertyAvailable( + HVAC_TEMPERATURE_SET, zone)) { + view.setTemperatureView(Float.NaN); return; } - view.setTemp(mHvacManager.getFloatProperty(id, zone)); + view.setTemperatureView( + mCarPropertyManager.getFloatProperty(HVAC_TEMPERATURE_SET, zone)); + view.setHvacController(this); } catch (Exception e) { - view.setTemp(Float.NaN); + view.setTemperatureView(Float.NaN); Log.e(TAG, "Failed to get value from hvac service", e); } } @@ -199,30 +208,32 @@ public class HvacController { } /** - * Key for storing {@link TemperatureView}s in a hash map + * Set the temperature in Celsius of the specified zone */ - private static class HvacKey { - - int mPropertyId; - int mAreaId; - - private HvacKey(int propertyId, int areaId) { - mPropertyId = propertyId; - mAreaId = areaId; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - HvacKey hvacKey = (HvacKey) o; - return mPropertyId == hvacKey.mPropertyId - && mAreaId == hvacKey.mAreaId; - } - - @Override - public int hashCode() { - return Objects.hash(mPropertyId, mAreaId); + public void setTemperature(float tempC, int zone) { + if (mCarPropertyManager != null) { + // Internally, all temperatures are represented in floating point Celsius + mCarPropertyManager.setFloatProperty(HVAC_TEMPERATURE_SET, zone, tempC); } } + + /** + * Convert the given temperature in Celsius into Fahrenheit + * + * @param tempC - The temperature in Celsius + * @return Temperature in Fahrenheit. + */ + public static float convertToFahrenheit(float tempC) { + return (tempC * 9f / 5f) + 32; + } + + /** + * Convert the given temperature in Fahrenheit to Celsius + * + * @param tempF - The temperature in Fahrenheit. + * @return Temperature in Celsius. + */ + public static float convertToCelsius(float tempF) { + return (float) ((tempF - 32) * 0.55555555556); + } } diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextView.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextView.java index 521a665da5f61..252f7830b72cc 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextView.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureTextView.java @@ -16,6 +16,8 @@ package com.android.systemui.car.hvac; +import static com.android.systemui.car.hvac.HvacController.convertToFahrenheit; + import android.content.Context; import android.content.res.TypedArray; import android.util.AttributeSet; @@ -27,24 +29,25 @@ import com.android.systemui.R; * Simple text display of HVAC properties, It is designed to show temperature and is configured in * the XML. * XML properties: - * hvacPropertyId - Example: CarHvacManager.ID_ZONED_TEMP_SETPOINT (16385) - * hvacAreaId - Example: VehicleSeat.SEAT_ROW_1_LEFT (1) - * hvacTempFormat - Example: "%.1f\u00B0" (1 decimal and the degree symbol) + * hvacAreaId - Example: VehicleAreaSeat.SEAT_ROW_1_LEFT (1) */ public class TemperatureTextView extends TextView implements TemperatureView { private final int mAreaId; - private final int mPropertyId; private final String mTempFormat; + private HvacController mHvacController; private boolean mDisplayFahrenheit = false; public TemperatureTextView(Context context, AttributeSet attrs) { super(context, attrs); TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.TemperatureView); mAreaId = typedArray.getInt(R.styleable.TemperatureView_hvacAreaId, -1); - mPropertyId = typedArray.getInt(R.styleable.TemperatureView_hvacPropertyId, -1); - String format = typedArray.getString(R.styleable.TemperatureView_hvacTempFormat); - mTempFormat = (format == null) ? "%.1f\u00B0" : format; + mTempFormat = getResources().getString(R.string.hvac_temperature_format); + } + + @Override + public void setHvacController(HvacController controller) { + mHvacController = controller; } /** @@ -53,7 +56,7 @@ public class TemperatureTextView extends TextView implements TemperatureView { * @param temp - The current temp or NaN */ @Override - public void setTemp(float temp) { + public void setTemperatureView(float temp) { if (Float.isNaN(temp)) { setText("--"); return; @@ -70,15 +73,7 @@ public class TemperatureTextView extends TextView implements TemperatureView { } /** - * @return propertiyId Example: CarHvacManager.ID_ZONED_TEMP_SETPOINT (16385) - */ - @Override - public int getPropertyId() { - return mPropertyId; - } - - /** - * @return hvac AreaId - Example: VehicleSeat.SEAT_ROW_1_LEFT (1) + * @return hvac AreaId - Example: VehicleAreaSeat.SEAT_ROW_1_LEFT (1) */ @Override public int getAreaId() { diff --git a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureView.java b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureView.java index 6b903fad505ce..3c0e0acc446c1 100644 --- a/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureView.java +++ b/packages/CarSystemUI/src/com/android/systemui/car/hvac/TemperatureView.java @@ -17,15 +17,23 @@ package com.android.systemui.car.hvac; /** - * Interface for Views that display temperature HVAC properties + * Interface for Views that display temperature HVAC properties. */ public interface TemperatureView { + + /** + * Sets the {@link HvacController} to handle changes to HVAC properties. The View is only + * responsible for the UI to display temperature. It should not contain logic that makes direct + * changes to HVAC properties and instead use this {@link HvacController}. + */ + void setHvacController(HvacController controller); + /** * Formats the float for display * * @param temp - The current temp in Celsius or NaN */ - void setTemp(float temp); + void setTemperatureView(float temp); /** * Render the displayed temperature in Fahrenheit @@ -35,22 +43,7 @@ public interface TemperatureView { void setDisplayInFahrenheit(boolean displayFahrenheit); /** - * Convert the given temperature in Celsius into Fahrenheit - * - * @param realTemp - The temperature in Celsius - * @return Temperature in Fahrenheit. - */ - default float convertToFahrenheit(float realTemp) { - return (realTemp * 9f / 5f) + 32; - } - - /** - * @return propertiyId Example: CarHvacManager.ID_ZONED_TEMP_SETPOINT (16385) - */ - int getPropertyId(); - - /** - * @return hvac AreaId - Example: VehicleSeat.SEAT_ROW_1_LEFT (1) + * @return hvac AreaId - Example: VehicleAreaSeat.SEAT_ROW_1_LEFT (1) */ int getAreaId(); } diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/AdjustableTemperatureViewTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/AdjustableTemperatureViewTest.java new file mode 100644 index 0000000000000..e8850def6bcd1 --- /dev/null +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/AdjustableTemperatureViewTest.java @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2020 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. + */ + +package com.android.systemui.car.hvac; + +import static android.car.VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL; +import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS; +import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_SET; + +import static com.android.systemui.car.hvac.HvacController.convertToCelsius; +import static com.android.systemui.car.hvac.HvacController.convertToFahrenheit; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.car.Car; +import android.car.VehicleUnit; +import android.car.hardware.property.CarPropertyManager; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.widget.TextView; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.R; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.car.CarServiceProvider; +import com.android.systemui.car.CarSystemUiTest; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@CarSystemUiTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +@SmallTest +public class AdjustableTemperatureViewTest extends SysuiTestCase { + + private static final float TEMP_CELSIUS = 22.0f; + private final String mFormat = getContext().getString(R.string.hvac_temperature_format); + private AdjustableTemperatureView mAdjustableTemperatureView; + private HvacController mHvacController; + + @Mock + private Car mCar; + @Mock + private CarPropertyManager mCarPropertyManager; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(mCar.isConnected()).thenReturn(true); + when(mCar.getCarManager(Car.PROPERTY_SERVICE)).thenReturn(mCarPropertyManager); + + CarServiceProvider carServiceProvider = new CarServiceProvider(mContext, mCar); + mHvacController = new HvacController(carServiceProvider); + mHvacController.connectToCarService(); + mAdjustableTemperatureView = new AdjustableTemperatureView(getContext(), /* attrs= */ null); + mAdjustableTemperatureView.setHvacController(mHvacController); + } + + @Test + public void addTemperatureViewToController_setsTemperatureView() { + when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET), + anyInt())).thenReturn(true); + when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn( + TEMP_CELSIUS); + + mHvacController.addTemperatureViewToController(mAdjustableTemperatureView); + + TextView tempText = mAdjustableTemperatureView.findViewById(R.id.hvac_temperature_text); + assertEquals(tempText.getText(), String.format(mFormat, TEMP_CELSIUS)); + } + + @Test + public void setTemperatureToFahrenheit_callsViewSetDisplayInFahrenheit() { + when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET), + anyInt())).thenReturn(true); + when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn( + TEMP_CELSIUS); + when(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_DISPLAY_UNITS, + VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(true); + when(mCarPropertyManager.getIntProperty(HVAC_TEMPERATURE_DISPLAY_UNITS, + VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(VehicleUnit.FAHRENHEIT); + + mHvacController.addTemperatureViewToController(mAdjustableTemperatureView); + + TextView tempText = mAdjustableTemperatureView.findViewById(R.id.hvac_temperature_text); + assertEquals(tempText.getText(), String.format(mFormat, convertToFahrenheit(TEMP_CELSIUS))); + } + + @Test + public void adjustableViewIncreaseButton_setsTempWithCarPropertyManager() { + when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET), + anyInt())).thenReturn(true); + when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn( + TEMP_CELSIUS); + mHvacController.addTemperatureViewToController(mAdjustableTemperatureView); + + mAdjustableTemperatureView.findViewById(R.id.hvac_increase_button).callOnClick(); + + verify(mCarPropertyManager).setFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt(), + eq(TEMP_CELSIUS + 1)); + } + + @Test + public void adjustableViewDecreaseButton_setsTempWithCarPropertyManager() { + when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET), + anyInt())).thenReturn(true); + when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn( + TEMP_CELSIUS); + mHvacController.addTemperatureViewToController(mAdjustableTemperatureView); + + mAdjustableTemperatureView.findViewById(R.id.hvac_decrease_button).callOnClick(); + + verify(mCarPropertyManager).setFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt(), + eq(TEMP_CELSIUS - 1)); + } + + @Test + public void adjustableViewIncreaseButton_inFahrenheit_setsTempWithCarPropertyManager() { + when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET), + anyInt())).thenReturn(true); + when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn( + TEMP_CELSIUS); + when(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_DISPLAY_UNITS, + VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(true); + when(mCarPropertyManager.getIntProperty(HVAC_TEMPERATURE_DISPLAY_UNITS, + VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(VehicleUnit.FAHRENHEIT); + mHvacController.addTemperatureViewToController(mAdjustableTemperatureView); + + mAdjustableTemperatureView.findViewById(R.id.hvac_increase_button).callOnClick(); + + verify(mCarPropertyManager).setFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt(), + eq(convertToCelsius(convertToFahrenheit(TEMP_CELSIUS) + 1))); + } + + @Test + public void adjustableViewDecreaseButton_inFahrenheit_setsTempWithCarPropertyManager() { + when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET), + anyInt())).thenReturn(true); + when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn( + TEMP_CELSIUS); + when(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_DISPLAY_UNITS, + VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(true); + when(mCarPropertyManager.getIntProperty(HVAC_TEMPERATURE_DISPLAY_UNITS, + VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(VehicleUnit.FAHRENHEIT); + mHvacController.addTemperatureViewToController(mAdjustableTemperatureView); + + mAdjustableTemperatureView.findViewById(R.id.hvac_decrease_button).callOnClick(); + + verify(mCarPropertyManager).setFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt(), + eq(convertToCelsius(convertToFahrenheit(TEMP_CELSIUS) - 1))); + } +} diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java index e179ef1ce2a41..9912657d78e1b 100644 --- a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/HvacControllerTest.java @@ -16,7 +16,13 @@ package com.android.systemui.car.hvac; +import static android.car.VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL; +import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS; +import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_SET; + import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyFloat; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; @@ -24,7 +30,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.car.Car; -import android.car.hardware.hvac.CarHvacManager; +import android.car.VehicleUnit; +import android.car.hardware.property.CarPropertyManager; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; @@ -46,92 +53,91 @@ import org.mockito.MockitoAnnotations; @SmallTest public class HvacControllerTest extends SysuiTestCase { - private static final int PROPERTY_ID = 1; private static final int AREA_ID = 1; - private static final float VALUE = 72.0f; + private static final float TEMP = 72.0f; private HvacController mHvacController; - private CarServiceProvider mCarServiceProvider; @Mock private Car mCar; @Mock - private CarHvacManager mCarHvacManager; + private CarPropertyManager mCarPropertyManager; @Before public void setUp() { MockitoAnnotations.initMocks(this); when(mCar.isConnected()).thenReturn(true); - when(mCar.getCarManager(Car.HVAC_SERVICE)).thenReturn(mCarHvacManager); + when(mCar.getCarManager(Car.PROPERTY_SERVICE)).thenReturn(mCarPropertyManager); - mCarServiceProvider = new CarServiceProvider(mContext, mCar); - mHvacController = new HvacController(mCarServiceProvider); + CarServiceProvider carServiceProvider = new CarServiceProvider(mContext, mCar); + mHvacController = new HvacController(carServiceProvider); mHvacController.connectToCarService(); } @Test public void connectToCarService_registersCallback() { - verify(mCarHvacManager).registerCallback(any()); + verify(mCarPropertyManager).registerCallback(any(), eq(HVAC_TEMPERATURE_SET), anyFloat()); + verify(mCarPropertyManager).registerCallback(any(), eq(HVAC_TEMPERATURE_DISPLAY_UNITS), + anyFloat()); } @Test public void addTemperatureViewToController_usingTemperatureView_registersView() { - TemperatureTextView v = setupMockTemperatureTextView(PROPERTY_ID, AREA_ID, VALUE); + TemperatureTextView v = setupMockTemperatureTextView(AREA_ID, TEMP); mHvacController.addTemperatureViewToController(v); - verify(v).setTemp(VALUE); + verify(v).setTemperatureView(TEMP); } @Test public void addTemperatureViewToController_usingSameTemperatureView_registersFirstView() { - TemperatureTextView v = setupMockTemperatureTextView(PROPERTY_ID, AREA_ID, VALUE); + TemperatureTextView v = setupMockTemperatureTextView(AREA_ID, TEMP); mHvacController.addTemperatureViewToController(v); - verify(v).setTemp(VALUE); - resetTemperatureView(v, PROPERTY_ID, AREA_ID); + verify(v).setTemperatureView(TEMP); + resetTemperatureView(v, AREA_ID); mHvacController.addTemperatureViewToController(v); - verify(v, never()).setTemp(VALUE); + verify(v, never()).setTemperatureView(TEMP); } @Test public void addTemperatureViewToController_usingDifferentTemperatureView_registersBothViews() { - TemperatureTextView v1 = setupMockTemperatureTextView(PROPERTY_ID, AREA_ID, VALUE); + TemperatureTextView v1 = setupMockTemperatureTextView(AREA_ID, TEMP); mHvacController.addTemperatureViewToController(v1); - verify(v1).setTemp(VALUE); + verify(v1).setTemperatureView(TEMP); TemperatureTextView v2 = setupMockTemperatureTextView( - PROPERTY_ID + 1, AREA_ID + 1, - VALUE + 1); + TEMP + 1); mHvacController.addTemperatureViewToController(v2); - verify(v2).setTemp(VALUE + 1); + verify(v2).setTemperatureView(TEMP + 1); } @Test - public void removeAllComponents_ableToRegisterSameView() { - TemperatureTextView v = setupMockTemperatureTextView(PROPERTY_ID, AREA_ID, VALUE); - mHvacController.addTemperatureViewToController(v); - verify(v).setTemp(VALUE); - - mHvacController.removeAllComponents(); - resetTemperatureView(v, PROPERTY_ID, AREA_ID); + public void setTemperatureToFahrenheit_callsViewSetDisplayInFahrenheit() { + when(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_DISPLAY_UNITS, + VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(true); + when(mCarPropertyManager.getIntProperty(HVAC_TEMPERATURE_DISPLAY_UNITS, + VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(VehicleUnit.FAHRENHEIT); + TemperatureTextView v = setupMockTemperatureTextView(AREA_ID, TEMP); mHvacController.addTemperatureViewToController(v); - verify(v).setTemp(VALUE); + + verify(v).setDisplayInFahrenheit(true); + verify(v).setTemperatureView(TEMP); } - private TemperatureTextView setupMockTemperatureTextView(int propertyId, int areaId, - float value) { + private TemperatureTextView setupMockTemperatureTextView(int areaId, float value) { TemperatureTextView v = mock(TemperatureTextView.class); - resetTemperatureView(v, propertyId, areaId); - when(mCarHvacManager.isPropertyAvailable(propertyId, areaId)).thenReturn(true); - when(mCarHvacManager.getFloatProperty(propertyId, areaId)).thenReturn(value); + resetTemperatureView(v, areaId); + when(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_SET, areaId)).thenReturn( + true); + when(mCarPropertyManager.getFloatProperty(HVAC_TEMPERATURE_SET, areaId)).thenReturn(value); return v; } - private void resetTemperatureView(TemperatureTextView view, int propertyId, int areaId) { + private void resetTemperatureView(TemperatureTextView view, int areaId) { reset(view); - when(view.getPropertyId()).thenReturn(propertyId); when(view.getAreaId()).thenReturn(areaId); } } diff --git a/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/TemperatureTextViewTest.java b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/TemperatureTextViewTest.java new file mode 100644 index 0000000000000..e97d9d9b3f6a9 --- /dev/null +++ b/packages/CarSystemUI/tests/src/com/android/systemui/car/hvac/TemperatureTextViewTest.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2020 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. + */ + +package com.android.systemui.car.hvac; + +import static android.car.VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL; +import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS; +import static android.car.VehiclePropertyIds.HVAC_TEMPERATURE_SET; + +import static com.android.systemui.car.hvac.HvacController.convertToFahrenheit; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; + +import android.car.Car; +import android.car.VehicleUnit; +import android.car.hardware.property.CarPropertyManager; +import android.content.Context; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.R; +import com.android.systemui.SysuiTestCase; +import com.android.systemui.car.CarServiceProvider; +import com.android.systemui.car.CarSystemUiTest; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@CarSystemUiTest +@RunWith(AndroidTestingRunner.class) +@TestableLooper.RunWithLooper +@SmallTest +public class TemperatureTextViewTest extends SysuiTestCase { + private static final float TEMP = 72.0f; + private final String mFormat = getContext().getString(R.string.hvac_temperature_format); + private HvacController mHvacController; + private TemperatureTextView mTextView; + + @Mock + private Context mContext; + + @Mock + private Car mCar; + @Mock + private CarPropertyManager mCarPropertyManager; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + when(mCar.isConnected()).thenReturn(true); + when(mCar.getCarManager(Car.PROPERTY_SERVICE)).thenReturn(mCarPropertyManager); + + CarServiceProvider carServiceProvider = new CarServiceProvider(mContext, mCar); + mHvacController = new HvacController(carServiceProvider); + mHvacController.connectToCarService(); + mTextView = new TemperatureTextView(getContext(), /* attrs= */ null); + } + + @Test + public void addTemperatureViewToController_usingTemperatureView_registersView() { + when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET), + anyInt())).thenReturn(true); + when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn( + TEMP); + + mHvacController.addTemperatureViewToController(mTextView); + + assertEquals(mTextView.getText(), String.format(mFormat, TEMP)); + } + + @Test + public void setTemperatureToFahrenheit_callsViewSetDisplayInFahrenheit() { + when(mCarPropertyManager.isPropertyAvailable(eq(HVAC_TEMPERATURE_SET), + anyInt())).thenReturn(true); + when(mCarPropertyManager.getFloatProperty(eq(HVAC_TEMPERATURE_SET), anyInt())).thenReturn( + TEMP); + when(mCarPropertyManager.isPropertyAvailable(HVAC_TEMPERATURE_DISPLAY_UNITS, + VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(true); + when(mCarPropertyManager.getIntProperty(HVAC_TEMPERATURE_DISPLAY_UNITS, + VEHICLE_AREA_TYPE_GLOBAL)).thenReturn(VehicleUnit.FAHRENHEIT); + + mHvacController.addTemperatureViewToController(mTextView); + + assertEquals(mTextView.getText(), String.format(mFormat, convertToFahrenheit(TEMP))); + } +}