Merge "Format sensor values and imperial unit conversions"
diff --git a/tests/DirectRenderingClusterSample/res/values-en-rUS/dimens.xml b/tests/DirectRenderingClusterSample/res/values-en-rUS/dimens.xml
new file mode 100644
index 0000000..05eef22
--- /dev/null
+++ b/tests/DirectRenderingClusterSample/res/values-en-rUS/dimens.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <!-- -->
+ <!-- Sensor value conversion constants -->
+ <!-- -->
+ <!-- Speed: meters per second to miles per hour -->
+ <item name="speed_factor" format="float" type="dimen">2.236936</item>
+ <!-- Distance: miles to meters -->
+ <item name="distance_factor" format="float" type="dimen">1609.344</item>
+</resources>
\ No newline at end of file
diff --git a/tests/DirectRenderingClusterSample/res/values/dimens.xml b/tests/DirectRenderingClusterSample/res/values/dimens.xml
index 2979b36..6d22a70 100644
--- a/tests/DirectRenderingClusterSample/res/values/dimens.xml
+++ b/tests/DirectRenderingClusterSample/res/values/dimens.xml
@@ -40,4 +40,12 @@
<dimen name="laneview_height">25dp</dimen>
<dimen name="lane_width">50dp</dimen>
<dimen name="lane_height">50dp</dimen>
+
+ <!-- -->
+ <!-- Sensor value conversion constants -->
+ <!-- -->
+ <!-- Speed: meters per second to kilometers per hour -->
+ <item name="speed_factor" format="float" type="dimen">3.6</item>
+ <!-- Distance: kilometers to meters -->
+ <item name="distance_factor" format="float" type="dimen">1000</item>
</resources>
diff --git a/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/ClusterViewModel.java b/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/ClusterViewModel.java
index a53f4ba..d1e6ee6 100644
--- a/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/ClusterViewModel.java
+++ b/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/ClusterViewModel.java
@@ -28,6 +28,7 @@
import android.content.ServiceConnection;
import android.os.IBinder;
import android.util.Log;
+import android.util.TypedValue;
import androidx.annotation.NonNull;
import androidx.core.util.Preconditions;
@@ -36,6 +37,7 @@
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Transformations;
+import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@@ -48,6 +50,9 @@
private static final int PROPERTIES_REFRESH_RATE_UI = 5;
+ private float mSpeedFactor;
+ private float mDistanceFactor;
+
public enum NavigationActivityState {
/** No activity has been selected to be displayed on the navigation fragment yet */
NOT_SELECTED,
@@ -110,42 +115,43 @@
}
}
-
private CarPropertyManager.CarPropertyEventListener mCarPropertyEventListener =
new CarPropertyManager.CarPropertyEventListener() {
- @Override
- public void onChangeEvent(CarPropertyValue value) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "CarProperty change: property " + value.getPropertyId() + ", area"
- + value.getAreaId() + ", value: " + value.getValue());
- }
- for (Sensor<?> sensorId : Sensors.getInstance()
- .getSensorsForPropertyId(value.getPropertyId())) {
- if (sensorId.mAreaId == Sensors.GLOBAL_AREA_ID
- || (sensorId.mAreaId & value.getAreaId()) != 0) {
- setSensorValue(sensorId, value);
+ @Override
+ public void onChangeEvent(CarPropertyValue value) {
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG,
+ "CarProperty change: property " + value.getPropertyId() + ", area"
+ + value.getAreaId() + ", value: " + value.getValue());
+ }
+ for (Sensor<?> sensorId : Sensors.getInstance()
+ .getSensorsForPropertyId(value.getPropertyId())) {
+ if (sensorId.mAreaId == Sensors.GLOBAL_AREA_ID
+ || (sensorId.mAreaId & value.getAreaId()) != 0) {
+ setSensorValue(sensorId, value);
+ }
+ }
}
- }
- }
- @Override
- public void onErrorEvent(int propId, int zone) {
- for (Sensor<?> sensorId : Sensors.getInstance().getSensorsForPropertyId(propId)) {
- if (sensorId.mAreaId == VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL
- || (sensorId.mAreaId & zone) != 0) {
- setSensorValue(sensorId, null);
+ @Override
+ public void onErrorEvent(int propId, int zone) {
+ for (Sensor<?> sensorId : Sensors.getInstance().getSensorsForPropertyId(
+ propId)) {
+ if (sensorId.mAreaId == VehicleAreaType.VEHICLE_AREA_TYPE_GLOBAL
+ || (sensorId.mAreaId & zone) != 0) {
+ setSensorValue(sensorId, null);
+ }
+ }
}
- }
- }
- private <T> void setSensorValue(Sensor<T> id, CarPropertyValue<?> value) {
- T newValue = value != null ? id.mAdapter.apply(value) : null;
- if (Log.isLoggable(TAG, Log.DEBUG)) {
- Log.d(TAG, "Sensor " + id.mName + " = " + newValue);
- }
- getSensorMutableLiveData(id).setValue(newValue);
- }
- };
+ private <T> void setSensorValue(Sensor<T> id, CarPropertyValue<?> value) {
+ T newValue = value != null ? id.mAdapter.apply(value) : null;
+ if (Log.isLoggable(TAG, Log.DEBUG)) {
+ Log.d(TAG, "Sensor " + id.mName + " = " + newValue);
+ }
+ getSensorMutableLiveData(id).setValue(newValue);
+ }
+ };
/**
* New {@link ClusterViewModel} instance
@@ -154,6 +160,13 @@
super(application);
mCar = Car.createCar(application, mCarServiceConnection);
mCar.connect();
+
+ TypedValue tv = new TypedValue();
+ getApplication().getResources().getValue(R.dimen.speed_factor, tv, true);
+ mSpeedFactor = tv.getFloat();
+
+ getApplication().getResources().getValue(R.dimen.distance_factor, tv, true);
+ mDistanceFactor = tv.getFloat();
}
@Override
@@ -187,7 +200,7 @@
* own data type. The list of all supported sensors can be found at {@link Sensors}
*
* @param sensor sensor to observe
- * @param <T> data type of such sensor
+ * @param <T> data type of such sensor
*/
@SuppressWarnings("unchecked")
@NonNull
@@ -199,8 +212,8 @@
* Returns the current value of the sensor, directly from the VHAL.
*
* @param sensor sensor to read
- * @param <V> VHAL data type
- * @param <T> data type of such sensor
+ * @param <V> VHAL data type
+ * @param <T> data type of such sensor
*/
@Nullable
public <T> T getSensorValue(@NonNull Sensor<T> sensor) {
@@ -210,21 +223,48 @@
}
/**
- * Returns a {@link LiveData} that tracks the fuel level in a range from 0.0 to 1.0.
+ * Returns a {@link LiveData} that tracks the fuel level in a range from 0 to 100.
*/
- public LiveData<Float> getFuelLevel() {
+ public LiveData<Integer> getFuelLevel() {
return Transformations.map(getSensor(Sensors.SENSOR_FUEL), (fuelValue) -> {
Float fuelCapacityValue = getSensorValue(Sensors.SENSOR_FUEL_CAPACITY);
if (fuelValue == null || fuelCapacityValue == null || fuelCapacityValue == 0) {
return null;
}
if (fuelValue < 0.0f) {
- return 0.0f;
+ return 0;
}
if (fuelValue > fuelCapacityValue) {
- return 1.0f;
+ return 100;
}
- return fuelValue / fuelCapacityValue;
+ return Math.round(fuelValue / (fuelCapacityValue * 100f));
+ });
+ }
+
+ /**
+ * Returns a {@link LiveData} that tracks the RPM x 1000
+ */
+ public LiveData<String> getRPM() {
+ return Transformations.map(getSensor(Sensors.SENSOR_RPM), (rpmValue) -> {
+ return new DecimalFormat("#0.0").format(rpmValue / 1000f);
+ });
+ }
+
+ /**
+ * Returns a {@link LiveData} that tracks the speed in either mi/h or km/h depending on locale.
+ */
+ public LiveData<Integer> getSpeed() {
+ return Transformations.map(getSensor(Sensors.SENSOR_SPEED), (speedValue) -> {
+ return Math.round(speedValue * mSpeedFactor);
+ });
+ }
+
+ /**
+ * Returns a {@link LiveData} that tracks the range the vehicle has until it runs out of gas.
+ */
+ public LiveData<Integer> getRange() {
+ return Transformations.map(getSensor(Sensors.SENSOR_FUEL_RANGE), (rangeValue) -> {
+ return Math.round(rangeValue / mDistanceFactor);
});
}
diff --git a/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/MainClusterActivity.java b/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/MainClusterActivity.java
index 13a1399..9f4f931 100644
--- a/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/MainClusterActivity.java
+++ b/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/MainClusterActivity.java
@@ -227,12 +227,9 @@
mClusterViewModel.getSensor(Sensors.SENSOR_GEAR).observe(this, this::updateSelectedGear);
registerSensor(findViewById(R.id.info_fuel), mClusterViewModel.getFuelLevel());
- registerSensor(findViewById(R.id.info_speed),
- mClusterViewModel.getSensor(Sensors.SENSOR_SPEED));
- registerSensor(findViewById(R.id.info_range),
- mClusterViewModel.getSensor(Sensors.SENSOR_FUEL_RANGE));
- registerSensor(findViewById(R.id.info_rpm),
- mClusterViewModel.getSensor(Sensors.SENSOR_RPM));
+ registerSensor(findViewById(R.id.info_speed), mClusterViewModel.getSpeed());
+ registerSensor(findViewById(R.id.info_range), mClusterViewModel.getRange());
+ registerSensor(findViewById(R.id.info_rpm), mClusterViewModel.getRPM());
mActivityMonitor.start();
diff --git a/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/sensors/Sensors.java b/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/sensors/Sensors.java
index 6e49931..90d6350 100644
--- a/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/sensors/Sensors.java
+++ b/tests/DirectRenderingClusterSample/src/android/car/cluster/sample/sensors/Sensors.java
@@ -60,12 +60,12 @@
"RPM", VehiclePropertyIds.ENGINE_RPM, GLOBAL_AREA_ID,
VehiclePropertyType.FLOAT,
value -> (Float) value.getValue());
- /** Fuel range in kilometers */
+ /** Fuel range in meters */
public static final Sensor<Float> SENSOR_FUEL_RANGE = registerSensor(
"Fuel Range", VehiclePropertyIds.RANGE_REMAINING, GLOBAL_AREA_ID,
VehiclePropertyType.FLOAT,
value -> (Float) value.getValue());
- /** Speed in kph */
+ /** Speed in meters per second */
public static final Sensor<Float> SENSOR_SPEED = registerSensor(
"Speed", VehiclePropertyIds.PERF_VEHICLE_SPEED, GLOBAL_AREA_ID,
VehiclePropertyType.FLOAT,