Merge "Rename SensorsHidlEnvironmentBase to SensorsVtsEnvironmentBase"
diff --git a/camera/metadata/3.7/Android.bp b/camera/metadata/3.7/Android.bp
new file mode 100644
index 0000000..a2908ca
--- /dev/null
+++ b/camera/metadata/3.7/Android.bp
@@ -0,0 +1,17 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.camera.metadata@3.7",
+ root: "android.hardware",
+ srcs: [
+ "types.hal",
+ ],
+ interfaces: [
+ "android.hardware.camera.metadata@3.2",
+ "android.hardware.camera.metadata@3.3",
+ "android.hardware.camera.metadata@3.4",
+ "android.hardware.camera.metadata@3.5",
+ "android.hardware.camera.metadata@3.6",
+ ],
+ gen_java: true,
+}
diff --git a/camera/metadata/3.8/Android.bp b/camera/metadata/3.8/Android.bp
new file mode 100644
index 0000000..30068d8
--- /dev/null
+++ b/camera/metadata/3.8/Android.bp
@@ -0,0 +1,18 @@
+// This file is autogenerated by hidl-gen -Landroidbp.
+
+hidl_interface {
+ name: "android.hardware.camera.metadata@3.8",
+ root: "android.hardware",
+ srcs: [
+ "types.hal",
+ ],
+ interfaces: [
+ "android.hardware.camera.metadata@3.2",
+ "android.hardware.camera.metadata@3.3",
+ "android.hardware.camera.metadata@3.4",
+ "android.hardware.camera.metadata@3.5",
+ "android.hardware.camera.metadata@3.6",
+ "android.hardware.camera.metadata@3.7",
+ ],
+ gen_java: true,
+}
diff --git a/camera/metadata/3.8/types.hal b/camera/metadata/3.8/types.hal
index dcee775..b20af18 100644
--- a/camera/metadata/3.8/types.hal
+++ b/camera/metadata/3.8/types.hal
@@ -58,3 +58,11 @@
/*
* Enumeration definitions for the various entries that need them
*/
+
+/** android.control.videoStabilizationMode enumeration values added since v3.2
+ * @see ANDROID_CONTROL_VIDEO_STABILIZATION_MODE
+ */
+enum CameraMetadataEnumAndroidControlVideoStabilizationMode :
+ @3.2::CameraMetadataEnumAndroidControlVideoStabilizationMode {
+ ANDROID_CONTROL_VIDEO_STABILIZATION_MODE_PREVIEW_STABILIZATION,
+};
diff --git a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
index 62de3af..d02547c 100644
--- a/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
+++ b/camera/provider/2.4/vts/functional/VtsHalCameraProviderV2_4TargetTest.cpp
@@ -936,6 +936,9 @@
camera_metadata_ro_entry* streamConfigs,
camera_metadata_ro_entry* maxResolutionStreamConfigs,
const camera_metadata_t* staticMetadata);
+ void getPrivacyTestPatternModes(
+ const camera_metadata_t* staticMetadata,
+ std::unordered_set<int32_t>* privacyTestPatternModes/*out*/);
static bool isColorCamera(const camera_metadata_t *metadata);
static V3_2::DataspaceFlags getDataspace(PixelFormat format);
@@ -6762,6 +6765,25 @@
ASSERT_TRUE(-ENOENT == retcode || 0 == retcode);
}
+void CameraHidlTest::getPrivacyTestPatternModes(
+ const camera_metadata_t* staticMetadata,
+ std::unordered_set<int32_t>* privacyTestPatternModes/*out*/) {
+ ASSERT_NE(staticMetadata, nullptr);
+ ASSERT_NE(privacyTestPatternModes, nullptr);
+
+ camera_metadata_ro_entry entry;
+ int retcode = find_camera_metadata_ro_entry(
+ staticMetadata, ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES, &entry);
+ ASSERT_TRUE(0 == retcode);
+
+ for (auto i = 0; i < entry.count; i++) {
+ if (entry.data.i32[i] == ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR ||
+ entry.data.i32[i] == ANDROID_SENSOR_TEST_PATTERN_MODE_BLACK) {
+ privacyTestPatternModes->insert(entry.data.i32[i]);
+ }
+ }
+}
+
// Select an appropriate dataspace given a specific pixel format.
V3_2::DataspaceFlags CameraHidlTest::getDataspace(PixelFormat format) {
switch (format) {
@@ -7816,6 +7838,16 @@
ASSERT_TRUE(isUltraHighResCamera && !isMultiCamera);
physicalIds.insert(cameraId);
}
+
+ std::unordered_set<int32_t> physicalRequestKeyIDs;
+ rc = getSupportedKeys(const_cast<camera_metadata_t *>(metadata),
+ ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS, &physicalRequestKeyIDs);
+ ASSERT_TRUE(Status::OK == rc);
+ bool hasTestPatternPhysicalRequestKey = physicalRequestKeyIDs.find(
+ ANDROID_SENSOR_TEST_PATTERN_MODE) != physicalRequestKeyIDs.end();
+ std::unordered_set<int32_t> privacyTestPatternModes;
+ getPrivacyTestPatternModes(metadata, &privacyTestPatternModes);
+
// Map from image format to number of multi-resolution sizes for that format
std::unordered_map<int32_t, size_t> multiResOutputFormatCounterMap;
std::unordered_map<int32_t, size_t> multiResInputFormatCounterMap;
@@ -7837,6 +7869,7 @@
camera_metadata_ro_entry physicalStreamConfigs;
camera_metadata_ro_entry physicalMaxResolutionStreamConfigs;
bool isUltraHighRes = false;
+ std::unordered_set<int32_t> subCameraPrivacyTestPatterns;
if (isPublicId) {
::android::sp<::android::hardware::camera::device::V3_2::ICameraDevice> subDevice;
Return<void> ret;
@@ -7867,6 +7900,8 @@
&physicalMultiResStreamConfigs, &physicalStreamConfigs,
&physicalMaxResolutionStreamConfigs, staticMetadata);
isUltraHighRes = isUltraHighResolution(staticMetadata);
+
+ getPrivacyTestPatternModes(staticMetadata, &subCameraPrivacyTestPatterns);
});
ASSERT_TRUE(ret.isOk());
} else {
@@ -7893,6 +7928,7 @@
&physicalMultiResStreamConfigs, &physicalStreamConfigs,
&physicalMaxResolutionStreamConfigs, staticMetadata);
isUltraHighRes = isUltraHighResolution(staticMetadata);
+ getPrivacyTestPatternModes(staticMetadata, &subCameraPrivacyTestPatterns);
});
ASSERT_TRUE(ret.isOk());
@@ -7909,6 +7945,10 @@
ASSERT_TRUE(ret.isOk());
}
+ if (hasTestPatternPhysicalRequestKey) {
+ ASSERT_TRUE(privacyTestPatternModes == subCameraPrivacyTestPatterns);
+ }
+
if (physicalMultiResStreamConfigs.count > 0) {
ASSERT_GE(deviceVersion, CAMERA_DEVICE_API_VERSION_3_7);
ASSERT_EQ(physicalMultiResStreamConfigs.count % 4, 0);
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 5e65849..5d92304 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -248,6 +248,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.gnss</name>
+ <version>2</version>
<interface>
<name>IGnss</name>
<instance>default</instance>
diff --git a/gnss/1.1/default/Android.bp b/gnss/1.1/default/Android.bp
index 3c9c29a..a73182e 100644
--- a/gnss/1.1/default/Android.bp
+++ b/gnss/1.1/default/Android.bp
@@ -27,7 +27,7 @@
"android.hardware.gnss@2.0",
"android.hardware.gnss@1.1",
"android.hardware.gnss@1.0",
- "android.hardware.gnss-V1-ndk",
+ "android.hardware.gnss-V2-ndk",
],
static_libs: [
"android.hardware.gnss@common-default-lib",
diff --git a/gnss/2.0/default/Android.bp b/gnss/2.0/default/Android.bp
index 695246a..769e8ae 100644
--- a/gnss/2.0/default/Android.bp
+++ b/gnss/2.0/default/Android.bp
@@ -50,7 +50,7 @@
"android.hardware.gnss@2.0",
"android.hardware.gnss@1.1",
"android.hardware.gnss@1.0",
- "android.hardware.gnss-V1-ndk",
+ "android.hardware.gnss-V2-ndk",
],
static_libs: [
"android.hardware.gnss@common-default-lib",
diff --git a/gnss/2.1/default/Android.bp b/gnss/2.1/default/Android.bp
index c46c735..2979f5c 100644
--- a/gnss/2.1/default/Android.bp
+++ b/gnss/2.1/default/Android.bp
@@ -44,7 +44,7 @@
"android.hardware.gnss@1.0",
"android.hardware.gnss@1.1",
"android.hardware.gnss@2.0",
- "android.hardware.gnss-V1-ndk",
+ "android.hardware.gnss-V2-ndk",
],
static_libs: [
"android.hardware.gnss@common-default-lib",
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssLocation.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssLocation.aidl
new file mode 100644
index 0000000..54c126c
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/GnssLocation.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+parcelable GnssLocation {
+ int gnssLocationFlags;
+ double latitudeDegrees;
+ double longitudeDegrees;
+ double altitudeMeters;
+ double speedMetersPerSec;
+ double bearingDegrees;
+ double horizontalAccuracyMeters;
+ double verticalAccuracyMeters;
+ double speedAccuracyMetersPerSecond;
+ double bearingAccuracyDegrees;
+ long timestampMillis;
+ android.hardware.gnss.ElapsedRealtime elapsedRealtime;
+ const int HAS_LAT_LONG = 1;
+ const int HAS_ALTITUDE = 2;
+ const int HAS_SPEED = 4;
+ const int HAS_BEARING = 8;
+ const int HAS_HORIZONTAL_ACCURACY = 16;
+ const int HAS_VERTICAL_ACCURACY = 32;
+ const int HAS_SPEED_ACCURACY = 64;
+ const int HAS_BEARING_ACCURACY = 128;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
index f93b496..52276b4 100644
--- a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnss.aidl
@@ -36,10 +36,11 @@
interface IGnss {
void setCallback(in android.hardware.gnss.IGnssCallback callback);
void close();
- android.hardware.gnss.IGnssPsds getExtensionPsds();
+ @nullable android.hardware.gnss.IGnssPsds getExtensionPsds();
android.hardware.gnss.IGnssConfiguration getExtensionGnssConfiguration();
android.hardware.gnss.IGnssMeasurementInterface getExtensionGnssMeasurement();
android.hardware.gnss.IGnssPowerIndication getExtensionGnssPowerIndication();
+ @nullable android.hardware.gnss.IGnssBatching getExtensionGnssBatching();
const int ERROR_INVALID_ARGUMENT = 1;
const int ERROR_ALREADY_INIT = 2;
const int ERROR_GENERIC = 3;
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatching.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatching.aidl
new file mode 100644
index 0000000..492edc3
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatching.aidl
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+interface IGnssBatching {
+ void init(in android.hardware.gnss.IGnssBatchingCallback callback);
+ int getBatchSize();
+ void start(in long periodNanos, in int flags);
+ void flush();
+ void stop();
+ void cleanup();
+ const int WAKEUP_ON_FIFO_FULL = 1;
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatchingCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatchingCallback.aidl
new file mode 100644
index 0000000..427137a
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssBatchingCallback.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.gnss;
+@VintfStability
+interface IGnssBatchingCallback {
+ void gnssLocationBatchCb(in android.hardware.gnss.GnssLocation[] locations);
+}
diff --git a/gnss/aidl/android/hardware/gnss/GnssLocation.aidl b/gnss/aidl/android/hardware/gnss/GnssLocation.aidl
new file mode 100644
index 0000000..25aea4d
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/GnssLocation.aidl
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2021 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.hardware.gnss;
+
+import android.hardware.gnss.ElapsedRealtime;
+
+/** Represents a location. */
+@VintfStability
+parcelable GnssLocation {
+ /** Bit mask to indicate GnssLocation has valid latitude and longitude. */
+ const int HAS_LAT_LONG = 0x0001;
+ /** Bit mask to indicate GnssLocation has valid altitude. */
+ const int HAS_ALTITUDE = 0x0002;
+ /** Bit mask to indicate GnssLocation has valid speed. */
+ const int HAS_SPEED = 0x0004;
+ /** Bit mask to indicate GnssLocation has valid bearing. */
+ const int HAS_BEARING = 0x0008;
+ /** Bit mask to indicate GnssLocation has valid horizontal accuracy. */
+ const int HAS_HORIZONTAL_ACCURACY = 0x0010;
+ /** Bit mask to indicate GnssLocation has valid vertical accuracy. */
+ const int HAS_VERTICAL_ACCURACY = 0x0020;
+ /** Bit mask to indicate GnssLocation has valid speed accuracy. */
+ const int HAS_SPEED_ACCURACY = 0x0040;
+ /** Bit mask to indicate GnssLocation has valid bearing accuracy. */
+ const int HAS_BEARING_ACCURACY = 0x0080;
+
+ /** A bit field of flags indicating the validity of the fields in this GnssLocation. */
+ int gnssLocationFlags;
+
+ /** Represents latitude in degrees. */
+ double latitudeDegrees;
+
+ /** Represents longitude in degrees. */
+ double longitudeDegrees;
+
+ /** Represents altitude in meters above the WGS 84 reference ellipsoid. */
+ double altitudeMeters;
+
+ /** Represents speed in meters per second. */
+ double speedMetersPerSec;
+
+ /** Represents heading in degrees. */
+ double bearingDegrees;
+
+ /**
+ * Represents expected horizontal position accuracy, radial, in meters (68% confidence).
+ */
+ double horizontalAccuracyMeters;
+
+ /**
+ * Represents expected vertical position accuracy in meters (68% confidence).
+ */
+ double verticalAccuracyMeters;
+
+ /**
+ * Represents expected speed accuracy in meter per seconds (68% confidence).
+ */
+ double speedAccuracyMetersPerSecond;
+
+ /**
+ * Represents expected bearing accuracy in degrees (68% confidence).
+ */
+ double bearingAccuracyDegrees;
+
+ /** Timestamp for the location fix in milliseconds since January 1, 1970. */
+ long timestampMillis;
+
+ /**
+ * Timing information of the GNSS location synchronized with SystemClock.elapsedRealtimeNanos()
+ * clock.
+ *
+ * This clock information can be obtained from SystemClock.elapsedRealtimeNanos(), when the GNSS
+ * is attached straight to the AP/SOC. When it is attached to a separate module the timestamp
+ * needs to be estimated by syncing the notion of time via PTP or some other mechanism.
+ */
+ ElapsedRealtime elapsedRealtime;
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index f99b512..b12fb82 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -16,6 +16,7 @@
package android.hardware.gnss;
+import android.hardware.gnss.IGnssBatching;
import android.hardware.gnss.IGnssCallback;
import android.hardware.gnss.IGnssConfiguration;
import android.hardware.gnss.IGnssMeasurementInterface;
@@ -27,9 +28,8 @@
*/
@VintfStability
interface IGnss {
-
/**
- * All GNSS Binder calls may return a ServiceSpecificException with the following error
+ * All GNSS binder calls may return a ServiceSpecificException with the following error
* codes.
*/
const int ERROR_INVALID_ARGUMENT = 1;
@@ -73,11 +73,9 @@
/**
* This method returns the IGnssPsds interface.
*
- * This method must return non-null.
- *
* @return Handle to the IGnssPsds interface.
*/
- IGnssPsds getExtensionPsds();
+ @nullable IGnssPsds getExtensionPsds();
/**
* This method returns the IGnssConfiguration interface.
@@ -89,7 +87,7 @@
IGnssConfiguration getExtensionGnssConfiguration();
/**
- * This methods returns the IGnssMeasurementInterface interface.
+ * This method returns the IGnssMeasurementInterface interface.
*
* This method must return non-null.
*
@@ -105,4 +103,11 @@
* @return Handle to the IGnssPowerIndication interface.
*/
IGnssPowerIndication getExtensionGnssPowerIndication();
+
+ /**
+ * This method returns the IGnssBatching interface.
+ *
+ * @return Handle to the IGnssBatching interface.
+ */
+ @nullable IGnssBatching getExtensionGnssBatching();
}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssBatching.aidl b/gnss/aidl/android/hardware/gnss/IGnssBatching.aidl
new file mode 100644
index 0000000..0d48ee1
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssBatching.aidl
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2021 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.hardware.gnss;
+
+import android.hardware.gnss.IGnssBatchingCallback;
+
+/**
+ * Extended interface for GNSS Batching support.
+ *
+ * If this interface is supported, this batching request must be able to run in parallel with, or
+ * without, non-batched location requested by the IGnss start() & stop() - i.e. both requests must
+ * be handled independently, and not interfere with each other.
+ *
+ * For example, if a 1Hz continuous output is underway on the IGnssCallback, due to an IGnss start()
+ * operation, and then a IGnssBatching start() is called for a location every 10 seconds, the newly
+ * added batching request must not disrupt the 1Hz continuous location output on the IGnssCallback.
+ *
+ * As with GNSS Location outputs, source of location must be GNSS satellite measurements, optionally
+ * using interial and baro sensors to improve relative motion filtering. No additional absolute
+ * positioning information, such as WiFi derived location, may be mixed with the GNSS information.
+ */
+@VintfStability
+interface IGnssBatching {
+ /**
+ * Bit mask indicating batching supports wake up and flush when FIFO is full.
+ *
+ * If this flag is set, the hardware implementation must wake up the application processor when
+ * the FIFO is full, and call IGnssBatchingCallback to return the locations.
+ *
+ * If the flag is not set, the hardware implementation must drop the oldest data when the FIFO
+ * is full.
+ */
+ const int WAKEUP_ON_FIFO_FULL = 0x01;
+
+ /**
+ * Open the interface and provides the callback routines to the implementation of this
+ * interface.
+ *
+ * @param callback Callback interface for IGnssBatching.
+ */
+ void init(in IGnssBatchingCallback callback);
+
+ /**
+ * Return the batch size (in number of GnssLocation objects) available in this hardware
+ * implementation.
+ *
+ * If the available size is variable, for example, based on other operations consuming memory,
+ * this is the minimum size guaranteed to be available for batching operations.
+ *
+ * This may, for example, be used by the client, to decide on the batching interval and whether
+ * the AP should be woken up or not.
+ *
+ * @return the number of location objects supported per batch
+ */
+ int getBatchSize();
+
+ /**
+ * Start batching locations. This API is primarily used when the AP is asleep and the device can
+ * batch locations in the hardware.
+ *
+ * The implementation must invoke IGnssBatchingCallback, provided in init(), to return the
+ * location.
+ *
+ * When the buffer is full and WAKEUP_ON_FIFO_FULL is used, IGnssBatchingCallback must be called
+ * to return the locations.
+ *
+ * When the buffer is full and WAKEUP_ON_FIFO_FULL is not set, the oldest location object is
+ * dropped. In this case the AP must not be woken up. The AP would then generally be responsible
+ * for using flushBatchedLocation to explicitly ask for the location as needed, to avoid it
+ * being dropped.
+ *
+ * @param periodNanos Time interval between samples in the location batch, in nanoseconds
+ * @param flags A bitfield of flags (WAKEUP_ON_FIFO_FULL) indicating the batching behavior
+ */
+ void start(in long periodNanos, in int flags);
+
+ /**
+ * Retrieve all batched locations currently stored.
+ *
+ * The implementation must invoke IGnssBatchingCallback, provided in init(), to return the
+ * location.
+ *
+ * IGnssBatchingCallback must be called in response, even if there are no locations to flush
+ * (in which case the Location vector must be empty).
+ *
+ * Subsequent calls to flush must not return any of the locations returned in this call.
+ */
+ void flush();
+
+ /**
+ * Stop batching.
+ */
+ void stop();
+
+ /**
+ * Closes the interface. If any batch operations are in progress, they must be stopped. If any
+ * locations are in the hardware batch, they must be deleted (and not sent via callback.)
+ *
+ * init() may be called again, after this, if the interface is to be restored
+ */
+ void cleanup();
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssBatchingCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssBatchingCallback.aidl
new file mode 100644
index 0000000..b1bfc57
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssBatchingCallback.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 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.hardware.gnss;
+
+import android.hardware.gnss.GnssLocation;
+
+/** The callback interface to report batched GNSS locations from the HAL. */
+@VintfStability
+interface IGnssBatchingCallback {
+ /**
+ * Called when a batch of locations is output, by various means, including
+ * a flush request, as well as the buffer becoming full (if appropriate option
+ * is set.)
+ *
+ * All locations returned by this callback must be cleared from the hardware
+ * buffer, such the sequential calls of this callback do not return any
+ * redundant locations. (Same lat/lon, at a new time, is acceptable.)
+ *
+ * @param locations A list of GNSS Locations
+ */
+ void gnssLocationBatchCb(in GnssLocation[] locations);
+}
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index c028dd7..892ad15 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -52,10 +52,11 @@
"android.hardware.gnss.measurement_corrections@1.1",
"android.hardware.gnss.measurement_corrections@1.0",
"android.hardware.gnss.visibility_control@1.0",
- "android.hardware.gnss-V1-ndk",
+ "android.hardware.gnss-V2-ndk",
],
srcs: [
"Gnss.cpp",
+ "GnssBatching.cpp",
"GnssHidlHal.cpp",
"GnssPowerIndication.cpp",
"GnssPsds.cpp",
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index 6061eec..fbfa2bb 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -18,6 +18,7 @@
#include "Gnss.h"
#include <log/log.h>
+#include "GnssBatching.h"
#include "GnssConfiguration.h"
#include "GnssMeasurementInterface.h"
#include "GnssPsds.h"
@@ -88,4 +89,11 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Gnss::getExtensionGnssBatching(std::shared_ptr<IGnssBatching>* iGnssBatching) {
+ ALOGD("Gnss::getExtensionGnssBatching");
+
+ *iGnssBatching = SharedRefBase::make<GnssBatching>();
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index 76ebe4d..3959ef8 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -17,6 +17,7 @@
#pragma once
#include <aidl/android/hardware/gnss/BnGnss.h>
+#include <aidl/android/hardware/gnss/BnGnssBatching.h>
#include <aidl/android/hardware/gnss/BnGnssConfiguration.h>
#include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
#include <aidl/android/hardware/gnss/BnGnssPowerIndication.h>
@@ -37,6 +38,8 @@
std::shared_ptr<IGnssPowerIndication>* iGnssPowerIndication) override;
ndk::ScopedAStatus getExtensionGnssMeasurement(
std::shared_ptr<IGnssMeasurementInterface>* iGnssMeasurement) override;
+ ndk::ScopedAStatus getExtensionGnssBatching(
+ std::shared_ptr<IGnssBatching>* iGnssBatching) override;
std::shared_ptr<GnssConfiguration> mGnssConfiguration;
std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
diff --git a/gnss/aidl/default/GnssBatching.cpp b/gnss/aidl/default/GnssBatching.cpp
new file mode 100644
index 0000000..b8be5e5
--- /dev/null
+++ b/gnss/aidl/default/GnssBatching.cpp
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#define LOG_TAG "GnssBatchingAidl"
+
+#include "GnssBatching.h"
+#include <aidl/android/hardware/gnss/BnGnss.h>
+#include <inttypes.h>
+#include <log/log.h>
+#include <utils/SystemClock.h>
+#include "Utils.h"
+
+namespace aidl::android::hardware::gnss {
+
+using namespace ::android::hardware::gnss;
+
+constexpr int BATCH_SIZE = 10;
+
+std::shared_ptr<IGnssBatchingCallback> GnssBatching::sCallback = nullptr;
+
+GnssBatching::GnssBatching()
+ : mMinIntervalMs(1000),
+ mWakeUpOnFifoFull(false),
+ mBatchedLocations(std::vector<GnssLocation>()) {}
+GnssBatching::~GnssBatching() {
+ cleanup();
+}
+
+ndk::ScopedAStatus GnssBatching::init(const std::shared_ptr<IGnssBatchingCallback>& callback) {
+ ALOGD("init");
+ std::unique_lock<std::mutex> lock(mMutex);
+ sCallback = callback;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssBatching::getBatchSize(int* size) {
+ ALOGD("getBatchingSize");
+ *size = BATCH_SIZE;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssBatching::start(int64_t periodNanos, int flags) {
+ ALOGD("start: periodNanos=%" PRId64 ", flags=%d", periodNanos, flags);
+ if (mIsActive) {
+ ALOGW("Gnss has started. Restarting...");
+ stop();
+ }
+
+ mWakeUpOnFifoFull = (flags & IGnssBatching::WAKEUP_ON_FIFO_FULL) ? true : false;
+ // mMinIntervalMs is not smaller than 1 sec
+ periodNanos = (periodNanos < 1e9) ? 1e9 : periodNanos;
+ mMinIntervalMs = periodNanos / 1e6;
+
+ mIsActive = true;
+ mThread = std::thread([this]() {
+ while (mIsActive == true) {
+ const auto location = common::Utils::getMockLocation();
+ this->batchLocation(location);
+ std::this_thread::sleep_for(std::chrono::milliseconds(mMinIntervalMs));
+ }
+ });
+
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssBatching::flush() {
+ ALOGD("flush");
+ std::vector<GnssLocation> copy = std::vector<GnssLocation>(mBatchedLocations);
+ ndk::ScopedAStatus status;
+ if (sCallback != nullptr) {
+ sCallback->gnssLocationBatchCb(copy);
+ status = ndk::ScopedAStatus::ok();
+ } else {
+ ALOGE("GnssBatchingCallback is null. flush() failed.");
+ status = ndk::ScopedAStatus::fromServiceSpecificError(IGnss::ERROR_GENERIC);
+ }
+ mBatchedLocations.clear();
+ return status;
+}
+
+ndk::ScopedAStatus GnssBatching::stop() {
+ ALOGD("stop");
+ // Do not call flush() at stop()
+ mIsActive = false;
+ if (mThread.joinable()) {
+ mThread.join();
+ }
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssBatching::cleanup() {
+ ALOGD("cleanup");
+ std::unique_lock<std::mutex> lock(mMutex);
+ if (mIsActive) {
+ stop();
+ }
+ flush();
+
+ sCallback = nullptr;
+ return ndk::ScopedAStatus::ok();
+}
+
+void GnssBatching::batchLocation(const GnssLocation& location) {
+ if (mBatchedLocations.size() > BATCH_SIZE) {
+ mBatchedLocations.erase(mBatchedLocations.begin());
+ }
+ mBatchedLocations.push_back(location);
+ if (mWakeUpOnFifoFull && mBatchedLocations.size() == BATCH_SIZE) {
+ flush();
+ }
+}
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssBatching.h b/gnss/aidl/default/GnssBatching.h
new file mode 100644
index 0000000..7cd6e85
--- /dev/null
+++ b/gnss/aidl/default/GnssBatching.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <aidl/android/hardware/gnss/BnGnssBatching.h>
+#include <atomic>
+#include <thread>
+
+namespace aidl::android::hardware::gnss {
+
+struct GnssBatching : public BnGnssBatching {
+ public:
+ GnssBatching();
+ ~GnssBatching();
+ ndk::ScopedAStatus init(const std::shared_ptr<IGnssBatchingCallback>& callback) override;
+ ndk::ScopedAStatus getBatchSize(int* size) override;
+ ndk::ScopedAStatus start(int64_t periodNanos, int flags) override;
+ ndk::ScopedAStatus flush() override;
+ ndk::ScopedAStatus stop() override;
+ ndk::ScopedAStatus cleanup() override;
+
+ private:
+ void batchLocation(const GnssLocation&);
+
+ // Guarded by mMutex
+ static std::shared_ptr<IGnssBatchingCallback> sCallback;
+
+ std::thread mThread;
+ std::atomic<bool> mIsActive;
+ std::atomic<long> mMinIntervalMs;
+ std::atomic<bool> mWakeUpOnFifoFull;
+
+ // Synchronization lock for sCallback
+ mutable std::mutex mMutex;
+
+ std::vector<GnssLocation> mBatchedLocations;
+};
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/gnss-default.xml b/gnss/aidl/default/gnss-default.xml
index 2b06cd2..7449310 100644
--- a/gnss/aidl/default/gnss-default.xml
+++ b/gnss/aidl/default/gnss-default.xml
@@ -1,6 +1,7 @@
<manifest version="1.0" type="device">
<hal format="aidl">
<name>android.hardware.gnss</name>
+ <version>2</version>
<interface>
<name>IGnss</name>
<instance>default</instance>
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
index 838849d..6096d4d 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -30,6 +30,7 @@
srcs: [
"gnss_hal_test.cpp",
"gnss_hal_test_cases.cpp",
+ "GnssBatchingCallback.cpp",
"GnssCallbackAidl.cpp",
"GnssMeasurementCallbackAidl.cpp",
"GnssPowerIndicationCallback.cpp",
@@ -43,7 +44,7 @@
"libbinder",
],
static_libs: [
- "android.hardware.gnss-V1-cpp",
+ "android.hardware.gnss-V2-cpp",
"android.hardware.gnss@common-vts-lib",
],
test_suites: [
diff --git a/gnss/aidl/vts/GnssBatchingCallback.cpp b/gnss/aidl/vts/GnssBatchingCallback.cpp
new file mode 100644
index 0000000..2da3b12
--- /dev/null
+++ b/gnss/aidl/vts/GnssBatchingCallback.cpp
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include "GnssBatchingCallback.h"
+#include <inttypes.h>
+#include <log/log.h>
+
+android::binder::Status GnssBatchingCallback::gnssLocationBatchCb(
+ const std::vector<android::hardware::gnss::GnssLocation>& locations) {
+ ALOGI("Batched locations received with size=%d", (int)locations.size());
+ for (const auto& location : locations) {
+ ALOGI("elapsedRealtime: flags = %d, timestampNs: %" PRId64 ", timeUncertaintyNs=%lf",
+ location.elapsedRealtime.flags, location.elapsedRealtime.timestampNs,
+ location.elapsedRealtime.timeUncertaintyNs);
+ }
+ batched_locations_cbq_.store(locations);
+ return android::binder::Status::ok();
+}
diff --git a/gnss/aidl/vts/GnssBatchingCallback.h b/gnss/aidl/vts/GnssBatchingCallback.h
new file mode 100644
index 0000000..310a134
--- /dev/null
+++ b/gnss/aidl/vts/GnssBatchingCallback.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/BnGnssBatchingCallback.h>
+#include <vector>
+#include "GnssCallbackEventQueue.h"
+
+/** Implementation for IGnssBatchingCallback. */
+class GnssBatchingCallback : public android::hardware::gnss::BnGnssBatchingCallback {
+ public:
+ GnssBatchingCallback() : batched_locations_cbq_("batched_locations") {}
+ ~GnssBatchingCallback() {}
+
+ android::binder::Status gnssLocationBatchCb(
+ const std::vector<android::hardware::gnss::GnssLocation>& locations) override;
+
+ android::hardware::gnss::common::GnssCallbackEventQueue<
+ std::vector<android::hardware::gnss::GnssLocation>>
+ batched_locations_cbq_;
+ std::vector<android::hardware::gnss::GnssLocation> last_batched_locations_;
+};
diff --git a/gnss/aidl/vts/gnss_hal_test.h b/gnss/aidl/vts/gnss_hal_test.h
index f72f7fe..e3ecbed 100644
--- a/gnss/aidl/vts/gnss_hal_test.h
+++ b/gnss/aidl/vts/gnss_hal_test.h
@@ -23,6 +23,7 @@
#include <binder/IServiceManager.h>
#include <android/hardware/gnss/2.1/IGnss.h>
+#include "GnssBatchingCallback.h"
#include "GnssCallbackAidl.h"
#include "v2_1/gnss_hal_test_template.h"
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 0cd782e..86140cc 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -17,10 +17,12 @@
#define LOG_TAG "GnssHalTestCases"
#include <android/hardware/gnss/IGnss.h>
+#include <android/hardware/gnss/IGnssBatching.h>
#include <android/hardware/gnss/IGnssMeasurementCallback.h>
#include <android/hardware/gnss/IGnssMeasurementInterface.h>
#include <android/hardware/gnss/IGnssPowerIndication.h>
#include <android/hardware/gnss/IGnssPsds.h>
+#include "GnssBatchingCallback.h"
#include "GnssMeasurementCallbackAidl.h"
#include "GnssPowerIndicationCallback.h"
#include "gnss_hal_test.h"
@@ -33,6 +35,8 @@
using android::hardware::gnss::GnssMeasurement;
using android::hardware::gnss::GnssPowerStats;
using android::hardware::gnss::IGnss;
+using android::hardware::gnss::IGnssBatching;
+using android::hardware::gnss::IGnssBatchingCallback;
using android::hardware::gnss::IGnssConfiguration;
using android::hardware::gnss::IGnssMeasurementCallback;
using android::hardware::gnss::IGnssMeasurementInterface;
@@ -749,3 +753,25 @@
status = gnss_configuration_hal->setBlocklist(sources);
ASSERT_TRUE(status.isOk());
}
+
+/*
+ * TestGnssBatchingExtension:
+ * 1. Gets the IGnssBatching extension.
+ * 2. Initializes the interface with an IGnssBatchingCallback.
+ * 3. Clean up.
+ */
+TEST_P(GnssHalTest, TestGnssBatchingExtension) {
+ sp<IGnssBatching> iGnssBatching;
+ auto status = aidl_gnss_hal_->getExtensionGnssBatching(&iGnssBatching);
+ if (!status.isOk() || iGnssBatching == nullptr) {
+ // Device doesn't support batching. Skip the test.
+ return;
+ }
+
+ sp<IGnssBatchingCallback> iGnssBatchingCallback;
+ status = iGnssBatching->init(iGnssBatchingCallback);
+ ASSERT_TRUE(status.isOk());
+
+ status = iGnssBatching->cleanup();
+ ASSERT_TRUE(status.isOk());
+}
diff --git a/gnss/common/utils/default/Android.bp b/gnss/common/utils/default/Android.bp
index 5294409..05bec88 100644
--- a/gnss/common/utils/default/Android.bp
+++ b/gnss/common/utils/default/Android.bp
@@ -56,6 +56,6 @@
"android.hardware.gnss@2.1",
"android.hardware.gnss.measurement_corrections@1.1",
"android.hardware.gnss.measurement_corrections@1.0",
- "android.hardware.gnss-V1-ndk",
+ "android.hardware.gnss-V2-ndk",
],
}
diff --git a/gnss/common/utils/default/Utils.cpp b/gnss/common/utils/default/Utils.cpp
index dfcf9a9..c339e72 100644
--- a/gnss/common/utils/default/Utils.cpp
+++ b/gnss/common/utils/default/Utils.cpp
@@ -28,6 +28,7 @@
using aidl::android::hardware::gnss::ElapsedRealtime;
using aidl::android::hardware::gnss::GnssClock;
using aidl::android::hardware::gnss::GnssData;
+using aidl::android::hardware::gnss::GnssLocation;
using aidl::android::hardware::gnss::GnssMeasurement;
using aidl::android::hardware::gnss::IGnss;
using aidl::android::hardware::gnss::IGnssMeasurementCallback;
@@ -232,6 +233,30 @@
return gnssData;
}
+GnssLocation Utils::getMockLocation() {
+ ElapsedRealtime elapsedRealtime = {
+ .flags = ElapsedRealtime::HAS_TIMESTAMP_NS | ElapsedRealtime::HAS_TIME_UNCERTAINTY_NS,
+ .timestampNs = ::android::elapsedRealtimeNano(),
+ // This is an hardcoded value indicating a 1ms of uncertainty between the two clocks.
+ // In an actual implementation provide an estimate of the synchronization uncertainty
+ // or don't set the field.
+ .timeUncertaintyNs = 1020400};
+ GnssLocation location = {.gnssLocationFlags = 0xFF,
+ .latitudeDegrees = gMockLatitudeDegrees,
+ .longitudeDegrees = gMockLongitudeDegrees,
+ .altitudeMeters = gMockAltitudeMeters,
+ .speedMetersPerSec = gMockSpeedMetersPerSec,
+ .bearingDegrees = gMockBearingDegrees,
+ .horizontalAccuracyMeters = kMockHorizontalAccuracyMeters,
+ .verticalAccuracyMeters = kMockVerticalAccuracyMeters,
+ .speedAccuracyMetersPerSecond = kMockSpeedAccuracyMetersPerSecond,
+ .bearingAccuracyDegrees = kMockBearingAccuracyDegrees,
+ .timestampMillis = static_cast<int64_t>(
+ kMockTimestamp + ::android::elapsedRealtimeNano() / 1e6),
+ .elapsedRealtime = elapsedRealtime};
+ return location;
+}
+
V2_0::GnssLocation Utils::getMockLocationV2_0() {
const V2_0::ElapsedRealtime timestamp = {
.flags = V2_0::ElapsedRealtimeFlags::HAS_TIMESTAMP_NS |
diff --git a/gnss/common/utils/default/include/Utils.h b/gnss/common/utils/default/include/Utils.h
index 43772ce..4500ee6 100644
--- a/gnss/common/utils/default/include/Utils.h
+++ b/gnss/common/utils/default/include/Utils.h
@@ -17,6 +17,7 @@
#ifndef android_hardware_gnss_common_default_Utils_H_
#define android_hardware_gnss_common_default_Utils_H_
+#include <aidl/android/hardware/gnss/BnGnss.h>
#include <aidl/android/hardware/gnss/BnGnssMeasurementInterface.h>
#include <android/hardware/gnss/1.0/IGnss.h>
#include <android/hardware/gnss/2.0/IGnss.h>
@@ -34,6 +35,7 @@
const bool enableCorrVecOutputs);
static V2_0::IGnssMeasurementCallback::GnssData getMockMeasurementV2_0();
static V2_1::IGnssMeasurementCallback::GnssData getMockMeasurementV2_1();
+ static aidl::android::hardware::gnss::GnssLocation getMockLocation();
static V2_0::GnssLocation getMockLocationV2_0();
static V1_0::GnssLocation getMockLocationV1_0();
static hidl_vec<V2_1::IGnssCallback::GnssSvInfo> getMockSvInfoListV2_1();
diff --git a/gnss/common/utils/vts/Utils.cpp b/gnss/common/utils/vts/Utils.cpp
index 9c84e80..be22ff6 100644
--- a/gnss/common/utils/vts/Utils.cpp
+++ b/gnss/common/utils/vts/Utils.cpp
@@ -24,12 +24,10 @@
namespace gnss {
namespace common {
-using GnssConstellationType_V1_0 = V1_0::GnssConstellationType;
-using GnssConstellationType_V2_0 = V2_0::GnssConstellationType;
-
+using namespace measurement_corrections::V1_0;
using V1_0::GnssLocationFlags;
-void Utils::checkLocation(const GnssLocation& location, bool check_speed,
+void Utils::checkLocation(const V1_0::GnssLocation& location, bool check_speed,
bool check_more_accuracies) {
EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_LAT_LONG);
EXPECT_TRUE(location.gnssLocationFlags & GnssLocationFlags::HAS_ALTITUDE);
@@ -96,7 +94,7 @@
EXPECT_GT(location.timestamp, 1.48e12);
}
-const MeasurementCorrections_1_0 Utils::getMockMeasurementCorrections() {
+const MeasurementCorrections Utils::getMockMeasurementCorrections() {
ReflectingPlane reflectingPlane = {
.latitudeDegrees = 37.4220039,
.longitudeDegrees = -122.0840991,
@@ -104,12 +102,12 @@
.azimuthDegrees = 203.0,
};
- SingleSatCorrection_V1_0 singleSatCorrection1 = {
+ SingleSatCorrection singleSatCorrection1 = {
.singleSatCorrectionFlags = GnssSingleSatCorrectionFlags::HAS_SAT_IS_LOS_PROBABILITY |
GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH |
GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH_UNC |
GnssSingleSatCorrectionFlags::HAS_REFLECTING_PLANE,
- .constellation = GnssConstellationType_V1_0::GPS,
+ .constellation = V1_0::GnssConstellationType::GPS,
.svid = 12,
.carrierFrequencyHz = 1.59975e+09,
.probSatIsLos = 0.50001,
@@ -117,11 +115,11 @@
.excessPathLengthUncertaintyMeters = 25.5,
.reflectingPlane = reflectingPlane,
};
- SingleSatCorrection_V1_0 singleSatCorrection2 = {
+ SingleSatCorrection singleSatCorrection2 = {
.singleSatCorrectionFlags = GnssSingleSatCorrectionFlags::HAS_SAT_IS_LOS_PROBABILITY |
GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH |
GnssSingleSatCorrectionFlags::HAS_EXCESS_PATH_LENGTH_UNC,
- .constellation = GnssConstellationType_V1_0::GPS,
+ .constellation = V1_0::GnssConstellationType::GPS,
.svid = 9,
.carrierFrequencyHz = 1.59975e+09,
.probSatIsLos = 0.873,
@@ -129,9 +127,9 @@
.excessPathLengthUncertaintyMeters = 10.0,
};
- hidl_vec<SingleSatCorrection_V1_0> singleSatCorrections = {singleSatCorrection1,
- singleSatCorrection2};
- MeasurementCorrections_1_0 mockCorrections = {
+ hidl_vec<SingleSatCorrection> singleSatCorrections = {singleSatCorrection1,
+ singleSatCorrection2};
+ MeasurementCorrections mockCorrections = {
.latitudeDegrees = 37.4219999,
.longitudeDegrees = -122.0840575,
.altitudeMeters = 30.60062531,
@@ -143,25 +141,26 @@
return mockCorrections;
}
-const MeasurementCorrections_1_1 Utils::getMockMeasurementCorrections_1_1() {
- MeasurementCorrections_1_0 mockCorrections_1_0 = getMockMeasurementCorrections();
+const measurement_corrections::V1_1::MeasurementCorrections
+Utils::getMockMeasurementCorrections_1_1() {
+ MeasurementCorrections mockCorrections_1_0 = getMockMeasurementCorrections();
- SingleSatCorrection_V1_1 singleSatCorrection1 = {
+ measurement_corrections::V1_1::SingleSatCorrection singleSatCorrection1 = {
.v1_0 = mockCorrections_1_0.satCorrections[0],
- .constellation = GnssConstellationType_V2_0::IRNSS,
+ .constellation = V2_0::GnssConstellationType::IRNSS,
};
- SingleSatCorrection_V1_1 singleSatCorrection2 = {
+ measurement_corrections::V1_1::SingleSatCorrection singleSatCorrection2 = {
.v1_0 = mockCorrections_1_0.satCorrections[1],
- .constellation = GnssConstellationType_V2_0::IRNSS,
+ .constellation = V2_0::GnssConstellationType::IRNSS,
};
- mockCorrections_1_0.satCorrections[0].constellation = GnssConstellationType_V1_0::UNKNOWN;
- mockCorrections_1_0.satCorrections[1].constellation = GnssConstellationType_V1_0::UNKNOWN;
+ mockCorrections_1_0.satCorrections[0].constellation = V1_0::GnssConstellationType::UNKNOWN;
+ mockCorrections_1_0.satCorrections[1].constellation = V1_0::GnssConstellationType::UNKNOWN;
- hidl_vec<SingleSatCorrection_V1_1> singleSatCorrections = {singleSatCorrection1,
- singleSatCorrection2};
+ hidl_vec<measurement_corrections::V1_1::SingleSatCorrection> singleSatCorrections = {
+ singleSatCorrection1, singleSatCorrection2};
- MeasurementCorrections_1_1 mockCorrections_1_1 = {
+ measurement_corrections::V1_1::MeasurementCorrections mockCorrections_1_1 = {
.v1_0 = mockCorrections_1_0,
.hasEnvironmentBearing = true,
.environmentBearingDegrees = 45.0,
@@ -177,22 +176,22 @@
* GnssConstellationType_1_0 type constellation. For constellations that do not have
* an equivalent value, maps to GnssConstellationType_1_0::UNKNOWN
*/
-GnssConstellationType_1_0 Utils::mapConstellationType(GnssConstellationType_2_0 constellation) {
+V1_0::GnssConstellationType Utils::mapConstellationType(V2_0::GnssConstellationType constellation) {
switch (constellation) {
- case GnssConstellationType_2_0::GPS:
- return GnssConstellationType_1_0::GPS;
- case GnssConstellationType_2_0::SBAS:
- return GnssConstellationType_1_0::SBAS;
- case GnssConstellationType_2_0::GLONASS:
- return GnssConstellationType_1_0::GLONASS;
- case GnssConstellationType_2_0::QZSS:
- return GnssConstellationType_1_0::QZSS;
- case GnssConstellationType_2_0::BEIDOU:
- return GnssConstellationType_1_0::BEIDOU;
- case GnssConstellationType_2_0::GALILEO:
- return GnssConstellationType_1_0::GALILEO;
+ case V2_0::GnssConstellationType::GPS:
+ return V1_0::GnssConstellationType::GPS;
+ case V2_0::GnssConstellationType::SBAS:
+ return V1_0::GnssConstellationType::SBAS;
+ case V2_0::GnssConstellationType::GLONASS:
+ return V1_0::GnssConstellationType::GLONASS;
+ case V2_0::GnssConstellationType::QZSS:
+ return V1_0::GnssConstellationType::QZSS;
+ case V2_0::GnssConstellationType::BEIDOU:
+ return V1_0::GnssConstellationType::BEIDOU;
+ case V2_0::GnssConstellationType::GALILEO:
+ return V1_0::GnssConstellationType::GALILEO;
default:
- return GnssConstellationType_1_0::UNKNOWN;
+ return V1_0::GnssConstellationType::UNKNOWN;
}
}
diff --git a/gnss/common/utils/vts/include/Utils.h b/gnss/common/utils/vts/include/Utils.h
index a4aad80..91c1167 100644
--- a/gnss/common/utils/vts/include/Utils.h
+++ b/gnss/common/utils/vts/include/Utils.h
@@ -22,33 +22,21 @@
#include <android/hardware/gnss/measurement_corrections/1.0/IMeasurementCorrections.h>
#include <android/hardware/gnss/measurement_corrections/1.1/IMeasurementCorrections.h>
-using GnssConstellationType_1_0 = android::hardware::gnss::V1_0::GnssConstellationType;
-using GnssConstellationType_2_0 = android::hardware::gnss::V2_0::GnssConstellationType;
-using GnssLocation = ::android::hardware::gnss::V1_0::GnssLocation;
-using namespace android::hardware::gnss::measurement_corrections::V1_0;
-
-using MeasurementCorrections_1_0 =
- android::hardware::gnss::measurement_corrections::V1_0::MeasurementCorrections;
-using MeasurementCorrections_1_1 =
- android::hardware::gnss::measurement_corrections::V1_1::MeasurementCorrections;
-
-using SingleSatCorrection_V1_0 =
- android::hardware::gnss::measurement_corrections::V1_0::SingleSatCorrection;
-using SingleSatCorrection_V1_1 =
- android::hardware::gnss::measurement_corrections::V1_1::SingleSatCorrection;
-
namespace android {
namespace hardware {
namespace gnss {
namespace common {
struct Utils {
- static void checkLocation(const GnssLocation& location, bool check_speed,
+ static void checkLocation(const V1_0::GnssLocation& location, bool check_speed,
bool check_more_accuracies);
- static const MeasurementCorrections_1_0 getMockMeasurementCorrections();
- static const MeasurementCorrections_1_1 getMockMeasurementCorrections_1_1();
+ static const measurement_corrections::V1_0::MeasurementCorrections
+ getMockMeasurementCorrections();
+ static const measurement_corrections::V1_1::MeasurementCorrections
+ getMockMeasurementCorrections_1_1();
- static GnssConstellationType_1_0 mapConstellationType(GnssConstellationType_2_0 constellation);
+ static V1_0::GnssConstellationType mapConstellationType(
+ V2_0::GnssConstellationType constellation);
static bool isAutomotiveDevice();
};
diff --git a/graphics/composer/2.2/utils/vts/Android.bp b/graphics/composer/2.2/utils/vts/Android.bp
index 5c085cb..51295a6 100644
--- a/graphics/composer/2.2/utils/vts/Android.bp
+++ b/graphics/composer/2.2/utils/vts/Android.bp
@@ -43,6 +43,7 @@
"libmath",
"libnativewindow",
"librenderengine",
+ "libtonemap",
"android.hardware.graphics.mapper@3.0",
"android.hardware.graphics.mapper@3.0-vts",
"android.hardware.graphics.mapper@4.0",
diff --git a/graphics/composer/2.2/vts/functional/Android.bp b/graphics/composer/2.2/vts/functional/Android.bp
index 36f3c00..79ed368 100644
--- a/graphics/composer/2.2/vts/functional/Android.bp
+++ b/graphics/composer/2.2/vts/functional/Android.bp
@@ -67,6 +67,7 @@
"android.hardware.graphics.mapper@4.0-vts",
"libgtest",
"librenderengine",
+ "libtonemap",
],
header_libs: [
"android.hardware.graphics.composer@2.1-command-buffer",
diff --git a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
index 5c37018..d7cab2b 100644
--- a/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/aidl_api/android.hardware.graphics.composer3/current/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -85,4 +85,5 @@
const int EX_UNSUPPORTED = 8;
const int EX_SEAMLESS_NOT_ALLOWED = 9;
const int EX_SEAMLESS_NOT_POSSIBLE = 10;
+ const int INVALID_CONFIGURATION = 2147483647;
}
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
index 2a9545d..230980d 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/IComposerClient.aidl
@@ -90,6 +90,12 @@
const int EX_SEAMLESS_NOT_POSSIBLE = 10;
/**
+ * Integer.MAX_VALUE is reserved for the invalid configuration.
+ * This should not be returned as a valid configuration.
+ */
+ const int INVALID_CONFIGURATION = 0x7fffffff;
+
+ /**
* Creates a new layer on the given display.
*
* @param display is the display on which to create the layer.
@@ -282,6 +288,7 @@
/**
* Returns handles for all of the valid display configurations on this
* display.
+ * This should never return INVALID_CONFIGURATION as a valid value.
*
* @param display is the display to query.
*
diff --git a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
index 2dc80fc..97684ca 100644
--- a/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
+++ b/graphics/composer/aidl/android/hardware/graphics/composer3/vts/functional/VtsHalGraphicsComposer3_TargetTest.cpp
@@ -8,15 +8,19 @@
#include <binder/ProcessState.h>
#include <composer-vts/include/GraphicsComposerCallback.h>
#include <gtest/gtest.h>
+#include <algorithm>
+#include <numeric>
+#include <regex>
#include <string>
#include <thread>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
#pragma push_macro("LOG_TAG")
#undef LOG_TAG
#define LOG_TAG "VtsHalGraphicsComposer3_TargetTest"
-typedef int32_t Config;
-
namespace aidl::android::hardware::graphics::composer3::vts {
namespace {
@@ -61,8 +65,8 @@
// returns an invalid display id (one that has not been registered to a
// display. Currently assuming that a device will never have close to
// std::numeric_limit<uint64_t>::max() displays registered while running tests
- uint64_t GetInvalidDisplayId() {
- uint64_t id = std::numeric_limits<uint64_t>::max();
+ int64_t GetInvalidDisplayId() {
+ int64_t id = std::numeric_limits<int64_t>::max();
while (id > 0) {
if (std::none_of(mDisplays.begin(), mDisplays.end(),
[&](const VtsDisplay& display) { return id == display.get(); })) {
@@ -87,7 +91,7 @@
std::vector<VtsDisplay> vtsDisplays;
vtsDisplays.reserve(displays.size());
for (int64_t display : displays) {
- Config activeConfig;
+ int32_t activeConfig;
EXPECT_TRUE(mComposerClient->getActiveConfig(display, &activeConfig).isOk());
int32_t displayWidth;
EXPECT_TRUE(mComposerClient
@@ -106,9 +110,65 @@
}
}
+ // returns an invalid config id which is std::numeric_limit<int32_t>::max()
+ int32_t GetInvalidConfigId() { return IComposerClient::INVALID_CONFIGURATION; }
+
+ ndk::ScopedAStatus setActiveConfigWithConstraints(
+ VtsDisplay& display, int32_t config, const VsyncPeriodChangeConstraints& constraints,
+ VsyncPeriodChangeTimeline* timeline) {
+ auto error = mComposerClient->setActiveConfigWithConstraints(display.get(), config,
+ constraints, timeline);
+ if (error.isOk()) {
+ int32_t displayWidth;
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(display.get(), config,
+ DisplayAttribute::WIDTH, &displayWidth)
+ .isOk());
+ int32_t displayHeight;
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(display.get(), config,
+ DisplayAttribute::HEIGHT, &displayHeight)
+ .isOk());
+ display.setDimensions(displayWidth, displayHeight);
+ }
+ return error;
+ }
+
+ void Test_setContentTypeForDisplay(const int64_t& display,
+ const std::vector<ContentType>& capabilities,
+ const ContentType& contentType, const char* contentTypeStr) {
+ const bool contentTypeSupport = std::find(capabilities.begin(), capabilities.end(),
+ contentType) != capabilities.end();
+
+ if (!contentTypeSupport) {
+ EXPECT_EQ(IComposerClient::EX_UNSUPPORTED,
+ mComposerClient->setContentType(display, contentType)
+ .getServiceSpecificError());
+ GTEST_SUCCEED() << contentTypeStr << " content type is not supported on display "
+ << std::to_string(display) << ", skipping test";
+ return;
+ }
+
+ EXPECT_TRUE(mComposerClient->setContentType(display, contentType).isOk());
+ EXPECT_TRUE(mComposerClient->setContentType(display, ContentType::NONE).isOk());
+ }
+
+ void Test_setContentType(const ContentType& contentType, const char* contentTypeStr) {
+ for (const auto& display : mDisplays) {
+ std::vector<ContentType> supportedContentTypes;
+ const auto error = mComposerClient->getSupportedContentTypes(display.get(),
+ &supportedContentTypes);
+ EXPECT_TRUE(error.isOk());
+
+ Test_setContentTypeForDisplay(display.get(), supportedContentTypes, contentType,
+ contentTypeStr);
+ }
+ }
+
std::shared_ptr<IComposer> mComposer;
std::shared_ptr<IComposerClient> mComposerClient;
int64_t mInvalidDisplayId;
+ int64_t mPrimaryDisplay;
std::vector<VtsDisplay> mDisplays;
std::shared_ptr<GraphicsComposerCallback> mComposerCallback;
};
@@ -129,6 +189,557 @@
}
}
+TEST_P(GraphicsComposerAidlTest, GetDisplayIdentificationData) {
+ DisplayIdentification displayIdentification0;
+
+ const auto error =
+ mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &displayIdentification0);
+ if (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+ return;
+ }
+ ASSERT_TRUE(error.isOk()) << "failed to get display identification data";
+ ASSERT_FALSE(displayIdentification0.data.empty());
+
+ constexpr size_t kEdidBlockSize = 128;
+ ASSERT_TRUE(displayIdentification0.data.size() % kEdidBlockSize == 0)
+ << "EDID blob length is not a multiple of " << kEdidBlockSize;
+
+ const uint8_t kEdidHeader[] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
+ ASSERT_TRUE(std::equal(std::begin(kEdidHeader), std::end(kEdidHeader),
+ displayIdentification0.data.begin()))
+ << "EDID blob doesn't start with the fixed EDID header";
+ ASSERT_EQ(0, std::accumulate(displayIdentification0.data.begin(),
+ displayIdentification0.data.begin() + kEdidBlockSize,
+ static_cast<uint8_t>(0)))
+ << "EDID base block doesn't checksum";
+
+ DisplayIdentification displayIdentification1;
+ ASSERT_TRUE(
+ mComposerClient->getDisplayIdentificationData(mPrimaryDisplay, &displayIdentification1)
+ .isOk());
+
+ ASSERT_EQ(displayIdentification0.port, displayIdentification1.port) << "ports are not stable";
+ ASSERT_TRUE(displayIdentification0.data.size() == displayIdentification1.data.size() &&
+ std::equal(displayIdentification0.data.begin(), displayIdentification0.data.end(),
+ displayIdentification1.data.begin()))
+ << "data is not stable";
+}
+
+TEST_P(GraphicsComposerAidlTest, GetHdrCapabilities) {
+ HdrCapabilities hdrCapabilities;
+ const auto error = mComposerClient->getHdrCapabilities(mPrimaryDisplay, &hdrCapabilities);
+
+ ASSERT_TRUE(error.isOk());
+ ASSERT_TRUE(hdrCapabilities.maxLuminance >= hdrCapabilities.minLuminance);
+}
+
+TEST_P(GraphicsComposerAidlTest, GetPerFrameMetadataKeys) {
+ std::vector<PerFrameMetadataKey> keys;
+ const auto error = mComposerClient->getPerFrameMetadataKeys(mPrimaryDisplay, &keys);
+
+ if (error.isOk()) {
+ EXPECT_EQ(EX_NONE, error.getServiceSpecificError());
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, GetReadbackBufferAttributes) {
+ ReadbackBufferAttributes readBackBufferAttributes;
+ const auto error = mComposerClient->getReadbackBufferAttributes(mPrimaryDisplay,
+ &readBackBufferAttributes);
+
+ if (error.isOk()) {
+ EXPECT_EQ(EX_NONE, error.getServiceSpecificError());
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, GetRenderIntents) {
+ std::vector<ColorMode> modes;
+ EXPECT_TRUE(mComposerClient->getColorModes(mPrimaryDisplay, &modes).isOk());
+ for (auto mode : modes) {
+ std::vector<RenderIntent> intents;
+ EXPECT_TRUE(mComposerClient->getRenderIntents(mPrimaryDisplay, mode, &intents).isOk());
+
+ bool isHdr;
+ switch (mode) {
+ case ColorMode::BT2100_PQ:
+ case ColorMode::BT2100_HLG:
+ isHdr = true;
+ break;
+ default:
+ isHdr = false;
+ break;
+ }
+ RenderIntent requiredIntent =
+ isHdr ? RenderIntent::TONE_MAP_COLORIMETRIC : RenderIntent::COLORIMETRIC;
+
+ auto iter = std::find(intents.cbegin(), intents.cend(), requiredIntent);
+ EXPECT_NE(intents.cend(), iter);
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, GetRenderIntentsBadDisplay) {
+ std::vector<ColorMode> modes;
+ EXPECT_TRUE(mComposerClient->getColorModes(mPrimaryDisplay, &modes).isOk());
+ for (auto mode : modes) {
+ std::vector<RenderIntent> renderIntents;
+ const auto error =
+ mComposerClient->getRenderIntents(mInvalidDisplayId, mode, &renderIntents);
+ EXPECT_FALSE(error.isOk());
+ EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, GetRenderIntentsBadParameter) {
+ std::vector<RenderIntent> renderIntents;
+ const auto error = mComposerClient->getRenderIntents(
+ mPrimaryDisplay, static_cast<ColorMode>(-1), &renderIntents);
+ EXPECT_FALSE(error.isOk());
+ EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetColorModes) {
+ std::vector<ColorMode> colorModes;
+ EXPECT_TRUE(mComposerClient->getColorModes(mPrimaryDisplay, &colorModes).isOk());
+
+ auto native = std::find(colorModes.cbegin(), colorModes.cend(), ColorMode::NATIVE);
+ ASSERT_NE(colorModes.cend(), native);
+}
+
+TEST_P(GraphicsComposerAidlTest, GetColorModeBadDisplay) {
+ std::vector<ColorMode> colorModes;
+ const auto error = mComposerClient->getColorModes(mInvalidDisplayId, &colorModes);
+
+ EXPECT_FALSE(error.isOk());
+ EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, SetColorMode) {
+ std::vector<ColorMode> colorModes;
+ EXPECT_TRUE(mComposerClient->getColorModes(mPrimaryDisplay, &colorModes).isOk());
+ for (auto mode : colorModes) {
+ std::vector<RenderIntent> intents;
+ EXPECT_TRUE(mComposerClient->getRenderIntents(mPrimaryDisplay, mode, &intents).isOk())
+ << "failed to get render intents";
+ for (auto intent : intents) {
+ const auto error = mComposerClient->setColorMode(mPrimaryDisplay, mode, intent);
+ EXPECT_TRUE(error.isOk() ||
+ IComposerClient::EX_UNSUPPORTED == error.getServiceSpecificError())
+ << "failed to set color mode";
+ }
+ }
+
+ const auto error = mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::NATIVE,
+ RenderIntent::COLORIMETRIC);
+ EXPECT_TRUE(error.isOk() || IComposerClient::EX_UNSUPPORTED == error.getServiceSpecificError())
+ << "failed to set color mode";
+}
+
+TEST_P(GraphicsComposerAidlTest, SetColorModeBadDisplay) {
+ auto const error = mComposerClient->setColorMode(mInvalidDisplayId, ColorMode::NATIVE,
+ RenderIntent::COLORIMETRIC);
+
+ EXPECT_FALSE(error.isOk());
+ ASSERT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, SetColorModeBadParameter) {
+ const auto colorModeError = mComposerClient->setColorMode(
+ mPrimaryDisplay, static_cast<ColorMode>(-1), RenderIntent::COLORIMETRIC);
+
+ EXPECT_FALSE(colorModeError.isOk());
+ EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, colorModeError.getServiceSpecificError());
+
+ const auto renderIntentError = mComposerClient->setColorMode(mPrimaryDisplay, ColorMode::NATIVE,
+ static_cast<RenderIntent>(-1));
+
+ EXPECT_FALSE(renderIntentError.isOk());
+ EXPECT_EQ(IComposerClient::EX_BAD_PARAMETER, renderIntentError.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDisplayedContentSamplingAttributes) {
+ int constexpr invalid = -1;
+
+ DisplayContentSamplingAttributes format;
+ auto error = mComposerClient->getDisplayedContentSamplingAttributes(mPrimaryDisplay, &format);
+
+ if (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+ SUCCEED() << "Device does not support optional extension. Test skipped";
+ return;
+ }
+
+ EXPECT_TRUE(error.isOk());
+ EXPECT_NE(format.format, static_cast<common::PixelFormat>(invalid));
+ EXPECT_NE(format.dataspace, static_cast<common::Dataspace>(invalid));
+ EXPECT_NE(format.componentMask, static_cast<FormatColorComponent>(invalid));
+};
+
+TEST_P(GraphicsComposerAidlTest, SetDisplayedContentSamplingEnabled) {
+ auto const maxFrames = 10;
+ FormatColorComponent enableAllComponents = FormatColorComponent::FORMAT_COMPONENT_0;
+ auto error = mComposerClient->setDisplayedContentSamplingEnabled(
+ mPrimaryDisplay, true, enableAllComponents, maxFrames);
+ if (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+ SUCCEED() << "Device does not support optional extension. Test skipped";
+ return;
+ }
+ EXPECT_TRUE(error.isOk());
+
+ error = mComposerClient->setDisplayedContentSamplingEnabled(mPrimaryDisplay, false,
+ enableAllComponents, maxFrames);
+ EXPECT_TRUE(error.isOk());
+}
+
+TEST_P(GraphicsComposerAidlTest, GetDisplayedContentSample) {
+ DisplayContentSamplingAttributes displayContentSamplingAttributes;
+ int constexpr invalid = -1;
+ displayContentSamplingAttributes.format = static_cast<common::PixelFormat>(invalid);
+ displayContentSamplingAttributes.dataspace = static_cast<common::Dataspace>(invalid);
+ displayContentSamplingAttributes.componentMask = static_cast<FormatColorComponent>(invalid);
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayedContentSamplingAttributes(mPrimaryDisplay,
+ &displayContentSamplingAttributes)
+ .isOk());
+
+ uint64_t maxFrames = 10;
+ uint64_t timestamp = 0;
+ uint64_t frameCount = 0;
+ DisplayContentSample displayContentSample;
+ auto error = mComposerClient->getDisplayedContentSample(mPrimaryDisplay, maxFrames, timestamp,
+ &displayContentSample);
+ if (error.getServiceSpecificError() == IComposerClient::EX_UNSUPPORTED) {
+ SUCCEED() << "Device does not support optional extension. Test skipped";
+ return;
+ }
+
+ EXPECT_TRUE(error.isOk());
+ EXPECT_LE(frameCount, maxFrames);
+ std::vector<std::vector<int64_t>> histogram = {
+ displayContentSample.sampleComponent0, displayContentSample.sampleComponent1,
+ displayContentSample.sampleComponent2, displayContentSample.sampleComponent3};
+
+ for (auto i = 0; i < histogram.size(); i++) {
+ if (static_cast<int>(displayContentSamplingAttributes.componentMask) & (1 << i)) {
+ EXPECT_NE(histogram[i].size(), 0);
+ } else {
+ EXPECT_EQ(histogram[i].size(), 0);
+ }
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, getDisplayCapabilitiesBasic) {
+ std::vector<DisplayCapability> capabilities;
+ const auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities);
+ ASSERT_TRUE(error.isOk());
+ const bool hasDozeSupport = std::find(capabilities.begin(), capabilities.end(),
+ DisplayCapability::DOZE) != capabilities.end();
+ bool isDozeSupported = false;
+ EXPECT_TRUE(mComposerClient->getDozeSupport(mPrimaryDisplay, &isDozeSupported).isOk());
+ EXPECT_EQ(hasDozeSupport, isDozeSupported);
+
+ bool hasBrightnessSupport = std::find(capabilities.begin(), capabilities.end(),
+ DisplayCapability::BRIGHTNESS) != capabilities.end();
+ bool isBrightnessSupported = false;
+ EXPECT_TRUE(
+ mComposerClient->getDisplayBrightnessSupport(mPrimaryDisplay, &isBrightnessSupported)
+ .isOk());
+ EXPECT_EQ(isBrightnessSupported, hasBrightnessSupport);
+}
+
+/*
+ * Test that if brightness operations are supported, setDisplayBrightness works as expected.
+ */
+TEST_P(GraphicsComposerAidlTest, setDisplayBrightness) {
+ std::vector<DisplayCapability> capabilities;
+ auto error = mComposerClient->getDisplayCapabilities(mPrimaryDisplay, &capabilities);
+ ASSERT_TRUE(error.isOk());
+ bool brightnessSupport = std::find(capabilities.begin(), capabilities.end(),
+ DisplayCapability::BRIGHTNESS) != capabilities.end();
+ if (!brightnessSupport) {
+ EXPECT_EQ(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.5f)
+ .getServiceSpecificError(),
+ IComposerClient::EX_UNSUPPORTED);
+ GTEST_SUCCEED() << "Brightness operations are not supported";
+ return;
+ }
+
+ EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.0f).isOk());
+ EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 0.5f).isOk());
+ EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, 1.0f).isOk());
+ EXPECT_TRUE(mComposerClient->setDisplayBrightness(mPrimaryDisplay, -1.0f).isOk());
+
+ error = mComposerClient->setDisplayBrightness(mPrimaryDisplay, +2.0f);
+ EXPECT_FALSE(error.isOk());
+ EXPECT_EQ(error.getServiceSpecificError(), IComposerClient::EX_BAD_PARAMETER);
+
+ error = mComposerClient->setDisplayBrightness(mPrimaryDisplay, -2.0f);
+ EXPECT_FALSE(error.isOk());
+ EXPECT_EQ(error.getServiceSpecificError(), IComposerClient::EX_BAD_PARAMETER);
+}
+
+TEST_P(GraphicsComposerAidlTest, getDisplayConnectionType) {
+ DisplayConnectionType type;
+ EXPECT_FALSE(mComposerClient->getDisplayConnectionType(mInvalidDisplayId, &type).isOk());
+ for (const auto& display : mDisplays) {
+ EXPECT_TRUE(mComposerClient->getDisplayConnectionType(display.get(), &type).isOk());
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, getDisplayAttribute) {
+ for (const auto& display : mDisplays) {
+ std::vector<int32_t> configs;
+ mComposerClient->getDisplayConfigs(display.get(), &configs);
+ for (const auto& config : configs) {
+ const std::array<DisplayAttribute, 4> requiredAttributes = {{
+ DisplayAttribute::WIDTH,
+ DisplayAttribute::HEIGHT,
+ DisplayAttribute::VSYNC_PERIOD,
+ DisplayAttribute::CONFIG_GROUP,
+ }};
+ int32_t value;
+ for (const auto& attribute : requiredAttributes) {
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(display.get(), config, attribute, &value)
+ .isOk());
+ EXPECT_NE(-1, value);
+ }
+
+ const std::array<DisplayAttribute, 2> optionalAttributes = {{
+ DisplayAttribute::DPI_X,
+ DisplayAttribute::DPI_Y,
+ }};
+ for (const auto& attribute : optionalAttributes) {
+ const auto error = mComposerClient->getDisplayAttribute(display.get(), config,
+ attribute, &value);
+ if (error.isOk()) {
+ EXPECT_EQ(EX_NONE, error.getServiceSpecificError());
+ } else {
+ EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, error.getServiceSpecificError());
+ }
+ }
+ }
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, checkConfigsAreValid) {
+ for (const auto& display : mDisplays) {
+ std::vector<int32_t> configs;
+ mComposerClient->getDisplayConfigs(display.get(), &configs);
+
+ EXPECT_FALSE(std::any_of(configs.begin(), configs.end(), [](auto config) {
+ return config == IComposerClient::INVALID_CONFIGURATION;
+ }));
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, getDisplayAttributeConfigsInAGroupDifferOnlyByVsyncPeriod) {
+ struct Resolution {
+ int32_t width;
+ int32_t height;
+ };
+ struct Dpi {
+ int32_t x;
+ int32_t y;
+ };
+ for (const auto& display : mDisplays) {
+ std::vector<int32_t> configs;
+ EXPECT_TRUE(mComposerClient->getDisplayConfigs(display.get(), &configs).isOk());
+ std::unordered_map<int32_t, Resolution> configGroupToResolutionMap;
+ std::unordered_map<int32_t, Dpi> configGroupToDpiMap;
+ for (const auto& config : configs) {
+ int32_t configGroup = -1;
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(display.get(), config,
+ DisplayAttribute::CONFIG_GROUP, &configGroup)
+ .isOk());
+ int32_t width = -1;
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(display.get(), config,
+ DisplayAttribute::WIDTH, &width)
+ .isOk());
+ int32_t height = -1;
+ EXPECT_TRUE(mComposerClient
+ ->getDisplayAttribute(display.get(), config,
+ DisplayAttribute::HEIGHT, &height)
+ .isOk());
+ if (configGroupToResolutionMap.find(configGroup) == configGroupToResolutionMap.end()) {
+ configGroupToResolutionMap[configGroup] = {width, height};
+ }
+ EXPECT_EQ(configGroupToResolutionMap[configGroup].width, width);
+ EXPECT_EQ(configGroupToResolutionMap[configGroup].height, height);
+
+ int32_t dpiX = -1;
+ mComposerClient->getDisplayAttribute(display.get(), config, DisplayAttribute::DPI_X,
+ &dpiX);
+
+ int32_t dpiY = -1;
+ mComposerClient->getDisplayAttribute(display.get(), config, DisplayAttribute::DPI_Y,
+ &dpiY);
+ if (dpiX == -1 && dpiY == -1) {
+ continue;
+ }
+
+ if (configGroupToDpiMap.find(configGroup) == configGroupToDpiMap.end()) {
+ configGroupToDpiMap[configGroup] = {dpiX, dpiY};
+ }
+ EXPECT_EQ(configGroupToDpiMap[configGroup].x, dpiX);
+ EXPECT_EQ(configGroupToDpiMap[configGroup].y, dpiY);
+ }
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, getDisplayVsyncPeriod_BadDisplay) {
+ int32_t vsyncPeriodNanos;
+ const auto error = mComposerClient->getDisplayVsyncPeriod(mInvalidDisplayId, &vsyncPeriodNanos);
+ EXPECT_FALSE(error.isOk());
+ EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, setActiveConfigWithConstraints_BadDisplay) {
+ VsyncPeriodChangeTimeline timeline;
+ VsyncPeriodChangeConstraints constraints;
+
+ constraints.seamlessRequired = false;
+ constraints.desiredTimeNanos = systemTime();
+ int32_t config = 0;
+ auto const error = mComposerClient->setActiveConfigWithConstraints(mInvalidDisplayId, config,
+ constraints, &timeline);
+
+ EXPECT_FALSE(error.isOk());
+ EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, setActiveConfigWithConstraints_BadConfig) {
+ VsyncPeriodChangeTimeline timeline;
+ VsyncPeriodChangeConstraints constraints;
+
+ constraints.seamlessRequired = false;
+ constraints.desiredTimeNanos = systemTime();
+
+ for (VtsDisplay& display : mDisplays) {
+ int32_t invalidConfigId = GetInvalidConfigId();
+ const auto error =
+ setActiveConfigWithConstraints(display, invalidConfigId, constraints, &timeline);
+ EXPECT_FALSE(error.isOk());
+ EXPECT_EQ(IComposerClient::EX_BAD_CONFIG, error.getServiceSpecificError());
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, setAutoLowLatencyModeBadDisplay) {
+ EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY,
+ mComposerClient->setAutoLowLatencyMode(mInvalidDisplayId, true)
+ .getServiceSpecificError());
+ EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY,
+ mComposerClient->setAutoLowLatencyMode(mInvalidDisplayId, false)
+ .getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, setAutoLowLatencyMode) {
+ for (const auto& display : mDisplays) {
+ std::vector<DisplayCapability> capabilities;
+ const auto error = mComposerClient->getDisplayCapabilities(display.get(), &capabilities);
+ EXPECT_TRUE(error.isOk());
+
+ const bool allmSupport =
+ std::find(capabilities.begin(), capabilities.end(),
+ DisplayCapability::AUTO_LOW_LATENCY_MODE) != capabilities.end();
+
+ if (!allmSupport) {
+ const auto errorIsOn = mComposerClient->setAutoLowLatencyMode(display.get(), true);
+ EXPECT_FALSE(errorIsOn.isOk());
+ EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errorIsOn.getServiceSpecificError());
+ const auto errorIsOff = mComposerClient->setAutoLowLatencyMode(display.get(), false);
+ EXPECT_FALSE(errorIsOff.isOk());
+ EXPECT_EQ(IComposerClient::EX_UNSUPPORTED, errorIsOff.getServiceSpecificError());
+ GTEST_SUCCEED() << "Auto Low Latency Mode is not supported on display "
+ << std::to_string(display.get()) << ", skipping test";
+ return;
+ }
+
+ EXPECT_TRUE(mComposerClient->setAutoLowLatencyMode(display.get(), true).isOk());
+ EXPECT_TRUE(mComposerClient->setAutoLowLatencyMode(display.get(), false).isOk());
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, getSupportedContentTypesBadDisplay) {
+ std::vector<ContentType> supportedContentTypes;
+ const auto error =
+ mComposerClient->getSupportedContentTypes(mInvalidDisplayId, &supportedContentTypes);
+ EXPECT_FALSE(error.isOk());
+ EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+}
+
+TEST_P(GraphicsComposerAidlTest, getSupportedContentTypes) {
+ std::vector<ContentType> supportedContentTypes;
+ for (const auto& display : mDisplays) {
+ supportedContentTypes.clear();
+ const auto error =
+ mComposerClient->getSupportedContentTypes(display.get(), &supportedContentTypes);
+
+ ASSERT_TRUE(error.isOk());
+
+ const bool noneSupported =
+ std::find(supportedContentTypes.begin(), supportedContentTypes.end(),
+ ContentType::NONE) != supportedContentTypes.end();
+ EXPECT_FALSE(noneSupported);
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, setContentTypeNoneAlwaysAccepted) {
+ for (const auto& display : mDisplays) {
+ const auto error = mComposerClient->setContentType(display.get(), ContentType::NONE);
+ EXPECT_TRUE(error.isOk());
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, setContentTypeBadDisplay) {
+ constexpr ContentType types[] = {ContentType::NONE, ContentType::GRAPHICS, ContentType::PHOTO,
+ ContentType::CINEMA, ContentType::GAME};
+ for (const auto& type : types) {
+ auto const error = mComposerClient->setContentType(mInvalidDisplayId, type);
+
+ EXPECT_FALSE(error.isOk());
+ EXPECT_EQ(IComposerClient::EX_BAD_DISPLAY, error.getServiceSpecificError());
+ }
+}
+
+TEST_P(GraphicsComposerAidlTest, setGraphicsContentType) {
+ Test_setContentType(ContentType::GRAPHICS, "GRAPHICS");
+}
+
+TEST_P(GraphicsComposerAidlTest, setPhotoContentType) {
+ Test_setContentType(ContentType::PHOTO, "PHOTO");
+}
+
+TEST_P(GraphicsComposerAidlTest, setCinemaContentType) {
+ Test_setContentType(ContentType::CINEMA, "CINEMA");
+}
+
+TEST_P(GraphicsComposerAidlTest, setGameContentType) {
+ Test_setContentType(ContentType::GAME, "GAME");
+}
+
+TEST_P(GraphicsComposerAidlTest, getLayerGenericMetadataKeys) {
+ std::vector<LayerGenericMetadataKey> keys;
+ EXPECT_TRUE(mComposerClient->getLayerGenericMetadataKeys(&keys).isOk());
+
+ std::regex reverseDomainName("^[a-zA-Z-]{2,}(\\.[a-zA-Z0-9-]+)+$");
+ std::unordered_set<std::string> uniqueNames;
+ for (const auto& key : keys) {
+ std::string name(key.name.c_str());
+
+ // Keys must not start with 'android' or 'com.android'
+ EXPECT_FALSE(name.find("android") == 0);
+ EXPECT_FALSE(name.find("com.android") == 0);
+
+ // Keys must be in reverse domain name format
+ EXPECT_TRUE(std::regex_match(name, reverseDomainName));
+
+ // Keys must be unique within this list
+ const auto& [iter, inserted] = uniqueNames.insert(name);
+ EXPECT_TRUE(inserted);
+ }
+}
+
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GraphicsComposerAidlTest);
INSTANTIATE_TEST_SUITE_P(
PerInstance, GraphicsComposerAidlTest,
diff --git a/health/aidl/README.md b/health/aidl/README.md
new file mode 100644
index 0000000..53a4f91
--- /dev/null
+++ b/health/aidl/README.md
@@ -0,0 +1,293 @@
+# Health AIDL HAL
+
+## Determine whether the example service implementation is sufficient {#determine}
+
+You need a custom implementation if any of the following is true:
+
+* You are migrating from a custom
+ [health 2.1 HIDL HAL implementation](../2.1/README.md).
+* System properties `ro.charger.enable_suspend` and/or `ro.charger.no_ui`
+ are set to a `true` value. See [below](#charger-sysprops).
+* The device supports offline charging mode, and the `service`
+ declaration with `class charger` in `init.rc` is different from the one
+ provided by the example implementation. See [below](#charger-init-rc).
+
+If the example HAL service is sufficient, [install it](#use-example). Otherwise,
+[implement a custom HAL service](#use-custom).
+
+### System properties for charger {#charger-sysprops}
+
+The health AIDL HAL service also provides functionalities of `charger`. As a
+result, the system charger at `/system/bin/charger` is deprecated.
+
+However, the health AIDL HAL service is not allowed to read `ro.charger.*`
+system properties. These properties include:
+* `ro.charger.enable_suspend`. If set, you need a custom health AIDL HAL
+ service. See [below](#charger-enable-suspend).
+* `ro.charger.no_ui`. If set, you need a custom health AIDL HAL service.
+ See [below](#charger-no-ui).
+* `ro.charger.draw_split_screen`. The system property is deprecated.
+* `ro.charger.draw_split_offset`. The system property is deprecated.
+* `ro.charger.disable_init_blank`. The system property is deprecated.
+
+If you need to set any of the deprecated system properties, contact
+[OWNERS](OWNERS).
+
+### Default `service` declaration for charger in `init.rc` {#charger-init-rc}
+
+See
+[android.hardware.health-service.example.rc](default/android.hardware.health-service.example.rc).
+
+Check the `service` declaration in your device-specific `init.rc` file that
+has `class charger`. Most likely, the declaration looks something like this
+(Below is an excerpt from Pixel 3):
+
+```text
+service vendor.charger /system/bin/charger
+ class charger
+ seclabel u:r:charger:s0
+ user system
+ group system wakelock input
+ capabilities SYS_BOOT
+ file /dev/kmsg w
+ file /sys/fs/pstore/console-ramoops-0 r
+ file /sys/fs/pstore/console-ramoops r
+ file /proc/last_kmsg r
+```
+
+Compare each line against the one provided by the example health AIDL HAL
+service in
+[android.hardware.health-service.example.rc](default/android.hardware.health-service.example.rc).
+Specifically:
+
+* You may ignore the `service` line. The name of the service does not matter.
+* If your service belongs to additional classes beside `charger`, you need a
+ custom health AIDL service.
+* You may ignore the `seclabel` line. When the health AIDL service runs in
+ charger mode, its original SELinux domain is kept.
+* If your service has a different `user` (not `system`), you need a custom
+ health AIDL service.
+* If your service belongs to additional `group`s beside
+ `system wakelock input`, you need a custom health AIDL service.
+* If your service requires additional capabilities beside `SYS_BOOT`,
+ you need a custom health AIDL service.
+* If your service requires additional `file`s to be opened prior to execution,
+ you need a custom health AIDL service.
+
+## Using the example health AIDL HAL service {#use-example}
+
+If you [determined](#determine) that the example health AIDL HAL service works
+for your device, install it with
+
+```mk
+PRODUCT_PACKAGES += android.hardware.health-service.example
+```
+
+Then, delete any existing `service` with `class charger` in your device-specific
+`init.rc` files, because
+[android.hardware.health-service.example.rc](default/android.hardware.health-service.example.rc)
+already contains an entry for charger.
+
+If your device supports charger mode and it has custom charger resources,
+[move charger resources to `/vendor`](#charger-res)
+
+## Implementing a custom health AIDL HAL service {#use-custom}
+
+### Override the `Health` class {#health-impl}
+
+See [`Health.h`](default/include/health-impl/Health.h) for its class
+declaration. Inherit the class to customize for your device.
+
+```c++
+namespace aidl::android::hardware::health {
+class HealthImpl : public Health {
+ // ...
+};
+} // namespace aidl::android::hardware::health
+int main(int, char**) {
+ // ...
+ auto binder = ndk::SharedRefBase::make<aidl::android::hardware::health::HealthImpl>(
+ "default", std::move(config));
+ // ...
+}
+```
+
+* The logic to modify `healthd_config`, traditionally in `healthd_board_init()`
+ should be called before passing the `healthd_config` struct to your
+ `HealthImpl` class in [`main()`](#main).
+
+* The following functions are similar to the ones in the health 2.1 HIDL HAL:
+
+| AIDL implementation | HIDL implementation |
+|-------------------------------------|-----------------------------|
+| `Health::getChargeCounterUah` | `Health::getChargeCounter` |
+| `Health::getCurrentNowMicroamps` | `Health::getCurrentNow` |
+| `Health::getCurrentAverageMicroamps`| `Health::getCurrentAverage` |
+| `Health::getCapacity` | `Health::getCapacity` |
+| `Health::getChargeStatus` | `Health::getChargeStatus` |
+| `Health::getEnergyCounterNwh` | `Health::getEnergyCounter` |
+| `Health::getDiskStats` | `Health::getDiskStats` |
+| `Health::getStorageInfo` | `Health::getStorageInfo` |
+| `Health::BinderEvent` | `BinderHealth::BinderEvent` |
+| `Health::dump` | `Health::debug` |
+| `Health::ShouldKeepScreenOn` | `Health::shouldKeepScreenOn`|
+| `Health::UpdateHealthInfo` | `Health::UpdateHealthInfo` |
+
+### Implement `main()` {#main}
+
+See the [`main.cpp`](default/main.cpp) for the example health AIDL service for
+an example.
+
+If you need to modify `healthd_config`, do it before passing it to the
+constructor of `HealthImpl` (or `Health` if you did not implement a subclass
+of it).
+
+```c++
+int main(int argc, char** argv) {
+ auto config = std::make_unique<healthd_config>();
+ ::android::hardware::health::InitHealthdConfig(config.get());
+ healthd_board_init(config.get());
+ auto binder = ndk::SharedRefBase::make<Health>("default", std::move(config));
+ // ...
+}
+```
+
+If your device does not support off-line charging mode, or does not have a UI
+for charger (`ro.charger.no_ui=true`), skip the invocation of
+`ChargerModeMain()` in `main()`.
+
+### SELinux rules
+
+Add device specific permissions to the domain where the health HAL
+process is executed, especially if a device-specific `libhealthd` is used
+and/or device-specific storage related APIs are implemented.
+
+If you did not define a separate domain, the domain is likely
+`hal_health_default`. The device-specific rules for it is likely at
+`device/<manufacturer>/<device>/sepolicy/vendor/hal_health_default.te`.
+
+### Implementing charger {#charger}
+
+#### Move charger resources to `/vendor`
+
+Ensure that charger resources are installed to `/vendor`, not `/product`.
+
+`animation.txt` must be moved to the following location:
+
+```text
+/vendor/etc/res/values/charger/animation.txt
+```
+
+Charger resources in `/system` is not read by the health HAL service in
+`/vendor`. Specifically, resources should be installed to the following
+location:
+
+```
+/vendor/etc/res/images/charger/*.png
+```
+
+If resources are not found in these locations, the health HAL service falls
+back to the following locations:
+
+```
+/vendor/etc/res/images/charger/default/*.png
+```
+
+You can use the default resources by installing the default module:
+
+```makefile
+PRODUCT_PACKAGES += charger_res_images_vendor
+```
+
+#### Modify `init.rc` for charger
+
+It is recommended that you move the existing `service` entry with
+`class charger` to the `init.rc` file in your custom health service.
+
+Modify the entry to invoke the health service binary with `--charger` argument.
+See
+[android.hardware.health-service.example.rc](default/android.hardware.health-service.example.rc)
+for an example:
+
+```text
+service vendor.charger-tuna /vendor/bin/hw/android.hardware.health-service-tuna --charger
+ # ...
+```
+
+#### No charger mode {#no-charger}
+
+If your device does not support off-line charging mode, skip the invocation of
+`ChargerModeMain()` in `main()`.
+
+```c++
+int main(int, char**) {
+ // ...
+ // Skip checking if arguments contain "--charger"
+ auto hal_health_loop = std::make_shared<HalHealthLoop>(binder, binder);
+ return hal_health_loop->StartLoop();
+}
+```
+
+You may optionally delete the `service` entry with `class charger` in the
+`init.rc` file.
+
+#### No charger UI {#charger-no-ui}
+
+If your device does not have a UI for charger (`ro.charger.no_ui=true`), skip
+the invocation of `ChargerModeMain()` in `main()`.
+
+You may want to keep the `KernelLogger` so that charger still logs battery
+information to the kernel logs.
+
+```c++
+int main(int argc, char** argv) {
+ // ...
+ if (argc >= 2 && argv[1] == "--charger"sv) {
+ android::base::InitLogging(argv, &android::base::KernelLogger);
+ // fallthrough to HalHealthLoop::StartLoop()
+ }
+ auto hal_health_loop = std::make_shared<HalHealthLoop>(binder, binder);
+ return hal_health_loop->StartLoop();
+}
+```
+
+#### Enable suspend {#charger-enable-suspend}
+
+If your device has `ro.charger.enable_suspend=true`, implement a new class,
+`ChargerCallbackImpl`, that inherits from
+[`ChargerCallback`](default/include/health-impl/ChargerUtils.h). Then
+override the `ChargerEnableSuspend` function to return `true`. Then pass an
+instance of `ChargerCallbackImpl` to `ChargerModeMain()` instead.
+
+```c++
+namespace aidl::android::hardware::health {
+class ChargerCallbackImpl : public ChargerCallback {
+ bool ChargerEnableSuspend() override { return true; }
+};
+} // namespace aidl::android::hardware::health
+int main(int argc, char** argv) {
+ // ...
+ if (argc >= 2 && argv[1] == "--charger"sv) {
+ android::base::InitLogging(argv, &android::base::KernelLogger);
+#if !CHARGER_FORCE_NO_UI
+ return ChargerModeMain(binder,
+ std::make_shared<aidl::android::hardware::health::ChargerCallbackImpl>(binder));
+#endif
+ }
+ // ...
+}
+```
+
+#### SELinux rules for charger
+
+If your health AIDL service runs in a domain other than `hal_health_default`,
+add `charger_type` to it so the health HAL service can have charger-specific
+permissions. Example (assuming that your health AIDL service runs in domain
+`hal_health_tuna`:
+
+```text
+type hal_health_tuna, charger_type, domain;
+hal_server_domain(hal_health_default, hal_health)
+```
+
+[comment: TODO(b/170338625): explain recovery]: #
diff --git a/health/aidl/default/Android.bp b/health/aidl/default/Android.bp
index 7e635d4..a13c677 100644
--- a/health/aidl/default/Android.bp
+++ b/health/aidl/default/Android.bp
@@ -45,6 +45,52 @@
],
}
+// Dependency to libhealthd_charger_ui. No UI in recovery.
+cc_defaults {
+ name: "libhealth_aidl_charger_defaults",
+ shared_libs: [
+ // common
+ "android.hardware.health-V1-ndk",
+ "libbase",
+ "libcutils",
+ "liblog",
+ "libutils",
+
+ // charger UI only
+ "libpng",
+ ],
+
+ static_libs: [
+ // common
+ "libbatterymonitor",
+ "libhealthloop",
+
+ // charger UI only
+ "libhealthd_draw",
+ "libhealthd_charger_ui",
+ "libminui",
+ "libsuspend",
+ ],
+
+ target: {
+ recovery: {
+ // No UI and libsuspend for recovery charger.
+ cflags: [
+ "-DCHARGER_FORCE_NO_UI=1",
+ ],
+ exclude_shared_libs: [
+ "libpng",
+ ],
+ exclude_static_libs: [
+ "libhealthd_draw",
+ "libhealthd_charger_ui",
+ "libminui",
+ "libsuspend",
+ ],
+ },
+ },
+}
+
// AIDL version of libhealth2impl.
// A helper library for health HAL implementation.
// HAL implementations can link to this library and extend the Health class.
@@ -52,21 +98,26 @@
name: "libhealth_aidl_impl",
defaults: [
"libhealth_aidl_common_defaults",
+ "libhealth_aidl_charger_defaults",
],
export_include_dirs: ["include"],
export_static_lib_headers: [
"libbatterymonitor",
],
srcs: [
+ "ChargerUtils.cpp",
"health-convert.cpp",
"HalHealthLoop.cpp",
"Health.cpp",
"LinkedCallback.cpp",
],
- visibility: [
- ":__subpackages__",
- "//hardware/interfaces/tests/extension/health:__subpackages__",
- ],
+ target: {
+ recovery: {
+ exclude_srcs: [
+ "ChargerUtils.cpp",
+ ],
+ },
+ },
}
// AIDL version of android.hardware.health@2.1-service.
@@ -78,9 +129,13 @@
vintf_fragments: ["android.hardware.health-service.example.xml"],
defaults: [
"libhealth_aidl_common_defaults",
+ "libhealth_aidl_charger_defaults",
],
static_libs: [
"libhealth_aidl_impl",
],
srcs: ["main.cpp"],
+ overrides: [
+ "charger",
+ ],
}
diff --git a/health/aidl/default/ChargerUtils.cpp b/health/aidl/default/ChargerUtils.cpp
new file mode 100644
index 0000000..f8e208b
--- /dev/null
+++ b/health/aidl/default/ChargerUtils.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <android-base/logging.h>
+#include <health-impl/ChargerUtils.h>
+
+namespace aidl::android::hardware::health::charger {
+
+std::optional<bool> ChargerCallback::ChargerShouldKeepScreenOn() {
+ return service_->ShouldKeepScreenOn();
+}
+
+bool ChargerCallback::ChargerIsOnline() {
+ auto hal_health_loop_sp = hal_health_loop_.lock();
+ if (hal_health_loop_sp == nullptr) {
+ // Assume no charger
+ return false;
+ }
+ return hal_health_loop_sp->charger_online();
+}
+
+void ChargerCallback::ChargerInitConfig(healthd_config* config) {
+ auto hal_health_loop_sp = hal_health_loop_.lock();
+ if (hal_health_loop_sp == nullptr) {
+ return;
+ }
+ return service_->OnInit(hal_health_loop_sp.get(), config);
+}
+
+int ChargerCallback::ChargerRegisterEvent(int fd, BoundFunction func, EventWakeup wakeup) {
+ auto hal_health_loop_sp = hal_health_loop_.lock();
+ if (hal_health_loop_sp == nullptr) {
+ return -1;
+ }
+ return hal_health_loop_sp->RegisterEvent(fd, func, wakeup);
+}
+
+void ChargerCallback::set_hal_health_loop(const std::weak_ptr<HalHealthLoop>& hal_health_loop) {
+ hal_health_loop_ = std::move(hal_health_loop);
+}
+
+// Implements HalHealthLoopCallback for AIDL charger
+// Adapter of (Charger, Health) -> HalHealthLoopCallback
+class LoopCallback : public HalHealthLoopCallback {
+ public:
+ LoopCallback(const std::shared_ptr<Health>& service, ChargerCallback* charger_callback)
+ : service_(service), charger_(std::make_unique<::android::Charger>(charger_callback)) {}
+
+ void OnHeartbeat() override {
+ service_->OnHeartbeat();
+ charger_->OnHeartbeat();
+ }
+ // Return the minimum timeout. Negative values are treated as no values.
+ int OnPrepareToWait() override {
+ int timeout1 = service_->OnPrepareToWait();
+ int timeout2 = charger_->OnPrepareToWait();
+
+ if (timeout1 < 0) return timeout2;
+ if (timeout2 < 0) return timeout1;
+ return std::min(timeout1, timeout2);
+ }
+
+ void OnInit(HalHealthLoop*, struct healthd_config* config) override {
+ // Charger::OnInit calls ChargerInitConfig, which calls into the real Health::OnInit.
+ charger_->OnInit(config);
+ }
+
+ void OnHealthInfoChanged(const HealthInfo& health_info) override {
+ charger_->OnHealthInfoChanged(::android::ChargerHealthInfo{
+ .battery_level = health_info.batteryLevel,
+ .battery_status = health_info.batteryStatus,
+ });
+ service_->OnHealthInfoChanged(health_info);
+ }
+
+ private:
+ std::shared_ptr<Health> service_;
+ std::unique_ptr<::android::Charger> charger_;
+};
+
+int ChargerModeMain(const std::shared_ptr<Health>& binder,
+ const std::shared_ptr<ChargerCallback>& charger_callback) {
+ LOG(INFO) << "Starting charger mode.";
+ // parent stack ==========================================
+ // current stack ||
+ // || ||
+ // V V
+ // hal_health_loop => loop_callback => charger --(raw)--> charger_callback
+ // ^----------------(weak)---------------------------------'
+ auto loop_callback = std::make_shared<LoopCallback>(binder, charger_callback.get());
+ auto hal_health_loop = std::make_shared<HalHealthLoop>(binder, std::move(loop_callback));
+ charger_callback->set_hal_health_loop(hal_health_loop);
+ return hal_health_loop->StartLoop();
+}
+
+} // namespace aidl::android::hardware::health::charger
diff --git a/health/aidl/default/android.hardware.health-service.example.rc b/health/aidl/default/android.hardware.health-service.example.rc
index b393c58..dee3d11 100644
--- a/health/aidl/default/android.hardware.health-service.example.rc
+++ b/health/aidl/default/android.hardware.health-service.example.rc
@@ -4,3 +4,13 @@
group system
capabilities WAKE_ALARM BLOCK_SUSPEND
file /dev/kmsg w
+
+service vendor.charger-default /vendor/bin/hw/android.hardware.health-service.example --charger
+ class charger
+ user system
+ group system wakelock input
+ capabilities SYS_BOOT
+ file /dev/kmsg w
+ file /sys/fs/pstore/console-ramoops-0 r
+ file /sys/fs/pstore/console-ramoops r
+ file /proc/last_kmsg r
diff --git a/health/aidl/default/include/health-impl/ChargerUtils.h b/health/aidl/default/include/health-impl/ChargerUtils.h
new file mode 100644
index 0000000..8f94181
--- /dev/null
+++ b/health/aidl/default/include/health-impl/ChargerUtils.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+#include <optional>
+#include <type_traits>
+
+#include <android/binder_auto_utils.h>
+#include <charger/healthd_mode_charger.h>
+#include <health-impl/Health.h>
+
+#pragma once
+
+namespace aidl::android::hardware::health::charger {
+
+// Implements ChargerHalHealthLoopInterface for AIDL charger
+// Adapter of (Health, HalHealthLoop) -> ChargerHalHealthLoopInterface
+class ChargerCallback : public ::android::ChargerConfigurationInterface {
+ public:
+ ChargerCallback(const std::shared_ptr<Health>& service) : service_(service) {}
+ std::optional<bool> ChargerShouldKeepScreenOn() override;
+ bool ChargerIsOnline() override;
+ void ChargerInitConfig(healthd_config* config) override;
+ int ChargerRegisterEvent(int fd, BoundFunction func, EventWakeup wakeup) override;
+
+ // Override to return true to replace `ro.charger.enable_suspend=true`
+ bool ChargerEnableSuspend() override { return false; }
+
+ void set_hal_health_loop(const std::weak_ptr<HalHealthLoop>& hal_health_loop);
+
+ private:
+ std::shared_ptr<Health> service_;
+ std::weak_ptr<HalHealthLoop> hal_health_loop_;
+};
+
+int ChargerModeMain(const std::shared_ptr<Health>& binder,
+ const std::shared_ptr<ChargerCallback>& charger_callback);
+
+} // namespace aidl::android::hardware::health::charger
diff --git a/health/aidl/default/main.cpp b/health/aidl/default/main.cpp
index 014ae34..76c6ba0 100644
--- a/health/aidl/default/main.cpp
+++ b/health/aidl/default/main.cpp
@@ -19,17 +19,46 @@
#include <health-impl/Health.h>
#include <health/utils.h>
+#ifndef CHARGER_FORCE_NO_UI
+#define CHARGER_FORCE_NO_UI 0
+#endif
+
+#if !CHARGER_FORCE_NO_UI
+#include <health-impl/ChargerUtils.h>
+#endif
+
using aidl::android::hardware::health::HalHealthLoop;
using aidl::android::hardware::health::Health;
-static constexpr const char* gInstanceName = "default";
+#if !CHARGER_FORCE_NO_UI
+using aidl::android::hardware::health::charger::ChargerCallback;
+using aidl::android::hardware::health::charger::ChargerModeMain;
+#endif
-int main() {
- // TODO(b/203246116): handle charger
+static constexpr const char* gInstanceName = "default";
+static constexpr std::string_view gChargerArg{"--charger"};
+
+int main(int argc, char** argv) {
// make a default health service
auto config = std::make_unique<healthd_config>();
::android::hardware::health::InitHealthdConfig(config.get());
auto binder = ndk::SharedRefBase::make<Health>(gInstanceName, std::move(config));
+
+ if (argc >= 2 && argv[1] == gChargerArg) {
+ android::base::InitLogging(argv, &android::base::KernelLogger);
+
+#if !CHARGER_FORCE_NO_UI
+ // If charger shouldn't have UI for your device, simply drop the line below
+ // for your service implementation. This corresponds to
+ // ro.charger.no_ui=true
+ return ChargerModeMain(binder, std::make_shared<ChargerCallback>(binder));
+#endif
+
+ LOG(INFO) << "Starting charger mode without UI.";
+ } else {
+ LOG(INFO) << "Starting health HAL.";
+ }
+
auto hal_health_loop = std::make_shared<HalHealthLoop>(binder, binder);
return hal_health_loop->StartLoop();
}
diff --git a/health/utils/libhealthtest/Android.bp b/health/utils/libhealthtest/Android.bp
index dbe02d6..0993cb6 100644
--- a/health/utils/libhealthtest/Android.bp
+++ b/health/utils/libhealthtest/Android.bp
@@ -13,6 +13,15 @@
// limitations under the License.
// Utils library for VTS tests.
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "hardware_interfaces_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["hardware_interfaces_license"],
+}
+
cc_library_headers {
name: "libhealthtest_headers",
static_libs: [
diff --git a/neuralnetworks/aidl/utils/include/AidlBufferTracker.h b/neuralnetworks/aidl/utils/include/AidlBufferTracker.h
deleted file mode 100644
index 4421876..0000000
--- a/neuralnetworks/aidl/utils/include/AidlBufferTracker.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#include "nnapi/hal/aidl/BufferTracker.h"
diff --git a/neuralnetworks/aidl/utils/include/AidlHalInterfaces.h b/neuralnetworks/aidl/utils/include/AidlHalInterfaces.h
deleted file mode 100644
index 3777969..0000000
--- a/neuralnetworks/aidl/utils/include/AidlHalInterfaces.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#include "nnapi/hal/aidl/HalInterfaces.h"
diff --git a/neuralnetworks/aidl/utils/include/AidlHalUtils.h b/neuralnetworks/aidl/utils/include/AidlHalUtils.h
deleted file mode 100644
index 98bfbad..0000000
--- a/neuralnetworks/aidl/utils/include/AidlHalUtils.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#include "nnapi/hal/aidl/HalUtils.h"
diff --git a/neuralnetworks/aidl/utils/include/AidlValidateHal.h b/neuralnetworks/aidl/utils/include/AidlValidateHal.h
deleted file mode 100644
index 5aaa74d..0000000
--- a/neuralnetworks/aidl/utils/include/AidlValidateHal.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-#include "nnapi/hal/aidl/ValidateHal.h"
diff --git a/neuralnetworks/aidl/utils/src/Buffer.cpp b/neuralnetworks/aidl/utils/src/Buffer.cpp
index c729a68..9af3c9e 100644
--- a/neuralnetworks/aidl/utils/src/Buffer.cpp
+++ b/neuralnetworks/aidl/utils/src/Buffer.cpp
@@ -22,7 +22,6 @@
#include "Conversions.h"
#include "Utils.h"
-#include "nnapi/hal/aidl/Conversions.h"
#include <memory>
#include <utility>
diff --git a/neuralnetworks/aidl/utils/src/AidlBufferTracker.cpp b/neuralnetworks/aidl/utils/src/BufferTracker.cpp
similarity index 98%
rename from neuralnetworks/aidl/utils/src/AidlBufferTracker.cpp
rename to neuralnetworks/aidl/utils/src/BufferTracker.cpp
index 15d0810..94dc891 100644
--- a/neuralnetworks/aidl/utils/src/AidlBufferTracker.cpp
+++ b/neuralnetworks/aidl/utils/src/BufferTracker.cpp
@@ -14,9 +14,12 @@
* limitations under the License.
*/
-#include "AidlBufferTracker.h"
+#include "BufferTracker.h"
+
+#include "HalInterfaces.h"
#include <android-base/macros.h>
+#include <nnapi/TypeUtils.h>
#include <memory>
#include <mutex>
@@ -25,9 +28,6 @@
#include <utility>
#include <vector>
-#include "AidlHalInterfaces.h"
-#include "nnapi/TypeUtils.h"
-
namespace android::nn {
std::shared_ptr<AidlManagedBuffer> AidlManagedBuffer::create(
diff --git a/neuralnetworks/aidl/utils/src/AidlHalUtils.cpp b/neuralnetworks/aidl/utils/src/HalUtils.cpp
similarity index 96%
rename from neuralnetworks/aidl/utils/src/AidlHalUtils.cpp
rename to neuralnetworks/aidl/utils/src/HalUtils.cpp
index 6fc46ab..64b6259 100644
--- a/neuralnetworks/aidl/utils/src/AidlHalUtils.cpp
+++ b/neuralnetworks/aidl/utils/src/HalUtils.cpp
@@ -17,9 +17,12 @@
// utilities. LegacyUtils.h is the subset of these utilities that do not touch
// HAL.
-#include "AidlHalUtils.h"
+#include "HalUtils.h"
+
+#include "HalInterfaces.h"
#include <android-base/logging.h>
+#include <nnapi/TypeUtils.h>
#include <nnapi/hal/aidl/Conversions.h>
#include <algorithm>
@@ -27,9 +30,6 @@
#include <type_traits>
#include <vector>
-#include "AidlHalInterfaces.h"
-#include "nnapi/TypeUtils.h"
-
namespace android::nn {
std::vector<aidl_hal::OperandPerformance> nonExtensionOperandPerformance(
diff --git a/neuralnetworks/aidl/utils/src/AidlValidateHal.cpp b/neuralnetworks/aidl/utils/src/ValidateHal.cpp
similarity index 98%
rename from neuralnetworks/aidl/utils/src/AidlValidateHal.cpp
rename to neuralnetworks/aidl/utils/src/ValidateHal.cpp
index a1c496a..a56de21 100644
--- a/neuralnetworks/aidl/utils/src/AidlValidateHal.cpp
+++ b/neuralnetworks/aidl/utils/src/ValidateHal.cpp
@@ -16,9 +16,12 @@
#define LOG_TAG "ValidateHal"
-#include "AidlValidateHal.h"
+#include "ValidateHal.h"
+
+#include "HalUtils.h"
#include <android-base/logging.h>
+#include <nnapi/TypeUtils.h>
#include <nnapi/hal/aidl/Conversions.h>
#include <algorithm>
@@ -27,9 +30,6 @@
#include <utility>
#include <vector>
-#include "AidlHalUtils.h"
-#include "nnapi/TypeUtils.h"
-
namespace android {
namespace nn {
diff --git a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
index 1819699..cd5475c 100644
--- a/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
+++ b/neuralnetworks/aidl/vts/functional/MemoryDomainTests.cpp
@@ -28,9 +28,9 @@
#include <Utils.h>
#include <nnapi/SharedMemory.h>
#include <nnapi/hal/aidl/Conversions.h>
+#include <nnapi/hal/aidl/HalInterfaces.h>
#include <nnapi/hal/aidl/Utils.h>
-#include "AidlHalInterfaces.h"
#include "Callbacks.h"
#include "GeneratedTestHarness.h"
#include "MemoryUtils.h"
diff --git a/power/aidl/default/Android.bp b/power/aidl/default/Android.bp
index e10d329..9acb9e0 100644
--- a/power/aidl/default/Android.bp
+++ b/power/aidl/default/Android.bp
@@ -24,8 +24,8 @@
cc_binary {
name: "android.hardware.power-service.example",
relative_install_path: "hw",
- init_rc: ["power-default.rc"],
- vintf_fragments: ["power-default.xml"],
+ init_rc: [":android.hardware.power.rc"],
+ vintf_fragments: [":android.hardware.power.xml"],
vendor: true,
shared_libs: [
"libbase",
@@ -37,3 +37,13 @@
"Power.cpp",
],
}
+
+filegroup {
+ name: "android.hardware.power.xml",
+ srcs: ["power-default.xml"],
+}
+
+filegroup {
+ name: "android.hardware.power.rc",
+ srcs: ["power-default.rc"],
+}
diff --git a/power/aidl/default/apex/Android.bp b/power/aidl/default/apex/Android.bp
new file mode 100644
index 0000000..eb04087
--- /dev/null
+++ b/power/aidl/default/apex/Android.bp
@@ -0,0 +1,72 @@
+// Copyright (C) 2021 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+apex_key {
+ name: "com.android.hardware.power.key",
+ public_key: "com.android.hardware.power.avbpubkey",
+ private_key: "com.android.hardware.power.pem",
+}
+
+android_app_certificate {
+ name: "com.android.hardware.power.certificate",
+ certificate: "com.android.hardware.power",
+}
+
+genrule {
+ name: "com.android.hardware.power.rc-srcs",
+ srcs: [
+ ":android.hardware.power.rc",
+ ":android.hardware.power.stats.rc",
+ ],
+ out: ["com.android.hardware.power.rc"],
+ cmd: "sed -E 's/\\/vendor/\\/apex\\/com.android.hardware.power/' $(in) > $(out)",
+}
+
+prebuilt_etc {
+ name: "com.android.hardware.power.rc",
+ src: ":com.android.hardware.power.rc-srcs",
+ installable: false,
+}
+
+apex {
+ name: "com.android.hardware.power",
+ manifest: "apex_manifest.json",
+ key: "com.android.hardware.power.key",
+ certificate: ":com.android.hardware.power.certificate",
+ file_contexts: "file_contexts",
+ use_vndk_as_stable: true,
+ updatable: false,
+ // Install the apex in /vendor/apex
+ soc_specific: true,
+ // Bundle the Power and PowerStats HALs into this one APEX.
+ binaries: [
+ "android.hardware.power-service.example",
+ "android.hardware.power.stats-service.example",
+ ],
+ prebuilts: [
+ "com.android.hardware.power.rc",
+ ],
+ vintf_fragments: [
+ ":android.hardware.power.xml",
+ ":android.hardware.power.stats.xml",
+ ],
+ overrides: [
+ // Shared lib installed by default but unused by the AIDL implementation.
+ "power.default",
+ ],
+}
diff --git a/power/aidl/default/apex/apex_manifest.json b/power/aidl/default/apex/apex_manifest.json
new file mode 100644
index 0000000..faa937d
--- /dev/null
+++ b/power/aidl/default/apex/apex_manifest.json
@@ -0,0 +1,4 @@
+{
+ "name": "com.android.hardware.power",
+ "version": 1
+}
diff --git a/power/aidl/default/apex/com.android.hardware.power.avbpubkey b/power/aidl/default/apex/com.android.hardware.power.avbpubkey
new file mode 100644
index 0000000..3b6411d
--- /dev/null
+++ b/power/aidl/default/apex/com.android.hardware.power.avbpubkey
Binary files differ
diff --git a/power/aidl/default/apex/com.android.hardware.power.pem b/power/aidl/default/apex/com.android.hardware.power.pem
new file mode 100644
index 0000000..d18ae98
--- /dev/null
+++ b/power/aidl/default/apex/com.android.hardware.power.pem
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIJKQIBAAKCAgEAsUdFjtLq05tWKdQd4aj8V7tmV4KXw41pKGT5Q1CPzrdHF3yJ
+B/8VWdMpjZ+eQO1q8SijPgfvWExeWQVMfxKmwTmj26xWXhIOgo5G02Zva7zOptig
+KGnl/RdFlOiIGC36XeWDhzdIOhlGv+er9Sykf6Ot84OvktTBUTZNJrXQsyYTBRUX
+6B+wloPdBVxVf1HgzjeHUyCy5dTz0xZSWWELoW24tHIvV5FtJVKSY8ZDfuXWLLfT
+he7E93TepjT027U/J/iW4ITJzw4Qq87ick1D/jZDUbTrkqUMFEgPdgCouZ9zt5xG
+pcHAZ/Fcz9DZfEdX9Xy0R5/XbfrJdvDPguJlwK1pZnr/Pe13xxmE+TEohMmaQDqX
+jQNX3UlcfOYUAjnFMGucHDM10KjTMbP8ytCys88aNLiv7FOgVGrQ/djZN8rkMyVP
+ccoksUBMQmjYaQQZ2yZuJMiLD3P6aYkgU5tMEMoMTrBzfcx05GfElal+ZqOFKAzj
+eUxoZTR27wJb684FRbeE45D+y4jpFfrTEXry+aI7GrfDsVDnUqmyObCUttRtaT04
+6kuUmC44wFEg1EBfcWZc1szI192GBjMuZjFcYvJ4vMdCuennqvLNPBDY1PtqzCOf
+D8vpOE3T9rjS23xxFmmSmorwKKQOGChKqO/SaY0axkXgt+FbSsvTBQtZTSsCAwEA
+AQKCAgEArEu3t+MYJcdwS8EDtcF2V5IkGmMrOvziOkdA14Kh8efBKXt49xOc3atU
+VHfQ6AuXh4DWf0BZB7lZbS2wNkSbW2q47ZSmcFEeVxcOkQGawtxDAHfD2ONrirqm
+ft4s/0sYbU/WsIEzKnxMfdEdGHFmA0PCmczfxFYQ+OxMuZW1m5ginirtDEZYa0EH
+e+FMmyypz+K6HDnIhYWd4Aduy718/0zTWlUr2/DUYpTJAD2+dcPNj7Kt2xq/xj2I
+84K+hBa4phF+GgIU3a8u1ryA61RbA+QbM3siBWlxvvh2RlrHoXjuj4JMS2dup9c2
+PCggaCAyxb2IvaAFUbePPJE5LVz6RFT4HnLEydd5Yt+CEAm+iZKfCzyUgFRtb5y0
+HHTME1eVAt/rf/yIXUYA7q8nQ/PtSzIol5KLX4FUjX1MVKNmIWMa+836kxbuYDFB
+K1M1IKc1k0t9Q9F3TRCMhP/6qH/vJfubCGQhSRUMq7JyjivK9GjYST8R07Dpgu9Z
+4i9TRI8d+UVERsg8niCXONVkmNa3U49u2duUvqV3KmKgQ/Hgyy3keDjz6x56ie5w
+e0EusHAsot60W1BvHrdwlmGZjW3JmZEyazUPh9nBUAaQve1rIOpn80kGXx4EAE2o
+HcrcInJx/zVBk1Wk3UQDwmhUNpa64q9+nd9VMaR9SQNK3ah4NDECggEBAOeput2F
+CgRrvzka69i7FbgY4VmpNMIICPIB6gxvwpir/g4/GgYknuBB6ep1ksf/IZfsMp5A
+JTH1KdXqqQm8nV9v+ETYQAO+VnmWKSBKHsNJqONxsKkQ+xIJcusmKBTYLfL88XQg
+YWH3VMXgqPP8DnJYCeVRIKj1WqfEFFHiaLJJB8FgKhtZBwBnibkVG1K0XCkTdUfY
+mME2GRKW/C7DMvuFOpcFVj7Obwn68R2k3zsOhWA5NQGZF5mqhg5KYLVDg3IbMJQQ
+D+DymQxnc2s2ar0q24isy1Y/FOXrA057j1vAN951+pk6F/PCJM/mtAiRjhP0Aru1
+P6bbR11p+wnpU7MCggEBAMPm8Jmwu3F0xsyFC+1sWPAzPiwaMa7/30wANNKKqHVO
+7lUv1WYFbFMyAOzYPp3Y5HxdxNa43reULGk0R20kSu6W6FkApSvAws0rLKRlS5UI
+oZqhLGHUH2M7q07m2RgQY2TJkU2Zq6AH1kjcbSr127ISXKanKpqonwSHy38BTcGt
+Dl2fVioPzK/vwmiNo2njhh95TV4kqlbUfl7xtDt56tbg8oFBwOsK7UGajXYOxTGB
+o1DtO5E+oiOmlclXuo3m4qpSSMv+wM91aRFhHZVIx0vmO8y5lrfU2kM/5DDhJBxV
+FM4TaA+c5tFOTuCLejHc7nM99wVx7O4QZ0wBwETUxKkCggEAH0tBT+1J1iEL+tXV
+KDjVjUHnJyqBUvis5Kw3hqiOO/t33UrO5CeMQrUEuURaqKOhURl6GQCHRcFdfmUt
+ooAVLjA89GfV9et/WPtc4NzCXRUVOGxCNgRyNhSKrpM/9NjjFCDxKQO6w/YaQITB
+rfvNo8qaw5x68ff64BDPweP4yqSs5IVuCrWzCW3zH8pnH3v3uyDCxgrPT8JUDrvQ
+oyyBNZLgwEfbR66xN0Lr0VpVQXALulzf+TBKDNsJMuL/P104Y3Ci1k15J6T94bwT
+zlbSgm1IrKTS7vqkgw6FKtPsILPNmEKNsKc1VxtRx7fdeA7Zh3595Adu6sZSVJ8d
+Z1BamwKCAQAnbu0vgqu4gtEhigaEnDKq5yW0qvElUMwZ+FCpsM+IDYNcEmzaRG0x
+sfcNtdmk3GvhvN5KepwaR/FInAVkqtGKhUXv5Hla/Uo5El/CF8HHFh2xio/sgU5w
+IyqwjzdT6LiZKRnejPhHFkzEDdrLswGuLpQH185zo02fE9aakiCcw8EIh3JItTV2
+lMSFVz11qx7sZvZz5N2E7PEjG3Q0JK5o4o7uBdZXebOYaQvgn8iB1p6RQ6+h5QGu
+O3IbPVWICtnFfxq4NWeKWw/zN6FE04mKdaXD5/e2uVnV/55nWGp0aYvuj2l6+xJb
+P3ARMwI910MIX4jBx9TxdsvUOOYC9PFBAoIBAQDWswLnaNth4pgutngVWbMenSpv
+eK1RA1ldw2NoTZrGlqPB+LvjEMSH/7ioby8YtOyJRIWs3si8HpVF12qneu8qi7b7
+QlUtqyJOTnGalvhrlq5zPhdW+kk2DXvtTylUnz3vSxxi2I7cLhQRryLC/1kAwy67
+wEr0+u59bOvaqe8L1zgtYJpLQZeskUMzdSMIRVDdFShEFrMJU7adUvGpA7OZ6Ogf
+ux2jWr2vv/eKq6fU6kDPi/66MQjPbZPf2Uq6+XedkNkAeELpN4o3hw0/l/rfiK/r
+YUMJBwtjQw/hehtvC4GlgsH1tMZWzCZULo0tcW4qbzyi9PBrWFPteb33OjBc
+-----END RSA PRIVATE KEY-----
diff --git a/power/aidl/default/apex/com.android.hardware.power.pk8 b/power/aidl/default/apex/com.android.hardware.power.pk8
new file mode 100644
index 0000000..e45435d
--- /dev/null
+++ b/power/aidl/default/apex/com.android.hardware.power.pk8
Binary files differ
diff --git a/power/aidl/default/apex/com.android.hardware.power.x509.pem b/power/aidl/default/apex/com.android.hardware.power.x509.pem
new file mode 100644
index 0000000..9f0c5f0
--- /dev/null
+++ b/power/aidl/default/apex/com.android.hardware.power.x509.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIF2TCCA8ECFDFsXbm5CdS/UtQZgTiF8Umr8LrLMA0GCSqGSIb3DQEBCwUAMIGn
+MQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91
+bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UECwwHQW5kcm9pZDEi
+MCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTEjMCEGA1UEAwwaY29t
+LmFuZHJvaWQuaGFyZHdhcmUucG93ZXIwIBcNMjExMDIwMTcwNTA0WhgPNDc1OTA5
+MTYxNzA1MDRaMIGnMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEW
+MBQGA1UEBwwNTW91bnRhaW4gVmlldzEQMA4GA1UECgwHQW5kcm9pZDEQMA4GA1UE
+CwwHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTEj
+MCEGA1UEAwwaY29tLmFuZHJvaWQuaGFyZHdhcmUucG93ZXIwggIiMA0GCSqGSIb3
+DQEBAQUAA4ICDwAwggIKAoICAQC/37fhOkOfgM2e+M7bMJ1baLFif8dKGwRa6mkJ
+9HWmuOgRcTKllzuEHtrJ0jzur3cDy6/0oZSfA/E1ck3DdRHMQadW26JSNSg6fCU9
+h1kDzkakZgyr3DsJnKGoSHCJ2V2kVbCnd6GuOaOU1ZZISw1I+BWJDc3t1mZPs80D
+ar7/hoIZnsWRoE/eWgJDcWWscRsquSi+q6hyqlCbRvwRznPaDGwmb4geHNugCXkz
+EtCswfc5jiT8DjMDkgVsGO/WcYj2GWT0K0H+Zf1CmEO9fAoXTLfVBjdumtGILgii
+d/TJe2tOBSWyZz6sVzfac2PvUH5Lm8TNUXuLV5IEdcpySge0vqYQwAyd2EgsTH1e
+mRNSk9NerpmfCFEySRRP3BWMGRhbST1d8M3v9Bq0QFhrxoAF12r6GXBUpp9XcOL5
+pBTcAkA9XI++mfz4pDzyGRGOy4WX+8XtsaVZ/14JklupSLr0Tt7oaNocUhoXB03g
+4B0jUTX0hNnVzCxzJypw6YJ60Zc8z+z8pEF34FWarHec1QbkFuyWxbaTPQ4d2NLH
+8zDxQpMILErWdAgKsRL0d8RFG5fBcleEoBM2kKHMAgnP+1qyDqBgt8zloWbmmblw
+JXMuoePFOgeVcgPrZ3EGJSx+s4+dQGQc6r/GwKLKSWpUvHxTIGug76IX9xmptB+I
+F3xb2QIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQANISf3Vi2eueOlzzfnEGGa+CXz
+nvlgUXKv8Gv0/Pbg5uC1BaHTAUgRu5rvrfP9p3Mdj86I/HbE/F4Vkuzqb8/JTWGA
+mG636zAsJRJr0fnkbPma9wVEPSK8MF1QqM6PmKXboixX82TqV1R1sRYG+9hh9W3u
+isDzYDb2ODE0X9M8/3hLS28zdCdtl4zCRK6KB86aGxvkVEj4qDA5l+AbVYevS/SU
+hz1+K/aM0Fi6MZovo5kd/Mof5l05e1TEgCoL1FtFX79r+PYGHJ8/LjtEMkFgwqvG
+CLx2sOV09EHZU27EbVvSs1JYMMXgeAvKaHsVZ51QlSzW4esg/E6z4pw654p8qyK/
+WLXIZ7BMILl1sHYmGqXitnu19puvNks2/+hyqVr0seM5GyQDuwBE8nx6xZzTRxdj
+4TZyN9LuMc9/cKJFvOPqD152bkA2frCLEzYCQreDWwxsWcUHzYrQT+v2SqzP6Ue2
+Xn06HDLx9wBL7Dz6no05SlNS0u1KdvKas6FKZHO+QaKKsBlDmXbMrBTcuUI6OXv2
+6NpVbeyDd0+A23hDiNSgI6zTY6jMidesNExB7rW/bCE4ltPyxFAB+sffyXounODc
+groB5CaS2bv+H1IXJzMMe4LkgQPl1C7G+I3KvJmnrYwmIhLIDuxP82arClIDzccS
+ExRR7ugEg91XCc87Zg==
+-----END CERTIFICATE-----
diff --git a/power/aidl/default/apex/file_contexts b/power/aidl/default/apex/file_contexts
new file mode 100644
index 0000000..3433851
--- /dev/null
+++ b/power/aidl/default/apex/file_contexts
@@ -0,0 +1,3 @@
+(/.*)? u:object_r:vendor_file:s0
+/bin/hw/android\.hardware\.power-service\.example u:object_r:hal_power_default_exec:s0
+/bin/hw/android\.hardware\.power\.stats-service\.example u:object_r:hal_power_stats_default_exec:s0
diff --git a/power/stats/aidl/default/Android.bp b/power/stats/aidl/default/Android.bp
index 7c0caf3..66be5f9 100644
--- a/power/stats/aidl/default/Android.bp
+++ b/power/stats/aidl/default/Android.bp
@@ -24,8 +24,8 @@
cc_binary {
name: "android.hardware.power.stats-service.example",
relative_install_path: "hw",
- init_rc: ["power.stats-default.rc"],
- vintf_fragments: ["power.stats-default.xml"],
+ init_rc: [":android.hardware.power.stats.rc"],
+ vintf_fragments: [":android.hardware.power.stats.xml"],
vendor: true,
shared_libs: [
"libbase",
@@ -37,3 +37,13 @@
"PowerStats.cpp",
],
}
+
+filegroup {
+ name: "android.hardware.power.stats.xml",
+ srcs: ["power.stats-default.xml"],
+}
+
+filegroup {
+ name: "android.hardware.power.stats.rc",
+ srcs: ["power.stats-default.rc"],
+}
diff --git a/sensors/1.0/vts/functional/OWNERS b/sensors/1.0/vts/functional/OWNERS
index 892da15..e20125b 100644
--- a/sensors/1.0/vts/functional/OWNERS
+++ b/sensors/1.0/vts/functional/OWNERS
@@ -1,8 +1,2 @@
-# Sensors team
-arthuri@google.com
-bduddie@google.com
-stange@google.com
-
-# VTS team
-trong@google.com
-yim@google.com
+# Bug component: 62965
+include ../../../common/vts/OWNERS
diff --git a/sensors/2.0/vts/functional/OWNERS b/sensors/2.0/vts/functional/OWNERS
index 892da15..e20125b 100644
--- a/sensors/2.0/vts/functional/OWNERS
+++ b/sensors/2.0/vts/functional/OWNERS
@@ -1,8 +1,2 @@
-# Sensors team
-arthuri@google.com
-bduddie@google.com
-stange@google.com
-
-# VTS team
-trong@google.com
-yim@google.com
+# Bug component: 62965
+include ../../../common/vts/OWNERS
diff --git a/sensors/2.1/vts/functional/OWNERS b/sensors/2.1/vts/functional/OWNERS
index 892da15..e20125b 100644
--- a/sensors/2.1/vts/functional/OWNERS
+++ b/sensors/2.1/vts/functional/OWNERS
@@ -1,8 +1,2 @@
-# Sensors team
-arthuri@google.com
-bduddie@google.com
-stange@google.com
-
-# VTS team
-trong@google.com
-yim@google.com
+# Bug component: 62965
+include ../../../common/vts/OWNERS
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInterleaveMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
index 5e03731..ac38731 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
@@ -38,4 +38,5 @@
android.hardware.tv.tuner.FrontendAtsc3TimeInterleaveMode atsc3 = android.hardware.tv.tuner.FrontendAtsc3TimeInterleaveMode.UNDEFINED;
android.hardware.tv.tuner.FrontendCableTimeInterleaveMode dvbc;
android.hardware.tv.tuner.FrontendDtmbTimeInterleaveMode dtmb;
+ android.hardware.tv.tuner.FrontendIsdbtTimeInterleaveMode isdbt;
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
index 097fcb8..dbf631b 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
@@ -40,4 +40,7 @@
int modulationCap;
int coderateCap;
int guardIntervalCap;
+ int timeInterleaveCap;
+ boolean isSegmentAuto;
+ boolean isFullSegment;
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl
new file mode 100644
index 0000000..0055793
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@VintfStability
+parcelable FrontendIsdbtLayerSettings {
+ android.hardware.tv.tuner.FrontendIsdbtModulation modulation = android.hardware.tv.tuner.FrontendIsdbtModulation.UNDEFINED;
+ android.hardware.tv.tuner.FrontendIsdbtCoderate coderate = android.hardware.tv.tuner.FrontendIsdbtCoderate.UNDEFINED;
+ android.hardware.tv.tuner.FrontendIsdbtTimeInterleaveMode timeInterleave = android.hardware.tv.tuner.FrontendIsdbtTimeInterleaveMode.UNDEFINED;
+ int numOfSegment;
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
new file mode 100644
index 0000000..133887f
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbtPartialReceptionFlag {
+ UNDEFINED = 0,
+ AUTO = 1,
+ FALSE = 2,
+ TRUE = 4,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
index 6249097..605bc21 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
@@ -38,10 +38,10 @@
long frequency;
long endFrequency;
android.hardware.tv.tuner.FrontendSpectralInversion inversion = android.hardware.tv.tuner.FrontendSpectralInversion.UNDEFINED;
- android.hardware.tv.tuner.FrontendIsdbtModulation modulation = android.hardware.tv.tuner.FrontendIsdbtModulation.UNDEFINED;
android.hardware.tv.tuner.FrontendIsdbtBandwidth bandwidth = android.hardware.tv.tuner.FrontendIsdbtBandwidth.UNDEFINED;
android.hardware.tv.tuner.FrontendIsdbtMode mode = android.hardware.tv.tuner.FrontendIsdbtMode.UNDEFINED;
- android.hardware.tv.tuner.FrontendIsdbtCoderate coderate = android.hardware.tv.tuner.FrontendIsdbtCoderate.UNDEFINED;
android.hardware.tv.tuner.FrontendIsdbtGuardInterval guardInterval = android.hardware.tv.tuner.FrontendIsdbtGuardInterval.UNDEFINED;
int serviceAreaId;
+ android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag partialReceptionFlag = android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag.UNDEFINED;
+ android.hardware.tv.tuner.FrontendIsdbtLayerSettings[] layerSettings;
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
new file mode 100644
index 0000000..50adde9
--- /dev/null
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.tv.tuner;
+/* @hide */
+@Backing(type="int") @VintfStability
+enum FrontendIsdbtTimeInterleaveMode {
+ UNDEFINED = 0,
+ AUTO = 1,
+ INTERLEAVE_1_0 = 2,
+ INTERLEAVE_1_4 = 4,
+ INTERLEAVE_1_8 = 8,
+ INTERLEAVE_1_16 = 16,
+ INTERLEAVE_2_0 = 32,
+ INTERLEAVE_2_2 = 64,
+ INTERLEAVE_2_4 = 128,
+ INTERLEAVE_2_8 = 256,
+ INTERLEAVE_3_0 = 512,
+ INTERLEAVE_3_1 = 1024,
+ INTERLEAVE_3_2 = 2048,
+ INTERLEAVE_3_4 = 4096,
+}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
index 6296cfc..7677221 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatus.aidl
@@ -72,4 +72,6 @@
boolean isMiso;
boolean isLinear;
boolean isShortFrames;
+ android.hardware.tv.tuner.FrontendIsdbtMode isdbtMode;
+ android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag partialReceptionFlag;
}
diff --git a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
index 7b8bc47..6342479 100644
--- a/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
+++ b/tv/tuner/aidl/aidl_api/android.hardware.tv.tuner/current/android/hardware/tv/tuner/FrontendStatusType.aidl
@@ -72,4 +72,6 @@
IS_MISO = 34,
IS_LINEAR = 35,
IS_SHORT_FRAMES = 36,
+ ISDBT_MODE = 37,
+ ISDBT_PARTIAL_RECEPTION_FLAG = 38,
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FilterDelayHint.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FilterDelayHint.aidl
index 8174a51..3f1ca35 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FilterDelayHint.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FilterDelayHint.aidl
@@ -22,6 +22,7 @@
* Filter Delay Hint
* Gives information to the filter to assist in delaying / accumulating filter events.
* See FilterDelayHintType for more information regarding the hintValue units.
+ * Note: this hint is not valid for media filters.
* @hide
*/
@VintfStability
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInterleaveMode.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
index 3aa17dd..106ef67 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendInterleaveMode.aidl
@@ -19,6 +19,7 @@
import android.hardware.tv.tuner.FrontendAtsc3TimeInterleaveMode;
import android.hardware.tv.tuner.FrontendCableTimeInterleaveMode;
import android.hardware.tv.tuner.FrontendDtmbTimeInterleaveMode;
+import android.hardware.tv.tuner.FrontendIsdbtTimeInterleaveMode;
/**
* @hide
@@ -31,4 +32,6 @@
FrontendCableTimeInterleaveMode dvbc;
FrontendDtmbTimeInterleaveMode dtmb;
+
+ FrontendIsdbtTimeInterleaveMode isdbt;
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
index 4b764ad..b2bdfd4 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtCapabilities.aidl
@@ -46,4 +46,19 @@
* Guard Interval Types defined by FrontendIsdbtGuardInterval.
*/
int guardIntervalCap;
+
+ /**
+ * Time Interleaves defined by FrontendIsdbtTimeInterleaveMode.
+ */
+ int timeInterleaveCap;
+
+ /**
+ * If segment auto Supported or not.
+ */
+ boolean isSegmentAuto;
+
+ /**
+ * If full segment supported or not.
+ */
+ boolean isFullSegment;
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl
new file mode 100644
index 0000000..0b44ecb
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtLayerSettings.aidl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2021 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.hardware.tv.tuner;
+
+import android.hardware.tv.tuner.FrontendIsdbtCoderate;
+import android.hardware.tv.tuner.FrontendIsdbtModulation;
+import android.hardware.tv.tuner.FrontendIsdbtTimeInterleaveMode;
+
+/**
+ * Layer Settings for ISDB-T Frontend.
+ * @hide
+ */
+@VintfStability
+parcelable FrontendIsdbtLayerSettings {
+ FrontendIsdbtModulation modulation = FrontendIsdbtModulation.UNDEFINED;
+
+ FrontendIsdbtCoderate coderate = FrontendIsdbtCoderate.UNDEFINED;
+
+ FrontendIsdbtTimeInterleaveMode timeInterleave = FrontendIsdbtTimeInterleaveMode.UNDEFINED;
+
+ /**
+ * 0 ~ 13 and 0xFF(Auto)
+ */
+ int numOfSegment;
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
new file mode 100644
index 0000000..81c28cd
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtPartialReceptionFlag.aidl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2021 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.hardware.tv.tuner;
+
+/**
+ * Partial Reception Flag for an ISTB-T Frontend.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIsdbtPartialReceptionFlag {
+ UNDEFINED = 0,
+
+ /**
+ * Hardware is able to detect and set Partial Reception Flag automatically.
+ */
+ AUTO = 1 << 0,
+
+ FALSE = 1 << 1,
+
+ TRUE = 1 << 2,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
index 08f6130..23a4769 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtSettings.aidl
@@ -17,10 +17,10 @@
package android.hardware.tv.tuner;
import android.hardware.tv.tuner.FrontendIsdbtBandwidth;
-import android.hardware.tv.tuner.FrontendIsdbtCoderate;
import android.hardware.tv.tuner.FrontendIsdbtGuardInterval;
+import android.hardware.tv.tuner.FrontendIsdbtLayerSettings;
import android.hardware.tv.tuner.FrontendIsdbtMode;
-import android.hardware.tv.tuner.FrontendIsdbtModulation;
+import android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag;
import android.hardware.tv.tuner.FrontendSpectralInversion;
/**
@@ -41,15 +41,15 @@
FrontendSpectralInversion inversion = FrontendSpectralInversion.UNDEFINED;
- FrontendIsdbtModulation modulation = FrontendIsdbtModulation.UNDEFINED;
-
FrontendIsdbtBandwidth bandwidth = FrontendIsdbtBandwidth.UNDEFINED;
FrontendIsdbtMode mode = FrontendIsdbtMode.UNDEFINED;
- FrontendIsdbtCoderate coderate = FrontendIsdbtCoderate.UNDEFINED;
-
FrontendIsdbtGuardInterval guardInterval = FrontendIsdbtGuardInterval.UNDEFINED;
int serviceAreaId;
+
+ FrontendIsdbtPartialReceptionFlag partialReceptionFlag = FrontendIsdbtPartialReceptionFlag.UNDEFINED;
+
+ FrontendIsdbtLayerSettings[] layerSettings;
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
new file mode 100644
index 0000000..6192fca
--- /dev/null
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendIsdbtTimeInterleaveMode.aidl
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2021 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.hardware.tv.tuner;
+
+/**
+ * Time Interleave Mode for ISDB-T Frontend.
+ * @hide
+ */
+@VintfStability
+@Backing(type="int")
+enum FrontendIsdbtTimeInterleaveMode {
+ UNDEFINED = 0,
+
+ /**
+ * Hardware is able to detect and set Time Interleave Mode automatically.
+ */
+ AUTO = 1 << 0,
+
+ INTERLEAVE_1_0 = 1 << 1,
+
+ INTERLEAVE_1_4 = 1 << 2,
+
+ INTERLEAVE_1_8 = 1 << 3,
+
+ INTERLEAVE_1_16 = 1 << 4,
+
+ INTERLEAVE_2_0 = 1 << 5,
+
+ INTERLEAVE_2_2 = 1 << 6,
+
+ INTERLEAVE_2_4 = 1 << 7,
+
+ INTERLEAVE_2_8 = 1 << 8,
+
+ INTERLEAVE_3_0 = 1 << 9,
+
+ INTERLEAVE_3_1 = 1 << 10,
+
+ INTERLEAVE_3_2 = 1 << 11,
+
+ INTERLEAVE_3_4 = 1 << 12,
+}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
index ddbd0f8..9302b76 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatus.aidl
@@ -21,6 +21,8 @@
import android.hardware.tv.tuner.FrontendGuardInterval;
import android.hardware.tv.tuner.FrontendInnerFec;
import android.hardware.tv.tuner.FrontendInterleaveMode;
+import android.hardware.tv.tuner.FrontendIsdbtMode;
+import android.hardware.tv.tuner.FrontendIsdbtPartialReceptionFlag;
import android.hardware.tv.tuner.FrontendModulation;
import android.hardware.tv.tuner.FrontendModulationStatus;
import android.hardware.tv.tuner.FrontendRollOff;
@@ -190,4 +192,14 @@
* If short frames is enabled or not.
*/
boolean isShortFrames;
+
+ /**
+ * ISDB-T Mode.
+ */
+ FrontendIsdbtMode isdbtMode;
+
+ /**
+ * ISDB-T Partial Reception Flag.
+ */
+ FrontendIsdbtPartialReceptionFlag partialReceptionFlag;
}
diff --git a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
index 93b75b0..103a4ab 100644
--- a/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
+++ b/tv/tuner/aidl/android/hardware/tv/tuner/FrontendStatusType.aidl
@@ -208,4 +208,14 @@
* If short frames is enabled or not.
*/
IS_SHORT_FRAMES,
+
+ /**
+ * ISDB-T Mode.
+ */
+ ISDBT_MODE,
+
+ /**
+ * ISDB-T Partial Reception Flag.
+ */
+ ISDBT_PARTIAL_RECEPTION_FLAG,
}
diff --git a/tv/tuner/aidl/default/Filter.cpp b/tv/tuner/aidl/default/Filter.cpp
index c377772..5b6debb 100644
--- a/tv/tuner/aidl/default/Filter.cpp
+++ b/tv/tuner/aidl/default/Filter.cpp
@@ -34,16 +34,135 @@
#define WAIT_TIMEOUT 3000000000
-Filter::Filter() {}
+FilterCallbackScheduler::FilterCallbackScheduler(const std::shared_ptr<IFilterCallback>& cb)
+ : mCallback(cb), mDataLength(0), mTimeDelayInMs(0), mDataSizeDelayInBytes(0) {
+ start();
+}
+
+FilterCallbackScheduler::~FilterCallbackScheduler() {
+ stop();
+}
+
+void FilterCallbackScheduler::onFilterEvent(DemuxFilterEvent&& event) {
+ std::lock_guard<std::mutex> lock(mLock);
+ mCallbackBuffer.push_back(std::move(event));
+ mDataLength += getDemuxFilterEventDataLength(event);
+
+ if (mDataLength >= mDataSizeDelayInBytes) {
+ // size limit has been reached, send out events
+ mCv.notify_all();
+ }
+}
+
+void FilterCallbackScheduler::onFilterStatus(const DemuxFilterStatus& status) {
+ if (mCallback) {
+ mCallback->onFilterStatus(status);
+ }
+}
+
+void FilterCallbackScheduler::setTimeDelayHint(int timeDelay) {
+ // updating the setTimeDelay does not go into effect until the condition
+ // variable times out or is notified.
+ // One possibility is to notify the condition variable right away when the
+ // time delay changes, but I don't see the benefit over waiting for the next
+ // timeout / push, since -- in any case -- this will not change very often.
+ mTimeDelayInMs = timeDelay;
+}
+
+void FilterCallbackScheduler::setDataSizeDelayHint(int dataSizeDelay) {
+ // similar to updating the time delay hint, when mDataSizeDelayInBytes
+ // changes, this will not go into immediate effect, but will wait until the
+ // next filterEvent.
+ // We could technically check the current data length and notify the
+ // condition variable if we wanted to, but again, this may be overkill.
+ mDataSizeDelayInBytes = dataSizeDelay;
+}
+
+bool FilterCallbackScheduler::hasCallbackRegistered() const {
+ return mCallback != nullptr;
+}
+
+void FilterCallbackScheduler::start() {
+ mIsRunning = true;
+ mCallbackThread = std::thread(&FilterCallbackScheduler::threadLoop, this);
+}
+
+void FilterCallbackScheduler::stop() {
+ mIsRunning = false;
+ if (mCallbackThread.joinable()) {
+ mCv.notify_all();
+ mCallbackThread.join();
+ }
+}
+
+void FilterCallbackScheduler::threadLoop() {
+ while (mIsRunning) {
+ threadLoopOnce();
+ }
+}
+
+void FilterCallbackScheduler::threadLoopOnce() {
+ std::unique_lock<std::mutex> lock(mLock);
+ // mTimeDelayInMs is an atomic value, so it should be copied into a local
+ // variable before use (to make sure both the if statement and wait_for use
+ // the same value).
+ int timeDelayInMs = mTimeDelayInMs;
+ if (timeDelayInMs > 0) {
+ mCv.wait_for(lock, std::chrono::milliseconds(timeDelayInMs));
+ } else {
+ // no reason to timeout, just wait until main thread determines it's
+ // okay to send data.
+ mCv.wait(lock);
+ }
+
+ // condition_variable wait locks mutex on timeout / notify
+ // Note: if stop() has been called in the meantime, do not send more filter
+ // events.
+ if (mIsRunning && !mCallbackBuffer.empty()) {
+ if (mCallback) {
+ mCallback->onFilterEvent(mCallbackBuffer);
+ }
+ mCallbackBuffer.clear();
+ mDataLength = 0;
+ }
+ lock.unlock();
+}
+
+int FilterCallbackScheduler::getDemuxFilterEventDataLength(const DemuxFilterEvent& event) {
+ // there is a risk that dataLength could be a negative value, but it
+ // *should* be safe to assume that it is always positive.
+ switch (event.getTag()) {
+ case DemuxFilterEvent::Tag::section:
+ return event.get<DemuxFilterEvent::Tag::section>().dataLength;
+ case DemuxFilterEvent::Tag::media:
+ return event.get<DemuxFilterEvent::Tag::media>().dataLength;
+ case DemuxFilterEvent::Tag::pes:
+ return event.get<DemuxFilterEvent::Tag::pes>().dataLength;
+ case DemuxFilterEvent::Tag::download:
+ return event.get<DemuxFilterEvent::Tag::download>().dataLength;
+ case DemuxFilterEvent::Tag::ipPayload:
+ return event.get<DemuxFilterEvent::Tag::ipPayload>().dataLength;
+
+ case DemuxFilterEvent::Tag::tsRecord:
+ case DemuxFilterEvent::Tag::mmtpRecord:
+ case DemuxFilterEvent::Tag::temi:
+ case DemuxFilterEvent::Tag::monitorEvent:
+ case DemuxFilterEvent::Tag::startId:
+ // these events do not include a payload and should therefore return
+ // 0.
+ // do not add a default option, so this will not compile when new types
+ // are added.
+ return 0;
+ }
+}
Filter::Filter(DemuxFilterType type, int64_t filterId, uint32_t bufferSize,
- const std::shared_ptr<IFilterCallback>& cb, std::shared_ptr<Demux> demux) {
- mType = type;
- mFilterId = filterId;
- mBufferSize = bufferSize;
- mDemux = demux;
- mCallback = cb;
-
+ const std::shared_ptr<IFilterCallback>& cb, std::shared_ptr<Demux> demux)
+ : mDemux(demux),
+ mCallbackScheduler(cb),
+ mFilterId(filterId),
+ mBufferSize(bufferSize),
+ mType(type) {
switch (mType.mainType) {
case DemuxFilterMainType::TS:
if (mType.subType.get<DemuxFilterSubType::Tag::tsFilterType>() ==
@@ -112,9 +231,29 @@
}
::ndk::ScopedAStatus Filter::setDelayHint(const FilterDelayHint& in_hint) {
+ if (mIsMediaFilter) {
+ // delay hint is not supported for media filters
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
ALOGV("%s", __FUNCTION__);
- (void)in_hint;
- // TODO: implement
+ if (in_hint.hintValue < 0) {
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_ARGUMENT));
+ }
+
+ switch (in_hint.hintType) {
+ case FilterDelayHintType::TIME_DELAY_IN_MS:
+ mCallbackScheduler.setTimeDelayHint(in_hint.hintValue);
+ break;
+ case FilterDelayHintType::DATA_SIZE_DELAY_IN_BYTES:
+ mCallbackScheduler.setDataSizeDelayHint(in_hint.hintValue);
+ break;
+ default:
+ return ::ndk::ScopedAStatus::fromServiceSpecificError(
+ static_cast<int32_t>(Result::INVALID_ARGUMENT));
+ }
return ::ndk::ScopedAStatus::ok();
}
@@ -155,40 +294,36 @@
::ndk::ScopedAStatus Filter::start() {
ALOGV("%s", __FUNCTION__);
mFilterThreadRunning = true;
- vector<DemuxFilterEvent> events;
+ std::vector<DemuxFilterEvent> events;
// All the filter event callbacks in start are for testing purpose.
switch (mType.mainType) {
case DemuxFilterMainType::TS:
createMediaEvent(events);
- mCallback->onFilterEvent(events);
createTsRecordEvent(events);
- mCallback->onFilterEvent(events);
createTemiEvent(events);
- mCallback->onFilterEvent(events);
break;
case DemuxFilterMainType::MMTP:
createDownloadEvent(events);
- mCallback->onFilterEvent(events);
createMmtpRecordEvent(events);
- mCallback->onFilterEvent(events);
break;
case DemuxFilterMainType::IP:
createSectionEvent(events);
- mCallback->onFilterEvent(events);
createIpPayloadEvent(events);
- mCallback->onFilterEvent(events);
break;
case DemuxFilterMainType::TLV:
createMonitorEvent(events);
- mCallback->onFilterEvent(events);
break;
case DemuxFilterMainType::ALP:
createMonitorEvent(events);
- mCallback->onFilterEvent(events);
break;
default:
break;
}
+
+ for (auto&& event : events) {
+ mCallbackScheduler.onFilterEvent(std::move(event));
+ }
+
return startFilterLoop();
}
@@ -327,15 +462,14 @@
if (newScramblingStatus ^ mScramblingStatusMonitored) {
mScramblingStatusMonitored = newScramblingStatus;
if (mScramblingStatusMonitored) {
- if (mCallback != nullptr) {
+ if (mCallbackScheduler.hasCallbackRegistered()) {
// Assuming current status is always NOT_SCRAMBLED
- vector<DemuxFilterEvent> events;
- DemuxFilterMonitorEvent monitorEvent;
- events.resize(1);
- monitorEvent.set<DemuxFilterMonitorEvent::Tag::scramblingStatus>(
+ auto monitorEvent = DemuxFilterMonitorEvent::make<
+ DemuxFilterMonitorEvent::Tag::scramblingStatus>(
ScramblingStatus::NOT_SCRAMBLED);
- events[0].set<DemuxFilterEvent::monitorEvent>(monitorEvent);
- mCallback->onFilterEvent(events);
+ auto event =
+ DemuxFilterEvent::make<DemuxFilterEvent::Tag::monitorEvent>(monitorEvent);
+ mCallbackScheduler.onFilterEvent(std::move(event));
} else {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_STATE));
@@ -347,14 +481,13 @@
if (newIpCid ^ mIpCidMonitored) {
mIpCidMonitored = newIpCid;
if (mIpCidMonitored) {
- if (mCallback != nullptr) {
+ if (mCallbackScheduler.hasCallbackRegistered()) {
// Return random cid
- vector<DemuxFilterEvent> events;
- DemuxFilterMonitorEvent monitorEvent;
- events.resize(1);
- monitorEvent.set<DemuxFilterMonitorEvent::Tag::cid>(1);
- events[0].set<DemuxFilterEvent::monitorEvent>(monitorEvent);
- mCallback->onFilterEvent(events);
+ auto monitorEvent =
+ DemuxFilterMonitorEvent::make<DemuxFilterMonitorEvent::Tag::cid>(1);
+ auto event =
+ DemuxFilterEvent::make<DemuxFilterEvent::Tag::monitorEvent>(monitorEvent);
+ mCallbackScheduler.onFilterEvent(std::move(event));
} else {
return ::ndk::ScopedAStatus::fromServiceSpecificError(
static_cast<int32_t>(Result::INVALID_STATE));
@@ -410,26 +543,26 @@
}
// After successfully write, send a callback and wait for the read to be done
- if (mCallback != nullptr) {
+ if (mCallbackScheduler.hasCallbackRegistered()) {
if (mConfigured) {
- vector<DemuxFilterEvent> startEvent;
- startEvent.resize(1);
- startEvent[0].set<DemuxFilterEvent::Tag::startId>(mStartId++);
- mCallback->onFilterEvent(startEvent);
+ auto startEvent =
+ DemuxFilterEvent::make<DemuxFilterEvent::Tag::startId>(mStartId++);
+ mCallbackScheduler.onFilterEvent(std::move(startEvent));
mConfigured = false;
}
- mCallback->onFilterEvent(mFilterEvents);
+
+ for (auto&& event : mFilterEvents) {
+ mCallbackScheduler.onFilterEvent(std::move(event));
+ }
} else {
ALOGD("[Filter] filter callback is not configured yet.");
mFilterThreadRunning = false;
return;
}
- mFilterEvents.resize(0);
+ mFilterEvents.clear();
mFilterStatus = DemuxFilterStatus::DATA_READY;
- if (mCallback != nullptr) {
- mCallback->onFilterStatus(mFilterStatus);
- }
+ mCallbackScheduler.onFilterStatus(mFilterStatus);
break;
}
@@ -460,10 +593,10 @@
continue;
}
// After successfully write, send a callback and wait for the read to be done
- if (mCallback != nullptr) {
- mCallback->onFilterEvent(mFilterEvents);
+ for (auto&& event : mFilterEvents) {
+ mCallbackScheduler.onFilterEvent(std::move(event));
}
- mFilterEvents.resize(0);
+ mFilterEvents.clear();
break;
}
// We do not wait for the last read to be done
@@ -499,9 +632,7 @@
DemuxFilterStatus newStatus = checkFilterStatusChange(
availableToWrite, availableToRead, ceil(fmqSize * 0.75), ceil(fmqSize * 0.25));
if (mFilterStatus != newStatus) {
- if (mCallback != nullptr) {
- mCallback->onFilterStatus(newStatus);
- }
+ mCallbackScheduler.onFilterStatus(newStatus);
mFilterStatus = newStatus;
}
}
@@ -657,9 +788,7 @@
ALOGD("[Filter] assembled pes data length %d", pesEvent.dataLength);
}
- int size = mFilterEvents.size();
- mFilterEvents.resize(size + 1);
- mFilterEvents[size].set<DemuxFilterEvent::Tag::pes>(pesEvent);
+ mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::pes>(pesEvent));
mPesOutput.clear();
}
@@ -763,11 +892,7 @@
.firstMbInSlice = 0, // random address
};
- int size;
- size = mFilterEvents.size();
- mFilterEvents.resize(size + 1);
- mFilterEvents[size].set<DemuxFilterEvent::Tag::tsRecord>(recordEvent);
-
+ mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::tsRecord>(recordEvent));
mRecordFilterOutput.clear();
return ::ndk::ScopedAStatus::ok();
}
@@ -789,8 +914,6 @@
if (!writeDataToFilterMQ(data)) {
return false;
}
- int size = mFilterEvents.size();
- mFilterEvents.resize(size + 1);
DemuxFilterSectionEvent secEvent;
secEvent = {
// temp dump meta data
@@ -799,7 +922,7 @@
.sectionNum = 1,
.dataLength = static_cast<int32_t>(data.size()),
};
- mFilterEvents[size].set<DemuxFilterEvent::Tag::section>(secEvent);
+ mFilterEvents.push_back(DemuxFilterEvent::make<DemuxFilterEvent::Tag::section>(secEvent));
return true;
}
@@ -888,19 +1011,16 @@
mDataId2Avfd[dataId] = dup(av_fd);
// Create mediaEvent and send callback
- int size = mFilterEvents.size();
- mFilterEvents.resize(size + 1);
-
- mFilterEvents[size] = DemuxFilterEvent::make<DemuxFilterEvent::Tag::media>();
- mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().avMemory =
- ::android::dupToAidl(nativeHandle);
- mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().dataLength =
- static_cast<int64_t>(output.size());
- mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().avDataId = static_cast<int64_t>(dataId);
+ auto event = DemuxFilterEvent::make<DemuxFilterEvent::Tag::media>();
+ auto& mediaEvent = event.get<DemuxFilterEvent::Tag::media>();
+ mediaEvent.avMemory = ::android::dupToAidl(nativeHandle);
+ mediaEvent.dataLength = static_cast<int64_t>(output.size());
+ mediaEvent.avDataId = static_cast<int64_t>(dataId);
if (mPts) {
- mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().pts = mPts;
+ mediaEvent.pts = mPts;
mPts = 0;
}
+ mFilterEvents.push_back(std::move(event));
// Clear and log
native_handle_close(nativeHandle);
@@ -931,18 +1051,17 @@
}
// Create mediaEvent and send callback
- int size = mFilterEvents.size();
- mFilterEvents.resize(size + 1);
- mFilterEvents[size] = DemuxFilterEvent::make<DemuxFilterEvent::Tag::media>();
- mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().avMemory =
- ::android::dupToAidl(nativeHandle);
- mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().offset = mSharedAvMemOffset;
- mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().dataLength =
- static_cast<int64_t>(output.size());
+ auto event = DemuxFilterEvent::make<DemuxFilterEvent::Tag::media>();
+ auto& mediaEvent = event.get<DemuxFilterEvent::Tag::media>();
+ mediaEvent.avMemory = ::android::dupToAidl(nativeHandle);
+ mediaEvent.offset = mSharedAvMemOffset;
+ mediaEvent.dataLength = static_cast<int64_t>(output.size());
if (mPts) {
- mFilterEvents[size].get<DemuxFilterEvent::Tag::media>().pts = mPts;
+ mediaEvent.pts = mPts;
mPts = 0;
}
+ mFilterEvents.push_back(std::move(event));
+
mSharedAvMemOffset += output.size();
// Clear and log
diff --git a/tv/tuner/aidl/default/Filter.h b/tv/tuner/aidl/default/Filter.h
index 11bbc11..a5adf4c 100644
--- a/tv/tuner/aidl/default/Filter.h
+++ b/tv/tuner/aidl/default/Filter.h
@@ -18,6 +18,8 @@
#include <aidl/android/hardware/tv/tuner/BnFilter.h>
#include <aidl/android/hardware/tv/tuner/Constant.h>
+#include <aidl/android/hardware/tv/tuner/DemuxFilterEvent.h>
+#include <aidl/android/hardware/tv/tuner/DemuxFilterStatus.h>
#include <fmq/AidlMessageQueue.h>
#include <inttypes.h>
@@ -25,6 +27,7 @@
#include <math.h>
#include <sys/stat.h>
#include <atomic>
+#include <condition_variable>
#include <set>
#include <thread>
@@ -52,10 +55,49 @@
class Demux;
class Dvr;
-class Filter : public BnFilter {
+class FilterCallbackScheduler final {
public:
- Filter();
+ FilterCallbackScheduler(const std::shared_ptr<IFilterCallback>& cb);
+ ~FilterCallbackScheduler();
+ void onFilterEvent(DemuxFilterEvent&& event);
+ void onFilterStatus(const DemuxFilterStatus& status);
+
+ void setTimeDelayHint(int timeDelay);
+ void setDataSizeDelayHint(int dataSizeDelay);
+
+ bool hasCallbackRegistered() const;
+
+ private:
+ void start();
+ void stop();
+
+ void threadLoop();
+ void threadLoopOnce();
+
+ static int getDemuxFilterEventDataLength(const DemuxFilterEvent& event);
+
+ private:
+ std::shared_ptr<IFilterCallback> mCallback;
+ std::thread mCallbackThread;
+ std::atomic<bool> mIsRunning;
+
+ // mLock protects mCallbackBuffer, mCv, and mDataLength
+ std::mutex mLock;
+ std::vector<DemuxFilterEvent> mCallbackBuffer;
+ std::condition_variable mCv;
+ int mDataLength;
+
+ // both of these need to be atomic (not just mTimeDelayInMs) as this class
+ // needs to be threadsafe.
+ std::atomic<int> mTimeDelayInMs;
+ std::atomic<int> mDataSizeDelayInBytes;
+};
+
+class Filter : public BnFilter {
+ friend class FilterCallbackScheduler;
+
+ public:
Filter(DemuxFilterType type, int64_t filterId, uint32_t bufferSize,
const std::shared_ptr<IFilterCallback>& cb, std::shared_ptr<Demux> demux);
@@ -104,10 +146,8 @@
std::shared_ptr<Demux> mDemux;
// Dvr reference once the filter is attached to any
std::shared_ptr<Dvr> mDvr = nullptr;
- /**
- * Filter callbacks used on filter events or FMQ status
- */
- std::shared_ptr<IFilterCallback> mCallback = nullptr;
+
+ FilterCallbackScheduler mCallbackScheduler;
int64_t mFilterId;
int32_t mCid = static_cast<int32_t>(Constant::INVALID_IP_FILTER_CONTEXT_ID);
diff --git a/tv/tuner/aidl/default/Frontend.cpp b/tv/tuner/aidl/default/Frontend.cpp
index f9e697e..77d20e2 100644
--- a/tv/tuner/aidl/default/Frontend.cpp
+++ b/tv/tuner/aidl/default/Frontend.cpp
@@ -607,6 +607,13 @@
status.set<FrontendStatus::interleaving>(interleaves);
break;
}
+ case FrontendType::ISDBT: {
+ interleave.set<FrontendInterleaveMode::Tag::isdbt>(
+ FrontendIsdbtTimeInterleaveMode::INTERLEAVE_1_0); // value = 1 << 1
+ interleaves.push_back(interleave);
+ status.set<FrontendStatus::interleaving>(interleaves);
+ break;
+ }
default:
break;
}
@@ -660,6 +667,15 @@
status.set<FrontendStatus::isShortFrames>(true);
break;
}
+ case FrontendStatusType::ISDBT_MODE: {
+ status.set<FrontendStatus::isdbtMode>(FrontendIsdbtMode::AUTO);
+ break;
+ }
+ case FrontendStatusType::ISDBT_PARTIAL_RECEPTION_FLAG: {
+ status.set<FrontendStatus::partialReceptionFlag>(
+ FrontendIsdbtPartialReceptionFlag::AUTO);
+ break;
+ }
default: {
continue;
}
diff --git a/tv/tuner/aidl/default/Tuner.cpp b/tv/tuner/aidl/default/Tuner.cpp
index 8468929..badb08f 100644
--- a/tv/tuner/aidl/default/Tuner.cpp
+++ b/tv/tuner/aidl/default/Tuner.cpp
@@ -119,6 +119,10 @@
.coderateCap = (int)FrontendIsdbtCoderate::CODERATE_4_5 |
(int)FrontendIsdbtCoderate::CODERATE_6_7,
.guardIntervalCap = (int)FrontendIsdbtGuardInterval::INTERVAL_1_128,
+ .timeInterleaveCap = (int)FrontendIsdbtTimeInterleaveMode::AUTO |
+ (int)FrontendIsdbtTimeInterleaveMode::INTERLEAVE_1_0,
+ .isSegmentAuto = true,
+ .isFullSegment = true,
};
capsIsdbt.set<FrontendCapabilities::Tag::isdbtCaps>(isdbtCaps);
mFrontendCaps[5] = capsIsdbt;
@@ -131,6 +135,9 @@
FrontendStatusType::GUARD_INTERVAL,
FrontendStatusType::TRANSMISSION_MODE,
FrontendStatusType::ISDBT_SEGMENTS,
+ FrontendStatusType::ISDBT_MODE,
+ FrontendStatusType::ISDBT_PARTIAL_RECEPTION_FLAG,
+ FrontendStatusType::INTERLEAVINGS,
};
mFrontendStatusCaps[5] = statusCaps;
diff --git a/tv/tuner/aidl/vts/functional/FilterTests.h b/tv/tuner/aidl/vts/functional/FilterTests.h
index 91a0a4a..c965d95 100644
--- a/tv/tuner/aidl/vts/functional/FilterTests.h
+++ b/tv/tuner/aidl/vts/functional/FilterTests.h
@@ -74,7 +74,6 @@
void setFilterId(int32_t filterId) { mFilterId = filterId; }
void setFilterInterface(std::shared_ptr<IFilter> filter) { mFilter = filter; }
- void setFilterEventType(FilterEventType type) { mFilterEventType = type; }
void setSharedHandle(native_handle_t* sharedHandle) { mAvSharedHandle = sharedHandle; }
void setMemSize(uint64_t size) { mAvSharedMemSize = size; }
@@ -89,7 +88,6 @@
private:
int32_t mFilterId;
std::shared_ptr<IFilter> mFilter;
- FilterEventType mFilterEventType;
native_handle_t* mAvSharedHandle = nullptr;
uint64_t mAvSharedMemSize = -1;
diff --git a/tv/tuner/aidl/vts/functional/FrontendTests.cpp b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
index 77add8e..f1c3595 100644
--- a/tv/tuner/aidl/vts/functional/FrontendTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FrontendTests.cpp
@@ -387,6 +387,16 @@
expectStatuses[i].get<FrontendStatus::Tag::isShortFrames>());
break;
}
+ case FrontendStatusType::ISDBT_MODE: {
+ ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::isdbtMode>() ==
+ expectStatuses[i].get<FrontendStatus::Tag::isdbtMode>());
+ break;
+ }
+ case FrontendStatusType::ISDBT_PARTIAL_RECEPTION_FLAG: {
+ ASSERT_TRUE(realStatuses[i].get<FrontendStatus::Tag::partialReceptionFlag>() ==
+ expectStatuses[i].get<FrontendStatus::Tag::partialReceptionFlag>());
+ break;
+ }
default: {
continue;
}
diff --git a/uwb/aidl/Android.bp b/uwb/aidl/Android.bp
index 0d1ebc2..a1a66e5 100755
--- a/uwb/aidl/Android.bp
+++ b/uwb/aidl/Android.bp
@@ -53,9 +53,6 @@
],
},
ndk: {
- vndk: {
- enabled: true,
- },
apex_available: [
"//apex_available:platform",
"com.android.uwb",
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
new file mode 100644
index 0000000..774133e
--- /dev/null
+++ b/uwb/aidl/aidl_api/android.hardware.uwb.fira_android/current/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+///////////////////////////////////////////////////////////////////////////////
+// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
+///////////////////////////////////////////////////////////////////////////////
+
+// This file is a snapshot of an AIDL file. Do not edit it manually. There are
+// two cases:
+// 1). this is a frozen version file - do not edit this in any case.
+// 2). this is a 'current' file. If you make a backwards compatible change to
+// the interface (from the latest frozen version), the build system will
+// prompt you to update this file with `m <name>-update-api`.
+//
+// You must not make a backward incompatible change to any AIDL file built
+// with the aidl_interface module type with versions property set. The module
+// type is used to build AIDL files in a way that they can be used across
+// independently updatable components of the system. If a device is shipped
+// with such a backward incompatible change, it has a high risk of breaking
+// later when a module using the interface is updated, e.g., Mainline modules.
+
+package android.hardware.uwb.fira_android;
+@Backing(type="long") @VintfStability
+enum UwbAndroidCapabilities {
+ POWER_STATS_QUERY = 1,
+}
diff --git a/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl b/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl
index 7074753..c4cb47b 100644
--- a/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl
+++ b/uwb/aidl/aidl_api/android.hardware.uwb/current/android/hardware/uwb/IUwbChip.aidl
@@ -40,6 +40,7 @@
void open(in android.hardware.uwb.IUwbClientCallback clientCallback);
void close();
void coreInit();
- int getSupportedVendorUciVersion();
+ int getSupportedAndroidUciVersion();
+ long getSupportedAndroidCapabilities();
int sendUciMessage(in byte[] data);
}
diff --git a/uwb/aidl/android/hardware/uwb/IUwbChip.aidl b/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
old mode 100755
new mode 100644
index 9530af4..0c98611
--- a/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
+++ b/uwb/aidl/android/hardware/uwb/IUwbChip.aidl
@@ -49,14 +49,24 @@
*/
void coreInit();
- /**
- * Supported version of vendor UCI specification.
- *
- * This corresponds to the version of the "android.hardware.uwb.fira_android" types-only
- * package included in the HAL implementation. This vendor params/commands package will be
- * updated on a different cadence to the main UWB HAL interface package.
- */
- int getSupportedVendorUciVersion();
+ /**
+ * Supported version of vendor UCI specification.
+ *
+ * @return Returns the version of the "android.hardware.uwb.fira_android" types-only
+ * package included in the HAL implementation. This vendor params/commands package will be
+ * updated on a different cadence to the main UWB HAL interface package.
+ */
+ int getSupportedAndroidUciVersion();
+
+ /**
+ * Mechanism to allow HAL implementation to optionally expose features that are defined
+ * in the "android.hardware.uwb.fira_android" types-only package.
+ *
+ * @return Returns the bitmask of capabilities
+ * (android.hardware.uwb.fira_android.UwbAndroidCapabilities) that is supported by the
+ * HAL implementation.
+ */
+ long getSupportedAndroidCapabilities();
/**
* Write the UCI message to the UWB Subsystem.
diff --git a/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl b/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
new file mode 100644
index 0000000..3486d5a
--- /dev/null
+++ b/uwb/aidl/android/hardware/uwb/fira_android/UwbAndroidCapabilities.aidl
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2021 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.hardware.uwb.fira_android;
+
+/**
+ * Android specific capabilities should be defined here.
+ *
+ * For any features enabled via the FIRA vendor commands for Android, use this bitmask
+ * to allow devices to expose the features supported by the HAL implementation.
+ *
+ */
+@VintfStability
+@Backing(type="long")
+enum UwbAndroidCapabilities {
+ /** TODO: Change the name if necessary when the corresponding vendor commands are added */
+ POWER_STATS_QUERY = 0x1,
+}
diff --git a/uwb/aidl/default/uwb_chip.cpp b/uwb/aidl/default/uwb_chip.cpp
index fe64fa7..10dbdb6 100644
--- a/uwb/aidl/default/uwb_chip.cpp
+++ b/uwb/aidl/default/uwb_chip.cpp
@@ -17,7 +17,8 @@
#include "uwb.h"
namespace {
-constexpr static int kVendorUciVersion = 1;
+constexpr static int32_t kAndroidUciVersion = 1;
+constexpr static int64_t kAndroidCapabilities = 0;
}
namespace android {
@@ -50,8 +51,13 @@
return ndk::ScopedAStatus::ok();
}
-::ndk::ScopedAStatus UwbChip::getSupportedVendorUciVersion(int32_t* version) {
- *version = kVendorUciVersion;
+::ndk::ScopedAStatus UwbChip::getSupportedAndroidUciVersion(int32_t* version) {
+ *version = kAndroidUciVersion;
+ return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus UwbChip::getSupportedAndroidCapabilities(int64_t* capabilities) {
+ *capabilities = kAndroidCapabilities;
return ndk::ScopedAStatus::ok();
}
diff --git a/uwb/aidl/default/uwb_chip.h b/uwb/aidl/default/uwb_chip.h
index ef1d5b6..ca97120 100644
--- a/uwb/aidl/default/uwb_chip.h
+++ b/uwb/aidl/default/uwb_chip.h
@@ -37,7 +37,8 @@
::ndk::ScopedAStatus open(const std::shared_ptr<IUwbClientCallback>& clientCallback) override;
::ndk::ScopedAStatus close() override;
::ndk::ScopedAStatus coreInit() override;
- ::ndk::ScopedAStatus getSupportedVendorUciVersion(int32_t* version) override;
+ ::ndk::ScopedAStatus getSupportedAndroidUciVersion(int32_t* version) override;
+ ::ndk::ScopedAStatus getSupportedAndroidCapabilities(int64_t* capabilities) override;
::ndk::ScopedAStatus sendUciMessage(const std::vector<uint8_t>& data,
int32_t* bytes_written) override;
diff --git a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
index 9ac2678..3820c0f 100644
--- a/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
+++ b/uwb/aidl/vts/VtsHalUwbTargetTest.cpp
@@ -166,15 +166,23 @@
EXPECT_TRUE(iuwb_chip->coreInit().isOk());
}
-TEST_P(UwbAidl, ChipGetSupportedVendorUciVersion) {
+TEST_P(UwbAidl, ChipGetSupportedAndroidUciVersion) {
const auto iuwb_chip = getAnyChipAndOpen();
EXPECT_TRUE(iuwb_chip->coreInit().isOk());
- int version;
- EXPECT_TRUE(iuwb_chip->getSupportedVendorUciVersion(&version).isOk());
+ int32_t version;
+ EXPECT_TRUE(iuwb_chip->getSupportedAndroidUciVersion(&version).isOk());
EXPECT_GT(version, 0);
}
+TEST_P(UwbAidl, ChipGetSupportedAndroidCapabilities) {
+ const auto iuwb_chip = getAnyChipAndOpen();
+ EXPECT_TRUE(iuwb_chip->coreInit().isOk());
+
+ int64_t capabilities;
+ EXPECT_TRUE(iuwb_chip->getSupportedAndroidCapabilities(&capabilities).isOk());
+}
+
TEST_P(UwbAidl, ChipGetName) {
std::string chip_name = getAnyChipName();
std::shared_ptr<IUwbChip> iuwb_chip;
diff --git a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
index 53f8c0e..09cc21b 100644
--- a/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
+++ b/vibrator/aidl/vts/VtsHalVibratorTargetTest.cpp
@@ -417,6 +417,9 @@
if (isPrimitiveSupported) {
EXPECT_EQ(Status::EX_NONE, status.exceptionCode());
+ if (primitive != CompositePrimitive::NOOP) {
+ ASSERT_GT(duration, 0) << toString(primitive) << " " << duration;
+ }
} else {
EXPECT_TRUE(isUnknownOrUnsupported(status)) << status;
}
diff --git a/wifi/hostapd/aidl/vts/functional/Android.bp b/wifi/hostapd/aidl/vts/functional/Android.bp
index d37da08..e58cf5e 100644
--- a/wifi/hostapd/aidl/vts/functional/Android.bp
+++ b/wifi/hostapd/aidl/vts/functional/Android.bp
@@ -16,9 +16,10 @@
srcs: ["VtsHalHostapdTargetTest.cpp"],
shared_libs: [
"libbinder",
+ "libbinder_ndk",
],
static_libs: [
- "android.hardware.wifi.hostapd-V1-cpp",
+ "android.hardware.wifi.hostapd-V1-ndk",
],
test_suites: [
"general-tests",
diff --git a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
index 92fbf50..41c54b3 100644
--- a/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
+++ b/wifi/hostapd/aidl/vts/functional/VtsHalHostapdTargetTest.cpp
@@ -14,33 +14,33 @@
* limitations under the License.
*/
#include <VtsCoreUtil.h>
-
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>
-#include <android/hardware/wifi/hostapd/BnHostapd.h>
+#include <aidl/android/hardware/wifi/hostapd/BnHostapd.h>
+#include <aidl/android/hardware/wifi/hostapd/BnHostapdCallback.h>
+#include <android/binder_manager.h>
#include <binder/IServiceManager.h>
#include <binder/ProcessState.h>
+using aidl::android::hardware::wifi::hostapd::BandMask;
+using aidl::android::hardware::wifi::hostapd::BnHostapdCallback;
+using aidl::android::hardware::wifi::hostapd::ChannelParams;
+using aidl::android::hardware::wifi::hostapd::DebugLevel;
+using aidl::android::hardware::wifi::hostapd::EncryptionType;
+using aidl::android::hardware::wifi::hostapd::FrequencyRange;
+using aidl::android::hardware::wifi::hostapd::Ieee80211ReasonCode;
+using aidl::android::hardware::wifi::hostapd::IfaceParams;
+using aidl::android::hardware::wifi::hostapd::IHostapd;
+using aidl::android::hardware::wifi::hostapd::NetworkParams;
using android::ProcessState;
-using android::sp;
-using android::String16;
-using android::hardware::wifi::hostapd::BandMask;
-using android::hardware::wifi::hostapd::ChannelParams;
-using android::hardware::wifi::hostapd::DebugLevel;
-using android::hardware::wifi::hostapd::EncryptionType;
-using android::hardware::wifi::hostapd::FrequencyRange;
-using android::hardware::wifi::hostapd::Ieee80211ReasonCode;
-using android::hardware::wifi::hostapd::IfaceParams;
-using android::hardware::wifi::hostapd::IHostapd;
-using android::hardware::wifi::hostapd::NetworkParams;
namespace {
const unsigned char kNwSsid[] = {'t', 'e', 's', 't', '1', '2', '3', '4', '5'};
-const String16 kIfaceName = String16("wlan0");
-const String16 kPassphrase = String16("test12345");
-const String16 kInvalidMinPassphrase = String16("test");
-const String16 kInvalidMaxPassphrase = String16(
- "0123456789012345678901234567890123456789012345678901234567890123456789");
+const std::string kIfaceName = "wlan0";
+const std::string kPassphrase = "test12345";
+const std::string kInvalidMinPassphrase = "test";
+const std::string kInvalidMaxPassphrase =
+ "0123456789012345678901234567890123456789012345678901234567890123456789";
const int kIfaceChannel = 6;
const int kIfaceInvalidChannel = 567;
const std::vector<uint8_t> kTestZeroMacAddr(6, 0x0);
@@ -56,8 +56,8 @@
class HostapdAidl : public testing::TestWithParam<std::string> {
public:
virtual void SetUp() override {
- hostapd = android::waitForDeclaredService<IHostapd>(
- String16(GetParam().c_str()));
+ hostapd = IHostapd::fromBinder(ndk::SpAIBinder(
+ AServiceManager_waitForService(GetParam().c_str())));
ASSERT_NE(hostapd, nullptr);
EXPECT_TRUE(hostapd->setDebugParams(DebugLevel::EXCESSIVE).isOk());
isAcsSupport = testing::checkSubstringInCommandOutput(
@@ -77,12 +77,12 @@
sleep(3);
}
- sp<IHostapd> hostapd;
+ std::shared_ptr<IHostapd> hostapd;
bool isAcsSupport;
bool isWpa3SaeSupport;
bool isBridgedSupport;
- IfaceParams getIfaceParamsWithoutAcs(String16 iface_name) {
+ IfaceParams getIfaceParamsWithoutAcs(std::string iface_name) {
IfaceParams iface_params;
ChannelParams channelParams;
std::vector<ChannelParams> vec_channelParams;
@@ -103,7 +103,7 @@
return iface_params;
}
- IfaceParams getIfaceParamsWithBridgedModeACS(String16 iface_name) {
+ IfaceParams getIfaceParamsWithBridgedModeACS(std::string iface_name) {
IfaceParams iface_params = getIfaceParamsWithoutAcs(iface_name);
iface_params.channelParams[0].enableAcs = true;
iface_params.channelParams[0].acsShouldExcludeDfs = true;
@@ -121,7 +121,7 @@
return iface_params;
}
- IfaceParams getIfaceParamsWithAcs(String16 iface_name) {
+ IfaceParams getIfaceParamsWithAcs(std::string iface_name) {
IfaceParams iface_params = getIfaceParamsWithoutAcs(iface_name);
iface_params.channelParams[0].enableAcs = true;
iface_params.channelParams[0].acsShouldExcludeDfs = true;
@@ -131,7 +131,7 @@
return iface_params;
}
- IfaceParams getIfaceParamsWithAcsAndFreqRange(String16 iface_name) {
+ IfaceParams getIfaceParamsWithAcsAndFreqRange(std::string iface_name) {
IfaceParams iface_params = getIfaceParamsWithAcs(iface_name);
FrequencyRange freqRange;
freqRange.startMhz = 2412;
@@ -143,7 +143,8 @@
return iface_params;
}
- IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange(String16 iface_name) {
+ IfaceParams getIfaceParamsWithAcsAndInvalidFreqRange(
+ std::string iface_name) {
IfaceParams iface_params =
getIfaceParamsWithAcsAndFreqRange(iface_name);
iface_params.channelParams[0].acsChannelFreqRangesMhz[0].startMhz =
@@ -153,7 +154,7 @@
return iface_params;
}
- IfaceParams getIfaceParamsWithInvalidChannel(String16 iface_name) {
+ IfaceParams getIfaceParamsWithInvalidChannel(std::string iface_name) {
IfaceParams iface_params = getIfaceParamsWithoutAcs(iface_name);
iface_params.channelParams[0].channel = kIfaceInvalidChannel;
return iface_params;
@@ -215,11 +216,37 @@
NetworkParams getInvalidSaeNwParams() {
NetworkParams nw_params = getOpenNwParams();
nw_params.encryptionType = EncryptionType::WPA3_SAE;
- nw_params.passphrase = String16("");
+ nw_params.passphrase = "";
return nw_params;
}
};
+class HostapdCallback : public BnHostapdCallback {
+ public:
+ HostapdCallback() = default;
+ ::ndk::ScopedAStatus onApInstanceInfoChanged(
+ const ::aidl::android::hardware::wifi::hostapd::ApInfo &) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onConnectedClientsChanged(
+ const ::aidl::android::hardware::wifi::hostapd::ClientInfo &) override {
+ return ndk::ScopedAStatus::ok();
+ }
+ ::ndk::ScopedAStatus onFailure(const std::string &) override {
+ return ndk::ScopedAStatus::ok();
+ }
+};
+
+/**
+ * Register callback
+ */
+TEST_P(HostapdAidl, RegisterCallback) {
+ std::shared_ptr<HostapdCallback> callback =
+ ndk::SharedRefBase::make<HostapdCallback>();
+ ASSERT_NE(callback, nullptr);
+ EXPECT_TRUE(hostapd->registerCallback(callback).isOk());
+}
+
/**
* Adds an access point with PSK network config & ACS enabled.
* Access point creation should pass.