Remove LOCAL_CLANG am: 7a3f3ef53e am: 1426ca0155 am: 97f6422cd3
am: 633e098d12
Change-Id: Idb9e2c2acae2649c49911329b45801cf647c73b0
diff --git a/car-lib/api/system-current.txt b/car-lib/api/system-current.txt
index 6f32dd7..568d611 100644
--- a/car-lib/api/system-current.txt
+++ b/car-lib/api/system-current.txt
@@ -32,11 +32,13 @@
field public static final java.lang.String PERMISSION_MILEAGE = "android.car.permission.CAR_MILEAGE";
field public static final deprecated java.lang.String PERMISSION_MOCK_VEHICLE_HAL = "android.car.permission.CAR_MOCK_VEHICLE_HAL";
field public static final java.lang.String PERMISSION_SPEED = "android.car.permission.CAR_SPEED";
+ field public static final java.lang.String PERMISSION_STORAGE_MONITORING = "android.car.permission.STORAGE_MONITORING";
field public static final java.lang.String PERMISSION_VEHICLE_DYNAMICS_STATE = "android.car.permission.VEHICLE_DYNAMICS_STATE";
field public static final java.lang.String PERMISSION_VENDOR_EXTENSION = "android.car.permission.CAR_VENDOR_EXTENSION";
field public static final java.lang.String PROJECTION_SERVICE = "projection";
field public static final java.lang.String RADIO_SERVICE = "radio";
field public static final java.lang.String SENSOR_SERVICE = "sensor";
+ field public static final java.lang.String STORAGE_MONITORING_SERVICE = "storage_monitoring";
field public static final java.lang.String TEST_SERVICE = "car-service-test";
field public static final java.lang.String VENDOR_EXTENSION_SERVICE = "vendor_extension";
field public static final int VERSION = 3; // 0x3
@@ -485,6 +487,7 @@
method public boolean isFreezeFrameNotificationSupported() throws android.car.CarNotConnectedException;
method public boolean isGetFreezeFrameSupported() throws android.car.CarNotConnectedException;
method public boolean isLiveFrameSupported() throws android.car.CarNotConnectedException;
+ method public boolean isSelectiveClearFreezeFramesSupported() throws android.car.CarNotConnectedException;
method public void onCarDisconnected();
method public boolean registerListener(android.car.diagnostic.CarDiagnosticManager.OnDiagnosticEventListener, int, int) throws android.car.CarNotConnectedException, java.lang.IllegalArgumentException;
method public void unregisterListener(android.car.diagnostic.CarDiagnosticManager.OnDiagnosticEventListener);
@@ -998,6 +1001,45 @@
}
+package android.car.storagemonitoring {
+
+ public final class CarStorageMonitoringManager {
+ method public int getPreEolIndicatorStatus() throws android.car.CarNotConnectedException;
+ method public android.car.storagemonitoring.WearEstimate getWearEstimate() throws android.car.CarNotConnectedException;
+ field public static final int PRE_EOL_INFO_NORMAL = 1; // 0x1
+ field public static final int PRE_EOL_INFO_UNKNOWN = 0; // 0x0
+ field public static final int PRE_EOL_INFO_URGENT = 3; // 0x3
+ field public static final int PRE_EOL_INFO_WARNING = 2; // 0x2
+ }
+
+ public class WearEstimate implements android.os.Parcelable {
+ ctor public WearEstimate(int, int);
+ ctor public WearEstimate(android.os.Parcel);
+ ctor public WearEstimate(android.util.JsonReader) throws java.io.IOException;
+ method public int describeContents();
+ method public void writeToJson(android.util.JsonWriter) throws java.io.IOException;
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.car.storagemonitoring.WearEstimate> CREATOR;
+ field public static final int UNKNOWN = -1; // 0xffffffff
+ field public final int typeA;
+ field public final int typeB;
+ }
+
+ public class WearEstimateChange implements android.os.Parcelable {
+ ctor public WearEstimateChange(android.car.storagemonitoring.WearEstimate, android.car.storagemonitoring.WearEstimate, long, Instant, boolean);
+ ctor public WearEstimateChange(android.os.Parcel);
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.car.storagemonitoring.WearEstimateChange> CREATOR;
+ field public final Instant dateAtChange;
+ field public final boolean isAcceptableDegradation;
+ field public final android.car.storagemonitoring.WearEstimate newEstimate;
+ field public final android.car.storagemonitoring.WearEstimate oldEstimate;
+ field public final long uptimeAtChange;
+ }
+
+}
+
package android.car.test {
public class CarTestManagerBinderWrapper {
@@ -1008,3 +1050,112 @@
}
+package android.car.vms {
+
+ public final class VmsAssociatedLayer implements android.os.Parcelable {
+ ctor public VmsAssociatedLayer(android.car.vms.VmsLayer, java.util.Set<java.lang.Integer>);
+ method public int describeContents();
+ method public java.util.Set<java.lang.Integer> getPublisherIds();
+ method public android.car.vms.VmsLayer getVmsLayer();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.car.vms.VmsAssociatedLayer> CREATOR;
+ }
+
+ public final class VmsLayer implements android.os.Parcelable {
+ ctor public VmsLayer(int, int, int);
+ method public int describeContents();
+ method public int getSubtype();
+ method public int getType();
+ method public int getVersion();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.car.vms.VmsLayer> CREATOR;
+ }
+
+ public final class VmsLayerDependency implements android.os.Parcelable {
+ ctor public VmsLayerDependency(android.car.vms.VmsLayer, java.util.Set<android.car.vms.VmsLayer>);
+ ctor public VmsLayerDependency(android.car.vms.VmsLayer);
+ method public int describeContents();
+ method public java.util.Set<android.car.vms.VmsLayer> getDependencies();
+ method public android.car.vms.VmsLayer getLayer();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.car.vms.VmsLayerDependency> CREATOR;
+ }
+
+ public final class VmsLayersOffering implements android.os.Parcelable {
+ ctor public VmsLayersOffering(java.util.Set<android.car.vms.VmsLayerDependency>, int);
+ method public int describeContents();
+ method public java.util.Set<android.car.vms.VmsLayerDependency> getDependencies();
+ method public int getPublisherId();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.car.vms.VmsLayersOffering> CREATOR;
+ }
+
+ public final class VmsOperationRecorder {
+ ctor public VmsOperationRecorder(android.car.vms.VmsOperationRecorder.Writer);
+ method public void addHalSubscription(int, android.car.vms.VmsLayer);
+ method public void addPromiscuousSubscription(int);
+ method public void addSubscription(int, android.car.vms.VmsLayer);
+ method public static android.car.vms.VmsOperationRecorder get();
+ method public void getPublisherId(int);
+ method public void removeHalSubscription(int, android.car.vms.VmsLayer);
+ method public void removePromiscuousSubscription(int);
+ method public void removeSubscription(int, android.car.vms.VmsLayer);
+ method public void setHalPublisherLayersOffering(android.car.vms.VmsLayersOffering);
+ method public void setLayersOffering(android.car.vms.VmsLayersOffering);
+ method public void setPublisherLayersOffering(android.car.vms.VmsLayersOffering);
+ method public void startMonitoring();
+ method public void stopMonitoring();
+ method public void subscribe(android.car.vms.VmsLayer);
+ method public void subscribe(android.car.vms.VmsLayer, int);
+ method public void unsubscribe(android.car.vms.VmsLayer);
+ method public void unsubscribe(android.car.vms.VmsLayer, int);
+ }
+
+ public static class VmsOperationRecorder.Writer {
+ ctor public VmsOperationRecorder.Writer();
+ method public boolean isEnabled();
+ method public void write(java.lang.String);
+ }
+
+ public abstract class VmsPublisherClientService extends android.app.Service {
+ ctor public VmsPublisherClientService();
+ method public final int getPublisherId(byte[]);
+ method public final android.car.vms.VmsSubscriptionState getSubscriptions();
+ method public final android.os.IBinder onBind(android.content.Intent);
+ method public final boolean onUnbind(android.content.Intent);
+ method protected abstract void onVmsPublisherServiceReady();
+ method public abstract void onVmsSubscriptionChange(android.car.vms.VmsSubscriptionState);
+ method public final void publish(android.car.vms.VmsLayer, int, byte[]);
+ method public final void setLayersOffering(android.car.vms.VmsLayersOffering);
+ }
+
+ public final class VmsSubscriberManager {
+ ctor public VmsSubscriberManager(android.os.IBinder, android.os.Handler);
+ method public byte[] getPublisherInfo(int) throws android.car.CarNotConnectedException, java.lang.IllegalStateException;
+ method public void registerClientCallback(android.car.vms.VmsSubscriberManager.VmsSubscriberClientCallback) throws android.car.CarNotConnectedException;
+ method public void startMonitoring() throws android.car.CarNotConnectedException;
+ method public void stopMonitoring();
+ method public void subscribe(android.car.vms.VmsLayer) throws android.car.CarNotConnectedException;
+ method public void subscribe(android.car.vms.VmsLayer, int) throws android.car.CarNotConnectedException;
+ method public void unregisterClientCallback() throws android.car.CarNotConnectedException;
+ method public void unsubscribe(android.car.vms.VmsLayer);
+ method public void unsubscribe(android.car.vms.VmsLayer, int);
+ }
+
+ public static abstract interface VmsSubscriberManager.VmsSubscriberClientCallback {
+ method public abstract void onLayersAvailabilityChanged(java.util.List<android.car.vms.VmsLayer>);
+ method public abstract void onVmsMessageReceived(android.car.vms.VmsLayer, byte[]);
+ }
+
+ public final class VmsSubscriptionState implements android.os.Parcelable {
+ ctor public VmsSubscriptionState(int, java.util.Set<android.car.vms.VmsLayer>, java.util.Set<android.car.vms.VmsAssociatedLayer>);
+ method public int describeContents();
+ method public java.util.Set<android.car.vms.VmsAssociatedLayer> getAssociatedLayers();
+ method public java.util.Set<android.car.vms.VmsLayer> getLayers();
+ method public int getSequenceNumber();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.car.vms.VmsSubscriptionState> CREATOR;
+ }
+
+}
+
diff --git a/car-lib/src/android/car/Car.java b/car-lib/src/android/car/Car.java
index c0b83f7..6101797 100644
--- a/car-lib/src/android/car/Car.java
+++ b/car-lib/src/android/car/Car.java
@@ -31,6 +31,7 @@
import android.car.media.CarAudioManager;
import android.car.navigation.CarNavigationStatusManager;
import android.car.CarBluetoothManager;
+import android.car.storagemonitoring.CarStorageMonitoringManager;
import android.car.test.CarTestManagerBinderWrapper;
import android.car.vms.VmsSubscriberManager;
import android.content.ComponentName;
@@ -141,6 +142,12 @@
public static final String VMS_SUBSCRIBER_SERVICE = "vehicle_map_subscriber_service";
/**
+ * @hide
+ */
+ @SystemApi
+ public static final String STORAGE_MONITORING_SERVICE = "storage_monitoring";
+
+ /**
* Service for testing. This is system app only feature.
* Service name for {@link CarTestManager}, to be used in {@link #getCarManager(String)}.
* @hide
@@ -293,6 +300,14 @@
@SystemApi
public static final String PERMISSION_CAR_DIAGNOSTIC_CLEAR = "android.car.permission.DIAGNOSTIC_CLEAR";
+ /**
+ * Permissions necessary to clear diagnostic information.
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final String PERMISSION_STORAGE_MONITORING = "android.car.permission.STORAGE_MONITORING";
+
/** Type of car connection: platform runs directly in car. */
public static final int CONNECTION_TYPE_EMBEDDED = 5;
@@ -655,12 +670,12 @@
manager = new CarTestManagerBinderWrapper(binder);
break;
case VMS_SUBSCRIBER_SERVICE:
- if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) {
- manager = new VmsSubscriberManager(binder, mEventHandler);
- }
+ manager = new VmsSubscriberManager(binder, mEventHandler);
break;
case BLUETOOTH_SERVICE:
manager = new CarBluetoothManager(binder, mContext);
+ case STORAGE_MONITORING_SERVICE:
+ manager = new CarStorageMonitoringManager(binder);
}
return manager;
}
diff --git a/car-lib/src/android/car/diagnostic/CarDiagnosticManager.java b/car-lib/src/android/car/diagnostic/CarDiagnosticManager.java
index 84cdd3e..88980bf 100644
--- a/car-lib/src/android/car/diagnostic/CarDiagnosticManager.java
+++ b/car-lib/src/android/car/diagnostic/CarDiagnosticManager.java
@@ -349,8 +349,13 @@
}
/**
- * Returns true if this vehicle supports clearing freeze frame timestamps.
+ * Returns true if this vehicle supports clearing all freeze frames.
* This is only meaningful if freeze frame data is also supported.
+ *
+ * A return value of true for this method indicates that it is supported to call
+ * carDiagnosticManager.clearFreezeFrames()
+ * to delete all freeze frames stored in vehicle memory.
+ *
* @return
* @throws CarNotConnectedException
*/
@@ -365,6 +370,28 @@
return false;
}
+ /**
+ * Returns true if this vehicle supports clearing specific freeze frames by timestamp.
+ * This is only meaningful if freeze frame data is also supported.
+ *
+ * A return value of true for this method indicates that it is supported to call
+ * carDiagnosticManager.clearFreezeFrames(timestamp1, timestamp2, ...)
+ * to delete the freeze frames stored for the provided input timestamps, provided any exist.
+ *
+ * @return
+ * @throws CarNotConnectedException
+ */
+ public boolean isSelectiveClearFreezeFramesSupported() throws CarNotConnectedException {
+ try {
+ return mService.isSelectiveClearFreezeFramesSupported();
+ } catch (IllegalStateException e) {
+ CarApiUtil.checkCarNotConnectedExceptionFromCarService(e);
+ } catch (RemoteException e) {
+ throw new CarNotConnectedException();
+ }
+ return false;
+ }
+
private static class CarDiagnosticEventListenerToService
extends Stub {
private final WeakReference<CarDiagnosticManager> mManager;
diff --git a/car-lib/src/android/car/diagnostic/ICarDiagnostic.aidl b/car-lib/src/android/car/diagnostic/ICarDiagnostic.aidl
index 3d1808f..57443d8 100644
--- a/car-lib/src/android/car/diagnostic/ICarDiagnostic.aidl
+++ b/car-lib/src/android/car/diagnostic/ICarDiagnostic.aidl
@@ -74,4 +74,10 @@
* Returns whether the underlying HAL supports clearing freeze frames.
*/
boolean isClearFreezeFramesSupported() = 10;
+
+ /**
+ * Returns whether the underlying HAL supports clearing specific freeze frames specified
+ * by means of their timestamps.
+ */
+ boolean isSelectiveClearFreezeFramesSupported() = 11;
}
diff --git a/car-lib/src/android/car/storagemonitoring/CarStorageMonitoringManager.java b/car-lib/src/android/car/storagemonitoring/CarStorageMonitoringManager.java
new file mode 100644
index 0000000..aa2ad84
--- /dev/null
+++ b/car-lib/src/android/car/storagemonitoring/CarStorageMonitoringManager.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2017 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 android.car.storagemonitoring;
+
+import android.annotation.SystemApi;
+import android.car.CarApiUtil;
+import android.car.CarManagerBase;
+import android.car.CarNotConnectedException;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+/**
+ * API for retrieving information and metrics about the flash storage.
+ *
+ * @hide
+ */
+@SystemApi
+public final class CarStorageMonitoringManager implements CarManagerBase {
+ private final ICarStorageMonitoring mService;
+
+ public static final int PRE_EOL_INFO_UNKNOWN = 0;
+ public static final int PRE_EOL_INFO_NORMAL = 1;
+ public static final int PRE_EOL_INFO_WARNING = 2;
+ public static final int PRE_EOL_INFO_URGENT = 3;
+
+ /** @hide */
+ public CarStorageMonitoringManager(IBinder service) {
+ mService = ICarStorageMonitoring.Stub.asInterface(service);
+ }
+
+ /** @hide */
+ @Override
+ public void onCarDisconnected() {
+ }
+
+ // ICarStorageMonitoring forwards
+
+ /**
+ * This method returns the value of the "pre EOL" indicator for the flash storage
+ * as retrieved during the current boot cycle.
+ *
+ * It will return either PRE_EOL_INFO_UNKNOWN if the value can't be determined,
+ * or one of PRE_EOL_INFO_{NORMAL|WARNING|URGENT} depending on the device state.
+ * @return
+ * @throws CarNotConnectedException
+ */
+ public int getPreEolIndicatorStatus() throws CarNotConnectedException {
+ try {
+ return mService.getPreEolIndicatorStatus();
+ } catch (IllegalStateException e) {
+ CarApiUtil.checkCarNotConnectedExceptionFromCarService(e);
+ } catch (RemoteException e) {
+ throw new CarNotConnectedException();
+ }
+ return PRE_EOL_INFO_UNKNOWN;
+ }
+
+ /**
+ * This method returns the value of the wear estimate indicators for the flash storage
+ * as retrieved during the current boot cycle.
+ *
+ * The indicators are guaranteed to be a lower-bound on the actual wear of the storage.
+ * Current technology in common automotive usage offers estimates in 10% increments.
+ *
+ * If either or both indicators are not available, they will be reported as UNKNOWN.
+ * @return
+ * @throws CarNotConnectedException
+ */
+ public WearEstimate getWearEstimate() throws CarNotConnectedException {
+ try {
+ return mService.getWearEstimate();
+ } catch (IllegalStateException e) {
+ CarApiUtil.checkCarNotConnectedExceptionFromCarService(e);
+ } catch (RemoteException e) {
+ throw new CarNotConnectedException();
+ }
+ return new WearEstimate(WearEstimate.UNKNOWN, WearEstimate.UNKNOWN);
+ }
+
+}
+
diff --git a/car-lib/src/android/car/storagemonitoring/ICarStorageMonitoring.aidl b/car-lib/src/android/car/storagemonitoring/ICarStorageMonitoring.aidl
new file mode 100644
index 0000000..61910c5
--- /dev/null
+++ b/car-lib/src/android/car/storagemonitoring/ICarStorageMonitoring.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 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 android.car.storagemonitoring;
+
+import android.car.storagemonitoring.WearEstimate;
+
+/** @hide */
+interface ICarStorageMonitoring {
+ /**
+ * Returns the value of the PRE_EOL register.
+ */
+ int getPreEolIndicatorStatus() = 1;
+
+ /**
+ * Returns the current wear estimate indicators.
+ */
+ WearEstimate getWearEstimate() = 2;
+}
diff --git a/car-lib/src/android/car/storagemonitoring/WearEstimate.aidl b/car-lib/src/android/car/storagemonitoring/WearEstimate.aidl
new file mode 100644
index 0000000..c7ea505
--- /dev/null
+++ b/car-lib/src/android/car/storagemonitoring/WearEstimate.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2017 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 android.car.storagemonitoring;
+
+parcelable WearEstimate;
diff --git a/car-lib/src/android/car/storagemonitoring/WearEstimate.java b/car-lib/src/android/car/storagemonitoring/WearEstimate.java
new file mode 100644
index 0000000..d7abc2b
--- /dev/null
+++ b/car-lib/src/android/car/storagemonitoring/WearEstimate.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2017 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 android.car.storagemonitoring;
+
+import android.annotation.IntRange;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.JsonReader;
+import android.util.JsonToken;
+import android.util.JsonWriter;
+import java.io.IOException;
+import java.util.Objects;
+
+/**
+ * Wear-out information for flash storage.
+ *
+ * Contains a lower-bound estimate of the wear of "type A" (SLC) and "type B" (MLC) storage.
+ *
+ * Current technology offers wear data in increments of 10% (i.e. from 0 == new device up to
+ * 100 == worn-out device). It is possible for a storage device to only support one type of memory
+ * cell, in which case it is expected that the storage type not supported will have UNKNOWN wear.
+ *
+ * @hide
+ */
+@SystemApi
+public class WearEstimate implements Parcelable {
+ public static final int UNKNOWN = -1;
+
+ public static final Parcelable.Creator<WearEstimate> CREATOR =
+ new Parcelable.Creator<WearEstimate>() {
+ public WearEstimate createFromParcel(Parcel in) {
+ return new WearEstimate(in);
+ }
+
+ public WearEstimate[] newArray(int size) {
+ return new WearEstimate[size];
+ }
+ };
+
+ /**
+ * Wear estimate data for "type A" storage.
+ */
+ @IntRange(from=-1, to=100)
+ public final int typeA;
+
+ /**
+ * Wear estimate data for "type B" storage.
+ */
+ @IntRange(from=-1, to=100)
+ public final int typeB;
+
+ private static final int validateWearValue(int value) {
+ if (value == UNKNOWN) return value;
+ if ((value >= 0) && (value <= 100)) return value;
+ throw new IllegalArgumentException(value + " is not a valid wear estimate");
+ }
+
+ public WearEstimate(int typeA, int typeB) {
+ this.typeA = validateWearValue(typeA);
+ this.typeB = validateWearValue(typeB);
+ }
+
+ public WearEstimate(Parcel in) {
+ typeA = validateWearValue(in.readInt());
+ typeB = validateWearValue(in.readInt());
+ }
+
+ public WearEstimate(JsonReader in) throws IOException {
+ int typeA = UNKNOWN;
+ int typeB = UNKNOWN;
+ in.beginObject();
+ while (in.hasNext()) {
+ switch (in.nextName()) {
+ case "wearEstimateTypeA":
+ typeA = validateWearValue(in.nextInt());
+ break;
+ case "wearEstimateTypeB":
+ typeB = validateWearValue(in.nextInt());
+ break;
+ }
+ }
+ in.endObject();
+ this.typeA = typeA;
+ this.typeB = typeB;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(typeA);
+ dest.writeInt(typeB);
+ }
+
+ public void writeToJson(JsonWriter jsonWriter) throws IOException {
+ jsonWriter.beginObject();
+ jsonWriter.name("wearEstimateTypeA").value(typeA);
+ jsonWriter.name("wearEstimateTypeB").value(typeB);
+ jsonWriter.endObject();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof WearEstimate) {
+ WearEstimate wo = (WearEstimate)other;
+ return wo.typeA == typeA && wo.typeB == typeB;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(typeA, typeB);
+ }
+
+ private static final String wearValueToString(int value) {
+ if (value == UNKNOWN) return "unknown";
+ return value + "%";
+ }
+
+ @Override
+ public String toString() {
+ return "type A: " + wearValueToString(typeA) + ", type B: " + wearValueToString(typeB);
+ }
+}
diff --git a/car-lib/src/android/car/storagemonitoring/WearEstimateChange.aidl b/car-lib/src/android/car/storagemonitoring/WearEstimateChange.aidl
new file mode 100644
index 0000000..49adfe5
--- /dev/null
+++ b/car-lib/src/android/car/storagemonitoring/WearEstimateChange.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2017 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 android.car.storagemonitoring;
+
+parcelable WearEstimateChange;
diff --git a/car-lib/src/android/car/storagemonitoring/WearEstimateChange.java b/car-lib/src/android/car/storagemonitoring/WearEstimateChange.java
new file mode 100644
index 0000000..5c80a31
--- /dev/null
+++ b/car-lib/src/android/car/storagemonitoring/WearEstimateChange.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2017 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 android.car.storagemonitoring;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import java.time.Instant;
+import java.util.Objects;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Change in wear-out information.
+ *
+ * Contains information about the first cycle during which the system detected a change
+ * in wear-out information of the flash storage.
+ *
+ * @hide
+ */
+@SystemApi
+public class WearEstimateChange implements Parcelable {
+ public static final Parcelable.Creator<WearEstimateChange> CREATOR =
+ new Parcelable.Creator<WearEstimateChange>() {
+ public WearEstimateChange createFromParcel(Parcel in) {
+ return new WearEstimateChange(in);
+ }
+
+ public WearEstimateChange[] newArray(int size) {
+ return new WearEstimateChange[size];
+ }
+ };
+
+ /**
+ * The previous wear estimate.
+ */
+ public final @NonNull WearEstimate oldEstimate;
+
+ /**
+ * The new wear estimate.
+ */
+ public final @NonNull WearEstimate newEstimate;
+
+ /**
+ * Total CarService uptime when this change was detected.
+ */
+ public final long uptimeAtChange;
+
+ /**
+ * Wall-clock time when this change was detected.
+ */
+ public final @NonNull Instant dateAtChange;
+
+ /**
+ * Whether this change was within the vendor range for acceptable flash degradation.
+ */
+ public final boolean isAcceptableDegradation;
+
+ public WearEstimateChange(WearEstimate oldEstimate,
+ WearEstimate newEstimate,
+ long uptimeAtChange,
+ Instant dateAtChange,
+ boolean isAcceptableDegradation) {
+ if (uptimeAtChange < 0) {
+ throw new IllegalArgumentException("uptimeAtChange must be >= 0");
+ }
+ this.oldEstimate = requireNonNull(oldEstimate);
+ this.newEstimate = requireNonNull(newEstimate);
+ this.uptimeAtChange = uptimeAtChange;
+ this.dateAtChange = requireNonNull(dateAtChange);
+ this.isAcceptableDegradation = isAcceptableDegradation;
+ }
+
+ public WearEstimateChange(Parcel in) {
+ oldEstimate = in.readParcelable(WearEstimate.class.getClassLoader());
+ newEstimate = in.readParcelable(WearEstimate.class.getClassLoader());
+ uptimeAtChange = in.readLong();
+ dateAtChange = Instant.ofEpochMilli(in.readLong());
+ isAcceptableDegradation = in.readInt() == 1;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeParcelable(oldEstimate, flags);
+ dest.writeParcelable(newEstimate, flags);
+ dest.writeLong(uptimeAtChange);
+ dest.writeLong(dateAtChange.toEpochMilli());
+ dest.writeInt(isAcceptableDegradation ? 1 : 0);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof WearEstimateChange) {
+ WearEstimateChange wo = (WearEstimateChange)other;
+ return wo.isAcceptableDegradation == isAcceptableDegradation &&
+ wo.uptimeAtChange == uptimeAtChange &&
+ wo.dateAtChange.equals(dateAtChange) &&
+ wo.oldEstimate.equals(oldEstimate) &&
+ wo.newEstimate.equals(newEstimate);
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(oldEstimate,
+ newEstimate,
+ uptimeAtChange,
+ dateAtChange,
+ isAcceptableDegradation);
+ }
+
+ @Override
+ public String toString() {
+ return String.format(
+ "wear change{old level=%s, new level=%s, uptime=%d, date=%s, acceptable=%s}",
+ oldEstimate,
+ newEstimate,
+ uptimeAtChange,
+ dateAtChange,
+ isAcceptableDegradation ? "yes" : "no");
+ }
+
+}
diff --git a/car-lib/src/android/car/vms/VmsAssociatedLayer.java b/car-lib/src/android/car/vms/VmsAssociatedLayer.java
index 023fd9c..55ea541 100644
--- a/car-lib/src/android/car/vms/VmsAssociatedLayer.java
+++ b/car-lib/src/android/car/vms/VmsAssociatedLayer.java
@@ -16,7 +16,6 @@
package android.car.vms;
-import android.car.annotation.FutureFeature;
import android.os.Parcel;
import android.os.Parcelable;
@@ -27,7 +26,6 @@
*
* @hide
*/
-@FutureFeature
public final class VmsAssociatedLayer implements Parcelable {
// The VmsLayer.
diff --git a/car-lib/src/android/car/vms/VmsLayer.java b/car-lib/src/android/car/vms/VmsLayer.java
index 9125796..b921230 100644
--- a/car-lib/src/android/car/vms/VmsLayer.java
+++ b/car-lib/src/android/car/vms/VmsLayer.java
@@ -16,7 +16,7 @@
package android.car.vms;
-import android.car.annotation.FutureFeature;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -27,7 +27,7 @@
*
* @hide
*/
-@FutureFeature
+@SystemApi
public final class VmsLayer implements Parcelable {
// The layer Type.
diff --git a/car-lib/src/android/car/vms/VmsLayerDependency.java b/car-lib/src/android/car/vms/VmsLayerDependency.java
index 3b82775..869fc84 100644
--- a/car-lib/src/android/car/vms/VmsLayerDependency.java
+++ b/car-lib/src/android/car/vms/VmsLayerDependency.java
@@ -16,7 +16,7 @@
package android.car.vms;
-import android.car.annotation.FutureFeature;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
@@ -31,7 +31,7 @@
*
* @hide
*/
-@FutureFeature
+@SystemApi
public final class VmsLayerDependency implements Parcelable {
private final VmsLayer mLayer;
private final Set<VmsLayer> mDependency;
diff --git a/car-lib/src/android/car/vms/VmsLayersOffering.java b/car-lib/src/android/car/vms/VmsLayersOffering.java
index 6abffc6..fc83696 100644
--- a/car-lib/src/android/car/vms/VmsLayersOffering.java
+++ b/car-lib/src/android/car/vms/VmsLayersOffering.java
@@ -16,7 +16,7 @@
package android.car.vms;
-import android.car.annotation.FutureFeature;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import java.util.ArrayList;
@@ -30,7 +30,7 @@
*
* @hide
*/
-@FutureFeature
+@SystemApi
public final class VmsLayersOffering implements Parcelable {
private final Set<VmsLayerDependency> mDependencies;
diff --git a/car-lib/src/android/car/vms/VmsOperationRecorder.java b/car-lib/src/android/car/vms/VmsOperationRecorder.java
index c873dce..bfb6055 100644
--- a/car-lib/src/android/car/vms/VmsOperationRecorder.java
+++ b/car-lib/src/android/car/vms/VmsOperationRecorder.java
@@ -1,6 +1,6 @@
package android.car.vms;
-import android.car.annotation.FutureFeature;
+import android.annotation.SystemApi;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -24,7 +24,7 @@
*
* @hide
*/
-@FutureFeature
+@SystemApi
public final class VmsOperationRecorder {
private static final String TAG = "VmsOperationRecorder";
private static final VmsOperationRecorder INSTANCE = new VmsOperationRecorder(new Writer());
diff --git a/car-lib/src/android/car/vms/VmsPublisherClientService.java b/car-lib/src/android/car/vms/VmsPublisherClientService.java
index 33ca1f3..024fc14 100644
--- a/car-lib/src/android/car/vms/VmsPublisherClientService.java
+++ b/car-lib/src/android/car/vms/VmsPublisherClientService.java
@@ -17,8 +17,8 @@
package android.car.vms;
+import android.annotation.SystemApi;
import android.app.Service;
-import android.car.annotation.FutureFeature;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
@@ -46,7 +46,7 @@
*
* @hide
*/
-@FutureFeature
+@SystemApi
public abstract class VmsPublisherClientService extends Service {
private static final boolean DBG = true;
private static final String TAG = "VmsPublisherClient";
diff --git a/car-lib/src/android/car/vms/VmsSubscriberManager.java b/car-lib/src/android/car/vms/VmsSubscriberManager.java
index 6f6377c..97d4d86 100644
--- a/car-lib/src/android/car/vms/VmsSubscriberManager.java
+++ b/car-lib/src/android/car/vms/VmsSubscriberManager.java
@@ -16,10 +16,10 @@
package android.car.vms;
+import android.annotation.SystemApi;
import android.car.Car;
import android.car.CarManagerBase;
import android.car.CarNotConnectedException;
-import android.car.annotation.FutureFeature;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -40,7 +40,7 @@
*
* @hide
*/
-@FutureFeature
+@SystemApi
public final class VmsSubscriberManager implements CarManagerBase {
private static final boolean DBG = true;
private static final String TAG = "VmsSubscriberManager";
diff --git a/car-lib/src/android/car/vms/VmsSubscriptionState.java b/car-lib/src/android/car/vms/VmsSubscriptionState.java
index ea433f7..1aba30c 100644
--- a/car-lib/src/android/car/vms/VmsSubscriptionState.java
+++ b/car-lib/src/android/car/vms/VmsSubscriptionState.java
@@ -16,7 +16,6 @@
package android.car.vms;
-import android.car.annotation.FutureFeature;
import android.os.Parcel;
import android.os.Parcelable;
@@ -32,7 +31,6 @@
*
* @hide
*/
-@FutureFeature
public final class VmsSubscriptionState implements Parcelable {
private final int mSequenceNumber;
private final Set<VmsLayer> mLayers;
diff --git a/car-lib/src_feature_current/com/android/car/internal/FeatureConfiguration.java b/car-lib/src_feature_current/com/android/car/internal/FeatureConfiguration.java
index 55da870..462f320 100644
--- a/car-lib/src_feature_current/com/android/car/internal/FeatureConfiguration.java
+++ b/car-lib/src_feature_current/com/android/car/internal/FeatureConfiguration.java
@@ -25,5 +25,4 @@
public static final boolean DEFAULT = false;
/** product configuration in CarInfoManager */
public static final boolean ENABLE_PRODUCT_CONFIGURATION_INFO = DEFAULT;
- public static final boolean ENABLE_VEHICLE_MAP_SERVICE = DEFAULT;
}
diff --git a/car-support-lib/proguard-extra-keeps.flags b/car-support-lib/proguard-extra-keeps.flags
index 5e67c6e..72ea927 100644
--- a/car-support-lib/proguard-extra-keeps.flags
+++ b/car-support-lib/proguard-extra-keeps.flags
@@ -17,3 +17,7 @@
public static ... createCluster(...);
public static ... createCustomImageCluster(...);
}
+
+-keep class android.support.car.CarManagerBase {
+ *;
+}
diff --git a/car-support-lib/src/android/support/car/Car.java b/car-support-lib/src/android/support/car/Car.java
index a374d87..e0e3a0d 100644
--- a/car-support-lib/src/android/support/car/Car.java
+++ b/car-support-lib/src/android/support/car/Car.java
@@ -237,6 +237,7 @@
if (mConnectionState == STATE_DISCONNECTED) {
return;
}
+ tearDownCarManagers();
mConnectionState = STATE_DISCONNECTED;
}
mCarConnectionCallback.onDisconnected(Car.this);
diff --git a/service/AndroidManifest.xml b/service/AndroidManifest.xml
index e39fb9e..05073e3 100644
--- a/service/AndroidManifest.xml
+++ b/service/AndroidManifest.xml
@@ -154,6 +154,11 @@
android:label="@string/car_permission_car_cluster_control"
android:description="@string/car_permission_desc_car_cluster_control" />
+ <permission android:name="android.car.permission.STORAGE_MONITORING"
+ android:protectionLevel="system|signature"
+ android:label="@string/car_permission_label_storage_monitoring"
+ android:description="@string/car_permission_desc_storage_monitoring" />
+
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.DEVICE_POWER" />
<uses-permission android:name="android.permission.GRANT_RUNTIME_PERMISSIONS" />
diff --git a/service/res/values/config.xml b/service/res/values/config.xml
index 61cef59..68996d1 100644
--- a/service/res/values/config.xml
+++ b/service/res/values/config.xml
@@ -60,7 +60,7 @@
<string name="instrumentClusterRendererService">android.car.cluster.sample/.SampleClusterServiceImpl</string>
- <!-- Whether to enable Avtivity blocking for safety. When Activity blocking is enabled,
+ <!-- Whether to enable Activity blocking for safety. When Activity blocking is enabled,
only whitelisted safe Activities will be allowed while car is not parked. -->
<bool name="enableActivityBlockingForSafety">true</bool>
<!-- Activity to be presented when un-safe activity is launched. Take a look at the javadoc of the
@@ -81,4 +81,13 @@
<string-array translatable="false" name="vmsSafePermissions">
<item>"android.permission.ACCESS_FINE_LOCATION"</item>
</string-array>
+
+ <!-- Hours of uptime (excluding sleep) after which a 1% increase in the wear of the flash
+ storage in the head-unit is considered as acceptable level of wear. -->
+ <integer name="acceptableHoursPerOnePercentFlashWear">70</integer>
+
+ <!-- How often (in hours of uptime excluding sleep) CarService will flush to disk information
+ about the total running time of the head-unit. A shutdown or reboot of the head-unit
+ will always cause a flush of the uptime information, regardless of this setting. -->
+ <integer name="uptimeHoursIntervalBetweenUptimeDataWrite">5</integer>
</resources>
diff --git a/service/res/values/strings.xml b/service/res/values/strings.xml
index 6cfff9a..37503ab 100644
--- a/service/res/values/strings.xml
+++ b/service/res/values/strings.xml
@@ -125,4 +125,9 @@
<string name="car_permission_label_vms_subscriber">VMS subscriber</string>
<!-- Permission text: apps can receive VMS messages from the car [CHAR LIMIT=NONE] -->
<string name="car_permission_desc_vms_subscriber">Subscribe to vms messages</string>
+
+ <!-- Permission text: apps can monitor flash storage usage [CHAR LIMIT=NONE] -->
+ <string name="car_permission_label_storage_monitoring">Flash storage monitoring</string>
+ <!-- Permission text: apps can monitor flash storage usage [CHAR LIMIT=NONE] -->
+ <string name="car_permission_desc_storage_monitoring">Monitor flash storage usage</string>
</resources>
diff --git a/service/src/com/android/car/CarAudioService.java b/service/src/com/android/car/CarAudioService.java
index f56b105..ab9d271 100644
--- a/service/src/com/android/car/CarAudioService.java
+++ b/service/src/com/android/car/CarAudioService.java
@@ -198,28 +198,32 @@
@Override
public void init() {
- AudioPolicy.Builder builder = new AudioPolicy.Builder(mContext);
- builder.setLooper(Looper.getMainLooper());
- boolean isFocusSupported = mAudioHal.isFocusSupported();
- if (isFocusSupported) {
- builder.setAudioPolicyFocusListener(mSystemFocusListener);
- FocusState currentState = FocusState.create(mAudioHal.getCurrentFocusState());
- int r = mAudioManager.requestAudioFocus(mBottomAudioFocusListener, mAttributeBottom,
- AudioManager.AUDIOFOCUS_GAIN, AudioManager.AUDIOFOCUS_FLAG_DELAY_OK);
- synchronized (mLock) {
- mCurrentFocusState = currentState;
- mCurrentAudioContexts = 0;
- }
- }
int audioHwVariant = mAudioHal.getHwVariant();
AudioRoutingPolicy audioRoutingPolicy = AudioRoutingPolicy.create(mContext, audioHwVariant);
- if (mUseDynamicRouting) {
- setupDynamicRouting(audioRoutingPolicy, builder);
- }
+
AudioPolicy audioPolicy = null;
+ boolean isFocusSupported = mAudioHal.isFocusSupported();
+
+ // Do we need to install a custom audio policy?
if (isFocusSupported || mUseDynamicRouting) {
+ AudioPolicy.Builder builder = new AudioPolicy.Builder(mContext);
+ builder.setLooper(Looper.getMainLooper());
+ if (isFocusSupported) {
+ builder.setAudioPolicyFocusListener(mSystemFocusListener);
+ FocusState currentState = FocusState.create(mAudioHal.getCurrentFocusState());
+ int r = mAudioManager.requestAudioFocus(mBottomAudioFocusListener, mAttributeBottom,
+ AudioManager.AUDIOFOCUS_GAIN, AudioManager.AUDIOFOCUS_FLAG_DELAY_OK);
+ synchronized (mLock) {
+ mCurrentFocusState = currentState;
+ mCurrentAudioContexts = 0;
+ }
+ }
+ if (mUseDynamicRouting) {
+ setupDynamicRouting(audioRoutingPolicy, builder);
+ }
audioPolicy = builder.build();
}
+
mAudioHal.setFocusListener(this);
mAudioHal.setAudioRoutingPolicy(audioRoutingPolicy);
mAudioHal.setOnParameterChangeListener(this);
diff --git a/service/src/com/android/car/CarDiagnosticService.java b/service/src/com/android/car/CarDiagnosticService.java
index 809439c..3bd9979 100644
--- a/service/src/com/android/car/CarDiagnosticService.java
+++ b/service/src/com/android/car/CarDiagnosticService.java
@@ -411,6 +411,13 @@
diagnosticCapabilities.isFreezeFrameSupported();
}
+ public boolean isSelectiveClearFreezeFramesSupported() {
+ DiagnosticCapabilities diagnosticCapabilities =
+ getDiagnosticHal().getDiagnosticCapabilities();
+ return isClearFreezeFramesSupported() &&
+ diagnosticCapabilities.isSelectiveClearFreezeFramesSupported();
+ }
+
// ICarDiagnostic implementations
@Override
@@ -441,14 +448,18 @@
@Override
public boolean clearFreezeFrames(long... timestamps) {
mDiagnosticClearPermission.assertGranted();
- if (mDiagnosticHal.getDiagnosticCapabilities().isFreezeFrameClearSupported()) {
- mFreezeFrameDiagnosticRecords.lock();
- mDiagnosticHal.clearFreezeFrames(timestamps);
- mFreezeFrameDiagnosticRecords.clearEvents();
- mFreezeFrameDiagnosticRecords.unlock();
- return true;
+ if (!isClearFreezeFramesSupported())
+ return false;
+ if (timestamps != null && timestamps.length != 0) {
+ if (!isSelectiveClearFreezeFramesSupported()) {
+ return false;
+ }
}
- return false;
+ mFreezeFrameDiagnosticRecords.lock();
+ mDiagnosticHal.clearFreezeFrames(timestamps);
+ mFreezeFrameDiagnosticRecords.clearEvents();
+ mFreezeFrameDiagnosticRecords.unlock();
+ return true;
}
/**
diff --git a/service/src/com/android/car/CarLog.java b/service/src/com/android/car/CarLog.java
index d9600d6..6ca570f 100644
--- a/service/src/com/android/car/CarLog.java
+++ b/service/src/com/android/car/CarLog.java
@@ -43,6 +43,7 @@
public static final String TAG_SYS = "CAR.SYS";
public static final String TAG_TEST = "CAR.TEST";
public static final String TAG_DIAGNOSTIC = "CAR.DIAGNOSTIC";
+ public static final String TAG_STORAGE = "CAR.STORAGE";
public static String concatTag(String tagPrefix, Class clazz) {
String tag = tagPrefix + "." + clazz.getSimpleName();
diff --git a/service/src/com/android/car/CarService.java b/service/src/com/android/car/CarService.java
index 87e891e..6026fce 100644
--- a/service/src/com/android/car/CarService.java
+++ b/service/src/com/android/car/CarService.java
@@ -95,6 +95,9 @@
super.onCreate();
}
+ // onDestroy is best-effort and might not get called on shutdown/reboot. As such it is not
+ // suitable for permanently saving state or other need-to-happen operation. If you have a
+ // cleanup task that you want to make sure happens on shutdown/reboot, see OnShutdownReboot.
@Override
public void onDestroy() {
Log.i(CarLog.TAG_SERVICE, "Service onDestroy");
diff --git a/service/src/com/android/car/CarStorageMonitoringService.java b/service/src/com/android/car/CarStorageMonitoringService.java
new file mode 100644
index 0000000..82a57af
--- /dev/null
+++ b/service/src/com/android/car/CarStorageMonitoringService.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2017 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.car;
+
+import android.car.Car;
+import android.car.storagemonitoring.ICarStorageMonitoring;
+import android.car.storagemonitoring.WearEstimate;
+import android.content.Context;
+import android.content.Intent;
+import android.util.Log;
+import com.android.car.internal.CarPermission;
+import com.android.car.storagemonitoring.WearInformation;
+import com.android.car.storagemonitoring.WearInformationProvider;
+import java.io.File;
+import java.io.PrintWriter;
+import java.time.Duration;
+import java.util.Optional;
+
+public class CarStorageMonitoringService extends ICarStorageMonitoring.Stub
+ implements CarServiceBase {
+
+ private static final String UPTIME_TRACKER_FILENAME = "service_uptime";
+ private static final String WEAR_INFO_FILENAME = "wear_info";
+
+ private final WearInformationProvider[] mWearInformationProviders;
+ private final Context mContext;
+ private final File mUptimeTrackerFile;
+ private final File mWearInfoFile;
+ private final OnShutdownReboot mOnShutdownReboot;
+
+ private final CarPermission mStorageMonitoringPermission;
+
+ private UptimeTracker mUptimeTracker;
+ private Optional<WearInformation> mWearInformation = Optional.empty();
+
+ public CarStorageMonitoringService(Context context, SystemInterface systemInterface) {
+ mContext = context;
+ mUptimeTrackerFile = new File(systemInterface.getFilesDir(), UPTIME_TRACKER_FILENAME);
+ mWearInfoFile = new File(systemInterface.getFilesDir(), WEAR_INFO_FILENAME);
+ mOnShutdownReboot = new OnShutdownReboot(mContext);
+ mWearInformationProviders = systemInterface.getFlashWearInformationProviders();
+ mStorageMonitoringPermission =
+ new CarPermission(mContext, Car.PERMISSION_STORAGE_MONITORING);
+ }
+
+ /**
+ * The overlay vends this data in hours/1% increase, but the current implementation
+ * works in terms of 10% increases. This method computes the number of milliseconds
+ * that make up an acceptable rate of 10% increases.
+ */
+ static long getAcceptableFlashWearRate() {
+ return 10 * Duration.ofHours(R.integer.acceptableHoursPerOnePercentFlashWear).toMillis();
+ }
+
+ /**
+ * We define the proper interval between uptime snapshots to be 1% of
+ * the value of uptimeHoursForAcceptableWearIncrease in the overlay.
+ */
+ private static long getUptimeSnapshotIntervalMs() {
+ return Duration.ofHours(R.integer.uptimeHoursIntervalBetweenUptimeDataWrite).toMillis();
+ }
+
+ private Optional<WearInformation> loadWearInformation() {
+ for (WearInformationProvider provider : mWearInformationProviders) {
+ WearInformation wearInfo = provider.load();
+ if (wearInfo != null) {
+ return Optional.of(wearInfo);
+ }
+ }
+ return Optional.empty();
+ }
+
+ @Override
+ public void init() {
+ Log.i(CarLog.TAG_STORAGE, "starting up CarStorageMonitoringService");
+ mUptimeTracker = new UptimeTracker(mUptimeTrackerFile, getUptimeSnapshotIntervalMs());
+ mWearInformation = loadWearInformation();
+ mOnShutdownReboot.addAction((Context ctx, Intent intent) -> release());
+ }
+
+ @Override
+ public void release() {
+ Log.i(CarLog.TAG_STORAGE, "tearing down CarStorageMonitoringService");
+ mUptimeTracker.onDestroy();
+ mOnShutdownReboot.clearActions();
+ }
+
+ @Override
+ public void dump(PrintWriter writer) {
+ writer.println("*CarStorageMonitoringService*");
+ writer.println("last wear information retrieved: " +
+ mWearInformation.map(WearInformation::toString).orElse("missing"));
+ }
+
+ // ICarStorageMonitoring implementation
+
+ @Override
+ public int getPreEolIndicatorStatus() {
+ mStorageMonitoringPermission.assertGranted();
+
+ return mWearInformation.map(wi -> wi.preEolInfo)
+ .orElse(WearInformation.UNKNOWN_PRE_EOL_INFO);
+ }
+
+ @Override
+ public WearEstimate getWearEstimate() {
+ mStorageMonitoringPermission.assertGranted();
+
+ return mWearInformation.map(wi ->
+ new WearEstimate(wi.lifetimeEstimateA,wi.lifetimeEstimateB)).orElse(
+ new WearEstimate(WearEstimate.UNKNOWN, WearEstimate.UNKNOWN));
+ }
+}
diff --git a/service/src/com/android/car/CarVolumeControllerFactory.java b/service/src/com/android/car/CarVolumeControllerFactory.java
index c83ef93..7dc3929 100644
--- a/service/src/com/android/car/CarVolumeControllerFactory.java
+++ b/service/src/com/android/car/CarVolumeControllerFactory.java
@@ -23,6 +23,7 @@
import android.media.IVolumeController;
import android.os.Handler;
import android.os.HandlerThread;
+import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteCallbackList;
@@ -90,8 +91,21 @@
* support volume controls.
*/
public static final class SimpleCarVolumeController extends CarVolumeController {
+ private static final String TAG = CarLog.TAG_AUDIO + ".SVolCtrl";
+ private static final int MSG_DISPLAY_SAFE_VOL_WARNING = 0;
+ private static final int MSG_VOL_CHANGED = 1;
+ private static final int MSG_MASTER_MUTE_CHANGED = 2;
+ private static final int MSG_SET_LAYOUT_DIRECTION = 3;
+ private static final int MSG_DISMISS = 4;
+ private static final int MSG_SET_ALLY_MODE = 5;
+
private final AudioManager mAudioManager;
private final Context mContext;
+ private RemoteCallbackList<IVolumeController> mVolumeCallbacks = new RemoteCallbackList<>();
+ @GuardedBy("this")
+ private IVolumeController mVolumeCallbackProxy;
+ private HandlerThread mVolumeThread;
+ private Handler mHandler;
public SimpleCarVolumeController(Context context) {
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
@@ -100,16 +114,27 @@
@Override
void init() {
+ synchronized (this) {
+ mVolumeThread = new HandlerThread(TAG);
+ mVolumeThread.start();
+ mHandler = new VolumeHandler(mVolumeThread.getLooper());
+ }
}
@Override
void release() {
+ synchronized (this) {
+ if (mVolumeThread != null) {
+ mVolumeThread.quit();
+ }
+ }
+ mVolumeCallbacks.kill();
}
@Override
public void setStreamVolume(int stream, int index, int flags) {
if (DBG) {
- Log.d(CarLog.TAG_AUDIO, "setStreamVolume " + stream + " " + index + " " + flags);
+ Log.d(TAG, "setStreamVolume " + stream + " " + index + " " + flags);
}
mAudioManager.setStreamVolume(stream, index, flags);
}
@@ -121,7 +146,13 @@
@Override
public void setVolumeController(IVolumeController controller) {
- mAudioManager.setVolumeController(controller);
+ synchronized (this) {
+ if (mVolumeCallbackProxy == null) {
+ mVolumeCallbackProxy = new VolumeControllerProxy();
+ mAudioManager.setVolumeController(mVolumeCallbackProxy);
+ }
+ }
+ mVolumeCallbacks.register(controller);
}
@Override
@@ -149,6 +180,146 @@
// nothing else to dump
}
+ private class VolumeHandler extends Handler {
+
+ public VolumeHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_DISPLAY_SAFE_VOL_WARNING:
+ int count = mVolumeCallbacks.beginBroadcast();
+ try {
+ for (int i = 0; i < count; i++) {
+ try {
+ mVolumeCallbacks.getBroadcastItem(i)
+ .displaySafeVolumeWarning(msg.arg1);
+ } catch (RemoteException ignored) {}
+ }
+ } finally {
+ mVolumeCallbacks.finishBroadcast();
+ }
+ break;
+ case MSG_VOL_CHANGED:
+ count = mVolumeCallbacks.beginBroadcast();
+ try {
+ for (int i = 0; i < count; i++) {
+ try {
+ mVolumeCallbacks.getBroadcastItem(i)
+ .volumeChanged(msg.arg1, msg.arg2);
+ } catch (RemoteException ignored) {}
+ }
+ } finally {
+ mVolumeCallbacks.finishBroadcast();
+ }
+ break;
+ case MSG_MASTER_MUTE_CHANGED:
+ count = mVolumeCallbacks.beginBroadcast();
+ try {
+ for (int i = 0; i < count; i++) {
+ try {
+ mVolumeCallbacks.getBroadcastItem(i)
+ .masterMuteChanged(msg.arg1);
+ } catch (RemoteException ignored) {}
+ }
+ } finally {
+ mVolumeCallbacks.finishBroadcast();
+ }
+ break;
+ case MSG_SET_LAYOUT_DIRECTION:
+ count = mVolumeCallbacks.beginBroadcast();
+ try {
+ for (int i = 0; i < count; i++) {
+ try {
+ mVolumeCallbacks.getBroadcastItem(i)
+ .setLayoutDirection(msg.arg1);
+ } catch (RemoteException ignored) {}
+ }
+ } finally {
+ mVolumeCallbacks.finishBroadcast();
+ }
+ break;
+ case MSG_DISMISS:
+ count = mVolumeCallbacks.beginBroadcast();
+ try {
+ for (int i = 0; i < count; i++) {
+ try {
+ mVolumeCallbacks.getBroadcastItem(i)
+ .dismiss();
+ } catch (RemoteException ignored) {}
+ }
+ } finally {
+ mVolumeCallbacks.finishBroadcast();
+ }
+ break;
+ case MSG_SET_ALLY_MODE:
+ count = mVolumeCallbacks.beginBroadcast();
+ try {
+ for (int i = 0; i < count; i++) {
+ try {
+ mVolumeCallbacks.getBroadcastItem(i)
+ .setA11yMode(msg.arg1);
+ } catch (RemoteException ignored) {}
+ }
+ } finally {
+ mVolumeCallbacks.finishBroadcast();
+ }
+ break;
+ }
+ }
+ }
+
+ private class VolumeControllerProxy extends IVolumeController.Stub {
+ @Override
+ public void displaySafeVolumeWarning(int flags) throws RemoteException {
+ synchronized (this) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_DISPLAY_SAFE_VOL_WARNING,
+ flags, 0 /*unused*/));
+ }
+ }
+
+ @Override
+ public void volumeChanged(int streamType, int flags) throws RemoteException {
+ synchronized (this) {
+ mHandler.sendMessage(
+ mHandler.obtainMessage(MSG_VOL_CHANGED, streamType, flags));
+ }
+ }
+
+ @Override
+ public void masterMuteChanged(int flags) throws RemoteException {
+ synchronized (this) {
+ mHandler.sendMessage(
+ mHandler.obtainMessage(MSG_VOL_CHANGED, flags, 0 /*unused*/));
+ }
+ }
+
+ @Override
+ public void setLayoutDirection(int layoutDirection) throws RemoteException {
+ synchronized (this) {
+ mHandler.sendMessage(
+ mHandler.obtainMessage(MSG_VOL_CHANGED, layoutDirection, 0 /*unused*/));
+ }
+ }
+
+ @Override
+ public void dismiss() throws RemoteException {
+ synchronized (this) {
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_DISMISS));
+ }
+ }
+
+ @Override
+ public void setA11yMode(int mode) throws RemoteException {
+ synchronized (this) {
+ mHandler.sendMessage(
+ mHandler.obtainMessage(MSG_SET_ALLY_MODE, mode, 0 /*unused*/));
+ }
+ }
+ }
+
private void handleVolumeKeyDefault(KeyEvent event) {
if (event.getAction() != KeyEvent.ACTION_DOWN
|| interceptVolKeyBeforeDispatching(mContext)) {
diff --git a/service/src/com/android/car/ICarImpl.java b/service/src/com/android/car/ICarImpl.java
index bd42454..c308d81 100644
--- a/service/src/com/android/car/ICarImpl.java
+++ b/service/src/com/android/car/ICarImpl.java
@@ -71,7 +71,8 @@
private final CarVendorExtensionService mCarVendorExtensionService;
private final CarBluetoothService mCarBluetoothService;
private final PerUserCarServiceHelper mPerUserCarServiceHelper;
- private CarDiagnosticService mCarDiagnosticService;
+ private final CarDiagnosticService mCarDiagnosticService;
+ private final CarStorageMonitoringService mCarStorageMonitoringService;
@FutureFeature
private VmsSubscriberService mVmsSubscriberService;
@FutureFeature
@@ -121,11 +122,11 @@
mPerUserCarServiceHelper = new PerUserCarServiceHelper(serviceContext);
mCarBluetoothService = new CarBluetoothService(serviceContext, mCarCabinService,
mCarSensorService, mPerUserCarServiceHelper);
- if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) {
- mVmsSubscriberService = new VmsSubscriberService(serviceContext, mHal.getVmsHal());
- mVmsPublisherService = new VmsPublisherService(serviceContext, mHal.getVmsHal());
- }
+ mVmsSubscriberService = new VmsSubscriberService(serviceContext, mHal.getVmsHal());
+ mVmsPublisherService = new VmsPublisherService(serviceContext, mHal.getVmsHal());
mCarDiagnosticService = new CarDiagnosticService(serviceContext, mHal.getDiagnosticHal());
+ mCarStorageMonitoringService = new CarStorageMonitoringService(serviceContext,
+ systemInterface);
// Be careful with order. Service depending on other service should be inited later.
List<CarServiceBase> allServices = new ArrayList<>(Arrays.asList(
@@ -148,16 +149,15 @@
mCarVendorExtensionService,
mCarBluetoothService,
mCarDiagnosticService,
- mPerUserCarServiceHelper
+ mPerUserCarServiceHelper,
+ mCarStorageMonitoringService,
+ mVmsSubscriberService,
+ mVmsPublisherService
));
- if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) {
- allServices.add(mVmsSubscriberService);
- allServices.add(mVmsPublisherService);
- }
mAllServices = allServices.toArray(new CarServiceBase[0]);
}
- public void init() {
+ void init() {
traceBegin("VehicleHal.init");
mHal.init();
traceEnd();
@@ -168,7 +168,7 @@
traceEnd();
}
- public void release() {
+ void release() {
// release done in opposite order from init
for (int i = mAllServices.length - 1; i >= 0; i--) {
mAllServices[i].release();
@@ -176,7 +176,7 @@
mHal.release();
}
- public void vehicleHalReconnected(IVehicle vehicle) {
+ void vehicleHalReconnected(IVehicle vehicle) {
mHal.vehicleHalReconnected(vehicle);
for (CarServiceBase service : mAllServices) {
service.vehicleHalReconnected();
@@ -234,11 +234,8 @@
assertVendorExtensionPermission(mContext);
return mCarVendorExtensionService;
case Car.VMS_SUBSCRIBER_SERVICE:
- FeatureUtil.assertFeature(FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE);
- if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) {
- assertVmsSubscriberPermission(mContext);
- return mVmsSubscriberService;
- }
+ assertVmsSubscriberPermission(mContext);
+ return mVmsSubscriberService;
case Car.TEST_SERVICE: {
assertPermission(mContext, Car.PERMISSION_CAR_TEST_SERVICE);
synchronized (this) {
@@ -250,6 +247,9 @@
}
case Car.BLUETOOTH_SERVICE:
return mCarBluetoothService;
+ case Car.STORAGE_MONITORING_SERVICE:
+ assertPermission(mContext, Car.PERMISSION_STORAGE_MONITORING);
+ return mCarStorageMonitoringService;
default:
Log.w(CarLog.TAG_SERVICE, "getCarService for unknown service:" + serviceName);
return null;
diff --git a/service/src/com/android/car/OnShutdownReboot.java b/service/src/com/android/car/OnShutdownReboot.java
new file mode 100644
index 0000000..701fabf
--- /dev/null
+++ b/service/src/com/android/car/OnShutdownReboot.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2017 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.car;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.BiConsumer;
+
+/**
+ * This class allows one to register actions they want executed when the vehicle is being shutdown
+ * or rebooted.
+ *
+ * To use this class instantiate it as part of your long-lived service, and then add actions to it.
+ * Actions receive the Context and Intent that go with the shutdown/reboot action, which allows the
+ * action to differentiate the two cases, should it need to do so.
+ *
+ * The actions will run on the UI thread.
+ */
+class OnShutdownReboot {
+ private final Object mLock = new Object();
+
+ private final Context mContext;
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ for (BiConsumer<Context, Intent> action : mActions) {
+ action.accept(context, intent);
+ }
+ }
+ };
+
+ private final CopyOnWriteArrayList<BiConsumer<Context, Intent>> mActions =
+ new CopyOnWriteArrayList<>();
+
+ OnShutdownReboot(Context context) {
+ mContext = context;
+ IntentFilter shutdownFilter = new IntentFilter(Intent.ACTION_SHUTDOWN);
+ IntentFilter rebootFilter = new IntentFilter(Intent.ACTION_REBOOT);
+ mContext.registerReceiver(mReceiver, shutdownFilter);
+ mContext.registerReceiver(mReceiver, rebootFilter);
+ }
+
+ void addAction(BiConsumer<Context, Intent> action) {
+ mActions.add(action);
+ }
+
+ void clearActions() {
+ mActions.clear();
+ }
+}
diff --git a/service/src/com/android/car/SystemInterface.java b/service/src/com/android/car/SystemInterface.java
index 6311d80..d991d87 100644
--- a/service/src/com/android/car/SystemInterface.java
+++ b/service/src/com/android/car/SystemInterface.java
@@ -23,11 +23,18 @@
import android.os.SystemClock;
import android.util.Log;
import android.view.Display;
+import com.android.car.storagemonitoring.EMmcWearInformationProvider;
+import com.android.car.storagemonitoring.UfsWearInformationProvider;
+import com.android.car.storagemonitoring.WearInformationProvider;
+import java.io.File;
/**
* Interface to abstract all system interaction.
*/
public abstract class SystemInterface {
+ public static final boolean INCLUDE_DEEP_SLEEP_TIME = true;
+ public static final boolean EXCLUDE_DEEP_SLEEP_TIME = false;
+
public abstract void setDisplayState(boolean on);
public abstract void releaseAllWakeLocks();
public abstract void shutdown();
@@ -38,7 +45,17 @@
public abstract void stopDisplayStateMonitoring();
public abstract boolean isSystemSupportingDeepSleep();
public abstract boolean isWakeupCausedByTimer();
+ public abstract WearInformationProvider[] getFlashWearInformationProviders();
+ public abstract File getFilesDir();
+ public final long getUptime() {
+ return getUptime(EXCLUDE_DEEP_SLEEP_TIME);
+ }
+ public long getUptime(boolean includeDeepSleepTime) {
+ return includeDeepSleepTime ?
+ SystemClock.elapsedRealtime() :
+ SystemClock.uptimeMillis();
+ }
public static SystemInterface getDefault(Context context) {
return new SystemInterfaceImpl(context);
@@ -50,6 +67,8 @@
private final WakeLock mFullWakeLock;
private final WakeLock mPartialWakeLock;
private final DisplayStateListener mDisplayListener;
+ private final WearInformationProvider[] mWearInformationProviders;
+ private final File mFilesDir;
private CarPowerManagementService mService;
private boolean mDisplayStateSet;
@@ -61,6 +80,11 @@
mPartialWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
CarLog.TAG_POWER);
mDisplayListener = new DisplayStateListener();
+ mWearInformationProviders = new WearInformationProvider[] {
+ new EMmcWearInformationProvider(),
+ new UfsWearInformationProvider()
+ };
+ mFilesDir = context.getFilesDir();
}
@Override
@@ -156,6 +180,16 @@
return false;
}
+ @Override
+ public WearInformationProvider[] getFlashWearInformationProviders() {
+ return mWearInformationProviders;
+ }
+
+ @Override
+ public File getFilesDir() {
+ return mFilesDir;
+ }
+
private void handleMainDisplayChanged() {
boolean isOn = isMainDisplayOn();
CarPowerManagementService service;
diff --git a/service/src/com/android/car/UptimeTracker.java b/service/src/com/android/car/UptimeTracker.java
new file mode 100644
index 0000000..a4f1d7c
--- /dev/null
+++ b/service/src/com/android/car/UptimeTracker.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2017 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.car;
+
+import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+import android.os.SystemClock;
+import android.util.JsonReader;
+import android.util.JsonWriter;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.concurrent.ScheduledExecutorService;
+
+/**
+ * A class that can keep track of how long its instances are alive for.
+ *
+ * It can be used as a helper object to track the lifetime of system components, e.g.
+ *
+ * class InterestingService {
+ * private UptimeTracker mTracker;
+ *
+ * public void onCreate() {
+ * mTracker = new UptimeTracker(
+ * "/storage/emulated/0/Android/data/interestingservice.uptime", 1 hour);
+ * mTracker.onCreate();
+ * }
+ *
+ * public void onDestroy() {
+ * mTracker.onDestroy();
+ * }
+ * }
+ *
+ * Now it's possible to know how long InterestingService has been alive in the system by querying
+ * mTracker.getTotalUptime(). Because this data is stored to disk, the uptime is maintained across
+ * process and system reboot boundaries. It is possible to configure periodic snapshot points to
+ * ensure that crashes do not cause more than a certain amount of uptime to go untracked.
+ */
+public class UptimeTracker {
+ @VisibleForTesting
+ interface TimingProvider {
+ long getCurrentRealtime();
+ void schedule(Runnable r, long delay);
+ void cancelAll();
+ }
+
+ // note: this implementation does not account for time spent in "suspend" mode
+ private static final class DefaultTimingProvider implements TimingProvider {
+ private ScheduledExecutorService mExecutor = newSingleThreadScheduledExecutor();
+
+ @Override
+ public long getCurrentRealtime() {
+ return SystemClock.uptimeMillis();
+ }
+
+ @Override
+ public void schedule(Runnable r, long delay) {
+ mExecutor.scheduleWithFixedDelay(r, delay, delay, MILLISECONDS);
+ }
+
+ @Override
+ public void cancelAll() {
+ mExecutor.shutdownNow();
+ }
+ }
+
+ /**
+ * In order to prevent excessive wear-out of the storage, do not allow snapshots to happen
+ * more frequently than this value
+ */
+ public static final long MINIMUM_SNAPSHOT_INTERVAL_MS = 60 * 60 * 1000;
+
+ /**
+ * The default snapshot interval if none is given
+ */
+ private static long DEFAULT_SNAPSHOT_INTERVAL_MS = 5 * 60 * 60 * 1000; // 5 hours
+
+ private final Object mLock = new Object();
+
+ /**
+ * The file that uptime metrics are stored to
+ */
+ private File mUptimeFile;
+
+ /**
+ * The uptime value retrieved from mUptimeFile
+ */
+ private Optional<Long> mHistoricalUptime;
+
+ /**
+ * Last value of elapsedRealTime read from the system
+ */
+ private long mLastRealTimeSnapshot;
+
+ /**
+ * The source of real-time and scheduling
+ */
+ private TimingProvider mTimingProvider;
+
+ public UptimeTracker(File file) {
+ this(file, DEFAULT_SNAPSHOT_INTERVAL_MS);
+ }
+
+ public UptimeTracker(File file, long snapshotInterval) {
+ this(file, snapshotInterval, new DefaultTimingProvider());
+ }
+
+ // By default, SystemClock::elapsedRealtime is used as the source of the uptime clock
+ // and a ScheduledExecutorService provides snapshot synchronization. For testing purposes
+ // this constructor allows using a controlled source of time information and scheduling.
+ @VisibleForTesting
+ UptimeTracker(File file,
+ long snapshotInterval,
+ TimingProvider timingProvider) {
+ snapshotInterval = Math.max(snapshotInterval, MINIMUM_SNAPSHOT_INTERVAL_MS);
+ mUptimeFile = Objects.requireNonNull(file);
+ mTimingProvider = timingProvider;
+ mLastRealTimeSnapshot = mTimingProvider.getCurrentRealtime();
+ mHistoricalUptime = Optional.empty();
+
+ mTimingProvider.schedule(this::flushSnapshot, snapshotInterval);
+ }
+
+ void onDestroy() {
+ synchronized (mLock) {
+ if (mTimingProvider != null) {
+ mTimingProvider.cancelAll();
+ }
+ flushSnapshot();
+ mTimingProvider = null;
+ mUptimeFile = null;
+ }
+ }
+
+ /**
+ * Return the total amount of uptime that has been observed, in milliseconds.
+ *
+ * This is the sum of the uptime stored on disk + the uptime seen since the last snapshot.
+ */
+ long getTotalUptime() {
+ synchronized (mLock) {
+ if (mTimingProvider == null) {
+ return 0;
+ }
+ return getHistoricalUptimeLocked() + (
+ mTimingProvider.getCurrentRealtime() - mLastRealTimeSnapshot);
+ }
+ }
+
+ private long getHistoricalUptimeLocked() {
+ if (!mHistoricalUptime.isPresent() && mUptimeFile != null) {
+ try {
+ JsonReader reader = new JsonReader(new FileReader(mUptimeFile));
+ reader.beginObject();
+ if (!reader.nextName().equals("uptime")) {
+ throw new IllegalArgumentException(
+ mUptimeFile + " is not in a valid format");
+ } else {
+ mHistoricalUptime = Optional.of(reader.nextLong());
+ }
+ reader.endObject();
+ reader.close();
+ } catch (IllegalArgumentException | IOException e) {
+ Log.w(CarLog.TAG_SERVICE, "unable to read historical uptime data", e);
+ mHistoricalUptime = Optional.empty();
+ }
+ }
+ return mHistoricalUptime.orElse(0L);
+ }
+
+ private void flushSnapshot() {
+ synchronized (mLock) {
+ if (mUptimeFile == null) {
+ return;
+ }
+ try {
+ long newUptime = getTotalUptime();
+ mHistoricalUptime = Optional.of(newUptime);
+ mLastRealTimeSnapshot = mTimingProvider.getCurrentRealtime();
+
+ JsonWriter writer = new JsonWriter(new FileWriter(mUptimeFile));
+ writer.beginObject();
+ writer.name("uptime");
+ writer.value(newUptime);
+ writer.endObject();
+ writer.close();
+ } catch (IOException e) {
+ Log.w(CarLog.TAG_SERVICE, "unable to write historical uptime data", e);
+ }
+ }
+ }
+}
diff --git a/service/src/com/android/car/VmsLayersAvailability.java b/service/src/com/android/car/VmsLayersAvailability.java
index 93b917c..4c730c1 100644
--- a/service/src/com/android/car/VmsLayersAvailability.java
+++ b/service/src/com/android/car/VmsLayersAvailability.java
@@ -16,7 +16,6 @@
package com.android.car;
-import android.car.annotation.FutureFeature;
import android.car.vms.VmsAssociatedLayer;
import android.car.vms.VmsLayer;
import android.car.vms.VmsLayerDependency;
@@ -40,9 +39,10 @@
* Each VMS publisher sets its layers offering which are a list of layers the publisher claims
* it might publish. VmsLayersAvailability calculates from all the offering what are the
* available layers.
+ *
+ * @hide
*/
-@FutureFeature
public class VmsLayersAvailability {
private static final boolean DBG = true;
diff --git a/service/src/com/android/car/VmsPublisherService.java b/service/src/com/android/car/VmsPublisherService.java
index 8a293e5..2d2acf6 100644
--- a/service/src/com/android/car/VmsPublisherService.java
+++ b/service/src/com/android/car/VmsPublisherService.java
@@ -16,7 +16,7 @@
package com.android.car;
-import android.car.annotation.FutureFeature;
+import android.annotation.SystemApi;
import android.car.vms.IVmsSubscriberClient;
import android.car.vms.IVmsPublisherClient;
import android.car.vms.IVmsPublisherService;
@@ -48,11 +48,13 @@
import java.util.Set;
/**
- * + Receives HAL updates by implementing VmsHalService.VmsHalListener.
- * + Binds to publishers and configures them to use this service.
- * + Notifies publishers of subscription changes.
+ * Receives HAL updates by implementing VmsHalService.VmsHalListener.
+ * Binds to publishers and configures them to use this service.
+ * Notifies publishers of subscription changes.
+ *
+ * @hide
*/
-@FutureFeature
+@SystemApi
public class VmsPublisherService extends IVmsPublisherService.Stub
implements CarServiceBase, VmsHalService.VmsHalPublisherListener {
private static final boolean DBG = true;
diff --git a/service/src/com/android/car/VmsPublishersInfo.java b/service/src/com/android/car/VmsPublishersInfo.java
index 04ee82f..0f73e5c 100644
--- a/service/src/com/android/car/VmsPublishersInfo.java
+++ b/service/src/com/android/car/VmsPublishersInfo.java
@@ -16,8 +16,6 @@
package com.android.car;
-
-import android.car.annotation.FutureFeature;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
@@ -26,7 +24,6 @@
import com.android.internal.annotations.GuardedBy;
import android.util.Log;
-@FutureFeature
public class VmsPublishersInfo {
private static final String TAG = "VmsPublishersInfo";
private static final boolean DBG = true;
diff --git a/service/src/com/android/car/VmsRouting.java b/service/src/com/android/car/VmsRouting.java
index 2e66781..fa29a27 100644
--- a/service/src/com/android/car/VmsRouting.java
+++ b/service/src/com/android/car/VmsRouting.java
@@ -16,7 +16,6 @@
package com.android.car;
-import android.car.annotation.FutureFeature;
import android.car.vms.IVmsSubscriberClient;
import android.car.vms.VmsAssociatedLayer;
import android.car.vms.VmsLayer;
@@ -39,7 +38,7 @@
* + Subscriptions to all data messages.
* + HAL subscriptions to layer + version.
*/
-@FutureFeature
+
public class VmsRouting {
private final Object mLock = new Object();
// A map of Layer + Version to subscribers.
diff --git a/service/src/com/android/car/VmsSubscriberService.java b/service/src/com/android/car/VmsSubscriberService.java
index 94f0844..5031fb4 100644
--- a/service/src/com/android/car/VmsSubscriberService.java
+++ b/service/src/com/android/car/VmsSubscriberService.java
@@ -16,8 +16,8 @@
package com.android.car;
+import android.annotation.SystemApi;
import android.car.Car;
-import android.car.annotation.FutureFeature;
import android.car.vms.IVmsSubscriberClient;
import android.car.vms.IVmsSubscriberService;
import android.car.vms.VmsAssociatedLayer;
@@ -43,7 +43,7 @@
* + Receives HAL updates by implementing VmsHalService.VmsHalListener.
* + Offers subscriber/publisher services by implementing IVmsService.Stub.
*/
-@FutureFeature
+@SystemApi
public class VmsSubscriberService extends IVmsSubscriberService.Stub
implements CarServiceBase, VmsHalService.VmsHalSubscriberListener {
private static final boolean DBG = true;
diff --git a/service/src/com/android/car/hal/DiagnosticHalService.java b/service/src/com/android/car/hal/DiagnosticHalService.java
index 4ff0ada..bcbae7a 100644
--- a/service/src/com/android/car/hal/DiagnosticHalService.java
+++ b/service/src/com/android/car/hal/DiagnosticHalService.java
@@ -42,6 +42,8 @@
* higher-level semantic information
*/
public class DiagnosticHalService extends SensorHalServiceBase {
+ static final int OBD2_SELECTIVE_FRAME_CLEAR = 1;
+
public static class DiagnosticCapabilities {
private final CopyOnWriteArraySet<Integer> mProperties = new CopyOnWriteArraySet<>();
@@ -69,6 +71,10 @@
return isSupported(VehicleProperty.OBD2_FREEZE_FRAME_CLEAR);
}
+ public boolean isSelectiveClearFreezeFramesSupported() {
+ return isSupported(OBD2_SELECTIVE_FRAME_CLEAR);
+ }
+
void clear() {
mProperties.clear();
}
@@ -102,6 +108,17 @@
return propConfig.prop;
case VehicleProperty.OBD2_FREEZE_FRAME_CLEAR:
mDiagnosticCapabilities.setSupported(propConfig.prop);
+ Log.i(CarLog.TAG_DIAGNOSTIC, String.format(
+ "configArray for OBD2_FREEZE_FRAME_CLEAR is %s", propConfig.configArray));
+ if (propConfig.configArray.size() < 1) {
+ Log.e(CarLog.TAG_DIAGNOSTIC, String.format(
+ "property 0x%x does not specify whether it supports selective " +
+ "clearing of freeze frames. assuming it does not.", propConfig.prop));
+ } else {
+ if (propConfig.configArray.get(0) == 1) {
+ mDiagnosticCapabilities.setSupported(OBD2_SELECTIVE_FRAME_CLEAR);
+ }
+ }
return propConfig.prop;
default:
return SENSOR_TYPE_INVALID;
diff --git a/service/src/com/android/car/hal/VehicleHal.java b/service/src/com/android/car/hal/VehicleHal.java
index 21f8f51..3c54bfc 100644
--- a/service/src/com/android/car/hal/VehicleHal.java
+++ b/service/src/com/android/car/hal/VehicleHal.java
@@ -108,9 +108,7 @@
mHvacHal = new HvacHalService(this);
mInputHal = new InputHalService(this);
mVendorExtensionHal = new VendorExtensionHalService(this);
- if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) {
- mVmsHal = new VmsHalService(this);
- }
+ mVmsHal = new VmsHalService(this);
mDiagnosticHal = new DiagnosticHalService(this);
mAllServices.addAll(Arrays.asList(mPowerHal,
mSensorHal,
@@ -121,10 +119,8 @@
mHvacHal,
mInputHal,
mVendorExtensionHal,
- mDiagnosticHal));
- if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) {
- mAllServices.add(mVmsHal);
- }
+ mDiagnosticHal,
+ mVmsHal));
mHalClient = new HalClient(vehicle, mHandlerThread.getLooper(), this /*IVehicleCallback*/);
}
@@ -132,7 +128,7 @@
/** Dummy version only for testing */
@VisibleForTesting
public VehicleHal(PowerHalService powerHal, SensorHalService sensorHal, InfoHalService infoHal,
- AudioHalService audioHal, CabinHalService cabinHal,
+ AudioHalService audioHal, CabinHalService cabinHal, DiagnosticHalService diagnosticHal,
RadioHalService radioHal, HvacHalService hvacHal, HalClient halClient) {
mHandlerThread = null;
mPowerHal = powerHal;
@@ -140,38 +136,14 @@
mInfoHal = infoHal;
mAudioHal = audioHal;
mCabinHal = cabinHal;
+ mDiagnosticHal = diagnosticHal;
mRadioHal = radioHal;
mHvacHal = hvacHal;
mInputHal = null;
mVendorExtensionHal = null;
- mDiagnosticHal = null;
-
- if (FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) {
- mVmsHal = null;
- }
-
+ mVmsHal = null;
mHalClient = halClient;
- }
-
- /** Dummy version only for testing */
- @VisibleForTesting
- public VehicleHal(PowerHalService powerHal, SensorHalService sensorHal, InfoHalService infoHal,
- AudioHalService audioHal, CabinHalService cabinHal, DiagnosticHalService diagnosticHal,
- RadioHalService radioHal, HvacHalService hvacHal, HalClient halClient) {
- mHandlerThread = null;
- mPowerHal = powerHal;
- mSensorHal = sensorHal;
- mInfoHal = infoHal;
- mAudioHal = audioHal;
- mCabinHal = cabinHal;
- mDiagnosticHal = diagnosticHal;
- mRadioHal = radioHal;
- mHvacHal = hvacHal;
- mInputHal = null;
- mVendorExtensionHal = null;
- mVmsHal = null;
- mHalClient = halClient;
- mDiagnosticHal = diagnosticHal;
+ mDiagnosticHal = diagnosticHal;
}
public void vehicleHalReconnected(IVehicle vehicle) {
diff --git a/service/src/com/android/car/hal/VmsHalService.java b/service/src/com/android/car/hal/VmsHalService.java
index d20a453..36da390 100644
--- a/service/src/com/android/car/hal/VmsHalService.java
+++ b/service/src/com/android/car/hal/VmsHalService.java
@@ -18,8 +18,8 @@
import static com.android.car.CarServiceUtils.toByteArray;
import static java.lang.Integer.toHexString;
+import android.annotation.SystemApi;
import android.car.VehicleAreaType;
-import android.car.annotation.FutureFeature;
import android.car.vms.IVmsSubscriberClient;
import android.car.vms.VmsLayer;
import android.car.vms.VmsAssociatedLayer;
@@ -61,7 +61,7 @@
* This is a glue layer between the VehicleHal and the VmsService. It sends VMS properties back and
* forth.
*/
-@FutureFeature
+@SystemApi
public class VmsHalService extends HalServiceBase {
private static final boolean DBG = true;
diff --git a/service/src/com/android/car/storagemonitoring/EMmcWearInformationProvider.java b/service/src/com/android/car/storagemonitoring/EMmcWearInformationProvider.java
new file mode 100644
index 0000000..3940578
--- /dev/null
+++ b/service/src/com/android/car/storagemonitoring/EMmcWearInformationProvider.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2017 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.car.storagemonitoring;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.Log;
+import com.android.car.CarLog;
+import com.android.internal.annotations.VisibleForTesting;
+import java.io.File;
+import java.io.FileReader;
+import java.io.BufferedReader;
+import java.io.IOException;
+
+/**
+ * Loads wear information from the eMMC sysfs entry points.
+ * sysfs exposes eMMC lifetime data in /sys/bus/mmc/devices/mmc0:0001/{pre_eol_info|life_time}
+ * The first file contains the value of the PRE_EOL_INFO register as an hexadecimal string
+ * The second file contains the values of the LIFE_TIME_EST A and B registers as two hexadecimal
+ * strings separated by a space.
+ */
+public class EMmcWearInformationProvider implements WearInformationProvider {
+ private static File DEFAULT_LIFE_TIME_FILE =
+ new File("/sys/bus/mmc/devices/mmc0:0001/life_time");
+
+ private static File DEFAULT_PRE_EOL_FILE =
+ new File("/sys/bus/mmc/devices/mmc0:0001/pre_eol_info");
+
+ private File mLifetimeFile;
+ private File mPreEolFile;
+
+ public EMmcWearInformationProvider() {
+ this(DEFAULT_LIFE_TIME_FILE, DEFAULT_PRE_EOL_FILE);
+ }
+
+ @VisibleForTesting
+ EMmcWearInformationProvider(@NonNull File lifetimeFile, @NonNull File preEolFile) {
+ mLifetimeFile = lifetimeFile;
+ mPreEolFile = preEolFile;
+ }
+
+ private String readLineFromFile(File f) {
+ if (!f.exists() || !f.isFile()) {
+ Log.i(CarLog.TAG_STORAGE, f + " does not exist or is not a file");
+ return null;
+ }
+
+ try {
+ BufferedReader reader = new BufferedReader(new FileReader(f));
+ String data = reader.readLine();
+ reader.close();
+ return data;
+ } catch (IOException e) {
+ Log.w(CarLog.TAG_STORAGE, f + " cannot be read from", e);
+ return null;
+ }
+ }
+
+ @Nullable
+ @Override
+ public WearInformation load() {
+ String lifetimeData = readLineFromFile(mLifetimeFile);
+ String eolData = readLineFromFile(mPreEolFile);
+
+ if ((lifetimeData == null) || (eolData == null)) {
+ return null;
+ }
+
+ String[] lifetimes = lifetimeData.split(" ");
+ if (lifetimes.length != 2) {
+ Log.w(CarLog.TAG_STORAGE, "lifetime data not in expected format: " + lifetimeData);
+ return null;
+ }
+
+ int lifetimeA;
+ int lifetimeB;
+ int eol;
+
+ try {
+ lifetimeA = Integer.decode(lifetimes[0]);
+ lifetimeB = Integer.decode(lifetimes[1]);
+ eol = Integer.decode("0x" + eolData);
+ } catch (NumberFormatException e) {
+ Log.w(CarLog.TAG_STORAGE,
+ "lifetime data not in expected format: " + lifetimeData, e);
+ return null;
+ }
+
+ return new WearInformation(convertLifetime(lifetimeA),
+ convertLifetime(lifetimeB),
+ adjustEol(eol));
+ }
+}
diff --git a/service/src/com/android/car/storagemonitoring/UfsWearInformationProvider.java b/service/src/com/android/car/storagemonitoring/UfsWearInformationProvider.java
new file mode 100644
index 0000000..fa7ba8b
--- /dev/null
+++ b/service/src/com/android/car/storagemonitoring/UfsWearInformationProvider.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2017 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.car.storagemonitoring;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.Log;
+import com.android.car.CarLog;
+import com.android.internal.annotations.VisibleForTesting;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.Optional;
+import java.util.Scanner;
+import java.util.regex.MatchResult;
+import java.util.regex.Pattern;
+
+/**
+ * Loads wear information from the UFS sysfs entry points.
+ * sysfs exposes UFS lifetime data in /sys/devices/soc/624000.ufshc/health
+ * The first line of the file contains the UFS version
+ * Subsequent lines contains individual information points in the format:
+ * Health Descriptor[Byte offset 0x%d]: %31s = 0x%hx
+ * Of these we care about the key values bPreEOLInfo and bDeviceLifeTimeEstA bDeviceLifeTimeEstB
+ */
+public class UfsWearInformationProvider implements WearInformationProvider {
+ private static File DEFAULT_FILE =
+ new File("/sys/devices/soc/624000.ufshc/health");
+
+ private File mFile;
+
+ public UfsWearInformationProvider() {
+ this(DEFAULT_FILE);
+ }
+
+ @VisibleForTesting
+ public UfsWearInformationProvider(@NonNull File file) {
+ mFile = file;
+ }
+
+ @Nullable
+ @Override
+ public WearInformation load() {
+ List<String> lifetimeData;
+ try {
+ lifetimeData = java.nio.file.Files.readAllLines(mFile.toPath());
+ } catch (IOException e) {
+ Log.w(CarLog.TAG_STORAGE, "error reading " + mFile, e);
+ return null;
+ }
+ if (lifetimeData == null || lifetimeData.size() < 4) {
+ return null;
+ }
+
+ Pattern infoPattern = Pattern.compile(
+ "Health Descriptor\\[Byte offset 0x\\d+\\]: (\\w+) = 0x([0-9a-fA-F]+)");
+
+ Optional<Integer> lifetimeA = Optional.empty();
+ Optional<Integer> lifetimeB = Optional.empty();
+ Optional<Integer> eol = Optional.empty();
+
+ for(String lifetimeInfo : lifetimeData) {
+ Scanner scanner = new Scanner(lifetimeInfo);
+ if (null == scanner.findInLine(infoPattern)) {
+ continue;
+ }
+ MatchResult match = scanner.match();
+ if (match.groupCount() != 2) {
+ continue;
+ }
+ String name = match.group(1);
+ String value = "0x" + match.group(2);
+ try {
+ switch (name) {
+ case "bPreEOLInfo":
+ eol = Optional.of(Integer.decode(value));
+ break;
+ case "bDeviceLifeTimeEstA":
+ lifetimeA = Optional.of(Integer.decode(value));
+ break;
+ case "bDeviceLifeTimeEstB":
+ lifetimeB = Optional.of(Integer.decode(value));
+ break;
+ }
+ } catch (NumberFormatException e) {
+ Log.w(CarLog.TAG_STORAGE,
+ "trying to decode key " + name + " value " + value + " didn't parse properly", e);
+ }
+ }
+
+ if (!lifetimeA.isPresent() || !lifetimeB.isPresent() || !eol.isPresent()) {
+ return null;
+ }
+
+ return new WearInformation(convertLifetime(lifetimeA.get()),
+ convertLifetime(lifetimeB.get()),
+ adjustEol(eol.get()));
+ }
+}
diff --git a/service/src/com/android/car/storagemonitoring/WearInformation.java b/service/src/com/android/car/storagemonitoring/WearInformation.java
new file mode 100644
index 0000000..2f885d4
--- /dev/null
+++ b/service/src/com/android/car/storagemonitoring/WearInformation.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2017 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.car.storagemonitoring;
+
+import static java.util.Objects.hash;
+
+public final class WearInformation {
+ public static final int UNKNOWN_LIFETIME_ESTIMATE = -1;
+
+ public static final int UNKNOWN_PRE_EOL_INFO = 0;
+ public static final int PRE_EOL_INFO_NORMAL = 1;
+ public static final int PRE_EOL_INFO_WARNING = 2;
+ public static final int PRE_EOL_INFO_URGENT = 3;
+
+ private static final String UNKNOWN = "unknown";
+ private static final String[] PRE_EOL_STRINGS = new String[] {
+ UNKNOWN, "normal", "warning", "urgent"
+ };
+
+ /**
+ * A lower bound on the lifetime estimate for "type A" memory cells, expressed as a percentage.
+ */
+ public final int lifetimeEstimateA;
+
+ /**
+ * A lower bound on the lifetime estimate for "type B" memory cells, expressed as a percentage.
+ */
+ public final int lifetimeEstimateB;
+
+ /**
+ * An estimate of the lifetime based on reserved block consumption.
+ */
+ public final int preEolInfo;
+
+ public WearInformation(int lifetimeA, int lifetimeB, int preEol) {
+ lifetimeEstimateA = lifetimeA;
+ lifetimeEstimateB = lifetimeB;
+ preEolInfo = preEol;
+ }
+
+ @Override
+ public int hashCode() {
+ return hash(lifetimeEstimateA, lifetimeEstimateB, preEolInfo);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ if (other instanceof WearInformation) {
+ WearInformation wi = (WearInformation)other;
+ return (wi.lifetimeEstimateA == lifetimeEstimateA) &&
+ (wi.lifetimeEstimateB == lifetimeEstimateB) &&
+ (wi.preEolInfo == preEolInfo);
+ } else {
+ return false;
+ }
+ }
+
+ private String lifetimeToString(int lifetime) {
+ if (lifetime == UNKNOWN_LIFETIME_ESTIMATE) return UNKNOWN;
+
+ return lifetime + "%";
+ }
+
+ @Override
+ public String toString() {
+ return "lifetime estimate A: " + lifetimeToString(lifetimeEstimateA) + '\n' +
+ "lifetime estimate B: " + lifetimeToString(lifetimeEstimateB) + '\n' +
+ "pre EOL info: " + PRE_EOL_STRINGS[preEolInfo] + '\n';
+ }
+}
diff --git a/service/src/com/android/car/storagemonitoring/WearInformationProvider.java b/service/src/com/android/car/storagemonitoring/WearInformationProvider.java
new file mode 100644
index 0000000..65574d7
--- /dev/null
+++ b/service/src/com/android/car/storagemonitoring/WearInformationProvider.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017 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.car.storagemonitoring;
+
+import android.annotation.Nullable;
+
+public interface WearInformationProvider {
+ @Nullable
+ WearInformation load();
+
+ default int convertLifetime(int lifetime) {
+ if ((lifetime <= 0) || (lifetime > 11)) return WearInformation.UNKNOWN_LIFETIME_ESTIMATE;
+ return 10 * (lifetime - 1);
+ }
+
+ default int adjustEol(int eol) {
+ if ((eol <= 0) || (eol > 3)) return WearInformation.UNKNOWN_PRE_EOL_INFO;
+ return eol;
+ }
+
+}
diff --git a/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml b/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml
index 2a96898..db09cba 100644
--- a/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml
+++ b/tests/EmbeddedKitchenSinkApp/AndroidManifest.xml
@@ -33,6 +33,7 @@
<uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME"/>
<uses-permission android:name="android.car.permission.VEHICLE_DYNAMICS_STATE"/>
<uses-permission android:name="android.car.permission.CAR_DISPLAY_IN_CLUSTER"/>
+ <uses-permission android:name="android.car.permission.STORAGE_MONITORING" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.MANAGE_USB" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
diff --git a/tests/EmbeddedKitchenSinkApp/res/layout/storagewear.xml b/tests/EmbeddedKitchenSinkApp/res/layout/storagewear.xml
new file mode 100644
index 0000000..bfb57c3
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/res/layout/storagewear.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+ <!-- Copyright (C) 2017 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.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="50dp"
+ android:orientation="vertical"
+ android:layout_weight="1" />
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_weight="1" >
+ <TextView
+ android:id="@+id/storage_wear_info"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="Storage Wear Information"
+ android:textSize="24dp"
+ android:textColor="#ff0000"
+ android:minLines="5"/>
+ </LinearLayout>
+</LinearLayout>
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
index e68c3fa..c1dd824 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/KitchenSinkActivity.java
@@ -49,6 +49,7 @@
import com.google.android.car.kitchensink.radio.RadioTestFragment;
import com.google.android.car.kitchensink.sensor.SensorsTestFragment;
import com.google.android.car.kitchensink.setting.CarServiceSettingsActivity;
+import com.google.android.car.kitchensink.storagelifetime.StorageLifetimeFragment;
import com.google.android.car.kitchensink.touch.TouchTestFragment;
import com.google.android.car.kitchensink.volume.VolumeTestFragment;
import java.util.ArrayList;
@@ -147,6 +148,7 @@
add("orientation test", OrientationTestFragment.class);
add("bluetooth headset",BluetoothHeadsetFragment.class);
add("bluetooth messaging test", MapMceTestFragment.class);
+ add("storage lifetime", StorageLifetimeFragment.class);
add("car service settings", () -> {
Intent intent = new Intent(KitchenSinkActivity.this,
CarServiceSettingsActivity.class);
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/storagelifetime/StorageLifetimeFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/storagelifetime/StorageLifetimeFragment.java
new file mode 100644
index 0000000..b5165a8
--- /dev/null
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/storagelifetime/StorageLifetimeFragment.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2017 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.google.android.car.kitchensink.storagelifetime;
+
+import android.annotation.Nullable;
+import android.car.Car;
+import android.car.storagemonitoring.CarStorageMonitoringManager;
+import android.graphics.Color;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.TextView;
+import com.google.android.car.kitchensink.KitchenSinkActivity;
+import com.google.android.car.kitchensink.R;
+
+public class StorageLifetimeFragment extends Fragment {
+ private static final String TAG = "CAR.STORAGELIFETIME.KS";
+
+ private KitchenSinkActivity mActivity;
+ private TextView mStorageWearInfo;
+ private CarStorageMonitoringManager mStorageManager;
+
+ // TODO(egranata): put this somewhere more useful than KitchenSink
+ private static String preEolToString(int preEol) {
+ switch (preEol) {
+ case 1: return "normal";
+ case 2: return "warning";
+ case 3: return "urgent";
+ default:
+ return "unknown";
+ }
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(
+ LayoutInflater inflater,
+ @Nullable ViewGroup container,
+ @Nullable Bundle savedInstanceState) {
+ View view = inflater.inflate(R.layout.storagewear, container, false);
+ mActivity = (KitchenSinkActivity) getHost();
+ mStorageWearInfo = (TextView) view.findViewById(R.id.storage_wear_info);
+ return view;
+ }
+
+ private void reloadInfo() {
+ try {
+ mStorageManager =
+ (CarStorageMonitoringManager) mActivity.getCar().getCarManager(
+ Car.STORAGE_MONITORING_SERVICE);
+
+ mStorageWearInfo.setText("Wear estimate: " +
+ mStorageManager.getWearEstimate() + "\nPre EOL indicator: " +
+ preEolToString(mStorageManager.getPreEolIndicatorStatus()));
+ } catch (android.car.CarNotConnectedException|
+ android.support.car.CarNotConnectedException e) {
+ Log.e(TAG, "Car not connected or not supported", e);
+ }
+
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ reloadInfo();
+ }
+}
diff --git a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/volume/VolumeTestFragment.java b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/volume/VolumeTestFragment.java
index 0d65500..874bc64 100644
--- a/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/volume/VolumeTestFragment.java
+++ b/tests/EmbeddedKitchenSinkApp/src/com/google/android/car/kitchensink/volume/VolumeTestFragment.java
@@ -18,11 +18,14 @@
import android.car.Car;
import android.car.CarNotConnectedException;
import android.car.media.CarAudioManager;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.ServiceConnection;
import android.media.AudioManager;
import android.media.IVolumeController;
import android.os.Bundle;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.support.annotation.Nullable;
@@ -36,10 +39,9 @@
import android.widget.Button;
import android.widget.ListView;
-import com.google.android.car.kitchensink.CarEmulator;
import com.google.android.car.kitchensink.R;
-public class VolumeTestFragment extends Fragment{
+public class VolumeTestFragment extends Fragment {
private static final String TAG = "CarVolumeTest";
private static final int MSG_VOLUME_CHANGED = 0;
private static final int MSG_REQUEST_FOCUS = 1;
@@ -52,7 +54,6 @@
private CarAudioManager mCarAudioManager;
private Car mCar;
- private CarEmulator mCarEmulator;
private Button mVolumeUp;
private Button mVolumeDown;
@@ -140,6 +141,26 @@
default: return "Unknown";
}
}
+ private final ServiceConnection mCarConnectionCallback =
+ new ServiceConnection() {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder binder) {
+ Log.d(TAG, "Connected to Car Service");
+ try {
+ mCarAudioManager = (CarAudioManager) mCar.getCarManager(Car.AUDIO_SERVICE);
+ initVolumeInfo();
+ mCarAudioManager.setVolumeController(mVolumeController);
+
+ } catch (CarNotConnectedException e) {
+ Log.e(TAG, "Car is not connected!", e);
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ Log.d(TAG, "Disconnect from Car Service");
+ }
+ };
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@@ -160,33 +181,8 @@
}
});
- mCarEmulator = CarEmulator.create(getContext());
- mCar = mCarEmulator.getCar();
- try {
- mCarAudioManager = (CarAudioManager) mCar.getCarManager(Car.AUDIO_SERVICE);
- initVolumeInfo();
- mCarAudioManager.setVolumeController(mVolumeController);
- } catch (CarNotConnectedException e) {
- throw new RuntimeException(e); // Should never occur in car emulator.
- }
-
- mVolumeUp = (Button) v.findViewById(R.id.volume_up);
- mVolumeDown = (Button) v.findViewById(R.id.volume_down);
-
- mVolumeUp.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- mCarEmulator.injectKey(KeyEvent.KEYCODE_VOLUME_UP);
- }
- });
-
- mVolumeDown.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- mCarEmulator.injectKey(KeyEvent.KEYCODE_VOLUME_DOWN);
- }
- });
-
+ mCar = Car.createCar(getActivity(), mCarConnectionCallback);
+ mCar.connect();
return v;
}
@@ -214,7 +210,8 @@
return;
}
try {
- mCarAudioManager.setStreamVolume(logicalStream, volume, 0);
+ mCarAudioManager.setStreamVolume(logicalStream, volume,
+ AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_PLAY_SOUND);
} catch (CarNotConnectedException e) {
Log.e(TAG, "car not connected", e);
}
diff --git a/tests/carservice_test/Android.mk b/tests/carservice_test/Android.mk
index 4be5354..9203cbd 100644
--- a/tests/carservice_test/Android.mk
+++ b/tests/carservice_test/Android.mk
@@ -41,7 +41,8 @@
vehicle-hal-support-lib \
car-systemtest \
android-support-test \
- android.hardware.automotive.vehicle-V2.0-java-static
+ android.hardware.automotive.vehicle-V2.0-java \
+ com.android.car.test.utils
LOCAL_JAVA_LIBRARIES := android.car android.test.runner
diff --git a/tests/carservice_test/AndroidManifest.xml b/tests/carservice_test/AndroidManifest.xml
index 6f7ba34..ee4917b 100644
--- a/tests/carservice_test/AndroidManifest.xml
+++ b/tests/carservice_test/AndroidManifest.xml
@@ -24,28 +24,30 @@
<uses-permission android:name="android.car.permission.CONTROL_APP_BLOCKING" />
<uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME" />
<uses-permission android:name="android.car.permission.CAR_CONTROL_AUDIO_SETTINGS" />
+ <uses-permission android:name="android.car.permission.STORAGE_MONITORING" />
<instrumentation android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.android.car.test"
android:label="Tests for Car APIs"/>
<application android:label="CarServiceTest">
<uses-library android:name="android.test.runner" />
- <service android:name="com.android.car.test.TestAppBlockingPolicyService"
+ <service android:name="com.android.car.TestAppBlockingPolicyService"
android:permission="android.car.permission.CONTROL_APP_BLOCKING">
<intent-filter>
<action android:name="android.car.content.pm.CarAppBlockingPolicyService"/>
</intent-filter>
</service>
- <activity android:name="com.android.car.test.SystemActivityMonitoringServiceTest$ActivityA" />
- <activity android:name="com.android.car.test.SystemActivityMonitoringServiceTest$ActivityB"
+ <activity android:name="com.android.car.SystemActivityMonitoringServiceTest$ActivityA" />
+ <activity android:name="com.android.car.SystemActivityMonitoringServiceTest$ActivityB"
android:taskAffinity="com.android.car.carservicetest.activity"/>
- <activity android:name="com.android.car.test.SystemActivityMonitoringServiceTest$ActivityC"
+ <activity android:name="com.android.car.SystemActivityMonitoringServiceTest$ActivityC"
android:process="com.android.car.carservicetest.activityC"/>
- <activity android:name="com.android.car.test.SystemActivityMonitoringServiceTest$BlockingActivity"
+ <activity android:name="com.android.car.SystemActivityMonitoringServiceTest$BlockingActivity"
android:taskAffinity="com.android.car.carservicetest.block"/>
- <service android:name=".SimpleVmsPublisherClientService"
+ <service android:name="com.android.car.SimpleVmsPublisherClientService"
android:exported="true"
/>
- <service android:name=".VmsPublisherClientMockService" android:exported="true" />
+ <service android:name="com.android.car.VmsPublisherClientMockService"
+ android:exported="true" />
</application>
</manifest>
diff --git a/tests/carservice_test/src/com/android/car/test/AppFocusTest.java b/tests/carservice_test/src/com/android/car/AppFocusTest.java
similarity index 99%
rename from tests/carservice_test/src/com/android/car/test/AppFocusTest.java
rename to tests/carservice_test/src/com/android/car/AppFocusTest.java
index b63383e..d9bce26 100644
--- a/tests/carservice_test/src/com/android/car/test/AppFocusTest.java
+++ b/tests/carservice_test/src/com/android/car/AppFocusTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.car.Car;
import android.car.CarAppFocusManager;
diff --git a/tests/carservice_test/src/com/android/car/test/AudioRoutingPolicyTest.java b/tests/carservice_test/src/com/android/car/AudioRoutingPolicyTest.java
similarity index 99%
rename from tests/carservice_test/src/com/android/car/test/AudioRoutingPolicyTest.java
rename to tests/carservice_test/src/com/android/car/AudioRoutingPolicyTest.java
index 7f4aeac..357da1d 100644
--- a/tests/carservice_test/src/com/android/car/test/AudioRoutingPolicyTest.java
+++ b/tests/carservice_test/src/com/android/car/AudioRoutingPolicyTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.hardware.automotive.vehicle.V2_0.VehicleAudioContextFlag;
import android.hardware.automotive.vehicle.V2_0.VehicleAudioRoutingPolicyIndex;
diff --git a/tests/carservice_test/src/com/android/car/test/AudioTestUtils.java b/tests/carservice_test/src/com/android/car/AudioTestUtils.java
similarity index 98%
rename from tests/carservice_test/src/com/android/car/test/AudioTestUtils.java
rename to tests/carservice_test/src/com/android/car/AudioTestUtils.java
index 8c3de7c..459daa2 100644
--- a/tests/carservice_test/src/com/android/car/test/AudioTestUtils.java
+++ b/tests/carservice_test/src/com/android/car/AudioTestUtils.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.media.AudioAttributes;
import android.media.AudioFocusRequest;
diff --git a/tests/carservice_test/src/com/android/car/test/CarAudioExtFocusTest.java b/tests/carservice_test/src/com/android/car/CarAudioExtFocusTest.java
similarity index 97%
rename from tests/carservice_test/src/com/android/car/test/CarAudioExtFocusTest.java
rename to tests/carservice_test/src/com/android/car/CarAudioExtFocusTest.java
index 71e0d04..46e1df6 100644
--- a/tests/carservice_test/src/com/android/car/test/CarAudioExtFocusTest.java
+++ b/tests/carservice_test/src/com/android/car/CarAudioExtFocusTest.java
@@ -13,10 +13,10 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import static android.hardware.automotive.vehicle.V2_0.VehicleProperty.AUDIO_FOCUS;
-import static com.android.car.test.AudioTestUtils.doRequestFocus;
+import static com.android.car.AudioTestUtils.doRequestFocus;
import static java.lang.Integer.toHexString;
import android.car.Car;
@@ -227,7 +227,7 @@
public void testMediaNavFocus() throws Exception {
//music start
AudioFocusListener listenerMusic = new AudioFocusListener();
- int res = doRequestFocus(mAudioManager, listenerMusic,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, listenerMusic,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -249,7 +249,7 @@
setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).
setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
build();
- doRequestFocus(mAudioManager, listenerNav, navAttrib,
+ AudioTestUtils.doRequestFocus(mAudioManager, listenerNav, navAttrib,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN, request[0]);
@@ -293,7 +293,7 @@
public void testMediaExternalMediaNavFocus() throws Exception {
// android music
AudioFocusListener listenerMusic = new AudioFocusListener();
- int res = doRequestFocus(mAudioManager, listenerMusic,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, listenerMusic,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -323,7 +323,7 @@
setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).
setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
build();
- doRequestFocus(mAudioManager, listenerNav, navAttrib,
+ AudioTestUtils.doRequestFocus(mAudioManager, listenerNav, navAttrib,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN_TRANSIENT_MAY_DUCK,
@@ -369,7 +369,7 @@
assertNotNull(carAudioManager);
AudioAttributes radioAttributes = carAudioManager.getAudioAttributesForCarUsage(
CarAudioManager.CAR_AUDIO_USAGE_RADIO);
- int res = doRequestFocus(mAudioManager, listenerRadio,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, listenerRadio,
radioAttributes, AudioManager.AUDIOFOCUS_GAIN);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
int[] request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
@@ -389,7 +389,7 @@
AudioFocusListener listenerNav = new AudioFocusListener();
AudioAttributes extNavAttributes = mCarAudioManager.getAudioAttributesForExternalSource(
CarAudioManager.CAR_EXTERNAL_SOURCE_TYPE_EXT_NAV_GUIDANCE);
- res = doRequestFocus(mAudioManager, listenerNav,
+ res = AudioTestUtils.doRequestFocus(mAudioManager, listenerNav,
extNavAttributes, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
@@ -438,7 +438,7 @@
public void testMediaExternalNav() throws Exception {
// android music
AudioFocusListener listenerMusic = new AudioFocusListener();
- int res = doRequestFocus(mAudioManager, listenerMusic,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, listenerMusic,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -458,7 +458,7 @@
AudioFocusListener listenerNav = new AudioFocusListener();
AudioAttributes extNavAttributes = mCarAudioManager.getAudioAttributesForExternalSource(
CarAudioManager.CAR_EXTERNAL_SOURCE_TYPE_EXT_NAV_GUIDANCE);
- res = doRequestFocus(mAudioManager, listenerNav,
+ res = AudioTestUtils.doRequestFocus(mAudioManager, listenerNav,
extNavAttributes, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
@@ -514,7 +514,7 @@
AudioFocusListener listenerIntNav = new AudioFocusListener();
AudioAttributes intNavAttributes = mCarAudioManager.getAudioAttributesForCarUsage(
CarAudioManager.CAR_AUDIO_USAGE_NAVIGATION_GUIDANCE);
- int res = doRequestFocus(mAudioManager, listenerIntNav, intNavAttributes,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, listenerIntNav, intNavAttributes,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
int[] request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
@@ -534,7 +534,7 @@
AudioFocusListener listenerExtNav = new AudioFocusListener();
AudioAttributes extNavAttributes = mCarAudioManager.getAudioAttributesForExternalSource(
CarAudioManager.CAR_EXTERNAL_SOURCE_TYPE_EXT_NAV_GUIDANCE);
- res = doRequestFocus(mAudioManager, listenerExtNav,
+ res = AudioTestUtils.doRequestFocus(mAudioManager, listenerExtNav,
extNavAttributes, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
@@ -582,7 +582,7 @@
public void testMediaExternalRadioNavMediaFocus() throws Exception {
// android music
AudioFocusListener listenerMusic = new AudioFocusListener();
- int res = doRequestFocus(mAudioManager, listenerMusic,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, listenerMusic,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -605,7 +605,7 @@
assertNotNull(carAudioManager);
AudioAttributes radioAttributes = carAudioManager.getAudioAttributesForCarUsage(
CarAudioManager.CAR_AUDIO_USAGE_RADIO);
- res = doRequestFocus(mAudioManager, listenerRadio,
+ res = AudioTestUtils.doRequestFocus(mAudioManager, listenerRadio,
radioAttributes, AudioManager.AUDIOFOCUS_GAIN);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
@@ -627,7 +627,7 @@
setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).
setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
build();
- res = doRequestFocus(mAudioManager, listenerNav, navAttrib,
+ res = AudioTestUtils.doRequestFocus(mAudioManager, listenerNav, navAttrib,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN,
@@ -763,7 +763,7 @@
assertNotNull(carAudioManager);
AudioAttributes radioAttributes = carAudioManager.getAudioAttributesForCarUsage(mediaUsage);
Log.i(TAG, "request media Focus");
- int res = doRequestFocus(mAudioManager, listenerMedia,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, listenerMedia,
radioAttributes, AudioManager.AUDIOFOCUS_GAIN);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
int[] request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
@@ -807,7 +807,7 @@
setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
build();
Log.i(TAG, "request nav Focus");
- res = doRequestFocus(mAudioManager, listenerNav, navAttrib,
+ res = AudioTestUtils.doRequestFocus(mAudioManager, listenerNav, navAttrib,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN_TRANSIENT_MAY_DUCK,
diff --git a/tests/carservice_test/src/com/android/car/test/CarAudioFocusSystemSoundTest.java b/tests/carservice_test/src/com/android/car/CarAudioFocusSystemSoundTest.java
similarity index 97%
rename from tests/carservice_test/src/com/android/car/test/CarAudioFocusSystemSoundTest.java
rename to tests/carservice_test/src/com/android/car/CarAudioFocusSystemSoundTest.java
index afafb28..5e0d2e7 100644
--- a/tests/carservice_test/src/com/android/car/test/CarAudioFocusSystemSoundTest.java
+++ b/tests/carservice_test/src/com/android/car/CarAudioFocusSystemSoundTest.java
@@ -13,11 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import static android.hardware.automotive.vehicle.V2_0.VehicleProperty.AUDIO_FOCUS;
import static android.hardware.automotive.vehicle.V2_0.VehicleProperty.AUDIO_STREAM_STATE;
-import static com.android.car.test.AudioTestUtils.doRequestFocus;
+import static com.android.car.AudioTestUtils.doRequestFocus;
import com.google.android.collect.Lists;
@@ -137,7 +137,7 @@
assertNotNull(carAudioManager);
AudioAttributes radioAttributes = carAudioManager.getAudioAttributesForCarUsage(
CarAudioManager.CAR_AUDIO_USAGE_RADIO);
- int res = doRequestFocus(mAudioManager, listenerRadio,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, listenerRadio,
radioAttributes, AudioManager.AUDIOFOCUS_GAIN);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
int[] request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
@@ -191,7 +191,7 @@
public void testMusicSystemSound() throws Exception {
// music start
AudioFocusListener listenerMusic = new AudioFocusListener();
- int res = doRequestFocus(mAudioManager, listenerMusic,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, listenerMusic,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -247,7 +247,7 @@
setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).
setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
build();
- int res = doRequestFocus(mAudioManager, listenerNav, navAttrib,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, listenerNav, navAttrib,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
int[] request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
diff --git a/tests/carservice_test/src/com/android/car/test/CarAudioFocusTest.java b/tests/carservice_test/src/com/android/car/CarAudioFocusTest.java
similarity index 96%
rename from tests/carservice_test/src/com/android/car/test/CarAudioFocusTest.java
rename to tests/carservice_test/src/com/android/car/CarAudioFocusTest.java
index 6f5da5f..982924f 100644
--- a/tests/carservice_test/src/com/android/car/test/CarAudioFocusTest.java
+++ b/tests/carservice_test/src/com/android/car/CarAudioFocusTest.java
@@ -13,10 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import static android.hardware.automotive.vehicle.V2_0.VehicleProperty.AUDIO_FOCUS;
-import static com.android.car.test.AudioTestUtils.doRequestFocus;
import android.car.Car;
import android.car.media.CarAudioManager;
@@ -136,7 +135,7 @@
public void testMediaNavFocus() throws Exception {
//music start
AudioFocusListener listenerMusic = new AudioFocusListener();
- int res = doRequestFocus(mAudioManager, listenerMusic,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, listenerMusic,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -156,7 +155,7 @@
setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).
setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
build();
- doRequestFocus(mAudioManager, listenerNav, navAttrib,
+ AudioTestUtils.doRequestFocus(mAudioManager, listenerNav, navAttrib,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN, request[0]);
@@ -194,7 +193,7 @@
public void testMediaExternalMediaNavFocus() throws Exception {
// android music
AudioFocusListener listenerMusic = new AudioFocusListener();
- int res = doRequestFocus(mAudioManager, listenerMusic,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, listenerMusic,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -222,7 +221,7 @@
setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).
setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
build();
- doRequestFocus(mAudioManager, listenerNav, navAttrib,
+ AudioTestUtils.doRequestFocus(mAudioManager, listenerNav, navAttrib,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN_TRANSIENT_MAY_DUCK,
@@ -259,7 +258,7 @@
public void testMediaExternalRadioNavMediaFocus() throws Exception {
// android music
AudioFocusListener listenerMusic = new AudioFocusListener();
- int res = doRequestFocus(mAudioManager, listenerMusic,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, listenerMusic,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -280,7 +279,7 @@
assertNotNull(carAudioManager);
AudioAttributes radioAttributes = carAudioManager.getAudioAttributesForCarUsage(
CarAudioManager.CAR_AUDIO_USAGE_RADIO);
- res = doRequestFocus(mAudioManager, listenerRadio,
+ res = AudioTestUtils.doRequestFocus(mAudioManager, listenerRadio,
radioAttributes, AudioManager.AUDIOFOCUS_GAIN);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
@@ -300,7 +299,7 @@
setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION).
setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
build();
- res = doRequestFocus(mAudioManager, listenerNav, navAttrib,
+ res = AudioTestUtils.doRequestFocus(mAudioManager, listenerNav, navAttrib,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN,
@@ -361,7 +360,7 @@
int context)
throws Exception {
AudioFocusListener lister = new AudioFocusListener();
- int res = doRequestFocus(mAudioManager, lister,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, lister,
streamType,
androidFocus);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -427,7 +426,7 @@
assertNotNull(carAudioManager);
AudioAttributes radioAttributes = carAudioManager.getAudioAttributesForCarUsage(mediaUsage);
Log.i(TAG, "request media Focus");
- int res = doRequestFocus(mAudioManager, listenerMedia,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, listenerMedia,
radioAttributes, AudioManager.AUDIOFOCUS_GAIN);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
int[] request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
@@ -462,7 +461,7 @@
setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE).
build();
Log.i(TAG, "request nav Focus");
- res = doRequestFocus(mAudioManager, listenerNav, navAttrib,
+ res = AudioTestUtils.doRequestFocus(mAudioManager, listenerNav, navAttrib,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
assertEquals(VehicleAudioFocusRequest.REQUEST_GAIN_TRANSIENT_MAY_DUCK,
diff --git a/tests/carservice_test/src/com/android/car/test/CarAudioManagerTest.java b/tests/carservice_test/src/com/android/car/CarAudioManagerTest.java
similarity index 99%
rename from tests/carservice_test/src/com/android/car/test/CarAudioManagerTest.java
rename to tests/carservice_test/src/com/android/car/CarAudioManagerTest.java
index 07646d4..a66cc60 100644
--- a/tests/carservice_test/src/com/android/car/test/CarAudioManagerTest.java
+++ b/tests/carservice_test/src/com/android/car/CarAudioManagerTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.car.Car;
import android.car.media.CarAudioManager;
diff --git a/tests/carservice_test/src/com/android/car/test/CarCabinManagerTest.java b/tests/carservice_test/src/com/android/car/CarCabinManagerTest.java
similarity index 99%
rename from tests/carservice_test/src/com/android/car/test/CarCabinManagerTest.java
rename to tests/carservice_test/src/com/android/car/CarCabinManagerTest.java
index cef163e..58b784b 100644
--- a/tests/carservice_test/src/com/android/car/test/CarCabinManagerTest.java
+++ b/tests/carservice_test/src/com/android/car/CarCabinManagerTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.car.Car;
import android.car.hardware.CarPropertyValue;
diff --git a/tests/carservice_test/src/com/android/car/test/CarDiagnosticConstantsTest.java b/tests/carservice_test/src/com/android/car/CarDiagnosticConstantsTest.java
similarity index 99%
rename from tests/carservice_test/src/com/android/car/test/CarDiagnosticConstantsTest.java
rename to tests/carservice_test/src/com/android/car/CarDiagnosticConstantsTest.java
index 2ed2658..33be912 100644
--- a/tests/carservice_test/src/com/android/car/test/CarDiagnosticConstantsTest.java
+++ b/tests/carservice_test/src/com/android/car/CarDiagnosticConstantsTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.test.suitebuilder.annotation.MediumTest;
import android.util.Log;
diff --git a/tests/carservice_test/src/com/android/car/test/CarDiagnosticManagerTest.java b/tests/carservice_test/src/com/android/car/CarDiagnosticManagerTest.java
similarity index 98%
rename from tests/carservice_test/src/com/android/car/test/CarDiagnosticManagerTest.java
rename to tests/carservice_test/src/com/android/car/CarDiagnosticManagerTest.java
index b77a844..eb7ef57 100644
--- a/tests/carservice_test/src/com/android/car/test/CarDiagnosticManagerTest.java
+++ b/tests/carservice_test/src/com/android/car/CarDiagnosticManagerTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import static java.lang.Integer.toHexString;
@@ -43,6 +43,7 @@
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
@@ -190,6 +191,7 @@
@Override
protected synchronized void configureMockedHal() {
java.util.Collection<Integer> numVendorSensors = Arrays.asList(0, 0);
+ java.util.Collection<Integer> selectiveClear = Collections.singletonList(1);
addProperty(VehicleProperty.OBD2_LIVE_FRAME, mLiveFrameEventBuilder.build())
.setConfigArray(numVendorSensors);
addProperty(
@@ -199,7 +201,8 @@
.setConfigArray(numVendorSensors);
addProperty(
VehicleProperty.OBD2_FREEZE_FRAME_CLEAR,
- mFreezeFrameProperties.mFreezeFrameClearHandler);
+ mFreezeFrameProperties.mFreezeFrameClearHandler)
+ .setConfigArray(selectiveClear);
}
@Override
@@ -732,6 +735,7 @@
assertTrue(mCarDiagnosticManager.isFreezeFrameNotificationSupported());
assertTrue(mCarDiagnosticManager.isGetFreezeFrameSupported());
assertTrue(mCarDiagnosticManager.isClearFreezeFramesSupported());
+ assertTrue(mCarDiagnosticManager.isSelectiveClearFreezeFramesSupported());
}
class Listener implements CarDiagnosticManager.OnDiagnosticEventListener {
diff --git a/tests/carservice_test/src/com/android/car/test/CarHvacManagerTest.java b/tests/carservice_test/src/com/android/car/CarHvacManagerTest.java
similarity index 99%
rename from tests/carservice_test/src/com/android/car/test/CarHvacManagerTest.java
rename to tests/carservice_test/src/com/android/car/CarHvacManagerTest.java
index 07f879e..9c89694 100644
--- a/tests/carservice_test/src/com/android/car/test/CarHvacManagerTest.java
+++ b/tests/carservice_test/src/com/android/car/CarHvacManagerTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.car.Car;
import android.car.hardware.CarPropertyValue;
diff --git a/tests/carservice_test/src/com/android/car/test/CarInfoManagerTest.java b/tests/carservice_test/src/com/android/car/CarInfoManagerTest.java
similarity index 98%
rename from tests/carservice_test/src/com/android/car/test/CarInfoManagerTest.java
rename to tests/carservice_test/src/com/android/car/CarInfoManagerTest.java
index 2cdbbb0..fe32615 100644
--- a/tests/carservice_test/src/com/android/car/test/CarInfoManagerTest.java
+++ b/tests/carservice_test/src/com/android/car/CarInfoManagerTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.car.Car;
import android.car.CarInfoManager;
diff --git a/tests/carservice_test/src/com/android/car/test/CarPackageManagerTest.java b/tests/carservice_test/src/com/android/car/CarPackageManagerTest.java
similarity index 99%
rename from tests/carservice_test/src/com/android/car/test/CarPackageManagerTest.java
rename to tests/carservice_test/src/com/android/car/CarPackageManagerTest.java
index c455bc4..ffbf5a4 100644
--- a/tests/carservice_test/src/com/android/car/test/CarPackageManagerTest.java
+++ b/tests/carservice_test/src/com/android/car/CarPackageManagerTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.car.Car;
import android.car.CarNotConnectedException;
diff --git a/tests/carservice_test/src/com/android/car/test/CarPowerManagementTest.java b/tests/carservice_test/src/com/android/car/CarPowerManagementTest.java
similarity index 99%
rename from tests/carservice_test/src/com/android/car/test/CarPowerManagementTest.java
rename to tests/carservice_test/src/com/android/car/CarPowerManagementTest.java
index d5e5bf8..64d9b82 100644
--- a/tests/carservice_test/src/com/android/car/test/CarPowerManagementTest.java
+++ b/tests/carservice_test/src/com/android/car/CarPowerManagementTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.hardware.automotive.vehicle.V2_0.VehicleApPowerBootupReason;
import android.hardware.automotive.vehicle.V2_0.VehicleApPowerSetState;
diff --git a/tests/carservice_test/src/com/android/car/test/CarProjectionManagerTest.java b/tests/carservice_test/src/com/android/car/CarProjectionManagerTest.java
similarity index 99%
rename from tests/carservice_test/src/com/android/car/test/CarProjectionManagerTest.java
rename to tests/carservice_test/src/com/android/car/CarProjectionManagerTest.java
index adf288c..773a296 100644
--- a/tests/carservice_test/src/com/android/car/test/CarProjectionManagerTest.java
+++ b/tests/carservice_test/src/com/android/car/CarProjectionManagerTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.car.Car;
import android.car.CarProjectionManager;
diff --git a/tests/carservice_test/src/com/android/car/test/CarRadioManagerTest.java b/tests/carservice_test/src/com/android/car/CarRadioManagerTest.java
similarity index 99%
rename from tests/carservice_test/src/com/android/car/test/CarRadioManagerTest.java
rename to tests/carservice_test/src/com/android/car/CarRadioManagerTest.java
index 169a370..7288259 100644
--- a/tests/carservice_test/src/com/android/car/test/CarRadioManagerTest.java
+++ b/tests/carservice_test/src/com/android/car/CarRadioManagerTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.car.Car;
import android.car.hardware.radio.CarRadioEvent;
diff --git a/tests/carservice_test/src/com/android/car/test/CarSensorManagerTest.java b/tests/carservice_test/src/com/android/car/CarSensorManagerTest.java
similarity index 99%
rename from tests/carservice_test/src/com/android/car/test/CarSensorManagerTest.java
rename to tests/carservice_test/src/com/android/car/CarSensorManagerTest.java
index daddfdb..00120a3 100644
--- a/tests/carservice_test/src/com/android/car/test/CarSensorManagerTest.java
+++ b/tests/carservice_test/src/com/android/car/CarSensorManagerTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.car.Car;
import android.car.CarNotConnectedException;
diff --git a/tests/carservice_test/src/com/android/car/CarStorageMonitoringTest.java b/tests/carservice_test/src/com/android/car/CarStorageMonitoringTest.java
new file mode 100644
index 0000000..cd104f8
--- /dev/null
+++ b/tests/carservice_test/src/com/android/car/CarStorageMonitoringTest.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 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.car;
+
+import android.car.Car;
+import android.car.storagemonitoring.CarStorageMonitoringManager;
+import android.car.storagemonitoring.WearEstimate;
+import android.test.suitebuilder.annotation.MediumTest;
+import com.android.car.storagemonitoring.WearInformation;
+
+/** Test the public entry points for the CarStorageMonitoringManager */
+@MediumTest
+public class CarStorageMonitoringTest extends MockedCarTestBase {
+ private static final String TAG = CarStorageMonitoringTest.class.getSimpleName();
+
+ private static final WearInformation DEFAULT_WEAR_INFORMATION =
+ new WearInformation(10, 0, WearInformation.PRE_EOL_INFO_NORMAL);
+
+ private CarStorageMonitoringManager mCarStorageMonitoringManager;
+
+ @Override
+ protected synchronized void configureFakeSystemInterface() {
+ setFlashWearInformation(DEFAULT_WEAR_INFORMATION);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mCarStorageMonitoringManager =
+ (CarStorageMonitoringManager) getCar().getCarManager(Car.STORAGE_MONITORING_SERVICE);
+ }
+
+ public void testReadPreEolInformation() throws Exception {
+ assertEquals(DEFAULT_WEAR_INFORMATION.preEolInfo,
+ mCarStorageMonitoringManager.getPreEolIndicatorStatus());
+ }
+
+ public void testReadWearEstimate() throws Exception {
+ final WearEstimate wearEstimate = mCarStorageMonitoringManager.getWearEstimate();
+
+ assertNotNull(wearEstimate);
+ assertEquals(DEFAULT_WEAR_INFORMATION.lifetimeEstimateA, wearEstimate.typeA);
+ assertEquals(DEFAULT_WEAR_INFORMATION.lifetimeEstimateB, wearEstimate.typeB);
+ }
+}
diff --git a/tests/carservice_test/src/com/android/car/test/CarVendorExtensionManagerTest.java b/tests/carservice_test/src/com/android/car/CarVendorExtensionManagerTest.java
similarity index 99%
rename from tests/carservice_test/src/com/android/car/test/CarVendorExtensionManagerTest.java
rename to tests/carservice_test/src/com/android/car/CarVendorExtensionManagerTest.java
index fa33e56..29b24e3 100644
--- a/tests/carservice_test/src/com/android/car/test/CarVendorExtensionManagerTest.java
+++ b/tests/carservice_test/src/com/android/car/CarVendorExtensionManagerTest.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import static com.android.car.CarServiceUtils.toByteArray;
diff --git a/tests/carservice_test/src/com/android/car/test/CarVolumeServiceTest.java b/tests/carservice_test/src/com/android/car/CarVolumeServiceTest.java
similarity index 90%
rename from tests/carservice_test/src/com/android/car/test/CarVolumeServiceTest.java
rename to tests/carservice_test/src/com/android/car/CarVolumeServiceTest.java
index 2e92a59..0d9a607 100644
--- a/tests/carservice_test/src/com/android/car/test/CarVolumeServiceTest.java
+++ b/tests/carservice_test/src/com/android/car/CarVolumeServiceTest.java
@@ -13,9 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.car.test;
-
-import static com.android.car.test.AudioTestUtils.doRequestFocus;
+package com.android.car;
import android.car.Car;
import android.car.CarNotConnectedException;
@@ -40,13 +38,12 @@
import android.util.SparseIntArray;
import android.view.KeyEvent;
-import com.android.car.VolumeUtils;
+import com.google.android.collect.Lists;
+
import com.android.car.vehiclehal.VehiclePropValueBuilder;
import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler;
import com.android.internal.annotations.GuardedBy;
-import com.google.android.collect.Lists;
-
import java.util.ArrayList;
import java.util.List;
@@ -54,7 +51,6 @@
public class CarVolumeServiceTest extends MockedCarTestBase {
private static final String TAG = CarVolumeServiceTest.class.getSimpleName();
- private static final int MIN_VOL = 1;
private static final int MAX_VOL = 20;
private static final long TIMEOUT_MS = 3000;
private static final long POLL_INTERVAL_MS = 50;
@@ -101,7 +97,7 @@
}
}
SingleChannelVolumeHandler handler =
- startVolumeEmulation(supportedAudioContext, maxs);
+ startVolumeEmulation(true, supportedAudioContext, maxs);
mCarAudioManager = (CarAudioManager) getCar().getCarManager(Car.AUDIO_SERVICE);
return handler;
}
@@ -114,7 +110,7 @@
// give focus to music, now current context becomes VehicleAudioContextFlag.MUSIC_FLAG
CarAudioFocusTest.AudioFocusListener listenerMusic =
new CarAudioFocusTest.AudioFocusListener();
- int res = doRequestFocus(mAudioManager, listenerMusic,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, listenerMusic,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -138,7 +134,7 @@
}
}
- public void testVolumeSet() throws Exception {
+ public void testVolumeSet() {
try {
setupExternalVolumeEmulation(false);
int callVol = 10;
@@ -154,8 +150,27 @@
volumeVerificationPoll(createStreamVolPair(AudioManager.STREAM_MUSIC, MAX_VOL),
createStreamVolPair(AudioManager.STREAM_VOICE_CALL, callVol));
- } catch (CarNotConnectedException e) {
- fail("Car not connected");
+ } catch (Exception e) {
+ fail(e.getMessage());
+ }
+ }
+
+ public void testMultipleVolumeControllers() {
+ try {
+ startVolumeEmulation(false, 0, new ArrayList<>());
+ mCarAudioManager = (CarAudioManager) getCar().getCarManager(Car.AUDIO_SERVICE);
+ mCarAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0);
+ VolumeController volumeController1 = new VolumeController();
+ VolumeController volumeController2 = new VolumeController();
+ mCarAudioManager.setVolumeController(volumeController1);
+ mCarAudioManager.setVolumeController(volumeController2);
+
+ mCarAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
+ 1, AudioManager.FLAG_SHOW_UI);
+ volumeChangeVerificationPoll(AudioManager.STREAM_MUSIC, true, volumeController1);
+ volumeChangeVerificationPoll(AudioManager.STREAM_MUSIC, true, volumeController2);
+ } catch (Exception e) {
+ fail(e.getMessage());
}
}
@@ -168,7 +183,7 @@
// first give focus to system sound
CarAudioFocusTest.AudioFocusListener listenerMusic =
new CarAudioFocusTest.AudioFocusListener();
- int res = doRequestFocus(mAudioManager, listenerMusic,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, listenerMusic,
AudioManager.STREAM_SYSTEM,
AudioManager.AUDIOFOCUS_GAIN);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -184,7 +199,7 @@
AudioAttributes callAttrib = (new AudioAttributes.Builder()).
setUsage(AudioAttributes.USAGE_ALARM).
build();
- res = doRequestFocus(mAudioManager, listenerAlarm, callAttrib,
+ res = AudioTestUtils.doRequestFocus(mAudioManager, listenerAlarm, callAttrib,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
@@ -207,7 +222,7 @@
}
}
- public void testVolumeKeys() throws Exception {
+ public void testVolumeKeys() {
try {
setupExternalVolumeEmulation(false);
int musicVol = 10;
@@ -217,7 +232,7 @@
CarAudioFocusTest.AudioFocusListener listenerMusic =
new CarAudioFocusTest.AudioFocusListener();
- int res = doRequestFocus(mAudioManager, listenerMusic,
+ int res = AudioTestUtils.doRequestFocus(mAudioManager, listenerMusic,
AudioManager.STREAM_MUSIC,
AudioManager.AUDIOFOCUS_GAIN);
assertEquals(AudioManager.AUDIOFOCUS_REQUEST_GRANTED, res);
@@ -239,7 +254,7 @@
AudioAttributes callAttrib = (new AudioAttributes.Builder()).
setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION).
build();
- doRequestFocus(mAudioManager, listenerCall, callAttrib,
+ AudioTestUtils.doRequestFocus(mAudioManager, listenerCall, callAttrib,
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
request = mAudioFocusPropertyHandler.waitForAudioFocusRequest(TIMEOUT_MS);
mAudioFocusPropertyHandler.sendAudioFocusState(
@@ -250,7 +265,7 @@
callVol++;
volumeVerificationPoll(createStreamVolPair(AudioManager.STREAM_MUSIC, musicVol),
createStreamVolPair(AudioManager.STREAM_VOICE_CALL, callVol));
- } catch (CarNotConnectedException | InterruptedException e) {
+ } catch (Exception e) {
fail(e.toString());
}
}
@@ -411,8 +426,8 @@
}
};
- private SingleChannelVolumeHandler startVolumeEmulation(int supportedAudioVolumeContext,
- List<Integer> maxs) {
+ private SingleChannelVolumeHandler startVolumeEmulation(boolean supportExternalVolume,
+ int supportedAudioVolumeContext, List<Integer> maxs) {
SingleChannelVolumeHandler singleChannelVolumeHandler =
new SingleChannelVolumeHandler(maxs);
int zones = (1<<maxs.size()) - 1;
@@ -425,9 +440,11 @@
0 /* reserved */);
audioVolumeConfigArray.addAll(maxs);
- addProperty(VehicleProperty.AUDIO_VOLUME, singleChannelVolumeHandler)
- .setConfigArray(audioVolumeConfigArray)
- .setSupportedAreas(zones);
+ if (supportExternalVolume) {
+ addProperty(VehicleProperty.AUDIO_VOLUME, singleChannelVolumeHandler)
+ .setConfigArray(audioVolumeConfigArray)
+ .setSupportedAreas(zones);
+ }
addProperty(VehicleProperty.HW_KEY_INPUT, mHWKeyHandler)
.setAccess(VehiclePropertyAccess.READ);
diff --git a/tests/carservice_test/src/com/android/car/test/GarageModeTest.java b/tests/carservice_test/src/com/android/car/GarageModeTest.java
similarity index 96%
rename from tests/carservice_test/src/com/android/car/test/GarageModeTest.java
rename to tests/carservice_test/src/com/android/car/GarageModeTest.java
index 19ccb6e..06abdc8 100644
--- a/tests/carservice_test/src/com/android/car/test/GarageModeTest.java
+++ b/tests/carservice_test/src/com/android/car/GarageModeTest.java
@@ -13,17 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.car.settings.CarSettings;
import android.content.Context;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
-import com.android.car.CarPowerManagementService;
-import com.android.car.DeviceIdleControllerWrapper;
-import com.android.car.GarageModeService;
-
@MediumTest
public class GarageModeTest extends AndroidTestCase {
diff --git a/tests/carservice_test/src/com/android/car/test/MockedCarTestBase.java b/tests/carservice_test/src/com/android/car/MockedCarTestBase.java
similarity index 76%
rename from tests/carservice_test/src/com/android/car/test/MockedCarTestBase.java
rename to tests/carservice_test/src/com/android/car/MockedCarTestBase.java
index a060496..f670832 100644
--- a/tests/carservice_test/src/com/android/car/test/MockedCarTestBase.java
+++ b/tests/carservice_test/src/com/android/car/MockedCarTestBase.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.car.test.CarTestManager;
import android.car.test.CarTestManagerBinderWrapper;
@@ -28,18 +28,22 @@
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
+import android.os.SystemClock;
import android.test.AndroidTestCase;
import android.util.Log;
-import com.android.car.CarPowerManagementService;
-import com.android.car.ICarImpl;
-import com.android.car.SystemInterface;
+import com.android.car.MockedCarTestBase.FakeSystemInterface.UptimeProvider;
+import com.android.car.storagemonitoring.WearInformation;
+import com.android.car.storagemonitoring.WearInformationProvider;
+import com.android.car.test.utils.TemporaryDirectory;
import com.android.car.vehiclehal.test.MockedVehicleHal;
import com.android.car.vehiclehal.test.MockedVehicleHal.DefaultPropertyHandler;
import com.android.car.vehiclehal.test.MockedVehicleHal.StaticPropertyHandler;
import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler;
import com.android.car.vehiclehal.test.VehiclePropConfigBuilder;
+import java.io.File;
+import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@@ -75,9 +79,24 @@
return mMockedVehicleHal;
}
+ protected synchronized FakeSystemInterface getFakeSystemInterface() {
+ return mFakeSystemInterface;
+ }
+
protected synchronized void configureMockedHal() {
}
+ protected synchronized void configureFakeSystemInterface() {
+ }
+
+ protected synchronized void setFlashWearInformation(WearInformation wearInformation) {
+ mFakeSystemInterface.mWearInformationProvider.setWearInformation(wearInformation);
+ }
+
+ protected synchronized void setUptimeProvider(UptimeProvider uptimeProvider) {
+ mFakeSystemInterface.mUptimeProvider = uptimeProvider;
+ }
+
@Override
protected synchronized void setUp() throws Exception {
super.setUp();
@@ -88,6 +107,8 @@
configureMockedHal();
mFakeSystemInterface = new FakeSystemInterface();
+ configureFakeSystemInterface();
+
Context context = getCarServiceContext();
mCarImpl = new ICarImpl(context, mMockedVehicleHal, mFakeSystemInterface,
null /* error notifier */);
@@ -103,6 +124,8 @@
mCar.disconnect();
mCarImpl.release();
+
+ mFakeSystemInterface.tearDown();
}
protected Context getCarServiceContext() throws NameNotFoundException {
@@ -239,10 +262,28 @@
}
}
- private static class FakeSystemInterface extends SystemInterface {
+ static class FakeSystemInterface extends SystemInterface {
+ interface UptimeProvider {
+ long getUptime(boolean includeDeepSleepTime);
+ }
private boolean mDisplayOn = true;
private final Semaphore mDisplayStateWait = new Semaphore(0);
+ private final class FakeWearInformationProvider implements WearInformationProvider {
+ private WearInformation mWearInformation = null;
+ public void setWearInformation(WearInformation wearInformation) {
+ mWearInformation = wearInformation;
+ }
+
+ @Override
+ public WearInformation load() {
+ return mWearInformation;
+ }
+ }
+ private final FakeWearInformationProvider mWearInformationProvider =
+ new FakeWearInformationProvider();
+ private TemporaryDirectory mFilesDir = null;
+ private UptimeProvider mUptimeProvider = null;
@Override
public synchronized void setDisplayState(boolean on) {
@@ -292,5 +333,41 @@
@Override
public boolean isWakeupCausedByTimer() { return false; }
+
+ @Override
+ public WearInformationProvider[] getFlashWearInformationProviders() {
+ return new WearInformationProvider[] { mWearInformationProvider };
+ }
+
+ @Override
+ public File getFilesDir() {
+ if (mFilesDir == null) {
+ try {
+ mFilesDir = new TemporaryDirectory(TAG);
+ } catch (IOException e) {
+ Log.e(TAG, "failed to create temporary directory", e);
+ fail("failed to create temporary directory. exception was: " + e);
+ }
+ }
+ return mFilesDir.getDirectory();
+ }
+
+ @Override
+ public long getUptime(boolean includeDeepSleepTime) {
+ if (mUptimeProvider != null) {
+ return mUptimeProvider.getUptime(includeDeepSleepTime);
+ }
+ return super.getUptime(includeDeepSleepTime);
+ }
+
+ void tearDown() {
+ if (mFilesDir != null) {
+ try {
+ mFilesDir.close();
+ } catch (Exception e) {
+ Log.w(TAG, "could not remove temporary directory", e);
+ }
+ }
+ }
}
}
diff --git a/tests/carservice_test/src/com/android/car/test/SimpleVmsPublisherClientService.java b/tests/carservice_test/src/com/android/car/SimpleVmsPublisherClientService.java
similarity index 93%
rename from tests/carservice_test/src/com/android/car/test/SimpleVmsPublisherClientService.java
rename to tests/carservice_test/src/com/android/car/SimpleVmsPublisherClientService.java
index c3c15f5..53491b1 100644
--- a/tests/carservice_test/src/com/android/car/test/SimpleVmsPublisherClientService.java
+++ b/tests/carservice_test/src/com/android/car/SimpleVmsPublisherClientService.java
@@ -14,16 +14,14 @@
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
-import android.car.annotation.FutureFeature;
import android.car.vms.VmsPublisherClientService;
import android.car.vms.VmsSubscriptionState;
/**
* This service is launched during the tests in VmsPublisherClientServiceTest.
*/
-@FutureFeature
public class SimpleVmsPublisherClientService extends VmsPublisherClientService {
@Override
public void onVmsSubscriptionChange(VmsSubscriptionState subscriptionState) {
diff --git a/tests/carservice_test/src/com/android/car/test/SystemActivityMonitoringServiceTest.java b/tests/carservice_test/src/com/android/car/SystemActivityMonitoringServiceTest.java
similarity index 98%
rename from tests/carservice_test/src/com/android/car/test/SystemActivityMonitoringServiceTest.java
rename to tests/carservice_test/src/com/android/car/SystemActivityMonitoringServiceTest.java
index 3345605..d95170d 100644
--- a/tests/carservice_test/src/com/android/car/test/SystemActivityMonitoringServiceTest.java
+++ b/tests/carservice_test/src/com/android/car/SystemActivityMonitoringServiceTest.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.app.Activity;
import android.content.ComponentName;
@@ -25,7 +25,6 @@
import android.os.SystemClock;
import android.test.suitebuilder.annotation.MediumTest;
-import com.android.car.SystemActivityMonitoringService;
import com.android.car.SystemActivityMonitoringService.TopTaskInfoContainer;
import com.android.car.vehiclehal.VehiclePropValueBuilder;
import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler;
diff --git a/tests/carservice_test/src/com/android/car/test/TestAppBlockingPolicyService.java b/tests/carservice_test/src/com/android/car/TestAppBlockingPolicyService.java
similarity index 98%
rename from tests/carservice_test/src/com/android/car/test/TestAppBlockingPolicyService.java
rename to tests/carservice_test/src/com/android/car/TestAppBlockingPolicyService.java
index dc1ad8a..ec30d0d 100644
--- a/tests/carservice_test/src/com/android/car/test/TestAppBlockingPolicyService.java
+++ b/tests/carservice_test/src/com/android/car/TestAppBlockingPolicyService.java
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.car.content.pm.AppBlockingPackageInfo;
import android.car.content.pm.CarAppBlockingPolicy;
diff --git a/tests/carservice_test/src/com/android/car/test/VmsHalServiceSubscriptionEventTest.java b/tests/carservice_test/src/com/android/car/VmsHalServiceSubscriptionEventTest.java
similarity index 95%
rename from tests/carservice_test/src/com/android/car/test/VmsHalServiceSubscriptionEventTest.java
rename to tests/carservice_test/src/com/android/car/VmsHalServiceSubscriptionEventTest.java
index cad3086..286c004 100644
--- a/tests/carservice_test/src/com/android/car/test/VmsHalServiceSubscriptionEventTest.java
+++ b/tests/carservice_test/src/com/android/car/VmsHalServiceSubscriptionEventTest.java
@@ -14,12 +14,11 @@
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import static org.junit.Assume.assumeTrue;
import android.car.VehicleAreaType;
-import android.car.annotation.FutureFeature;
import android.car.vms.VmsLayer;
import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
import android.hardware.automotive.vehicle.V2_0.VehiclePropertyAccess;
@@ -41,7 +40,6 @@
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
-@FutureFeature
@MediumTest
public class VmsHalServiceSubscriptionEventTest extends MockedCarTestBase {
private static final String TAG = "VmsHalServiceTest";
@@ -62,7 +60,6 @@
@Override
protected void setUp() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
super.setUp();
mHal = getMockedVehicleHal();
mHalHandlerSemaphore = new Semaphore(0);
@@ -70,24 +67,20 @@
@Override
protected synchronized void tearDown() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
super.tearDown();
}
public void testEmptySubscriptions() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
List<VmsLayer> layers = new ArrayList<>();
subscriptionTestLogic(layers);
}
public void testOneSubscription() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
List<VmsLayer> layers = Arrays.asList(new VmsLayer(8, 0, 3));
subscriptionTestLogic(layers);
}
public void testManySubscriptions() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
List<VmsLayer> layers = Arrays.asList(
new VmsLayer(8, 1, 3),
new VmsLayer(5, 2, 1),
diff --git a/tests/carservice_test/src/com/android/car/test/VmsOperationRecorderTest.java b/tests/carservice_test/src/com/android/car/VmsOperationRecorderTest.java
similarity index 73%
rename from tests/carservice_test/src/com/android/car/test/VmsOperationRecorderTest.java
rename to tests/carservice_test/src/com/android/car/VmsOperationRecorderTest.java
index a00ec68..f6b3be5 100644
--- a/tests/carservice_test/src/com/android/car/test/VmsOperationRecorderTest.java
+++ b/tests/carservice_test/src/com/android/car/VmsOperationRecorderTest.java
@@ -14,16 +14,19 @@
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.car.vms.VmsLayer;
import android.car.vms.VmsLayerDependency;
import android.car.vms.VmsLayersOffering;
import android.car.vms.VmsOperationRecorder;
import android.test.suitebuilder.annotation.MediumTest;
+import android.util.Log;
import junit.framework.TestCase;
+import org.json.JSONArray;
+import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
@@ -53,6 +56,7 @@
private TestWriter mWriter;
private VmsOperationRecorder mRecorder;
+ private static final String TAG = "VmsOperationRecorderTest";
private static final VmsLayer layer1 = new VmsLayer(1, 3, 2);
private static final VmsLayer layer2 = new VmsLayer(2, 4, 3);
@@ -76,7 +80,7 @@
public void testSubscribe() throws Exception {
mRecorder.subscribe(layer1);
- assertJsonMsgEquals("{'subscribe':{'layer':{'type':1,'subtype':3,'version':2}}}");
+ assertJsonMsgEquals("{'subscribe':{'layer':{'subtype':3,'type':1,'version':2}}}");
}
public void testUnsubscribe() throws Exception {
@@ -177,8 +181,65 @@
// quotes instead, which gets replaced here.
JSONObject expect = new JSONObject(expectJson.replace("'", "\""));
JSONObject got = new JSONObject(mWriter.mMsg);
- // Comparing the JSON strings works and is not flakey only because the JSON library
- // generates a consistent string representation when object construction is consistent.
- assertEquals(expect.toString(), got.toString());
+ assertTrue(similar(expect, got));
+ }
+
+ /*
+ * Determine if two JSONObjects are similar.
+ * They must contain the same set of names which must be associated with
+ * similar values.
+ */
+ private boolean similar(JSONObject expect, JSONObject got) {
+ try {
+ if (!expect.keySet().equals(got.keySet())) {
+ return false;
+ }
+
+ for (String key : expect.keySet()) {
+ Object valueExpect = expect.get(key);
+ Object valueGot = got.get(key);
+
+ if (valueExpect == valueGot) {
+ continue;
+ }
+
+ if (valueExpect == null) {
+ return false;
+ }
+
+ if (valueExpect instanceof JSONObject) {
+ return similar((JSONObject) valueExpect, (JSONObject) valueGot);
+ } else if (valueExpect instanceof JSONArray) {
+ // Equal JSONArray have the same length and one contains the other.
+ JSONArray expectArray = (JSONArray) valueExpect;
+ JSONArray gotArray = (JSONArray) valueGot;
+
+ if (expectArray.length() != gotArray.length()) {
+ return false;
+ }
+
+ for (int i = 0; i < expectArray.length(); i++) {
+ boolean gotContainsSimilar = false;
+ for (int j = 0; j < gotArray.length(); j++) {
+ if (similar((JSONObject) expectArray.get(i),
+ (JSONObject) gotArray.get(j))) {
+ gotContainsSimilar = true;
+ break;
+ }
+ }
+ if (!gotContainsSimilar) {
+ return false;
+ }
+ }
+ } else if (!valueExpect.equals(valueGot)) {
+ return false;
+ }
+ }
+
+ } catch (JSONException e) {
+ Log.d(TAG, "Could not compare JSONObjects: " + e);
+ return false;
+ }
+ return true;
}
}
diff --git a/tests/carservice_test/src/com/android/car/test/VmsPublisherClientMockService.java b/tests/carservice_test/src/com/android/car/VmsPublisherClientMockService.java
similarity index 96%
rename from tests/carservice_test/src/com/android/car/test/VmsPublisherClientMockService.java
rename to tests/carservice_test/src/com/android/car/VmsPublisherClientMockService.java
index 0d5c427..32d224b 100644
--- a/tests/carservice_test/src/com/android/car/test/VmsPublisherClientMockService.java
+++ b/tests/carservice_test/src/com/android/car/VmsPublisherClientMockService.java
@@ -14,18 +14,16 @@
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
-import android.car.annotation.FutureFeature;
import android.car.vms.VmsLayer;
import android.car.vms.VmsLayerDependency;
import android.car.vms.VmsLayersOffering;
import android.car.vms.VmsPublisherClientService;
import android.car.vms.VmsSubscriptionState;
import android.util.Log;
-import java.util.ArrayList;
+
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
/**
@@ -43,7 +41,6 @@
* both potential scenarios, this service publishes the test message in onVmsSubscriptionChange
* and in onVmsPublisherServiceReady. See comments below.
*/
-@FutureFeature
public class VmsPublisherClientMockService extends VmsPublisherClientService {
private static final String TAG = "VmsPublisherClientMockService";
diff --git a/tests/carservice_test/src/com/android/car/test/VmsPublisherClientServiceTest.java b/tests/carservice_test/src/com/android/car/VmsPublisherClientServiceTest.java
similarity index 94%
rename from tests/carservice_test/src/com/android/car/test/VmsPublisherClientServiceTest.java
rename to tests/carservice_test/src/com/android/car/VmsPublisherClientServiceTest.java
index 053bab7..0a53092 100644
--- a/tests/carservice_test/src/com/android/car/test/VmsPublisherClientServiceTest.java
+++ b/tests/carservice_test/src/com/android/car/VmsPublisherClientServiceTest.java
@@ -14,27 +14,25 @@
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.annotation.ArrayRes;
import android.car.VehicleAreaType;
-import android.car.annotation.FutureFeature;
import android.car.vms.VmsLayer;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.hardware.automotive.vehicle.V2_0.VehiclePropValue;
+import android.hardware.automotive.vehicle.V2_0.VehicleProperty;
import android.hardware.automotive.vehicle.V2_0.VehiclePropertyAccess;
import android.hardware.automotive.vehicle.V2_0.VehiclePropertyChangeMode;
-import android.hardware.automotive.vehicle.V2_0.VehicleProperty;
import android.hardware.automotive.vehicle.V2_0.VmsBaseMessageIntegerValuesIndex;
-import android.hardware.automotive.vehicle.V2_0.VmsMessageWithLayerIntegerValuesIndex;
import android.hardware.automotive.vehicle.V2_0.VmsMessageType;
+import android.hardware.automotive.vehicle.V2_0.VmsMessageWithLayerIntegerValuesIndex;
import android.test.suitebuilder.annotation.MediumTest;
import android.util.Log;
-import com.android.car.R;
import com.android.car.vehiclehal.VehiclePropValueBuilder;
import com.android.car.vehiclehal.test.MockedVehicleHal;
import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler;
@@ -44,7 +42,6 @@
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
-@FutureFeature
@MediumTest
public class VmsPublisherClientServiceTest extends MockedCarTestBase {
private static final String TAG = "VmsPublisherTest";
@@ -85,8 +82,12 @@
@Override
public String[] getStringArray(@ArrayRes int id) throws NotFoundException {
if (id == R.array.vmsPublisherClients) {
- return new String[]{"com.android.car.test/.SimpleVmsPublisherClientService"};
+ return new String[] {
+ javaClassToComponent(
+ getContext(), SimpleVmsPublisherClientService.class)
+ };
}
+
return super.getStringArray(id);
}
};
@@ -110,7 +111,6 @@
@Override
protected void setUp() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
/**
* First init the semaphore, setUp will start a series of events that will ultimately
* update the HAL layer and release this semaphore.
@@ -125,10 +125,13 @@
@Override
protected synchronized void tearDown() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
super.tearDown();
}
+ static String javaClassToComponent(Context context, Class<?> clazz) {
+ return context.getPackageName() + "/" + clazz.getName();
+ }
+
/**
* The method setUp initializes all the Car services, including the VmsPublisherService.
* The VmsPublisherService will start and configure its list of clients. This list was
@@ -138,7 +141,6 @@
* this test.
*/
public void testPublish() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
//TODO: This test is using minial synchronisation between clients.
// If more complexity is added this may result in publisher
// publishing before the subscriber subscribed, in which case
@@ -165,7 +167,7 @@
public synchronized void onPropertySet(VehiclePropValue value) {
mValue = value;
- // If this is the data message release the semaphone so the test can continue.
+ // If this is the data message release the semaphore so the test can continue.
ArrayList<Integer> int32Values = value.value.int32Values;
if (int32Values.get(VmsBaseMessageIntegerValuesIndex.MESSAGE_TYPE) ==
VmsMessageType.DATA) {
diff --git a/tests/carservice_test/src/com/android/car/test/VmsPublisherPermissionsTest.java b/tests/carservice_test/src/com/android/car/VmsPublisherPermissionsTest.java
similarity index 95%
rename from tests/carservice_test/src/com/android/car/test/VmsPublisherPermissionsTest.java
rename to tests/carservice_test/src/com/android/car/VmsPublisherPermissionsTest.java
index 1d14c57..14a2f18 100644
--- a/tests/carservice_test/src/com/android/car/test/VmsPublisherPermissionsTest.java
+++ b/tests/carservice_test/src/com/android/car/VmsPublisherPermissionsTest.java
@@ -14,11 +14,10 @@
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import android.annotation.ArrayRes;
import android.car.VehicleAreaType;
-import android.car.annotation.FutureFeature;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.PackageManager;
@@ -31,7 +30,6 @@
import android.hardware.automotive.vehicle.V2_0.VmsMessageType;
import android.test.suitebuilder.annotation.MediumTest;
-import com.android.car.R;
import com.android.car.vehiclehal.VehiclePropValueBuilder;
import com.android.car.vehiclehal.test.MockedVehicleHal;
import com.android.car.vehiclehal.test.MockedVehicleHal.VehicleHalPropertyHandler;
@@ -40,7 +38,6 @@
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
-@FutureFeature
@MediumTest
public class VmsPublisherPermissionsTest extends MockedCarTestBase {
private static final String TAG = "VmsPublisherTest";
@@ -104,7 +101,6 @@
@Override
protected void setUp() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
/**
* First init the semaphore, setUp will start a series of events that will ultimately
* update the HAL layer and release this semaphore.
@@ -119,7 +115,6 @@
@Override
protected synchronized void tearDown() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
super.tearDown();
}
@@ -132,7 +127,6 @@
* this test.
*/
public void testPermissions() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
assertTrue(mHalHandlerSemaphore.tryAcquire(2L, TimeUnit.SECONDS));
// At this point the client initialization finished. Let's validate the permissions.
// The VMS service is only allowed to grant ACCESS_FINE_LOCATION but not CAMERA.
diff --git a/tests/carservice_test/src/com/android/car/test/VmsPublisherSubscriberTest.java b/tests/carservice_test/src/com/android/car/VmsPublisherSubscriberTest.java
similarity index 93%
rename from tests/carservice_test/src/com/android/car/test/VmsPublisherSubscriberTest.java
rename to tests/carservice_test/src/com/android/car/VmsPublisherSubscriberTest.java
index 5b387d2..89dcba9 100644
--- a/tests/carservice_test/src/com/android/car/test/VmsPublisherSubscriberTest.java
+++ b/tests/carservice_test/src/com/android/car/VmsPublisherSubscriberTest.java
@@ -14,12 +14,13 @@
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
+
+import static com.android.car.VmsPublisherClientServiceTest.javaClassToComponent;
import android.annotation.ArrayRes;
import android.car.Car;
import android.car.VehicleAreaType;
-import android.car.annotation.FutureFeature;
import android.car.vms.VmsAssociatedLayer;
import android.car.vms.VmsLayer;
import android.car.vms.VmsSubscriberManager;
@@ -41,7 +42,6 @@
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
-@FutureFeature
@MediumTest
public class VmsPublisherSubscriberTest extends MockedCarTestBase {
private static final int LAYER_ID = 88;
@@ -97,8 +97,11 @@
@Override
public String[] getStringArray(@ArrayRes int id) throws NotFoundException {
if (id == com.android.car.R.array.vmsPublisherClients) {
- return new String[]{"com.android.car.test/.VmsPublisherClientMockService"};
+ return new String[] {
+ javaClassToComponent(getContext(), VmsPublisherClientMockService.class)
+ };
}
+
return super.getStringArray(id);
}
};
@@ -113,7 +116,6 @@
@Override
protected void setUp() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
super.setUp();
mSubscriberSemaphore = new Semaphore(0);
mAvailabilitySemaphore = new Semaphore(0);
@@ -121,7 +123,6 @@
@Override
protected synchronized void tearDown() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
super.tearDown();
}
@@ -134,7 +135,6 @@
* a message, which is validated in this test.
*/
public void testPublisherToSubscriber() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
Car.VMS_SUBSCRIBER_SERVICE);
TestClientCallback clientCallback = new TestClientCallback();
@@ -153,7 +153,6 @@
* that the Mock service has gotten its ServiceReady and publisherId.
*/
public void testPublisherInfo() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
Car.VMS_SUBSCRIBER_SERVICE);
// Subscribe to layer as a way to make sure the mock client completed setting the information.
@@ -173,7 +172,6 @@
* notification that it is available.
*/
public void testAvailabilityWithSubscription() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
Car.VMS_SUBSCRIBER_SERVICE);
TestClientCallback clientCallback = new TestClientCallback();
@@ -181,7 +179,7 @@
vmsSubscriberManager.subscribe(SUBSCRIBED_LAYER);
assertTrue(mAvailabilitySemaphore.tryAcquire(2L, TimeUnit.SECONDS));
- assertEquals(AVAILABLE_ASSOCIATED_LAYERS_WITH_SUBSCRIBED_LAYER, clientCallback.getAvailalbeLayers());
+ assertEquals(AVAILABLE_ASSOCIATED_LAYERS_WITH_SUBSCRIBED_LAYER, clientCallback.getAvailableLayers());
}
/**
@@ -190,14 +188,13 @@
* is available.
*/
public void testAvailabilityWithoutSubscription() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
Car.VMS_SUBSCRIBER_SERVICE);
TestClientCallback clientCallback = new TestClientCallback();
vmsSubscriberManager.registerClientCallback(clientCallback);
assertTrue(mAvailabilitySemaphore.tryAcquire(2L, TimeUnit.SECONDS));
- assertEquals(AVAILABLE_ASSOCIATED_LAYERS, clientCallback.getAvailalbeLayers());
+ assertEquals(AVAILABLE_ASSOCIATED_LAYERS, clientCallback.getAvailableLayers());
}
private class HalHandler implements MockedVehicleHal.VehicleHalPropertyHandler {
@@ -231,7 +228,7 @@
return mPayload;
}
- public List<VmsLayer> getAvailalbeLayers() {
+ public List<VmsLayer> getAvailableLayers() {
return mAvailableLayers;
}
}
diff --git a/tests/carservice_test/src/com/android/car/test/VmsSubscriberManagerTest.java b/tests/carservice_test/src/com/android/car/VmsSubscriberManagerTest.java
similarity index 96%
rename from tests/carservice_test/src/com/android/car/test/VmsSubscriberManagerTest.java
rename to tests/carservice_test/src/com/android/car/VmsSubscriberManagerTest.java
index 8e0c91b..954afee 100644
--- a/tests/carservice_test/src/com/android/car/test/VmsSubscriberManagerTest.java
+++ b/tests/carservice_test/src/com/android/car/VmsSubscriberManagerTest.java
@@ -14,13 +14,12 @@
* limitations under the License.
*/
-package com.android.car.test;
+package com.android.car;
import static org.junit.Assume.assumeTrue;
import android.car.Car;
import android.car.VehicleAreaType;
-import android.car.annotation.FutureFeature;
import android.car.vms.VmsAssociatedLayer;
import android.car.vms.VmsLayer;
import android.car.vms.VmsSubscriberManager;
@@ -44,7 +43,6 @@
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
-@FutureFeature
@MediumTest
public class VmsSubscriberManagerTest extends MockedCarTestBase {
private static final String TAG = "VmsSubscriberManagerTest";
@@ -102,7 +100,6 @@
@Override
protected void setUp() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
super.setUp();
mSubscriberSemaphore = new Semaphore(0);
mHalHandlerSemaphore = new Semaphore(0);
@@ -110,13 +107,11 @@
@Override
protected synchronized void tearDown() throws Exception {
- if (!VmsTestUtils.canRunTest(TAG)) return;
super.tearDown();
}
// Test injecting a value in the HAL and verifying it propagates to a subscriber.
public void testSubscribe() throws Exception {
- assumeTrue(VmsTestUtils.canRunTest(TAG));
VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
Car.VMS_SUBSCRIBER_SERVICE);
TestClientCallback clientCallback = new TestClientCallback();
@@ -147,7 +142,6 @@
// Test injecting a value in the HAL and verifying it propagates to a subscriber.
public void testSubscribeToPublisher() throws Exception {
- assumeTrue(VmsTestUtils.canRunTest(TAG));
VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
Car.VMS_SUBSCRIBER_SERVICE);
TestClientCallback clientCallback = new TestClientCallback();
@@ -175,7 +169,6 @@
// Test injecting a value in the HAL and verifying it propagates to a subscriber.
public void testSubscribeFromPublisher() throws Exception {
- assumeTrue(VmsTestUtils.canRunTest(TAG));
VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
Car.VMS_SUBSCRIBER_SERVICE);
TestClientCallback clientCallback = new TestClientCallback();
@@ -205,7 +198,6 @@
// Test injecting a value in the HAL and verifying it does not propagate to a subscriber.
public void testUnsubscribe() throws Exception {
- assumeTrue(VmsTestUtils.canRunTest(TAG));
VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
Car.VMS_SUBSCRIBER_SERVICE);
TestClientCallback clientCallback = new TestClientCallback();
@@ -233,7 +225,6 @@
// Test injecting a value in the HAL and verifying it does not propagate to a subscriber.
public void testSubscribeFromWrongPublisher() throws Exception {
- assumeTrue(VmsTestUtils.canRunTest(TAG));
VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
Car.VMS_SUBSCRIBER_SERVICE);
TestClientCallback clientCallback = new TestClientCallback();
@@ -260,7 +251,6 @@
// Test injecting a value in the HAL and verifying it does not propagate to a subscriber.
public void testUnsubscribeFromPublisher() throws Exception {
- assumeTrue(VmsTestUtils.canRunTest(TAG));
VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
Car.VMS_SUBSCRIBER_SERVICE);
TestClientCallback clientCallback = new TestClientCallback();
@@ -289,7 +279,6 @@
// Test injecting a value in the HAL and verifying it propagates to a subscriber.
public void testSubscribeAll() throws Exception {
- assumeTrue(VmsTestUtils.canRunTest(TAG));
VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
Car.VMS_SUBSCRIBER_SERVICE);
TestClientCallback clientCallback = new TestClientCallback();
@@ -319,7 +308,6 @@
// Test injecting a value in the HAL and verifying it propagates to a subscriber.
public void testSimpleAvailableLayers() throws Exception {
- assumeTrue(VmsTestUtils.canRunTest(TAG));
VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
Car.VMS_SUBSCRIBER_SERVICE);
TestClientCallback clientCallback = new TestClientCallback();
@@ -365,7 +353,6 @@
// Test injecting a value in the HAL and verifying it propagates to a subscriber after it has
// subscribed to a layer.
public void testSimpleAvailableLayersAfterSubscription() throws Exception {
- assumeTrue(VmsTestUtils.canRunTest(TAG));
VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
Car.VMS_SUBSCRIBER_SERVICE);
TestClientCallback clientCallback = new TestClientCallback();
@@ -412,7 +399,6 @@
// Test injecting a value in the HAL and verifying it does not propagates to a subscriber after
// it has unregistered its callback.
public void testSimpleAvailableLayersAfterUnregister() throws Exception {
- assumeTrue(VmsTestUtils.canRunTest(TAG));
VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
Car.VMS_SUBSCRIBER_SERVICE);
TestClientCallback clientCallback = new TestClientCallback();
@@ -455,7 +441,6 @@
// Test injecting a value in the HAL and verifying it does not propagates to a subscriber after
// it has unregistered its callback.
public void testSomething() throws Exception {
- assumeTrue(VmsTestUtils.canRunTest(TAG));
VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
Car.VMS_SUBSCRIBER_SERVICE);
TestClientCallback clientCallback = new TestClientCallback();
@@ -472,7 +457,6 @@
// Test injecting a value in the HAL and verifying it propagates to a subscriber.
public void testComplexAvailableLayers() throws Exception {
- assumeTrue(VmsTestUtils.canRunTest(TAG));
VmsSubscriberManager vmsSubscriberManager = (VmsSubscriberManager) getCar().getCarManager(
Car.VMS_SUBSCRIBER_SERVICE);
TestClientCallback clientCallback = new TestClientCallback();
diff --git a/tests/carservice_test/src/com/android/car/test/VmsTestUtils.java b/tests/carservice_test/src/com/android/car/test/VmsTestUtils.java
deleted file mode 100644
index 2f3af52..0000000
--- a/tests/carservice_test/src/com/android/car/test/VmsTestUtils.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.android.car.test;
-
-import android.car.annotation.FutureFeature;
-import android.util.Log;
-
-import com.android.car.internal.FeatureConfiguration;
-
-@FutureFeature
-public class VmsTestUtils {
- public static boolean canRunTest(String tag) {
- if (!FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE) {
- Log.i(tag, "Skipping test because ENABLE_VEHICLE_MAP_SERVICE = false");
- }
- return FeatureConfiguration.ENABLE_VEHICLE_MAP_SERVICE;
- }
-}
diff --git a/tests/carservice_unit_test/Android.mk b/tests/carservice_unit_test/Android.mk
index 1ec2008..1cf134c 100644
--- a/tests/carservice_unit_test/Android.mk
+++ b/tests/carservice_unit_test/Android.mk
@@ -34,6 +34,10 @@
LOCAL_INSTRUMENTATION_FOR := CarService
LOCAL_JAVA_LIBRARIES := android.car android.test.runner
-LOCAL_STATIC_JAVA_LIBRARIES := junit legacy-android-test android-support-test mockito-target-minus-junit4
+LOCAL_STATIC_JAVA_LIBRARIES := junit \
+ legacy-android-test \
+ android-support-test \
+ mockito-target-minus-junit4 \
+ com.android.car.test.utils
include $(BUILD_PACKAGE)
diff --git a/tests/carservice_unit_test/src/com/android/car/CarPowerManagementServiceTest.java b/tests/carservice_unit_test/src/com/android/car/CarPowerManagementServiceTest.java
index 78f13e3..e09d54d 100644
--- a/tests/carservice_unit_test/src/com/android/car/CarPowerManagementServiceTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/CarPowerManagementServiceTest.java
@@ -16,6 +16,7 @@
package com.android.car;
+import android.os.SystemClock;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
@@ -25,6 +26,10 @@
import com.android.car.hal.PowerHalService;
import com.android.car.hal.PowerHalService.PowerState;
+import com.android.car.storagemonitoring.WearInformationProvider;
+import com.android.car.test.utils.TemporaryDirectory;
+import java.io.File;
+import java.io.IOException;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
@@ -54,6 +59,9 @@
if (mService != null) {
mService.release();
}
+ if (mSystemInterface != null) {
+ mSystemInterface.tearDown();
+ }
}
public void testBootComplete() throws Exception {
@@ -266,6 +274,7 @@
private final Semaphore mShutdownWait = new Semaphore(0);
private final Semaphore mSleepWait = new Semaphore(0);
private final Semaphore mSleepExitWait = new Semaphore(0);
+ private TemporaryDirectory mFilesDir;
private int mWakeupTime;
private boolean mWakeupCausedByTimer = false;
@@ -340,6 +349,34 @@
return mWakeupCausedByTimer;
}
+ @Override
+ public WearInformationProvider[] getFlashWearInformationProviders() {
+ return new WearInformationProvider[] {};
+ }
+
+ @Override
+ public File getFilesDir() {
+ if (mFilesDir == null) {
+ try {
+ mFilesDir = new TemporaryDirectory(TAG);
+ } catch (IOException e) {
+ Log.e(TAG, "failed to create temporary directory", e);
+ fail("failed to create temporary directory. exception was: " + e);
+ }
+ }
+ return mFilesDir.getDirectory();
+ }
+
+ void tearDown() {
+ if (mFilesDir != null) {
+ try {
+ mFilesDir.close();
+ } catch (Exception e) {
+ Log.w(TAG, "could not remove temporary directory", e);
+ }
+ }
+ }
+
public synchronized void setWakeupCausedByTimer(boolean set) {
mWakeupCausedByTimer = set;
}
diff --git a/tests/carservice_unit_test/src/com/android/car/UptimeTrackerTest.java b/tests/carservice_unit_test/src/com/android/car/UptimeTrackerTest.java
new file mode 100644
index 0000000..a5f12dd
--- /dev/null
+++ b/tests/carservice_unit_test/src/com/android/car/UptimeTrackerTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2017 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.car;
+
+import android.test.suitebuilder.annotation.MediumTest;
+import com.android.car.test.utils.TemporaryFile;
+
+import junit.framework.TestCase;
+
+@MediumTest
+public class UptimeTrackerTest extends TestCase {
+ static final String TAG = UptimeTrackerTest.class.getSimpleName();
+
+ static final class TestTimingProvider implements UptimeTracker.TimingProvider {
+ private long mCurrentTime = 0;
+ private Runnable mRunnable = null;
+
+ TestTimingProvider incrementTime(long by) {
+ mCurrentTime += by;
+ return this;
+ }
+
+ TestTimingProvider tick() {
+ if (mRunnable != null) {
+ mRunnable.run();
+ }
+ return this;
+ }
+
+ @Override
+ public long getCurrentRealtime() {
+ return mCurrentTime;
+ }
+
+ @Override
+ public void schedule(Runnable r, long delay) {
+ if (mRunnable != null) {
+ throw new IllegalStateException("task already scheduled");
+ }
+ mRunnable = r;
+ }
+
+ @Override
+ public void cancelAll() {
+ mRunnable = null;
+ }
+ }
+
+ private static final long SNAPSHOT_INTERVAL = 0; // actual time doesn't matter for this test
+
+ public void testUptimeTrackerFromCleanSlate() throws Exception {
+ TestTimingProvider timingProvider = new TestTimingProvider();
+ try (TemporaryFile uptimeFile = new TemporaryFile(TAG)) {
+ UptimeTracker uptimeTracker = new UptimeTracker(uptimeFile.getFile(),
+ SNAPSHOT_INTERVAL, timingProvider);
+
+ assertEquals(0, uptimeTracker.getTotalUptime());
+
+ timingProvider.incrementTime(5000).tick();
+ assertEquals(5000, uptimeTracker.getTotalUptime());
+
+ timingProvider.tick();
+ assertEquals(5000, uptimeTracker.getTotalUptime());
+
+ timingProvider.incrementTime(1000).tick();
+ assertEquals(6000, uptimeTracker.getTotalUptime());
+
+ timingProvider.incrementTime(400).tick();
+ assertEquals(6400, uptimeTracker.getTotalUptime());
+ }
+ }
+
+ public void testUptimeTrackerWithHistoricalState() throws Exception {
+ TestTimingProvider timingProvider = new TestTimingProvider();
+ try (TemporaryFile uptimeFile = new TemporaryFile(TAG)) {
+ uptimeFile.write("{\"uptime\" : 5000}");
+ UptimeTracker uptimeTracker = new UptimeTracker(uptimeFile.getFile(),
+ SNAPSHOT_INTERVAL, timingProvider);
+
+ assertEquals(5000, uptimeTracker.getTotalUptime());
+
+ timingProvider.incrementTime(5000).tick();
+ assertEquals(10000, uptimeTracker.getTotalUptime());
+
+ timingProvider.incrementTime(1000).tick();
+ assertEquals(11000, uptimeTracker.getTotalUptime());
+ }
+ }
+
+ public void testUptimeTrackerAcrossHistoricalState() throws Exception {
+ TestTimingProvider timingProvider = new TestTimingProvider();
+ try (TemporaryFile uptimeFile = new TemporaryFile(TAG)) {
+ uptimeFile.write("{\"uptime\" : 5000}");
+ UptimeTracker uptimeTracker = new UptimeTracker(uptimeFile.getFile(),
+ SNAPSHOT_INTERVAL, timingProvider);
+
+ assertEquals(5000, uptimeTracker.getTotalUptime());
+
+ timingProvider.incrementTime(5000).tick();
+ assertEquals(10000, uptimeTracker.getTotalUptime());
+
+ timingProvider.incrementTime(500).tick();
+ uptimeTracker.onDestroy();
+ timingProvider.cancelAll();
+
+ uptimeTracker = new UptimeTracker(uptimeFile.getFile(),
+ SNAPSHOT_INTERVAL, timingProvider);
+
+ timingProvider.incrementTime(3000).tick();
+ assertEquals(13500, uptimeTracker.getTotalUptime());
+ }
+ }
+
+ public void testUptimeTrackerShutdown() throws Exception {
+ TestTimingProvider timingProvider = new TestTimingProvider();
+ try (TemporaryFile uptimeFile = new TemporaryFile(TAG)) {
+ UptimeTracker uptimeTracker = new UptimeTracker(uptimeFile.getFile(),
+ SNAPSHOT_INTERVAL, timingProvider);
+
+ timingProvider.incrementTime(6000);
+ uptimeTracker.onDestroy();
+ timingProvider.cancelAll();
+
+ uptimeTracker = new UptimeTracker(uptimeFile.getFile(),
+ SNAPSHOT_INTERVAL, timingProvider);
+ assertEquals(6000, uptimeTracker.getTotalUptime());
+ }
+ }
+}
diff --git a/tests/carservice_unit_test/src/com/android/car/VmsPublishersInfoTest.java b/tests/carservice_unit_test/src/com/android/car/VmsPublishersInfoTest.java
index 2b75012..3f922c9 100644
--- a/tests/carservice_unit_test/src/com/android/car/VmsPublishersInfoTest.java
+++ b/tests/carservice_unit_test/src/com/android/car/VmsPublishersInfoTest.java
@@ -16,14 +16,12 @@
package com.android.car;
-import android.car.annotation.FutureFeature;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
import java.util.Arrays;
import java.util.Map;
-@FutureFeature
@SmallTest
public class VmsPublishersInfoTest extends AndroidTestCase {
public static final byte[] MOCK_INFO_0 = new byte[]{2, 3, 5, 7, 11, 13, 17};
diff --git a/tests/carservice_unit_test/src/com/android/car/storagemonitoring/CarStorageMonitoringTest.java b/tests/carservice_unit_test/src/com/android/car/storagemonitoring/CarStorageMonitoringTest.java
new file mode 100644
index 0000000..250a0a7
--- /dev/null
+++ b/tests/carservice_unit_test/src/com/android/car/storagemonitoring/CarStorageMonitoringTest.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2017 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.car.storagemonitoring;
+
+import android.car.storagemonitoring.WearEstimate;
+import android.car.storagemonitoring.WearEstimateChange;
+import android.os.Parcel;
+import android.test.suitebuilder.annotation.MediumTest;
+
+import com.android.car.test.utils.TemporaryFile;
+import android.util.JsonReader;
+import android.util.JsonWriter;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.time.Instant;
+import junit.framework.TestCase;
+
+/**
+ * Tests the storage monitoring API in CarService.
+ */
+@MediumTest
+public class CarStorageMonitoringTest extends TestCase {
+ static final String TAG = CarStorageMonitoringTest.class.getSimpleName();
+
+ public void testEMmcWearInformationProvider() throws Exception {
+ try (TemporaryFile lifetimeFile = new TemporaryFile(TAG)) {
+ try (TemporaryFile eolFile = new TemporaryFile(TAG)) {
+ lifetimeFile.write("0x05 0x00");
+ eolFile.write("01");
+
+ EMmcWearInformationProvider wearInfoProvider = new EMmcWearInformationProvider(
+ lifetimeFile.getFile(), eolFile.getFile());
+
+ WearInformation wearInformation = wearInfoProvider.load();
+
+ assertNotNull(wearInformation);
+ assertEquals(40, wearInformation.lifetimeEstimateA);
+ assertEquals(WearInformation.UNKNOWN_LIFETIME_ESTIMATE,
+ wearInformation.lifetimeEstimateB);
+
+ assertEquals(WearInformation.PRE_EOL_INFO_NORMAL, wearInformation.preEolInfo);
+ }
+ }
+ }
+
+ public void testUfsWearInformationProvider() throws Exception {
+ try (TemporaryFile lifetimeFile = new TemporaryFile(TAG)) {
+ lifetimeFile.write("ufs version: 1.0\n" +
+ "Health Descriptor[Byte offset 0x2]: bPreEOLInfo = 0x2\n" +
+ "Health Descriptor[Byte offset 0x1]: bDescriptionIDN = 0x1\n" +
+ "Health Descriptor[Byte offset 0x3]: bDeviceLifeTimeEstA = 0x0\n" +
+ "Health Descriptor[Byte offset 0x5]: VendorPropInfo = somedatahere\n" +
+ "Health Descriptor[Byte offset 0x4]: bDeviceLifeTimeEstB = 0xA\n");
+
+ UfsWearInformationProvider wearInfoProvider = new UfsWearInformationProvider(
+ lifetimeFile.getFile());
+
+ WearInformation wearInformation = wearInfoProvider.load();
+
+ assertNotNull(wearInformation);
+ assertEquals(90, wearInformation.lifetimeEstimateB);
+ assertEquals(WearInformation.PRE_EOL_INFO_WARNING, wearInformation.preEolInfo);
+ assertEquals(WearInformation.UNKNOWN_LIFETIME_ESTIMATE,
+ wearInformation.lifetimeEstimateA);
+ }
+ }
+
+ public void testWearEstimateEquality() {
+ WearEstimate wearEstimate1 = new WearEstimate(10, 20);
+ WearEstimate wearEstimate2 = new WearEstimate(10, 20);
+ WearEstimate wearEstimate3 = new WearEstimate(20, 30);
+ assertEquals(wearEstimate1, wearEstimate1);
+ assertEquals(wearEstimate1, wearEstimate2);
+ assertNotSame(wearEstimate1, wearEstimate3);
+ }
+
+ public void testWearEstimateParcel() throws Exception {
+ WearEstimate originalWearEstimate = new WearEstimate(10, 20);
+ Parcel p = Parcel.obtain();
+ originalWearEstimate.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ WearEstimate newWearEstimate = new WearEstimate(p);
+ assertEquals(originalWearEstimate, newWearEstimate);
+ p.recycle();
+ }
+
+ public void testWearEstimateChangeEquality() {
+ WearEstimateChange wearEstimateChange1 = new WearEstimateChange(
+ new WearEstimate(10, 20),
+ new WearEstimate(20, 30),
+ 5000L,
+ Instant.now(),
+ false);
+ WearEstimateChange wearEstimateChange2 = new WearEstimateChange(
+ new WearEstimate(10, 20),
+ new WearEstimate(20, 30),
+ 5000L,
+ wearEstimateChange1.dateAtChange,
+ false);
+ assertEquals(wearEstimateChange1, wearEstimateChange1);
+ assertEquals(wearEstimateChange1, wearEstimateChange2);
+ WearEstimateChange wearEstimateChange3 = new WearEstimateChange(
+ new WearEstimate(10, 30),
+ new WearEstimate(20, 30),
+ 3000L,
+ Instant.now(),
+ true);
+ assertNotSame(wearEstimateChange1, wearEstimateChange3);
+ }
+
+ public void testWearEstimateChangeParcel() throws Exception {
+ WearEstimateChange originalWearEstimateChange = new WearEstimateChange(
+ new WearEstimate(10, 0),
+ new WearEstimate(20, 10),
+ 123456789L,
+ Instant.now(),
+ false);
+ Parcel p = Parcel.obtain();
+ originalWearEstimateChange.writeToParcel(p, 0);
+ p.setDataPosition(0);
+ WearEstimateChange newWearEstimateChange = new WearEstimateChange(p);
+ assertEquals(originalWearEstimateChange, newWearEstimateChange);
+ p.recycle();
+ }
+
+ public void testWearEstimateJson() throws Exception {
+ WearEstimate originalWearEstimate = new WearEstimate(20, 0);
+ StringWriter stringWriter = new StringWriter(1024);
+ JsonWriter jsonWriter = new JsonWriter(stringWriter);
+ originalWearEstimate.writeToJson(jsonWriter);
+ StringReader stringReader = new StringReader(stringWriter.toString());
+ JsonReader jsonReader = new JsonReader(stringReader);
+ WearEstimate newWearEstimate = new WearEstimate(jsonReader);
+ assertEquals(originalWearEstimate, newWearEstimate);
+ }
+}
diff --git a/tools/emulator/vhal_consts_2_1.py b/tests/common_utils/Android.mk
similarity index 72%
rename from tools/emulator/vhal_consts_2_1.py
rename to tests/common_utils/Android.mk
index e5dbcff..19302c6 100644
--- a/tools/emulator/vhal_consts_2_1.py
+++ b/tests/common_utils/Android.mk
@@ -12,6 +12,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
-# DO NOT EDIT MANUALLY
-# This file was autogenerated by vhal_const_generate.py
-from vhal_consts_2_0 import *
+
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := com.android.car.test.utils
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+include $(BUILD_STATIC_JAVA_LIBRARY)
diff --git a/tests/common_utils/src/com/android/car/test/utils/TemporaryDirectory.java b/tests/common_utils/src/com/android/car/test/utils/TemporaryDirectory.java
new file mode 100644
index 0000000..fa5727d
--- /dev/null
+++ b/tests/common_utils/src/com/android/car/test/utils/TemporaryDirectory.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2017 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.car.test.utils;
+
+import android.annotation.Nullable;
+import android.os.SystemClock;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+
+/**
+ * A utility class that creates a temporary directory.
+ * The directory, and any files contained within, are automatically deleted when calling close().
+ *
+ * Example usage:
+ *
+ * try (TemporaryDirectory tf = new TemporaryDirectory("myTest")) {
+ * ...
+ * } // directory gets deleted here
+ */
+public class TemporaryDirectory implements AutoCloseable {
+ private Path mDirectory;
+
+ private static final class DeletingVisitor extends SimpleFileVisitor<Path> {
+ FileVisitResult consume(Path path) throws IOException {
+ Files.delete(path);
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes)
+ throws IOException {
+ return consume(path);
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path path, IOException e)
+ throws IOException {
+ return consume(path);
+ }
+ }
+
+ private static final SimpleFileVisitor<Path> DELETE = new DeletingVisitor();
+
+ public TemporaryDirectory(@Nullable String prefix) throws IOException {
+ if (prefix == null) {
+ prefix = TemporaryDirectory.class.getSimpleName();
+ }
+ prefix += String.valueOf(SystemClock.elapsedRealtimeNanos());
+
+ mDirectory = Files.createTempDirectory(prefix);
+ }
+
+ @Override
+ public void close() throws Exception {
+ Files.walkFileTree(mDirectory, DELETE);
+ }
+
+ public File getDirectory() {
+ return mDirectory.toFile();
+ }
+}
diff --git a/tests/common_utils/src/com/android/car/test/utils/TemporaryFile.java b/tests/common_utils/src/com/android/car/test/utils/TemporaryFile.java
new file mode 100644
index 0000000..a26c1ab
--- /dev/null
+++ b/tests/common_utils/src/com/android/car/test/utils/TemporaryFile.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 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.car.test.utils;
+
+import android.annotation.Nullable;
+import android.os.SystemClock;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.file.Files;
+
+/**
+ * A utility class that creates a temporary file.
+ * The file is automatically deleted when calling close().
+ *
+ * Example usage:
+ *
+ * try (TemporaryFile tf = new TemporaryFile("myTest")) {
+ * ...
+ * } // file gets deleted here
+ */
+public final class TemporaryFile implements AutoCloseable {
+ private File mFile;
+
+ public TemporaryFile(@Nullable String prefix) throws IOException {
+ if (prefix == null) {
+ prefix = TemporaryFile.class.getSimpleName();
+ }
+ mFile = File.createTempFile(prefix, String.valueOf(SystemClock.elapsedRealtimeNanos()));
+ }
+
+ @Override
+ public void close() throws Exception {
+ Files.delete(mFile.toPath());
+ }
+
+ public void write(String s) throws IOException {
+ BufferedWriter writer = new BufferedWriter(new FileWriter(mFile));
+ writer.write(s);
+ writer.close();
+ }
+
+ public File getFile() {
+ return mFile;
+ }
+}
diff --git a/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/E2ePerformanceTest.java b/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/E2ePerformanceTest.java
index 6675713..196a6d4 100644
--- a/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/E2ePerformanceTest.java
+++ b/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/E2ePerformanceTest.java
@@ -20,6 +20,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.junit.Assume.assumeTrue;
import android.annotation.Nullable;
@@ -47,6 +48,7 @@
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.test.suitebuilder.annotation.MediumTest;
+import android.util.Log;
import android.util.SparseArray;
import android.util.SparseIntArray;
@@ -259,6 +261,27 @@
final int EXPECTED_INVOCATIONS = 1000; // How many time get/set will be called.
final int EXPECTED_DURATION_MS = 2500;
+ // This is a stress test and it can be flaky because it shares resources with all currently
+ // running process. Let's have this number of attempt before giving up.
+ final int ATTEMPTS = 3;
+
+ for (int curAttempt = 0; curAttempt < ATTEMPTS; curAttempt++) {
+ long missingInvocations = stressTestHvacProperties(mgr, cfg,
+ EXPECTED_INVOCATIONS, EXPECTED_DURATION_MS);
+ if (missingInvocations == 0) return; // All done.
+
+ Log.w(TAG, "Failed to invoke get/set " + EXPECTED_INVOCATIONS
+ + " within " + EXPECTED_DURATION_MS + "ms"
+ + ", actually invoked: "
+ + (EXPECTED_INVOCATIONS - missingInvocations));
+ }
+ fail("Failed to invoke get/set " + EXPECTED_INVOCATIONS + " within "
+ + EXPECTED_DURATION_MS + "ms. Number of attempts: " + ATTEMPTS
+ + ". See logs for details.");
+ }
+
+ private long stressTestHvacProperties(CarHvacManager mgr, CarPropertyConfig<Float> cfg,
+ int EXPECTED_INVOCATIONS, int EXPECTED_DURATION_MS) throws InterruptedException {
CountDownLatch counter = new CountDownLatch(EXPECTED_INVOCATIONS);
List<Thread> threads = new ArrayList<>(Lists.newArrayList(
@@ -271,15 +294,12 @@
counter.await(EXPECTED_DURATION_MS, TimeUnit.MILLISECONDS);
long missingInvocations = counter.getCount();
- assertTrue("Failed to invoke get/set " + EXPECTED_INVOCATIONS
- + " within " + EXPECTED_DURATION_MS + "ms"
- + ", actually invoked: " + (EXPECTED_INVOCATIONS - missingInvocations),
- missingInvocations == 0);
for (Thread t : threads) {
t.join(10000); // Let thread join to not interfere with other test.
assertFalse(t.isAlive());
}
+ return missingInvocations;
}
private void invokeSetAndGetForHvacFloat(CarHvacManager mgr,
diff --git a/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Utils.java b/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Utils.java
index 5221907..fb97e73 100644
--- a/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Utils.java
+++ b/tests/vehiclehal_test/src/com/android/car/vehiclehal/test/Utils.java
@@ -81,14 +81,12 @@
return readVhalProperty(vehicle, request, f);
}
- @Nullable
static IVehicle getVehicle() throws RemoteException {
IVehicle service;
try {
- service = android.hardware.automotive.vehicle.V2_0.IVehicle.getService();
+ service = IVehicle.getService();
} catch (NoSuchElementException ex) {
- Log.d(TAG, "Couldn't connect to vehicle@2.1, connecting to vehicle@2.0...");
- service = IVehicle.getService();
+ throw new RuntimeException("Couldn't connect to vehicle@2.0", ex);
}
Log.d(TAG, "Connected to IVehicle service: " + service);
return service;
diff --git a/tools/emulator/vhal_const_generate.py b/tools/emulator/vhal_const_generate.py
index 55bcd1b..df9713b 100755
--- a/tools/emulator/vhal_const_generate.py
+++ b/tools/emulator/vhal_const_generate.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.4
+#!/usr/bin/env python3
#
# Copyright (C) 2017 The Android Open Source Project
#
@@ -94,23 +94,15 @@
print("Vehicle HAL was not found at %s. lunch may provide a correct environment, or files moved" % vhal_location)
sys.exit(1)
-vhal_20_file = os.path.join(vhal_location, '2.0', 'types.hal')
-vhal_21_file = os.path.join(vhal_location, '2.1', 'types.hal')
-
-print("Generating content from Vehicle HAL 2.0 (%s) and 2.1 (%s)" % (vhal_20_file, vhal_21_file))
-
-vhal_20_doc = parser.parse(vhal_20_file)
-vhal_21_doc = parser.parse(vhal_21_file)
-
-# Work around the fact that the parser doesn't (yet?) deal with inheritance.
-# WARNING: This pattern is rather unsafe since we're not merging the lists as we should!
-# vhal_21_doc['enums']['VehiclePropertyGroup'] = vhal_20_doc['enums']['VehiclePropertyGroup']
-# vhal_21_doc['enums']['VehiclePropertyType'] = vhal_20_doc['enums']['VehiclePropertyType']
-# vhal_21_doc['enums']['VehicleArea'] = vhal_20_doc['enums']['VehicleArea']
-
def generateHal20():
- print("********************************")
- print("Generating VHal 2.0 constants...")
+ vhal_20_file = os.path.join(vhal_location, '2.0', 'types.hal')
+ if not(os.path.exists(vhal_20_file)):
+ print("Vehicle HAL was not found at %s. lunch may provide a correct environment, or files moved" % vhal_location)
+ sys.exit(1)
+
+ print("Generating constants from Vehicle HAL 2.0 (%s)" % (vhal_20_file))
+ vhal_20_doc = parser.parse(vhal_20_file)
+
vhal_20_file = open(os.path.join(script_directory, 'vhal_consts_2_0.py'), 'w')
printHeader(vhal_20_file)
@@ -131,17 +123,4 @@
print(" TYPE_FLOATS = [VEHICLEPROPERTYTYPE_FLOAT_VEC]", file=vhal_20_file)
print(" TYPE_COMPLEX = [VEHICLEPROPERTYTYPE_COMPLEX]", file=vhal_20_file)
-def generateHal21():
- print("********************************")
- print("Generating VHal 2.1 constants...")
- vhal_21_file = open(os.path.join(script_directory, 'vhal_consts_2_1.py'), 'w')
- printHeader(vhal_21_file)
- print('from vhal_consts_2_0 import *', file=vhal_21_file)
-
- for group in vhal_21_doc['enums']:
- print(group)
- printEnum(vhal_21_doc, group, vhal_21_file, lambda x : hex(x))
-
-
generateHal20()
-# generateHal21()
diff --git a/tools/emulator/vhal_consts_2_0.py b/tools/emulator/vhal_consts_2_0.py
index 59c430c..4eb3a1e 100644
--- a/tools/emulator/vhal_consts_2_0.py
+++ b/tools/emulator/vhal_consts_2_0.py
@@ -15,223 +15,9 @@
# DO NOT EDIT MANUALLY
# This file was autogenerated by vhal_const_generate.py
-# VehicleAudioContextFlag
-VEHICLEAUDIOCONTEXTFLAG_MUSIC_FLAG = 0x1
-VEHICLEAUDIOCONTEXTFLAG_NAVIGATION_FLAG = 0x2
-VEHICLEAUDIOCONTEXTFLAG_VOICE_COMMAND_FLAG = 0x4
-VEHICLEAUDIOCONTEXTFLAG_CALL_FLAG = 0x8
-VEHICLEAUDIOCONTEXTFLAG_ALARM_FLAG = 0x10
-VEHICLEAUDIOCONTEXTFLAG_NOTIFICATION_FLAG = 0x20
-VEHICLEAUDIOCONTEXTFLAG_UNKNOWN_FLAG = 0x40
-VEHICLEAUDIOCONTEXTFLAG_SAFETY_ALERT_FLAG = 0x80
-VEHICLEAUDIOCONTEXTFLAG_CD_ROM_FLAG = 0x100
-VEHICLEAUDIOCONTEXTFLAG_AUX_AUDIO_FLAG = 0x200
-VEHICLEAUDIOCONTEXTFLAG_SYSTEM_SOUND_FLAG = 0x400
-VEHICLEAUDIOCONTEXTFLAG_RADIO_FLAG = 0x800
-VEHICLEAUDIOCONTEXTFLAG_EXT_SOURCE_FLAG = 0x1000
-
-# VehicleAudioFocusIndex
-VEHICLEAUDIOFOCUSINDEX_FOCUS = 0x0
-VEHICLEAUDIOFOCUSINDEX_STREAMS = 0x1
-VEHICLEAUDIOFOCUSINDEX_EXTERNAL_FOCUS_STATE = 0x2
-VEHICLEAUDIOFOCUSINDEX_AUDIO_CONTEXTS = 0x3
-
-# Obd2CommonIgnitionMonitors
-OBD2COMMONIGNITIONMONITORS_COMPONENTS_AVAILABLE = 0x1
-OBD2COMMONIGNITIONMONITORS_COMPONENTS_INCOMPLETE = 0x2
-OBD2COMMONIGNITIONMONITORS_FUEL_SYSTEM_AVAILABLE = 0x4
-OBD2COMMONIGNITIONMONITORS_FUEL_SYSTEM_INCOMPLETE = 0x8
-OBD2COMMONIGNITIONMONITORS_MISFIRE_AVAILABLE = 0x10
-OBD2COMMONIGNITIONMONITORS_MISFIRE_INCOMPLETE = 0x20
-
-# Obd2FuelType
-OBD2FUELTYPE_NOT_AVAILABLE = 0x0
-OBD2FUELTYPE_GASOLINE = 0x1
-OBD2FUELTYPE_METHANOL = 0x2
-OBD2FUELTYPE_ETHANOL = 0x3
-OBD2FUELTYPE_DIESEL = 0x4
-OBD2FUELTYPE_LPG = 0x5
-OBD2FUELTYPE_CNG = 0x6
-OBD2FUELTYPE_PROPANE = 0x7
-OBD2FUELTYPE_ELECTRIC = 0x8
-OBD2FUELTYPE_BIFUEL_RUNNING_GASOLINE = 0x9
-OBD2FUELTYPE_BIFUEL_RUNNING_METHANOL = 0xa
-OBD2FUELTYPE_BIFUEL_RUNNING_ETHANOL = 0xb
-OBD2FUELTYPE_BIFUEL_RUNNING_LPG = 0xc
-OBD2FUELTYPE_BIFUEL_RUNNING_CNG = 0xd
-OBD2FUELTYPE_BIFUEL_RUNNING_PROPANE = 0xe
-OBD2FUELTYPE_BIFUEL_RUNNING_ELECTRIC = 0xf
-OBD2FUELTYPE_BIFUEL_RUNNING_ELECTRIC_AND_COMBUSTION = 0x10
-OBD2FUELTYPE_HYBRID_GASOLINE = 0x11
-OBD2FUELTYPE_HYBRID_ETHANOL = 0x12
-OBD2FUELTYPE_HYBRID_DIESEL = 0x13
-OBD2FUELTYPE_HYBRID_ELECTRIC = 0x14
-OBD2FUELTYPE_HYBRID_RUNNING_ELECTRIC_AND_COMBUSTION = 0x15
-OBD2FUELTYPE_HYBRID_REGENERATIVE = 0x16
-OBD2FUELTYPE_BIFUEL_RUNNING_DIESEL = 0x17
-
# VehicleAudioVolumeState
VEHICLEAUDIOVOLUMESTATE_STATE_OK = 0x0
-VEHICLEAUDIOVOLUMESTATE_LIMIT_REACHED = 0x1
-
-# VmsMessageWithLayerIntegerValuesIndex
-VMSMESSAGEWITHLAYERINTEGERVALUESINDEX_LAYER_TYPE = 0x1
-VMSMESSAGEWITHLAYERINTEGERVALUESINDEX_LAYER_SUBTYPE = 0x2
-VMSMESSAGEWITHLAYERINTEGERVALUESINDEX_LAYER_VERSION = 0x3
-
-# Obd2SparkIgnitionMonitors
-OBD2SPARKIGNITIONMONITORS_EGR_AVAILABLE = 0x40
-OBD2SPARKIGNITIONMONITORS_EGR_INCOMPLETE = 0x80
-OBD2SPARKIGNITIONMONITORS_OXYGEN_SENSOR_HEATER_AVAILABLE = 0x100
-OBD2SPARKIGNITIONMONITORS_OXYGEN_SENSOR_HEATER_INCOMPLETE = 0x200
-OBD2SPARKIGNITIONMONITORS_OXYGEN_SENSOR_AVAILABLE = 0x400
-OBD2SPARKIGNITIONMONITORS_OXYGEN_SENSOR_INCOMPLETE = 0x800
-OBD2SPARKIGNITIONMONITORS_AC_REFRIGERANT_AVAILABLE = 0x1000
-OBD2SPARKIGNITIONMONITORS_AC_REFRIGERANT_INCOMPLETE = 0x2000
-OBD2SPARKIGNITIONMONITORS_SECONDARY_AIR_SYSTEM_AVAILABLE = 0x4000
-OBD2SPARKIGNITIONMONITORS_SECONDARY_AIR_SYSTEM_INCOMPLETE = 0x8000
-OBD2SPARKIGNITIONMONITORS_EVAPORATIVE_SYSTEM_AVAILABLE = 0x10000
-OBD2SPARKIGNITIONMONITORS_EVAPORATIVE_SYSTEM_INCOMPLETE = 0x20000
-OBD2SPARKIGNITIONMONITORS_HEATED_CATALYST_AVAILABLE = 0x40000
-OBD2SPARKIGNITIONMONITORS_HEATED_CATALYST_INCOMPLETE = 0x80000
-OBD2SPARKIGNITIONMONITORS_CATALYST_AVAILABLE = 0x100000
-OBD2SPARKIGNITIONMONITORS_CATALYST_INCOMPLETE = 0x200000
-
-# VehicleArea
-VEHICLEAREA_GLOBAL = 0x1000000
-VEHICLEAREA_ZONE = 0x2000000
-VEHICLEAREA_WINDOW = 0x3000000
-VEHICLEAREA_MIRROR = 0x4000000
-VEHICLEAREA_SEAT = 0x5000000
-VEHICLEAREA_DOOR = 0x6000000
-VEHICLEAREA_MASK = 0xf000000
-
-# Obd2SecondaryAirStatus
-OBD2SECONDARYAIRSTATUS_UPSTREAM = 0x1
-OBD2SECONDARYAIRSTATUS_DOWNSTREAM_OF_CATALYCIC_CONVERTER = 0x2
-OBD2SECONDARYAIRSTATUS_FROM_OUTSIDE_OR_OFF = 0x4
-OBD2SECONDARYAIRSTATUS_PUMP_ON_FOR_DIAGNOSTICS = 0x8
-
-# VehicleAudioHwVariantConfigFlag
-VEHICLEAUDIOHWVARIANTCONFIGFLAG_INTERNAL_RADIO_FLAG = 0x1
-
-# VmsMessageWithLayerAndPublisherIdIntegerValuesIndex
-VMSMESSAGEWITHLAYERANDPUBLISHERIDINTEGERVALUESINDEX_PUBLISHER_ID = 0x4
-
-# Obd2CompressionIgnitionMonitors
-OBD2COMPRESSIONIGNITIONMONITORS_EGR_OR_VVT_AVAILABLE = 0x40
-OBD2COMPRESSIONIGNITIONMONITORS_EGR_OR_VVT_INCOMPLETE = 0x80
-OBD2COMPRESSIONIGNITIONMONITORS_PM_FILTER_AVAILABLE = 0x100
-OBD2COMPRESSIONIGNITIONMONITORS_PM_FILTER_INCOMPLETE = 0x200
-OBD2COMPRESSIONIGNITIONMONITORS_EXHAUST_GAS_SENSOR_AVAILABLE = 0x400
-OBD2COMPRESSIONIGNITIONMONITORS_EXHAUST_GAS_SENSOR_INCOMPLETE = 0x800
-OBD2COMPRESSIONIGNITIONMONITORS_BOOST_PRESSURE_AVAILABLE = 0x1000
-OBD2COMPRESSIONIGNITIONMONITORS_BOOST_PRESSURE_INCOMPLETE = 0x2000
-OBD2COMPRESSIONIGNITIONMONITORS_NOx_SCR_AVAILABLE = 0x4000
-OBD2COMPRESSIONIGNITIONMONITORS_NOx_SCR_INCOMPLETE = 0x8000
-OBD2COMPRESSIONIGNITIONMONITORS_NMHC_CATALYST_AVAILABLE = 0x10000
-OBD2COMPRESSIONIGNITIONMONITORS_NMHC_CATALYST_INCOMPLETE = 0x20000
-
-# VmsOfferingMessageIntegerValuesIndex
-VMSOFFERINGMESSAGEINTEGERVALUESINDEX_PUBLISHER_ID = 0x1
-VMSOFFERINGMESSAGEINTEGERVALUESINDEX_NUMBER_OF_OFFERS = 0x2
-VMSOFFERINGMESSAGEINTEGERVALUESINDEX_OFFERING_START = 0x3
-
-# VehicleAreaZone
-VEHICLEAREAZONE_ROW_1_LEFT = 0x1
-VEHICLEAREAZONE_ROW_1_CENTER = 0x2
-VEHICLEAREAZONE_ROW_1_RIGHT = 0x4
-VEHICLEAREAZONE_ROW_1 = 0x8
-VEHICLEAREAZONE_ROW_2_LEFT = 0x10
-VEHICLEAREAZONE_ROW_2_CENTER = 0x20
-VEHICLEAREAZONE_ROW_2_RIGHT = 0x40
-VEHICLEAREAZONE_ROW_2 = 0x80
-VEHICLEAREAZONE_ROW_3_LEFT = 0x100
-VEHICLEAREAZONE_ROW_3_CENTER = 0x200
-VEHICLEAREAZONE_ROW_3_RIGHT = 0x400
-VEHICLEAREAZONE_ROW_3 = 0x800
-VEHICLEAREAZONE_ROW_4_LEFT = 0x1000
-VEHICLEAREAZONE_ROW_4_CENTER = 0x2000
-VEHICLEAREAZONE_ROW_4_RIGHT = 0x4000
-VEHICLEAREAZONE_ROW_4 = 0x8000
-VEHICLEAREAZONE_WHOLE_CABIN = 0x80000000
-
-# Obd2IgnitionMonitorKind
-OBD2IGNITIONMONITORKIND_SPARK = 0x0
-OBD2IGNITIONMONITORKIND_COMPRESSION = 0x1
-
-# VmsAvailabilityStateIntegerValuesIndex
-VMSAVAILABILITYSTATEINTEGERVALUESINDEX_SEQUENCE_NUMBER = 0x1
-VMSAVAILABILITYSTATEINTEGERVALUESINDEX_NUMBER_OF_ASSOCIATED_LAYERS = 0x2
-VMSAVAILABILITYSTATEINTEGERVALUESINDEX_LAYERS_START = 0x3
-
-# VehicleApPowerStateConfigFlag
-VEHICLEAPPOWERSTATECONFIGFLAG_ENABLE_DEEP_SLEEP_FLAG = 0x1
-VEHICLEAPPOWERSTATECONFIGFLAG_CONFIG_SUPPORT_TIMER_POWER_ON_FLAG = 0x2
-
-# VehicleHvacFanDirection
-VEHICLEHVACFANDIRECTION_FACE = 0x1
-VEHICLEHVACFANDIRECTION_FLOOR = 0x2
-VEHICLEHVACFANDIRECTION_FACE_AND_FLOOR = 0x3
-VEHICLEHVACFANDIRECTION_DEFROST = 0x4
-VEHICLEHVACFANDIRECTION_DEFROST_AND_FLOOR = 0x5
-
-# VehicleHwKeyInputAction
-VEHICLEHWKEYINPUTACTION_ACTION_DOWN = 0x0
-VEHICLEHWKEYINPUTACTION_ACTION_UP = 0x1
-
-# Wheel
-WHEEL_UNKNOWN = 0x0
-WHEEL_LEFT_FRONT = 0x1
-WHEEL_RIGHT_FRONT = 0x2
-WHEEL_LEFT_REAR = 0x4
-WHEEL_RIGHT_REAR = 0x8
-
-# VehicleAudioVolumeCapabilityFlag
-VEHICLEAUDIOVOLUMECAPABILITYFLAG_PERSISTENT_STORAGE = 0x1
-VEHICLEAUDIOVOLUMECAPABILITYFLAG_MASTER_VOLUME_ONLY = 0x2
-
-# VehicleAudioVolumeIndex
-VEHICLEAUDIOVOLUMEINDEX_INDEX_STREAM = 0x0
-VEHICLEAUDIOVOLUMEINDEX_INDEX_VOLUME = 0x1
-VEHICLEAUDIOVOLUMEINDEX_INDEX_STATE = 0x2
-
-# VehicleRadioConstants
-VEHICLERADIOCONSTANTS_VEHICLE_RADIO_PRESET_MIN_VALUE = 0x1
-
-# VehicleGear
-VEHICLEGEAR_GEAR_NEUTRAL = 0x1
-VEHICLEGEAR_GEAR_REVERSE = 0x2
-VEHICLEGEAR_GEAR_PARK = 0x4
-VEHICLEGEAR_GEAR_DRIVE = 0x8
-VEHICLEGEAR_GEAR_LOW = 0x10
-VEHICLEGEAR_GEAR_1 = 0x10
-VEHICLEGEAR_GEAR_2 = 0x20
-VEHICLEGEAR_GEAR_3 = 0x40
-VEHICLEGEAR_GEAR_4 = 0x80
-VEHICLEGEAR_GEAR_5 = 0x100
-VEHICLEGEAR_GEAR_6 = 0x200
-VEHICLEGEAR_GEAR_7 = 0x400
-VEHICLEGEAR_GEAR_8 = 0x800
-VEHICLEGEAR_GEAR_9 = 0x1000
-
-# VehicleDrivingStatus
-VEHICLEDRIVINGSTATUS_UNRESTRICTED = 0x0
-VEHICLEDRIVINGSTATUS_NO_VIDEO = 0x1
-VEHICLEDRIVINGSTATUS_NO_KEYBOARD_INPUT = 0x2
-VEHICLEDRIVINGSTATUS_NO_VOICE_INPUT = 0x4
-VEHICLEDRIVINGSTATUS_NO_CONFIG = 0x8
-VEHICLEDRIVINGSTATUS_LIMIT_MESSAGE_LEN = 0x10
-
-# VehicleAudioRoutingPolicyIndex
-VEHICLEAUDIOROUTINGPOLICYINDEX_STREAM = 0x0
-VEHICLEAUDIOROUTINGPOLICYINDEX_CONTEXTS = 0x1
-
-# VmsSubscriptionsStateIntegerValuesIndex
-VMSSUBSCRIPTIONSSTATEINTEGERVALUESINDEX_SEQUENCE_NUMBER = 0x1
-VMSSUBSCRIPTIONSSTATEINTEGERVALUESINDEX_NUMBER_OF_LAYERS = 0x2
-VMSSUBSCRIPTIONSSTATEINTEGERVALUESINDEX_NUMBER_OF_ASSOCIATED_LAYERS = 0x3
-VMSSUBSCRIPTIONSSTATEINTEGERVALUESINDEX_SUBSCRIPTIONS_START = 0x4
+VEHICLEAUDIOVOLUMESTATE_STATE_LIMIT_REACHED = 0x1
# SubscribeFlags
SUBSCRIBEFLAGS_UNDEFINED = 0x0
@@ -239,60 +25,40 @@
SUBSCRIBEFLAGS_SET_CALL = 0x2
SUBSCRIBEFLAGS_DEFAULT = 0x1
-# VehicleAudioExtFocusFlag
-VEHICLEAUDIOEXTFOCUSFLAG_NONE_FLAG = 0x0
-VEHICLEAUDIOEXTFOCUSFLAG_PERMANENT_FLAG = 0x1
-VEHICLEAUDIOEXTFOCUSFLAG_TRANSIENT_FLAG = 0x2
-VEHICLEAUDIOEXTFOCUSFLAG_PLAY_ONLY_FLAG = 0x4
-VEHICLEAUDIOEXTFOCUSFLAG_MUTE_MEDIA_FLAG = 0x8
-
-# VehicleAudioFocusRequest
-VEHICLEAUDIOFOCUSREQUEST_REQUEST_GAIN = 0x1
-VEHICLEAUDIOFOCUSREQUEST_REQUEST_GAIN_TRANSIENT = 0x2
-VEHICLEAUDIOFOCUSREQUEST_REQUEST_GAIN_TRANSIENT_MAY_DUCK = 0x3
-VEHICLEAUDIOFOCUSREQUEST_REQUEST_GAIN_TRANSIENT_NO_DUCK = 0x4
-VEHICLEAUDIOFOCUSREQUEST_REQUEST_RELEASE = 0x5
-
-# VehiclePropertyType
-VEHICLEPROPERTYTYPE_STRING = 0x100000
-VEHICLEPROPERTYTYPE_BOOLEAN = 0x200000
-VEHICLEPROPERTYTYPE_INT32 = 0x400000
-VEHICLEPROPERTYTYPE_INT32_VEC = 0x410000
-VEHICLEPROPERTYTYPE_INT64 = 0x500000
-VEHICLEPROPERTYTYPE_FLOAT = 0x600000
-VEHICLEPROPERTYTYPE_FLOAT_VEC = 0x610000
-VEHICLEPROPERTYTYPE_BYTES = 0x700000
-VEHICLEPROPERTYTYPE_COMPLEX = 0xe00000
-VEHICLEPROPERTYTYPE_MASK = 0xff0000
-
-# VehiclePropertyAccess
-VEHICLEPROPERTYACCESS_NONE = 0x0
-VEHICLEPROPERTYACCESS_READ = 0x1
-VEHICLEPROPERTYACCESS_WRITE = 0x2
-VEHICLEPROPERTYACCESS_READ_WRITE = 0x3
-
-# Obd2FuelSystemStatus
-OBD2FUELSYSTEMSTATUS_OPEN_INSUFFICIENT_ENGINE_TEMPERATURE = 0x1
-OBD2FUELSYSTEMSTATUS_CLOSED_LOOP = 0x2
-OBD2FUELSYSTEMSTATUS_OPEN_ENGINE_LOAD_OR_DECELERATION = 0x4
-OBD2FUELSYSTEMSTATUS_OPEN_SYSTEM_FAILURE = 0x8
-OBD2FUELSYSTEMSTATUS_CLOSED_LOOP_BUT_FEEDBACK_FAULT = 0x10
-
-# VehicleTurnSignal
-VEHICLETURNSIGNAL_NONE = 0x0
-VEHICLETURNSIGNAL_RIGHT = 0x1
-VEHICLETURNSIGNAL_LEFT = 0x2
-VEHICLETURNSIGNAL_EMERGENCY = 0x4
-
-# VehicleAudioStreamFlag
-VEHICLEAUDIOSTREAMFLAG_STREAM0_FLAG = 0x1
-VEHICLEAUDIOSTREAMFLAG_STREAM1_FLAG = 0x2
-VEHICLEAUDIOSTREAMFLAG_STREAM2_FLAG = 0x4
-
-# VehicleApPowerBootupReason
-VEHICLEAPPOWERBOOTUPREASON_USER_POWER_ON = 0x0
-VEHICLEAPPOWERBOOTUPREASON_USER_UNLOCK = 0x1
-VEHICLEAPPOWERBOOTUPREASON_TIMER = 0x2
+# DiagnosticIntegerSensorIndex
+DIAGNOSTICINTEGERSENSORINDEX_FUEL_SYSTEM_STATUS = 0x0
+DIAGNOSTICINTEGERSENSORINDEX_MALFUNCTION_INDICATOR_LIGHT_ON = 0x1
+DIAGNOSTICINTEGERSENSORINDEX_IGNITION_MONITORS_SUPPORTED = 0x2
+DIAGNOSTICINTEGERSENSORINDEX_IGNITION_SPECIFIC_MONITORS = 0x3
+DIAGNOSTICINTEGERSENSORINDEX_INTAKE_AIR_TEMPERATURE = 0x4
+DIAGNOSTICINTEGERSENSORINDEX_COMMANDED_SECONDARY_AIR_STATUS = 0x5
+DIAGNOSTICINTEGERSENSORINDEX_NUM_OXYGEN_SENSORS_PRESENT = 0x6
+DIAGNOSTICINTEGERSENSORINDEX_RUNTIME_SINCE_ENGINE_START = 0x7
+DIAGNOSTICINTEGERSENSORINDEX_DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON = 0x8
+DIAGNOSTICINTEGERSENSORINDEX_WARMUPS_SINCE_CODES_CLEARED = 0x9
+DIAGNOSTICINTEGERSENSORINDEX_DISTANCE_TRAVELED_SINCE_CODES_CLEARED = 0xa
+DIAGNOSTICINTEGERSENSORINDEX_ABSOLUTE_BAROMETRIC_PRESSURE = 0xb
+DIAGNOSTICINTEGERSENSORINDEX_CONTROL_MODULE_VOLTAGE = 0xc
+DIAGNOSTICINTEGERSENSORINDEX_AMBIENT_AIR_TEMPERATURE = 0xd
+DIAGNOSTICINTEGERSENSORINDEX_TIME_WITH_MALFUNCTION_LIGHT_ON = 0xe
+DIAGNOSTICINTEGERSENSORINDEX_TIME_SINCE_TROUBLE_CODES_CLEARED = 0xf
+DIAGNOSTICINTEGERSENSORINDEX_MAX_FUEL_AIR_EQUIVALENCE_RATIO = 0x10
+DIAGNOSTICINTEGERSENSORINDEX_MAX_OXYGEN_SENSOR_VOLTAGE = 0x11
+DIAGNOSTICINTEGERSENSORINDEX_MAX_OXYGEN_SENSOR_CURRENT = 0x12
+DIAGNOSTICINTEGERSENSORINDEX_MAX_INTAKE_MANIFOLD_ABSOLUTE_PRESSURE = 0x13
+DIAGNOSTICINTEGERSENSORINDEX_MAX_AIR_FLOW_RATE_FROM_MASS_AIR_FLOW_SENSOR = 0x14
+DIAGNOSTICINTEGERSENSORINDEX_FUEL_TYPE = 0x15
+DIAGNOSTICINTEGERSENSORINDEX_FUEL_RAIL_ABSOLUTE_PRESSURE = 0x16
+DIAGNOSTICINTEGERSENSORINDEX_ENGINE_OIL_TEMPERATURE = 0x17
+DIAGNOSTICINTEGERSENSORINDEX_DRIVER_DEMAND_PERCENT_TORQUE = 0x18
+DIAGNOSTICINTEGERSENSORINDEX_ENGINE_ACTUAL_PERCENT_TORQUE = 0x19
+DIAGNOSTICINTEGERSENSORINDEX_ENGINE_REFERENCE_PERCENT_TORQUE = 0x1a
+DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_IDLE = 0x1b
+DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_POINT1 = 0x1c
+DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_POINT2 = 0x1d
+DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_POINT3 = 0x1e
+DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_POINT4 = 0x1f
+DIAGNOSTICINTEGERSENSORINDEX_LAST_SYSTEM_INDEX = 0x1f
# VehicleAudioFocusState
VEHICLEAUDIOFOCUSSTATE_STATE_GAIN = 0x1
@@ -302,9 +68,26 @@
VEHICLEAUDIOFOCUSSTATE_STATE_LOSS = 0x5
VEHICLEAUDIOFOCUSSTATE_STATE_LOSS_TRANSIENT_EXLCUSIVE = 0x6
-# VehicleAudioStream
-VEHICLEAUDIOSTREAM_STREAM0 = 0x0
-VEHICLEAUDIOSTREAM_STREAM1 = 0x1
+# Obd2CommonIgnitionMonitors
+OBD2COMMONIGNITIONMONITORS_COMPONENTS_AVAILABLE = 0x1
+OBD2COMMONIGNITIONMONITORS_COMPONENTS_INCOMPLETE = 0x2
+OBD2COMMONIGNITIONMONITORS_FUEL_SYSTEM_AVAILABLE = 0x4
+OBD2COMMONIGNITIONMONITORS_FUEL_SYSTEM_INCOMPLETE = 0x8
+OBD2COMMONIGNITIONMONITORS_MISFIRE_AVAILABLE = 0x10
+OBD2COMMONIGNITIONMONITORS_MISFIRE_INCOMPLETE = 0x20
+
+# VehicleHvacFanDirection
+VEHICLEHVACFANDIRECTION_FACE = 0x1
+VEHICLEHVACFANDIRECTION_FLOOR = 0x2
+VEHICLEHVACFANDIRECTION_FACE_AND_FLOOR = 0x3
+VEHICLEHVACFANDIRECTION_DEFROST = 0x4
+VEHICLEHVACFANDIRECTION_DEFROST_AND_FLOOR = 0x5
+
+# VehiclePropertyOperation
+VEHICLEPROPERTYOPERATION_GENERIC = 0x0
+VEHICLEPROPERTYOPERATION_SET = 0x1
+VEHICLEPROPERTYOPERATION_GET = 0x2
+VEHICLEPROPERTYOPERATION_SUBSCRIBE = 0x3
# DiagnosticFloatSensorIndex
DIAGNOSTICFLOATSENSORINDEX_CALCULATED_ENGINE_LOAD = 0x0
@@ -380,10 +163,9 @@
DIAGNOSTICFLOATSENSORINDEX_ENGINE_FUEL_RATE = 0x46
DIAGNOSTICFLOATSENSORINDEX_LAST_SYSTEM_INDEX = 0x46
-# VehicleAreaMirror
-VEHICLEAREAMIRROR_DRIVER_LEFT = 0x1
-VEHICLEAREAMIRROR_DRIVER_RIGHT = 0x2
-VEHICLEAREAMIRROR_DRIVER_CENTER = 0x4
+# VehicleAudioVolumeLimitIndex
+VEHICLEAUDIOVOLUMELIMITINDEX_STREAM = 0x0
+VEHICLEAUDIOVOLUMELIMITINDEX_MAX_VOLUME = 0x1
# VehicleAreaWindow
VEHICLEAREAWINDOW_FRONT_WINDSHIELD = 0x1
@@ -396,40 +178,97 @@
VEHICLEAREAWINDOW_ROW_3_LEFT = 0x1000
VEHICLEAREAWINDOW_ROW_3_RIGHT = 0x2000
-# VehiclePropertyOperation
-VEHICLEPROPERTYOPERATION_GENERIC = 0x0
-VEHICLEPROPERTYOPERATION_SET = 0x1
-VEHICLEPROPERTYOPERATION_GET = 0x2
-VEHICLEPROPERTYOPERATION_SUBSCRIBE = 0x3
+# VehicleGear
+VEHICLEGEAR_GEAR_NEUTRAL = 0x1
+VEHICLEGEAR_GEAR_REVERSE = 0x2
+VEHICLEGEAR_GEAR_PARK = 0x4
+VEHICLEGEAR_GEAR_DRIVE = 0x8
+VEHICLEGEAR_GEAR_LOW = 0x10
+VEHICLEGEAR_GEAR_1 = 0x10
+VEHICLEGEAR_GEAR_2 = 0x20
+VEHICLEGEAR_GEAR_3 = 0x40
+VEHICLEGEAR_GEAR_4 = 0x80
+VEHICLEGEAR_GEAR_5 = 0x100
+VEHICLEGEAR_GEAR_6 = 0x200
+VEHICLEGEAR_GEAR_7 = 0x400
+VEHICLEGEAR_GEAR_8 = 0x800
+VEHICLEGEAR_GEAR_9 = 0x1000
-# VehicleAreaDoor
-VEHICLEAREADOOR_ROW_1_LEFT = 0x1
-VEHICLEAREADOOR_ROW_1_RIGHT = 0x4
-VEHICLEAREADOOR_ROW_2_LEFT = 0x10
-VEHICLEAREADOOR_ROW_2_RIGHT = 0x40
-VEHICLEAREADOOR_ROW_3_LEFT = 0x100
-VEHICLEAREADOOR_ROW_3_RIGHT = 0x400
-VEHICLEAREADOOR_HOOD = 0x10000000
-VEHICLEAREADOOR_REAR = 0x20000000
+# VehicleAreaMirror
+VEHICLEAREAMIRROR_DRIVER_LEFT = 0x1
+VEHICLEAREAMIRROR_DRIVER_RIGHT = 0x2
+VEHICLEAREAMIRROR_DRIVER_CENTER = 0x4
-# StatusCode
-STATUSCODE_OK = 0x0
-STATUSCODE_TRY_AGAIN = 0x1
-STATUSCODE_INVALID_ARG = 0x2
-STATUSCODE_NOT_AVAILABLE = 0x3
-STATUSCODE_ACCESS_DENIED = 0x4
-STATUSCODE_INTERNAL_ERROR = 0x5
+# VehicleAudioContextFlag
+VEHICLEAUDIOCONTEXTFLAG_MUSIC_FLAG = 0x1
+VEHICLEAUDIOCONTEXTFLAG_NAVIGATION_FLAG = 0x2
+VEHICLEAUDIOCONTEXTFLAG_VOICE_COMMAND_FLAG = 0x4
+VEHICLEAUDIOCONTEXTFLAG_CALL_FLAG = 0x8
+VEHICLEAUDIOCONTEXTFLAG_ALARM_FLAG = 0x10
+VEHICLEAUDIOCONTEXTFLAG_NOTIFICATION_FLAG = 0x20
+VEHICLEAUDIOCONTEXTFLAG_UNKNOWN_FLAG = 0x40
+VEHICLEAUDIOCONTEXTFLAG_SAFETY_ALERT_FLAG = 0x80
+VEHICLEAUDIOCONTEXTFLAG_CD_ROM_FLAG = 0x100
+VEHICLEAUDIOCONTEXTFLAG_AUX_AUDIO_FLAG = 0x200
+VEHICLEAUDIOCONTEXTFLAG_SYSTEM_SOUND_FLAG = 0x400
+VEHICLEAUDIOCONTEXTFLAG_RADIO_FLAG = 0x800
+VEHICLEAUDIOCONTEXTFLAG_EXT_SOURCE_FLAG = 0x1000
+VEHICLEAUDIOCONTEXTFLAG_RINGTONE_FLAG = 0x2000
-# VehicleAreaSeat
-VEHICLEAREASEAT_ROW_1_LEFT = 0x1
-VEHICLEAREASEAT_ROW_1_CENTER = 0x2
-VEHICLEAREASEAT_ROW_1_RIGHT = 0x4
-VEHICLEAREASEAT_ROW_2_LEFT = 0x10
-VEHICLEAREASEAT_ROW_2_CENTER = 0x20
-VEHICLEAREASEAT_ROW_2_RIGHT = 0x40
-VEHICLEAREASEAT_ROW_3_LEFT = 0x100
-VEHICLEAREASEAT_ROW_3_CENTER = 0x200
-VEHICLEAREASEAT_ROW_3_RIGHT = 0x400
+# VmsMessageWithLayerAndPublisherIdIntegerValuesIndex
+VMSMESSAGEWITHLAYERANDPUBLISHERIDINTEGERVALUESINDEX_PUBLISHER_ID = 0x4
+
+# VehiclePropertyAccess
+VEHICLEPROPERTYACCESS_NONE = 0x0
+VEHICLEPROPERTYACCESS_READ = 0x1
+VEHICLEPROPERTYACCESS_WRITE = 0x2
+VEHICLEPROPERTYACCESS_READ_WRITE = 0x3
+
+# VehicleApPowerStateIndex
+VEHICLEAPPOWERSTATEINDEX_STATE = 0x0
+VEHICLEAPPOWERSTATEINDEX_ADDITIONAL = 0x1
+
+# VmsBaseMessageIntegerValuesIndex
+VMSBASEMESSAGEINTEGERVALUESINDEX_MESSAGE_TYPE = 0x0
+
+# VehicleAudioStream
+VEHICLEAUDIOSTREAM_STREAM0 = 0x0
+VEHICLEAUDIOSTREAM_STREAM1 = 0x1
+
+# VehiclePropertyChangeMode
+VEHICLEPROPERTYCHANGEMODE_STATIC = 0x0
+VEHICLEPROPERTYCHANGEMODE_ON_CHANGE = 0x1
+VEHICLEPROPERTYCHANGEMODE_CONTINUOUS = 0x2
+VEHICLEPROPERTYCHANGEMODE_POLL = 0x3
+VEHICLEPROPERTYCHANGEMODE_ON_SET = 0x4
+
+# Obd2CompressionIgnitionMonitors
+OBD2COMPRESSIONIGNITIONMONITORS_EGR_OR_VVT_AVAILABLE = 0x40
+OBD2COMPRESSIONIGNITIONMONITORS_EGR_OR_VVT_INCOMPLETE = 0x80
+OBD2COMPRESSIONIGNITIONMONITORS_PM_FILTER_AVAILABLE = 0x100
+OBD2COMPRESSIONIGNITIONMONITORS_PM_FILTER_INCOMPLETE = 0x200
+OBD2COMPRESSIONIGNITIONMONITORS_EXHAUST_GAS_SENSOR_AVAILABLE = 0x400
+OBD2COMPRESSIONIGNITIONMONITORS_EXHAUST_GAS_SENSOR_INCOMPLETE = 0x800
+OBD2COMPRESSIONIGNITIONMONITORS_BOOST_PRESSURE_AVAILABLE = 0x1000
+OBD2COMPRESSIONIGNITIONMONITORS_BOOST_PRESSURE_INCOMPLETE = 0x2000
+OBD2COMPRESSIONIGNITIONMONITORS_NOx_SCR_AVAILABLE = 0x4000
+OBD2COMPRESSIONIGNITIONMONITORS_NOx_SCR_INCOMPLETE = 0x8000
+OBD2COMPRESSIONIGNITIONMONITORS_NMHC_CATALYST_AVAILABLE = 0x10000
+OBD2COMPRESSIONIGNITIONMONITORS_NMHC_CATALYST_INCOMPLETE = 0x20000
+
+# VehiclePropertyGroup
+VEHICLEPROPERTYGROUP_SYSTEM = 0x10000000
+VEHICLEPROPERTYGROUP_VENDOR = 0x20000000
+VEHICLEPROPERTYGROUP_MASK = 0xf0000000
+
+# VehicleApPowerSetState
+VEHICLEAPPOWERSETSTATE_BOOT_COMPLETE = 0x1
+VEHICLEAPPOWERSETSTATE_DEEP_SLEEP_ENTRY = 0x2
+VEHICLEAPPOWERSETSTATE_DEEP_SLEEP_EXIT = 0x3
+VEHICLEAPPOWERSETSTATE_SHUTDOWN_POSTPONE = 0x4
+VEHICLEAPPOWERSETSTATE_SHUTDOWN_START = 0x5
+VEHICLEAPPOWERSETSTATE_DISPLAY_OFF = 0x6
+VEHICLEAPPOWERSETSTATE_DISPLAY_ON = 0x7
# VmsMessageType
VMSMESSAGETYPE_SUBSCRIBE = 0x1
@@ -445,6 +284,32 @@
VMSMESSAGETYPE_SUBSCRIPTIONS_CHANGE = 0xb
VMSMESSAGETYPE_DATA = 0xc
+# VehicleAreaZone
+VEHICLEAREAZONE_ROW_1_LEFT = 0x1
+VEHICLEAREAZONE_ROW_1_CENTER = 0x2
+VEHICLEAREAZONE_ROW_1_RIGHT = 0x4
+VEHICLEAREAZONE_ROW_1 = 0x8
+VEHICLEAREAZONE_ROW_2_LEFT = 0x10
+VEHICLEAREAZONE_ROW_2_CENTER = 0x20
+VEHICLEAREAZONE_ROW_2_RIGHT = 0x40
+VEHICLEAREAZONE_ROW_2 = 0x80
+VEHICLEAREAZONE_ROW_3_LEFT = 0x100
+VEHICLEAREAZONE_ROW_3_CENTER = 0x200
+VEHICLEAREAZONE_ROW_3_RIGHT = 0x400
+VEHICLEAREAZONE_ROW_3 = 0x800
+VEHICLEAREAZONE_ROW_4_LEFT = 0x1000
+VEHICLEAREAZONE_ROW_4_CENTER = 0x2000
+VEHICLEAREAZONE_ROW_4_RIGHT = 0x4000
+VEHICLEAREAZONE_ROW_4 = 0x8000
+VEHICLEAREAZONE_WHOLE_CABIN = 0x80000000
+
+# Wheel
+WHEEL_UNKNOWN = 0x0
+WHEEL_LEFT_FRONT = 0x1
+WHEEL_RIGHT_FRONT = 0x2
+WHEEL_LEFT_REAR = 0x4
+WHEEL_RIGHT_REAR = 0x8
+
# VehicleProperty
VEHICLEPROPERTY_INVALID = 0x0
VEHICLEPROPERTY_INFO_VIN = 0x11100100
@@ -457,6 +322,7 @@
VEHICLEPROPERTY_ENGINE_COOLANT_TEMP = 0x11600301
VEHICLEPROPERTY_ENGINE_OIL_TEMP = 0x11600304
VEHICLEPROPERTY_ENGINE_RPM = 0x11600305
+VEHICLEPROPERTY_WHEEL_TICK = 0x11e00306
VEHICLEPROPERTY_GEAR_SELECTION = 0x11400400
VEHICLEPROPERTY_CURRENT_GEAR = 0x11400401
VEHICLEPROPERTY_PARKING_BRAKE_ON = 0x11200402
@@ -465,6 +331,8 @@
VEHICLEPROPERTY_NIGHT_MODE = 0x11200407
VEHICLEPROPERTY_TURN_SIGNAL_STATE = 0x11400408
VEHICLEPROPERTY_IGNITION_STATE = 0x11400409
+VEHICLEPROPERTY_ABS_ACTIVE = 0x1120040a
+VEHICLEPROPERTY_TRACTION_CONTROL_ACTIVE = 0x1120040b
VEHICLEPROPERTY_HVAC_FAN_SPEED = 0x12400500
VEHICLEPROPERTY_HVAC_FAN_DIRECTION = 0x12400501
VEHICLEPROPERTY_HVAC_TEMPERATURE_CURRENT = 0x12600502
@@ -481,8 +349,9 @@
VEHICLEPROPERTY_HVAC_STEERING_WHEEL_TEMP = 0x1140050d
VEHICLEPROPERTY_HVAC_TEMPERATURE_UNITS = 0x1240050e
VEHICLEPROPERTY_HVAC_ACTUAL_FAN_SPEED_RPM = 0x1240050f
-VEHICLEPROPERTY_HVAC_FAN_DIRECTION_AVAILABLE = 0x12400511
VEHICLEPROPERTY_HVAC_POWER_ON = 0x12200510
+VEHICLEPROPERTY_HVAC_FAN_DIRECTION_AVAILABLE = 0x12400511
+VEHICLEPROPERTY_HVAC_AUTO_RECIRC_ON = 0x12200512
VEHICLEPROPERTY_ENV_OUTSIDE_TEMPERATURE = 0x11600703
VEHICLEPROPERTY_ENV_CABIN_TEMPERATURE = 0x11600704
VEHICLEPROPERTY_RADIO_PRESET = 0x11410801
@@ -544,10 +413,6 @@
VEHICLEPROPERTY_WINDOW_VENT_POS = 0x11400bc2
VEHICLEPROPERTY_WINDOW_VENT_MOVE = 0x11400bc3
VEHICLEPROPERTY_WINDOW_LOCK = 0x11200bc4
-VEHICLEPROPERTY_WHEEL_TICK = 0x11e00306
-VEHICLEPROPERTY_ABS_ACTIVE = 0x1120040a
-VEHICLEPROPERTY_TRACTION_CONTROL_ACTIVE = 0x1120040b
-VEHICLEPROPERTY_HVAC_AUTO_RECIRC_ON = 0x12200512
VEHICLEPROPERTY_VEHICLE_MAP_SERVICE = 0x11e00c00
VEHICLEPROPERTY_OBD2_LIVE_FRAME = 0x11e00d00
VEHICLEPROPERTY_OBD2_FREEZE_FRAME = 0x11e00d01
@@ -562,76 +427,25 @@
VEHICLEIGNITIONSTATE_ON = 0x4
VEHICLEIGNITIONSTATE_START = 0x5
-# VehiclePropertyGroup
-VEHICLEPROPERTYGROUP_SYSTEM = 0x10000000
-VEHICLEPROPERTYGROUP_VENDOR = 0x20000000
-VEHICLEPROPERTYGROUP_MASK = 0xf0000000
+# VehicleAudioVolumeCapabilityFlag
+VEHICLEAUDIOVOLUMECAPABILITYFLAG_PERSISTENT_STORAGE = 0x1
+VEHICLEAUDIOVOLUMECAPABILITYFLAG_MASTER_VOLUME_ONLY = 0x2
-# VehicleApPowerSetState
-VEHICLEAPPOWERSETSTATE_BOOT_COMPLETE = 0x1
-VEHICLEAPPOWERSETSTATE_DEEP_SLEEP_ENTRY = 0x2
-VEHICLEAPPOWERSETSTATE_DEEP_SLEEP_EXIT = 0x3
-VEHICLEAPPOWERSETSTATE_SHUTDOWN_POSTPONE = 0x4
-VEHICLEAPPOWERSETSTATE_SHUTDOWN_START = 0x5
-VEHICLEAPPOWERSETSTATE_DISPLAY_OFF = 0x6
-VEHICLEAPPOWERSETSTATE_DISPLAY_ON = 0x7
+# VehicleHwKeyInputAction
+VEHICLEHWKEYINPUTACTION_ACTION_DOWN = 0x0
+VEHICLEHWKEYINPUTACTION_ACTION_UP = 0x1
-# VmsBaseMessageIntegerValuesIndex
-VMSBASEMESSAGEINTEGERVALUESINDEX_MESSAGE_TYPE = 0x0
+# VehicleAudioStreamFlag
+VEHICLEAUDIOSTREAMFLAG_STREAM0_FLAG = 0x1
+VEHICLEAUDIOSTREAMFLAG_STREAM1_FLAG = 0x2
+VEHICLEAUDIOSTREAMFLAG_STREAM2_FLAG = 0x4
-# DiagnosticIntegerSensorIndex
-DIAGNOSTICINTEGERSENSORINDEX_FUEL_SYSTEM_STATUS = 0x0
-DIAGNOSTICINTEGERSENSORINDEX_MALFUNCTION_INDICATOR_LIGHT_ON = 0x1
-DIAGNOSTICINTEGERSENSORINDEX_IGNITION_MONITORS_SUPPORTED = 0x2
-DIAGNOSTICINTEGERSENSORINDEX_IGNITION_SPECIFIC_MONITORS = 0x3
-DIAGNOSTICINTEGERSENSORINDEX_INTAKE_AIR_TEMPERATURE = 0x4
-DIAGNOSTICINTEGERSENSORINDEX_COMMANDED_SECONDARY_AIR_STATUS = 0x5
-DIAGNOSTICINTEGERSENSORINDEX_NUM_OXYGEN_SENSORS_PRESENT = 0x6
-DIAGNOSTICINTEGERSENSORINDEX_RUNTIME_SINCE_ENGINE_START = 0x7
-DIAGNOSTICINTEGERSENSORINDEX_DISTANCE_TRAVELED_WITH_MALFUNCTION_INDICATOR_LIGHT_ON = 0x8
-DIAGNOSTICINTEGERSENSORINDEX_WARMUPS_SINCE_CODES_CLEARED = 0x9
-DIAGNOSTICINTEGERSENSORINDEX_DISTANCE_TRAVELED_SINCE_CODES_CLEARED = 0xa
-DIAGNOSTICINTEGERSENSORINDEX_ABSOLUTE_BAROMETRIC_PRESSURE = 0xb
-DIAGNOSTICINTEGERSENSORINDEX_CONTROL_MODULE_VOLTAGE = 0xc
-DIAGNOSTICINTEGERSENSORINDEX_AMBIENT_AIR_TEMPERATURE = 0xd
-DIAGNOSTICINTEGERSENSORINDEX_TIME_WITH_MALFUNCTION_LIGHT_ON = 0xe
-DIAGNOSTICINTEGERSENSORINDEX_TIME_SINCE_TROUBLE_CODES_CLEARED = 0xf
-DIAGNOSTICINTEGERSENSORINDEX_MAX_FUEL_AIR_EQUIVALENCE_RATIO = 0x10
-DIAGNOSTICINTEGERSENSORINDEX_MAX_OXYGEN_SENSOR_VOLTAGE = 0x11
-DIAGNOSTICINTEGERSENSORINDEX_MAX_OXYGEN_SENSOR_CURRENT = 0x12
-DIAGNOSTICINTEGERSENSORINDEX_MAX_INTAKE_MANIFOLD_ABSOLUTE_PRESSURE = 0x13
-DIAGNOSTICINTEGERSENSORINDEX_MAX_AIR_FLOW_RATE_FROM_MASS_AIR_FLOW_SENSOR = 0x14
-DIAGNOSTICINTEGERSENSORINDEX_FUEL_TYPE = 0x15
-DIAGNOSTICINTEGERSENSORINDEX_FUEL_RAIL_ABSOLUTE_PRESSURE = 0x16
-DIAGNOSTICINTEGERSENSORINDEX_ENGINE_OIL_TEMPERATURE = 0x17
-DIAGNOSTICINTEGERSENSORINDEX_DRIVER_DEMAND_PERCENT_TORQUE = 0x18
-DIAGNOSTICINTEGERSENSORINDEX_ENGINE_ACTUAL_PERCENT_TORQUE = 0x19
-DIAGNOSTICINTEGERSENSORINDEX_ENGINE_REFERENCE_PERCENT_TORQUE = 0x1a
-DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_IDLE = 0x1b
-DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_POINT1 = 0x1c
-DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_POINT2 = 0x1d
-DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_POINT3 = 0x1e
-DIAGNOSTICINTEGERSENSORINDEX_ENGINE_PERCENT_TORQUE_DATA_POINT4 = 0x1f
-DIAGNOSTICINTEGERSENSORINDEX_LAST_SYSTEM_INDEX = 0x1f
-
-# VehiclePropertyChangeMode
-VEHICLEPROPERTYCHANGEMODE_STATIC = 0x0
-VEHICLEPROPERTYCHANGEMODE_ON_CHANGE = 0x1
-VEHICLEPROPERTYCHANGEMODE_CONTINUOUS = 0x2
-VEHICLEPROPERTYCHANGEMODE_POLL = 0x3
-VEHICLEPROPERTYCHANGEMODE_ON_SET = 0x4
-
-# VehicleApPowerState
-VEHICLEAPPOWERSTATE_OFF = 0x0
-VEHICLEAPPOWERSTATE_DEEP_SLEEP = 0x1
-VEHICLEAPPOWERSTATE_ON_DISP_OFF = 0x2
-VEHICLEAPPOWERSTATE_ON_FULL = 0x3
-VEHICLEAPPOWERSTATE_SHUTDOWN_PREPARE = 0x4
-
-# VehicleInstrumentClusterType
-VEHICLEINSTRUMENTCLUSTERTYPE_NONE = 0x0
-VEHICLEINSTRUMENTCLUSTERTYPE_HAL_INTERFACE = 0x1
-VEHICLEINSTRUMENTCLUSTERTYPE_EXTERNAL_DISPLAY = 0x2
+# Obd2FuelSystemStatus
+OBD2FUELSYSTEMSTATUS_OPEN_INSUFFICIENT_ENGINE_TEMPERATURE = 0x1
+OBD2FUELSYSTEMSTATUS_CLOSED_LOOP = 0x2
+OBD2FUELSYSTEMSTATUS_OPEN_ENGINE_LOAD_OR_DECELERATION = 0x4
+OBD2FUELSYSTEMSTATUS_OPEN_SYSTEM_FAILURE = 0x8
+OBD2FUELSYSTEMSTATUS_CLOSED_LOOP_BUT_FEEDBACK_FAULT = 0x10
# VehicleUnit
VEHICLEUNIT_SHOULD_NOT_USE = 0x0
@@ -650,22 +464,209 @@
VEHICLEUNIT_SECS = 0x53
VEHICLEUNIT_YEAR = 0x59
-# VehicleAudioVolumeLimitIndex
-VEHICLEAUDIOVOLUMELIMITINDEX_STREAM = 0x0
-VEHICLEAUDIOVOLUMELIMITINDEX_MAX_VOLUME = 0x1
+# VehicleAudioFocusIndex
+VEHICLEAUDIOFOCUSINDEX_FOCUS = 0x0
+VEHICLEAUDIOFOCUSINDEX_STREAMS = 0x1
+VEHICLEAUDIOFOCUSINDEX_EXTERNAL_FOCUS_STATE = 0x2
+VEHICLEAUDIOFOCUSINDEX_AUDIO_CONTEXTS = 0x3
+
+# VehiclePropertyType
+VEHICLEPROPERTYTYPE_STRING = 0x100000
+VEHICLEPROPERTYTYPE_BOOLEAN = 0x200000
+VEHICLEPROPERTYTYPE_INT32 = 0x400000
+VEHICLEPROPERTYTYPE_INT32_VEC = 0x410000
+VEHICLEPROPERTYTYPE_INT64 = 0x500000
+VEHICLEPROPERTYTYPE_FLOAT = 0x600000
+VEHICLEPROPERTYTYPE_FLOAT_VEC = 0x610000
+VEHICLEPROPERTYTYPE_BYTES = 0x700000
+VEHICLEPROPERTYTYPE_COMPLEX = 0xe00000
+VEHICLEPROPERTYTYPE_MASK = 0xff0000
+
+# VehicleAudioVolumeIndex
+VEHICLEAUDIOVOLUMEINDEX_STREAM = 0x0
+VEHICLEAUDIOVOLUMEINDEX_VOLUME = 0x1
+VEHICLEAUDIOVOLUMEINDEX_STATE = 0x2
+
+# VehicleDrivingStatus
+VEHICLEDRIVINGSTATUS_UNRESTRICTED = 0x0
+VEHICLEDRIVINGSTATUS_NO_VIDEO = 0x1
+VEHICLEDRIVINGSTATUS_NO_KEYBOARD_INPUT = 0x2
+VEHICLEDRIVINGSTATUS_NO_VOICE_INPUT = 0x4
+VEHICLEDRIVINGSTATUS_NO_CONFIG = 0x8
+VEHICLEDRIVINGSTATUS_LIMIT_MESSAGE_LEN = 0x10
+
+# VmsAvailabilityStateIntegerValuesIndex
+VMSAVAILABILITYSTATEINTEGERVALUESINDEX_SEQUENCE_NUMBER = 0x1
+VMSAVAILABILITYSTATEINTEGERVALUESINDEX_NUMBER_OF_ASSOCIATED_LAYERS = 0x2
+VMSAVAILABILITYSTATEINTEGERVALUESINDEX_LAYERS_START = 0x3
+
+# VmsSubscriptionsStateIntegerValuesIndex
+VMSSUBSCRIPTIONSSTATEINTEGERVALUESINDEX_SEQUENCE_NUMBER = 0x1
+VMSSUBSCRIPTIONSSTATEINTEGERVALUESINDEX_NUMBER_OF_LAYERS = 0x2
+VMSSUBSCRIPTIONSSTATEINTEGERVALUESINDEX_NUMBER_OF_ASSOCIATED_LAYERS = 0x3
+VMSSUBSCRIPTIONSSTATEINTEGERVALUESINDEX_SUBSCRIPTIONS_START = 0x4
+
+# VmsMessageWithLayerIntegerValuesIndex
+VMSMESSAGEWITHLAYERINTEGERVALUESINDEX_LAYER_TYPE = 0x1
+VMSMESSAGEWITHLAYERINTEGERVALUESINDEX_LAYER_SUBTYPE = 0x2
+VMSMESSAGEWITHLAYERINTEGERVALUESINDEX_LAYER_VERSION = 0x3
+
+# VehicleAudioFocusRequest
+VEHICLEAUDIOFOCUSREQUEST_REQUEST_GAIN = 0x1
+VEHICLEAUDIOFOCUSREQUEST_REQUEST_GAIN_TRANSIENT = 0x2
+VEHICLEAUDIOFOCUSREQUEST_REQUEST_GAIN_TRANSIENT_MAY_DUCK = 0x3
+VEHICLEAUDIOFOCUSREQUEST_REQUEST_GAIN_TRANSIENT_NO_DUCK = 0x4
+VEHICLEAUDIOFOCUSREQUEST_REQUEST_RELEASE = 0x5
+
+# VehicleArea
+VEHICLEAREA_GLOBAL = 0x1000000
+VEHICLEAREA_ZONE = 0x2000000
+VEHICLEAREA_WINDOW = 0x3000000
+VEHICLEAREA_MIRROR = 0x4000000
+VEHICLEAREA_SEAT = 0x5000000
+VEHICLEAREA_DOOR = 0x6000000
+VEHICLEAREA_MASK = 0xf000000
+
+# VehicleTurnSignal
+VEHICLETURNSIGNAL_NONE = 0x0
+VEHICLETURNSIGNAL_RIGHT = 0x1
+VEHICLETURNSIGNAL_LEFT = 0x2
+VEHICLETURNSIGNAL_EMERGENCY = 0x4
+
+# VehicleDisplay
+VEHICLEDISPLAY_MAIN = 0x0
+VEHICLEDISPLAY_INSTRUMENT_CLUSTER = 0x1
+
+# VehicleAudioRoutingPolicyIndex
+VEHICLEAUDIOROUTINGPOLICYINDEX_STREAM = 0x0
+VEHICLEAUDIOROUTINGPOLICYINDEX_CONTEXTS = 0x1
+
+# Obd2IgnitionMonitorKind
+OBD2IGNITIONMONITORKIND_SPARK = 0x0
+OBD2IGNITIONMONITORKIND_COMPRESSION = 0x1
+
+# VehicleApPowerBootupReason
+VEHICLEAPPOWERBOOTUPREASON_USER_POWER_ON = 0x0
+VEHICLEAPPOWERBOOTUPREASON_USER_UNLOCK = 0x1
+VEHICLEAPPOWERBOOTUPREASON_TIMER = 0x2
+
+# Obd2FuelType
+OBD2FUELTYPE_NOT_AVAILABLE = 0x0
+OBD2FUELTYPE_GASOLINE = 0x1
+OBD2FUELTYPE_METHANOL = 0x2
+OBD2FUELTYPE_ETHANOL = 0x3
+OBD2FUELTYPE_DIESEL = 0x4
+OBD2FUELTYPE_LPG = 0x5
+OBD2FUELTYPE_CNG = 0x6
+OBD2FUELTYPE_PROPANE = 0x7
+OBD2FUELTYPE_ELECTRIC = 0x8
+OBD2FUELTYPE_BIFUEL_RUNNING_GASOLINE = 0x9
+OBD2FUELTYPE_BIFUEL_RUNNING_METHANOL = 0xa
+OBD2FUELTYPE_BIFUEL_RUNNING_ETHANOL = 0xb
+OBD2FUELTYPE_BIFUEL_RUNNING_LPG = 0xc
+OBD2FUELTYPE_BIFUEL_RUNNING_CNG = 0xd
+OBD2FUELTYPE_BIFUEL_RUNNING_PROPANE = 0xe
+OBD2FUELTYPE_BIFUEL_RUNNING_ELECTRIC = 0xf
+OBD2FUELTYPE_BIFUEL_RUNNING_ELECTRIC_AND_COMBUSTION = 0x10
+OBD2FUELTYPE_HYBRID_GASOLINE = 0x11
+OBD2FUELTYPE_HYBRID_ETHANOL = 0x12
+OBD2FUELTYPE_HYBRID_DIESEL = 0x13
+OBD2FUELTYPE_HYBRID_ELECTRIC = 0x14
+OBD2FUELTYPE_HYBRID_RUNNING_ELECTRIC_AND_COMBUSTION = 0x15
+OBD2FUELTYPE_HYBRID_REGENERATIVE = 0x16
+OBD2FUELTYPE_BIFUEL_RUNNING_DIESEL = 0x17
+
+# VehicleAudioExtFocusFlag
+VEHICLEAUDIOEXTFOCUSFLAG_NONE_FLAG = 0x0
+VEHICLEAUDIOEXTFOCUSFLAG_PERMANENT_FLAG = 0x1
+VEHICLEAUDIOEXTFOCUSFLAG_TRANSIENT_FLAG = 0x2
+VEHICLEAUDIOEXTFOCUSFLAG_PLAY_ONLY_FLAG = 0x4
+VEHICLEAUDIOEXTFOCUSFLAG_MUTE_MEDIA_FLAG = 0x8
# VehicleApPowerStateShutdownParam
VEHICLEAPPOWERSTATESHUTDOWNPARAM_SHUTDOWN_IMMEDIATELY = 0x1
VEHICLEAPPOWERSTATESHUTDOWNPARAM_CAN_SLEEP = 0x2
VEHICLEAPPOWERSTATESHUTDOWNPARAM_SHUTDOWN_ONLY = 0x3
-# VehicleApPowerStateIndex
-VEHICLEAPPOWERSTATEINDEX_STATE = 0x0
-VEHICLEAPPOWERSTATEINDEX_ADDITIONAL = 0x1
+# VehicleInstrumentClusterType
+VEHICLEINSTRUMENTCLUSTERTYPE_NONE = 0x0
+VEHICLEINSTRUMENTCLUSTERTYPE_HAL_INTERFACE = 0x1
+VEHICLEINSTRUMENTCLUSTERTYPE_EXTERNAL_DISPLAY = 0x2
-# VehicleDisplay
-VEHICLEDISPLAY_MAIN = 0x0
-VEHICLEDISPLAY_INSTRUMENT_CLUSTER = 0x1
+# Obd2SparkIgnitionMonitors
+OBD2SPARKIGNITIONMONITORS_EGR_AVAILABLE = 0x40
+OBD2SPARKIGNITIONMONITORS_EGR_INCOMPLETE = 0x80
+OBD2SPARKIGNITIONMONITORS_OXYGEN_SENSOR_HEATER_AVAILABLE = 0x100
+OBD2SPARKIGNITIONMONITORS_OXYGEN_SENSOR_HEATER_INCOMPLETE = 0x200
+OBD2SPARKIGNITIONMONITORS_OXYGEN_SENSOR_AVAILABLE = 0x400
+OBD2SPARKIGNITIONMONITORS_OXYGEN_SENSOR_INCOMPLETE = 0x800
+OBD2SPARKIGNITIONMONITORS_AC_REFRIGERANT_AVAILABLE = 0x1000
+OBD2SPARKIGNITIONMONITORS_AC_REFRIGERANT_INCOMPLETE = 0x2000
+OBD2SPARKIGNITIONMONITORS_SECONDARY_AIR_SYSTEM_AVAILABLE = 0x4000
+OBD2SPARKIGNITIONMONITORS_SECONDARY_AIR_SYSTEM_INCOMPLETE = 0x8000
+OBD2SPARKIGNITIONMONITORS_EVAPORATIVE_SYSTEM_AVAILABLE = 0x10000
+OBD2SPARKIGNITIONMONITORS_EVAPORATIVE_SYSTEM_INCOMPLETE = 0x20000
+OBD2SPARKIGNITIONMONITORS_HEATED_CATALYST_AVAILABLE = 0x40000
+OBD2SPARKIGNITIONMONITORS_HEATED_CATALYST_INCOMPLETE = 0x80000
+OBD2SPARKIGNITIONMONITORS_CATALYST_AVAILABLE = 0x100000
+OBD2SPARKIGNITIONMONITORS_CATALYST_INCOMPLETE = 0x200000
+
+# VehicleApPowerStateConfigFlag
+VEHICLEAPPOWERSTATECONFIGFLAG_ENABLE_DEEP_SLEEP_FLAG = 0x1
+VEHICLEAPPOWERSTATECONFIGFLAG_CONFIG_SUPPORT_TIMER_POWER_ON_FLAG = 0x2
+
+# VmsOfferingMessageIntegerValuesIndex
+VMSOFFERINGMESSAGEINTEGERVALUESINDEX_PUBLISHER_ID = 0x1
+VMSOFFERINGMESSAGEINTEGERVALUESINDEX_NUMBER_OF_OFFERS = 0x2
+VMSOFFERINGMESSAGEINTEGERVALUESINDEX_OFFERING_START = 0x3
+
+# VehicleAreaDoor
+VEHICLEAREADOOR_ROW_1_LEFT = 0x1
+VEHICLEAREADOOR_ROW_1_RIGHT = 0x4
+VEHICLEAREADOOR_ROW_2_LEFT = 0x10
+VEHICLEAREADOOR_ROW_2_RIGHT = 0x40
+VEHICLEAREADOOR_ROW_3_LEFT = 0x100
+VEHICLEAREADOOR_ROW_3_RIGHT = 0x400
+VEHICLEAREADOOR_HOOD = 0x10000000
+VEHICLEAREADOOR_REAR = 0x20000000
+
+# VehicleApPowerState
+VEHICLEAPPOWERSTATE_OFF = 0x0
+VEHICLEAPPOWERSTATE_DEEP_SLEEP = 0x1
+VEHICLEAPPOWERSTATE_ON_DISP_OFF = 0x2
+VEHICLEAPPOWERSTATE_ON_FULL = 0x3
+VEHICLEAPPOWERSTATE_SHUTDOWN_PREPARE = 0x4
+
+# VehicleAreaSeat
+VEHICLEAREASEAT_ROW_1_LEFT = 0x1
+VEHICLEAREASEAT_ROW_1_CENTER = 0x2
+VEHICLEAREASEAT_ROW_1_RIGHT = 0x4
+VEHICLEAREASEAT_ROW_2_LEFT = 0x10
+VEHICLEAREASEAT_ROW_2_CENTER = 0x20
+VEHICLEAREASEAT_ROW_2_RIGHT = 0x40
+VEHICLEAREASEAT_ROW_3_LEFT = 0x100
+VEHICLEAREASEAT_ROW_3_CENTER = 0x200
+VEHICLEAREASEAT_ROW_3_RIGHT = 0x400
+
+# Obd2SecondaryAirStatus
+OBD2SECONDARYAIRSTATUS_UPSTREAM = 0x1
+OBD2SECONDARYAIRSTATUS_DOWNSTREAM_OF_CATALYCIC_CONVERTER = 0x2
+OBD2SECONDARYAIRSTATUS_FROM_OUTSIDE_OR_OFF = 0x4
+OBD2SECONDARYAIRSTATUS_PUMP_ON_FOR_DIAGNOSTICS = 0x8
+
+# VehicleRadioConstants
+VEHICLERADIOCONSTANTS_VEHICLE_RADIO_PRESET_MIN_VALUE = 0x1
+
+# VehicleAudioHwVariantConfigFlag
+VEHICLEAUDIOHWVARIANTCONFIGFLAG_INTERNAL_RADIO_FLAG = 0x1
+
+# StatusCode
+STATUSCODE_OK = 0x0
+STATUSCODE_TRY_AGAIN = 0x1
+STATUSCODE_INVALID_ARG = 0x2
+STATUSCODE_NOT_AVAILABLE = 0x3
+STATUSCODE_ACCESS_DENIED = 0x4
+STATUSCODE_INTERNAL_ERROR = 0x5
# Create a container of value_type constants to be used by vhal_emulator
class vhal_types_2_0: