Merge "Fix typo in HostEndpointInfo definition"
diff --git a/compatibility_matrices/compatibility_matrix.current.xml b/compatibility_matrices/compatibility_matrix.current.xml
index 5d92304..74d93b3 100644
--- a/compatibility_matrices/compatibility_matrix.current.xml
+++ b/compatibility_matrices/compatibility_matrix.current.xml
@@ -429,7 +429,7 @@
</hal>
<hal format="aidl" optional="true">
<name>android.hardware.neuralnetworks</name>
- <version>1-2</version>
+ <version>1-3</version>
<interface>
<name>IDevice</name>
<regex-instance>.*</regex-instance>
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 52276b4..a3cd8ae 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
@@ -41,6 +41,7 @@
android.hardware.gnss.IGnssMeasurementInterface getExtensionGnssMeasurement();
android.hardware.gnss.IGnssPowerIndication getExtensionGnssPowerIndication();
@nullable android.hardware.gnss.IGnssBatching getExtensionGnssBatching();
+ @nullable android.hardware.gnss.IGnssGeofence getExtensionGnssGeofence();
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/IGnssGeofence.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssGeofence.aidl
new file mode 100644
index 0000000..50da5bf
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssGeofence.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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 IGnssGeofence {
+ void setCallback(in android.hardware.gnss.IGnssGeofenceCallback callback);
+ void addGeofence(in int geofenceId, in double latitudeDegrees, in double longitudeDegrees, in double radiusMeters, in int lastTransition, in int monitorTransitions, in int notificationResponsivenessMs, in int unknownTimerMs);
+ void pauseGeofence(in int geofenceId);
+ void resumeGeofence(in int geofenceId, in int monitorTransitions);
+ void removeGeofence(in int geofenceId);
+}
diff --git a/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssGeofenceCallback.aidl b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssGeofenceCallback.aidl
new file mode 100644
index 0000000..26482ea
--- /dev/null
+++ b/gnss/aidl/aidl_api/android.hardware.gnss/current/android/hardware/gnss/IGnssGeofenceCallback.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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 IGnssGeofenceCallback {
+ void gnssGeofenceTransitionCb(in int geofenceId, in android.hardware.gnss.GnssLocation location, in int transition, in long timestampMillis);
+ void gnssGeofenceStatusCb(in int availability, in android.hardware.gnss.GnssLocation lastLocation);
+ void gnssGeofenceAddCb(in int geofenceId, in int status);
+ void gnssGeofenceRemoveCb(in int geofenceId, in int status);
+ void gnssGeofencePauseCb(in int geofenceId, in int status);
+ void gnssGeofenceResumeCb(in int geofenceId, in int status);
+ const int ENTERED = 1;
+ const int EXITED = 2;
+ const int UNCERTAIN = 4;
+ const int UNAVAILABLE = 1;
+ const int AVAILABLE = 2;
+ const int OPERATION_SUCCESS = 0;
+ const int ERROR_TOO_MANY_GEOFENCES = -100;
+ const int ERROR_ID_EXISTS = -101;
+ const int ERROR_ID_UNKNOWN = -102;
+ const int ERROR_INVALID_TRANSITION = -103;
+ const int ERROR_GENERIC = -149;
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnss.aidl b/gnss/aidl/android/hardware/gnss/IGnss.aidl
index b12fb82..e019d35 100644
--- a/gnss/aidl/android/hardware/gnss/IGnss.aidl
+++ b/gnss/aidl/android/hardware/gnss/IGnss.aidl
@@ -19,6 +19,7 @@
import android.hardware.gnss.IGnssBatching;
import android.hardware.gnss.IGnssCallback;
import android.hardware.gnss.IGnssConfiguration;
+import android.hardware.gnss.IGnssGeofence;
import android.hardware.gnss.IGnssMeasurementInterface;
import android.hardware.gnss.IGnssPowerIndication;
import android.hardware.gnss.IGnssPsds;
@@ -110,4 +111,11 @@
* @return Handle to the IGnssBatching interface.
*/
@nullable IGnssBatching getExtensionGnssBatching();
+
+ /**
+ * This method returns the IGnssGeofence interface.
+ *
+ * @return Handle to the IGnssGeofence interface.
+ */
+ @nullable IGnssGeofence getExtensionGnssGeofence();
}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssGeofence.aidl b/gnss/aidl/android/hardware/gnss/IGnssGeofence.aidl
new file mode 100644
index 0000000..bb4ff93
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssGeofence.aidl
@@ -0,0 +1,82 @@
+/*
+ * 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.IGnssGeofenceCallback;
+
+/** Extended interface for GNSS Geofence support. */
+@VintfStability
+interface IGnssGeofence {
+ /**
+ * Opens the geofence interface and provides the callback routines to the HAL.
+ *
+ * @param callback Handle to the IGnssGeofenceCallback interface.
+ */
+ void setCallback(in IGnssGeofenceCallback callback);
+
+ /**
+ * Add a geofence area. This api currently supports circular geofences.
+ *
+ * @param geofenceId The id for the geofence. If a geofence with this id already exists, an
+ * error value (ERROR_ID_EXISTS) must be returned.
+ * @param latitudeDegrees The latitude(in degrees) for the geofence lastTransition.
+ * @param longitudeDegrees The longitude(in degrees) for the geofence lastTransition.
+ * @param radiusMeters The radius(in meters) for the geofence lastTransition.
+ * @param lastTransition The current state of the geofence. It can be one of the transition
+ * states (ENTERED, EXITED, UNCERTAIN) as defined in IGnssGeofenceCallback. For example, if
+ * the system already knows that the user is inside the geofence, this will be set to ENTERED.
+ * In most cases, it will be UNCERTAIN.
+ * @param monitorTransitions A bitfield of ENTERED, EXITED and UNCERTAIN. It represents which
+ * transitions to monitor.
+ * @param notificationResponsivenessMs - Defines the best-effort description of how soon must
+ * the callback be called when the transition associated with the Geofence is triggered. For
+ * instance, if set to 1000 milliseconds with ENTERED, the callback must be called 1000
+ * milliseconds within entering the geofence. This parameter is defined in milliseconds.
+ * NOTE: This is not to be confused with the rate that the GNSS is polled at. It is acceptable
+ * to dynamically vary the rate of sampling the GNSS for power-saving reasons; thus the rate of
+ * sampling may be faster or slower than this.
+ * @param unknownTimerMs - The time limit in millisecondsafter which the UNCERTAIN transition
+ * must be triggered.
+ */
+ void addGeofence(in int geofenceId, in double latitudeDegrees, in double longitudeDegrees,
+ in double radiusMeters, in int lastTransition, in int monitorTransitions,
+ in int notificationResponsivenessMs, in int unknownTimerMs);
+
+ /**
+ * Pause monitoring a particular geofence.
+ *
+ * @param geofenceId The id for the geofence.
+ */
+ void pauseGeofence(in int geofenceId);
+
+ /**
+ * Resume monitoring a particular geofence.
+ *
+ * @param geofenceId - The id for the geofence.
+ * @param monitorTransitions Specifies which transitions to monitor. It can be a bitwise OR of
+ * ENTERED, EXITED and UNCERTAIN. This supersedes the value associated provided in the
+ * addGeofence call.
+ */
+ void resumeGeofence(in int geofenceId, in int monitorTransitions);
+
+ /**
+ * Remove a geofence area. After the function returns, no notifications must be sent.
+ *
+ * @param geofenceId The id of the geofence.
+ */
+ void removeGeofence(in int geofenceId);
+}
diff --git a/gnss/aidl/android/hardware/gnss/IGnssGeofenceCallback.aidl b/gnss/aidl/android/hardware/gnss/IGnssGeofenceCallback.aidl
new file mode 100644
index 0000000..c176965
--- /dev/null
+++ b/gnss/aidl/android/hardware/gnss/IGnssGeofenceCallback.aidl
@@ -0,0 +1,184 @@
+/*
+ * 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 GNSS geofence events from the HAL.
+ *
+ * There are 3 states associated with a Geofence: Inside, Outside, Unknown.
+ * There are 3 transitions: ENTERED, EXITED, UNCERTAIN.
+ *
+ * An example state diagram with confidence level: 95% and Unknown time limit
+ * set as 30 secs is shown below. (confidence level and Unknown time limit are
+ * explained latter).
+ * ____________________________
+ * | Unknown (30 secs) |
+ * """"""""""""""""""""""""""""
+ * ^ | | ^
+ * UNCERTAIN| |ENTERED EXITED| |UNCERTAIN
+ * | v v |
+ * ________ EXITED _________
+ * | Inside | -----------> | Outside |
+ * | | <----------- | |
+ * """""""" ENTERED """""""""
+ *
+ * Inside state: We are 95% confident that the user is inside the geofence.
+ * Outside state: We are 95% confident that the user is outside the geofence
+ * Unknown state: Rest of the time.
+ *
+ * The Unknown state is better explained with an example:
+ *
+ * __________
+ * | c|
+ * | ___ | _______
+ * | |a| | | b |
+ * | """ | """""""
+ * | |
+ * """"""""""
+ * In the diagram above, "a" and "b" are 2 geofences and "c" is the accuracy
+ * circle reported by the GNSS subsystem. Now with regard to "b", the system is
+ * confident that the user is outside. But with regard to "a" is not confident
+ * whether it is inside or outside the geofence. If the accuracy remains the
+ * same for a sufficient period of time, the UNCERTAIN transition must be
+ * triggered with the state set to Unknown. If the accuracy improves later, an
+ * appropriate transition must be triggered. This "sufficient period of time"
+ * is defined by the parameter in the addGeofenceArea API.
+ * In other words, Unknown state can be interpreted as a state in which the
+ * GNSS subsystem isn't confident enough that the user is either inside or
+ * outside the Geofence. It moves to Unknown state only after the expiry of the
+ * timeout.
+ *
+ * The geofence callback needs to be triggered for the ENTERED and EXITED
+ * transitions, when the GNSS system is confident that the user has entered
+ * (Inside state) or exited (Outside state) the Geofence. An implementation
+ * which uses a value of 95% as the confidence is recommended. The callback
+ * must be triggered only for the transitions requested by the
+ * addGeofenceArea method.
+ *
+ * Even though the diagram and explanation talks about states and transitions,
+ * the callee is only interested in the transitions. The states are mentioned
+ * here for illustrative purposes.
+ *
+ * Startup Scenario: When the device boots up, if an application adds geofences,
+ * and then we get an accurate GNSS location fix, it needs to trigger the
+ * appropriate (ENTERED or EXITED) transition for every Geofence it knows about.
+ * By default, all the Geofences will be in the Unknown state.
+ *
+ * When the GNSS system is unavailable, gnssGeofenceStatusCb must be
+ * called to inform the upper layers of the same. Similarly, when it becomes
+ * available the callback must be called. This is a global state while the
+ * UNKNOWN transition described above is per geofence.
+ *
+ * An important aspect to note is that users of this API (framework), will use
+ * other subsystems like wifi, sensors, cell to handle Unknown case and
+ * hopefully provide a definitive state transition to the third party
+ * application. GNSS Geofence will just be a signal indicating what the GNSS
+ * subsystem knows about the Geofence.
+ */
+@VintfStability
+interface IGnssGeofenceCallback {
+ // Geofence transition status
+ const int ENTERED = 1 << 0;
+ const int EXITED = 1 << 1;
+ const int UNCERTAIN = 1 << 2;
+
+ // Geofence availability status
+ const int UNAVAILABLE = 1 << 0;
+ const int AVAILABLE = 1 << 1;
+
+ // Geofence operation status
+ const int OPERATION_SUCCESS = 0;
+ const int ERROR_TOO_MANY_GEOFENCES = -100;
+ const int ERROR_ID_EXISTS = -101;
+ const int ERROR_ID_UNKNOWN = -102;
+ const int ERROR_INVALID_TRANSITION = -103;
+ const int ERROR_GENERIC = -149;
+
+ /**
+ * The callback associated with the geofence transition.
+ *
+ * The callback must only be called when the caller is interested in that particular transition.
+ * For instance, if the caller is interested only in ENTERED transition, then the callback must
+ * not be called with the EXITED transition.
+ *
+ * IMPORTANT: If a transition is triggered resulting in this callback, the GNSS subsystem will
+ * wake up the application processor, if it is in suspend state.
+ *
+ * @param geofenceId The id associated with the addGeofenceArea.
+ * @param location The current GNSS location.
+ * @param transition Can be one of ENTERED, EXITED or UNCERTAIN.
+ * @param timestamp Timestamp (in UTC milliseconds) when the transition was detected.
+ */
+ void gnssGeofenceTransitionCb(in int geofenceId, in GnssLocation location, in int transition,
+ in long timestampMillis);
+
+ /**
+ * The callback associated with the availability of the GNSS system for geofencing monitoring.
+ * If the GNSS system determines that it cannot monitor geofences because of lack of reliability
+ * or unavailability of the GNSS signals, it will call this callback with UNAVAILABLE parameter.
+ *
+ * @param status - UNAVAILABLE or AVAILABLE.
+ * @param lastLocation - Last known location.
+ */
+ void gnssGeofenceStatusCb(in int availability, in GnssLocation lastLocation);
+
+ /**
+ * The callback associated with the addGeofence call.
+ *
+ * @param geofenceId Id of the geofence.
+ * @param status Returns OPERATION_SUCCESS if the geofence add was successful,
+ * returns ERROR_TOO_MANY_GEOFENCES if the geofence limit has been reached,
+ * returns ERROR_ID_EXISTS if geofence with id already exists,
+ * returns ERROR_INVALID_TRANSITION if the monitorTransition contains an invalid
+ * transition, and
+ * returns ERROR_GENERIC for other errors.
+ */
+ void gnssGeofenceAddCb(in int geofenceId, in int status);
+
+ /**
+ * The callback associated with the removeGeofence call.
+ *
+ * @param geofenceId Id of the geofence.
+ * @param status Returns OPERATION_SUCCESS if successful,
+ * returns ERROR_ID_UNKNOWN for invalid id and
+ * returns ERROR_GENERIC for others.
+ */
+ void gnssGeofenceRemoveCb(in int geofenceId, in int status);
+
+ /**
+ * The callback associated with the pauseGeofence call.
+ *
+ * @param geofenceId Id of the geofence.
+ * @param status Returns OPERATION_SUCCESS if success,
+ * returns ERROR_ID_UNKNOWN for invalid id,
+ * returns ERROR_INVALID_TRANSITION when monitorTransitions is invalid, and
+ * returns ERROR_GENERIC for other err errors.
+ */
+ void gnssGeofencePauseCb(in int geofenceId, in int status);
+
+ /**
+ * The callback associated with the resumeGeofence call.
+ *
+ * @param geofenceId - Id of the geofence.
+ * @param status Returns OPERATION_SUCCESS if successful,
+ * returns ERROR_ID_UNKNOWN for invalid id, and
+ * returns ERROR_GENERIC for others.
+ */
+ void gnssGeofenceResumeCb(in int geofenceId, in int status);
+}
diff --git a/gnss/aidl/default/Android.bp b/gnss/aidl/default/Android.bp
index 892ad15..29bc5c4 100644
--- a/gnss/aidl/default/Android.bp
+++ b/gnss/aidl/default/Android.bp
@@ -57,6 +57,7 @@
srcs: [
"Gnss.cpp",
"GnssBatching.cpp",
+ "GnssGeofence.cpp",
"GnssHidlHal.cpp",
"GnssPowerIndication.cpp",
"GnssPsds.cpp",
diff --git a/gnss/aidl/default/Gnss.cpp b/gnss/aidl/default/Gnss.cpp
index fbfa2bb..03d9e31 100644
--- a/gnss/aidl/default/Gnss.cpp
+++ b/gnss/aidl/default/Gnss.cpp
@@ -20,6 +20,7 @@
#include <log/log.h>
#include "GnssBatching.h"
#include "GnssConfiguration.h"
+#include "GnssGeofence.h"
#include "GnssMeasurementInterface.h"
#include "GnssPsds.h"
@@ -96,4 +97,11 @@
return ndk::ScopedAStatus::ok();
}
+ndk::ScopedAStatus Gnss::getExtensionGnssGeofence(std::shared_ptr<IGnssGeofence>* iGnssGeofence) {
+ ALOGD("Gnss::getExtensionGnssGeofence");
+
+ *iGnssGeofence = SharedRefBase::make<GnssGeofence>();
+ return ndk::ScopedAStatus::ok();
+}
+
} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/Gnss.h b/gnss/aidl/default/Gnss.h
index 3959ef8..8e573b5 100644
--- a/gnss/aidl/default/Gnss.h
+++ b/gnss/aidl/default/Gnss.h
@@ -40,6 +40,8 @@
std::shared_ptr<IGnssMeasurementInterface>* iGnssMeasurement) override;
ndk::ScopedAStatus getExtensionGnssBatching(
std::shared_ptr<IGnssBatching>* iGnssBatching) override;
+ ndk::ScopedAStatus getExtensionGnssGeofence(
+ std::shared_ptr<IGnssGeofence>* iGnssGeofence) override;
std::shared_ptr<GnssConfiguration> mGnssConfiguration;
std::shared_ptr<GnssPowerIndication> mGnssPowerIndication;
diff --git a/gnss/aidl/default/GnssGeofence.cpp b/gnss/aidl/default/GnssGeofence.cpp
new file mode 100644
index 0000000..eda33cc
--- /dev/null
+++ b/gnss/aidl/default/GnssGeofence.cpp
@@ -0,0 +1,61 @@
+/*
+ * 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 "GnssGeofenceAidl"
+
+#include "GnssGeofence.h"
+#include <aidl/android/hardware/gnss/BnGnssGeofence.h>
+#include <log/log.h>
+
+namespace aidl::android::hardware::gnss {
+
+std::shared_ptr<IGnssGeofenceCallback> GnssGeofence::sCallback = nullptr;
+
+ndk::ScopedAStatus GnssGeofence::setCallback(
+ const std::shared_ptr<IGnssGeofenceCallback>& callback) {
+ ALOGD("setCallback");
+ std::unique_lock<std::mutex> lock(mMutex);
+ sCallback = callback;
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssGeofence::addGeofence(int geofenceId, double latitudeDegrees,
+ double longitudeDegrees, double radiusMeters,
+ int lastTransition, int monitorTransitions,
+ int notificationResponsivenessMs, int unknownTimerMs) {
+ ALOGD("addGeofence. geofenceId=%d, lat=%lf, lng=%lf, rad=%lf, lastTransition=%d, "
+ "monitorTransitions=%d, notificationResponsivenessMs=%d, unknownTimerMs=%d",
+ geofenceId, latitudeDegrees, longitudeDegrees, radiusMeters, lastTransition,
+ monitorTransitions, notificationResponsivenessMs, unknownTimerMs);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssGeofence::pauseGeofence(int geofenceId) {
+ ALOGD("pauseGeofence. id=%d", geofenceId);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssGeofence::resumeGeofence(int geofenceId, int monitorTransitions) {
+ ALOGD("resumeGeofence. id=%d, monitorTransitions=%d", geofenceId, monitorTransitions);
+ return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus GnssGeofence::removeGeofence(int geofenceId) {
+ ALOGD("removeGeofence. id=%d", geofenceId);
+ return ndk::ScopedAStatus::ok();
+}
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/default/GnssGeofence.h b/gnss/aidl/default/GnssGeofence.h
new file mode 100644
index 0000000..313e832
--- /dev/null
+++ b/gnss/aidl/default/GnssGeofence.h
@@ -0,0 +1,41 @@
+/*
+ * 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/BnGnssGeofence.h>
+
+namespace aidl::android::hardware::gnss {
+
+struct GnssGeofence : public BnGnssGeofence {
+ public:
+ ndk::ScopedAStatus setCallback(const std::shared_ptr<IGnssGeofenceCallback>& callback) override;
+ ndk::ScopedAStatus addGeofence(int geofenceId, double latitudeDegrees, double longitudeDegrees,
+ double radiusMeters, int lastTransition, int monitorTransitions,
+ int notificationResponsivenessMs, int unknownTimerMs) override;
+ ndk::ScopedAStatus pauseGeofence(int geofenceId) override;
+ ndk::ScopedAStatus resumeGeofence(int geofenceId, int monitorTransitions) override;
+ ndk::ScopedAStatus removeGeofence(int geofenceId) override;
+
+ private:
+ // Guarded by mMutex
+ static std::shared_ptr<IGnssGeofenceCallback> sCallback;
+
+ // Synchronization lock for sCallback
+ mutable std::mutex mMutex;
+};
+
+} // namespace aidl::android::hardware::gnss
diff --git a/gnss/aidl/vts/Android.bp b/gnss/aidl/vts/Android.bp
index 6096d4d..8582b62 100644
--- a/gnss/aidl/vts/Android.bp
+++ b/gnss/aidl/vts/Android.bp
@@ -32,6 +32,7 @@
"gnss_hal_test_cases.cpp",
"GnssBatchingCallback.cpp",
"GnssCallbackAidl.cpp",
+ "GnssGeofenceCallback.cpp",
"GnssMeasurementCallbackAidl.cpp",
"GnssPowerIndicationCallback.cpp",
"VtsHalGnssTargetTest.cpp",
diff --git a/gnss/aidl/vts/GnssGeofenceCallback.cpp b/gnss/aidl/vts/GnssGeofenceCallback.cpp
new file mode 100644
index 0000000..b841cb9
--- /dev/null
+++ b/gnss/aidl/vts/GnssGeofenceCallback.cpp
@@ -0,0 +1,46 @@
+/*
+ * 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 "GnssGeofenceCallback.h"
+#include <log/log.h>
+
+using android::binder::Status;
+using android::hardware::gnss::GnssLocation;
+
+Status GnssGeofenceCallback::gnssGeofenceTransitionCb(int, const GnssLocation&, int, int64_t) {
+ // To implement
+ return Status::ok();
+}
+Status GnssGeofenceCallback::gnssGeofenceStatusCb(int, const GnssLocation&) {
+ // To implement
+ return Status::ok();
+}
+Status GnssGeofenceCallback::gnssGeofenceAddCb(int, int) {
+ // To implement
+ return Status::ok();
+}
+Status GnssGeofenceCallback::gnssGeofenceRemoveCb(int, int) {
+ // To implement
+ return Status::ok();
+}
+Status GnssGeofenceCallback::gnssGeofencePauseCb(int, int) {
+ // To implement
+ return Status::ok();
+}
+Status GnssGeofenceCallback::gnssGeofenceResumeCb(int, int) {
+ // To implement
+ return Status::ok();
+}
diff --git a/gnss/aidl/vts/GnssGeofenceCallback.h b/gnss/aidl/vts/GnssGeofenceCallback.h
new file mode 100644
index 0000000..b105518
--- /dev/null
+++ b/gnss/aidl/vts/GnssGeofenceCallback.h
@@ -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.
+ */
+
+#pragma once
+
+#include <android/hardware/gnss/BnGnssGeofenceCallback.h>
+#include <vector>
+#include "GnssCallbackEventQueue.h"
+
+/** Implementation for IGnssGeofenceCallback. */
+class GnssGeofenceCallback : public android::hardware::gnss::BnGnssGeofenceCallback {
+ public:
+ GnssGeofenceCallback() {}
+ ~GnssGeofenceCallback() {}
+
+ android::binder::Status gnssGeofenceTransitionCb(
+ int geofenceId, const android::hardware::gnss::GnssLocation& location, int transition,
+ int64_t timestampMillis) override;
+ android::binder::Status gnssGeofenceStatusCb(
+ int availability, const android::hardware::gnss::GnssLocation& lastLocation) override;
+ android::binder::Status gnssGeofenceAddCb(int geofenceId, int status) override;
+ android::binder::Status gnssGeofenceRemoveCb(int geofenceId, int status) override;
+ android::binder::Status gnssGeofencePauseCb(int geofenceId, int status) override;
+ android::binder::Status gnssGeofenceResumeCb(int geofenceId, int status) override;
+};
diff --git a/gnss/aidl/vts/gnss_hal_test_cases.cpp b/gnss/aidl/vts/gnss_hal_test_cases.cpp
index 86140cc..09f9412 100644
--- a/gnss/aidl/vts/gnss_hal_test_cases.cpp
+++ b/gnss/aidl/vts/gnss_hal_test_cases.cpp
@@ -23,6 +23,7 @@
#include <android/hardware/gnss/IGnssPowerIndication.h>
#include <android/hardware/gnss/IGnssPsds.h>
#include "GnssBatchingCallback.h"
+#include "GnssGeofenceCallback.h"
#include "GnssMeasurementCallbackAidl.h"
#include "GnssPowerIndicationCallback.h"
#include "gnss_hal_test.h"
@@ -38,6 +39,8 @@
using android::hardware::gnss::IGnssBatching;
using android::hardware::gnss::IGnssBatchingCallback;
using android::hardware::gnss::IGnssConfiguration;
+using android::hardware::gnss::IGnssGeofence;
+using android::hardware::gnss::IGnssGeofenceCallback;
using android::hardware::gnss::IGnssMeasurementCallback;
using android::hardware::gnss::IGnssMeasurementInterface;
using android::hardware::gnss::IGnssPowerIndication;
@@ -755,23 +758,25 @@
}
/*
- * TestGnssBatchingExtension:
- * 1. Gets the IGnssBatching extension.
- * 2. Initializes the interface with an IGnssBatchingCallback.
- * 3. Clean up.
+ * TestAllExtensions.
*/
-TEST_P(GnssHalTest, TestGnssBatchingExtension) {
+TEST_P(GnssHalTest, TestAllExtensions) {
sp<IGnssBatching> iGnssBatching;
auto status = aidl_gnss_hal_->getExtensionGnssBatching(&iGnssBatching);
- if (!status.isOk() || iGnssBatching == nullptr) {
- // Device doesn't support batching. Skip the test.
- return;
+ if (status.isOk() && iGnssBatching != nullptr) {
+ auto gnssBatchingCallback = sp<GnssBatchingCallback>::make();
+ status = iGnssBatching->init(gnssBatchingCallback);
+ ASSERT_TRUE(status.isOk());
+
+ status = iGnssBatching->cleanup();
+ ASSERT_TRUE(status.isOk());
}
- sp<IGnssBatchingCallback> iGnssBatchingCallback;
- status = iGnssBatching->init(iGnssBatchingCallback);
- ASSERT_TRUE(status.isOk());
-
- status = iGnssBatching->cleanup();
- ASSERT_TRUE(status.isOk());
+ sp<IGnssGeofence> iGnssGeofence;
+ status = aidl_gnss_hal_->getExtensionGnssGeofence(&iGnssGeofence);
+ if (status.isOk() && iGnssGeofence != nullptr) {
+ auto gnssGeofenceCallback = sp<GnssGeofenceCallback>::make();
+ status = iGnssGeofence->setCallback(gnssGeofenceCallback);
+ ASSERT_TRUE(status.isOk());
+ }
}
diff --git a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperationType.aidl
index 2eff11b..34506c8 100644
--- a/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperationType.aidl
+++ b/neuralnetworks/aidl/aidl_api/android.hardware.neuralnetworks/current/android/hardware/neuralnetworks/OperationType.aidl
@@ -138,4 +138,6 @@
RANK = 101,
BATCH_MATMUL = 102,
PACK = 103,
+ MIRROR_PAD = 104,
+ REVERSE = 105,
}
diff --git a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
index 2ec91ac..aebe8d9 100644
--- a/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
+++ b/neuralnetworks/aidl/android/hardware/neuralnetworks/OperationType.aidl
@@ -4318,6 +4318,8 @@
* Supported tensor {@link OperandType}:
* * {@link OperandType::TENSOR_FLOAT16}
* * {@link OperandType::TENSOR_FLOAT32}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM} (since NNAPI feature level 7)
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} (since NNAPI feature level 7)
*
* Supported tensor rank: from 1.
*
@@ -4326,6 +4328,9 @@
*
* Outputs:
* * 0: The output tensor of same shape as input0.
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
+ * the scale and zeroPoint can be different from inputs' scale and zeroPoint.
*/
RSQRT = 83,
@@ -5322,4 +5327,68 @@
* * 0: The packed tensor.
*/
PACK = 103,
+
+ /**
+ * Pads a tensor with mirrored values.
+ *
+ * Supported tensor {@link OperandType}:
+ * * {@link OperandType::TENSOR_FLOAT16}
+ * * {@link OperandType::TENSOR_FLOAT32}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED}
+ * * {@link OperandType::TENSOR_INT32}
+ *
+ * Supported tensor rank: from 1.
+ *
+ * Inputs:
+ * * 0: An n-D tensor, specifying the tensor to be padded.
+ * * 1: A 2-D tensor of {@link OperandType::TENSOR_INT32}, the paddings
+ * for each spatial dimension of the input tensor. The shape of the
+ * tensor must be {rank(input0), 2}.
+ * padding[i, 0] specifies the number of elements to be padded in the
+ * front of dimension i.
+ * padding[i, 1] specifies the number of elements to be padded after the
+ * end of dimension i.
+ * * 2: An {@link OperandType::INT32} scalar, specifying the mode.
+ * Options are 0:REFLECT and 1:SYMMETRIC.
+ *
+ * Outputs:
+ * * 0: A tensor of the same {@link OperandType} as input0. The
+ * output tensor has the same rank as input0, and each
+ * dimension of the output tensor has the same size as the
+ * corresponding dimension of the input tensor plus the size
+ * of the padding:
+ * output0.dimension[i] =
+ * padding[i, 0] + input0.dimension[i] + padding[i, 1]
+ * For a {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensor,
+ * the scale and zeroPoint must be the same as input0.
+ */
+ MIRROR_PAD = 104,
+
+ /**
+ * Reverses a specified dimension of a tensor.
+ *
+ * Supported tensor {@link OperandType}:
+ * * {@link OperandType::TENSOR_FLOAT16}
+ * * {@link OperandType::TENSOR_FLOAT32}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM}
+ * * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED}
+ * * {@link OperandType::TENSOR_INT32}
+ *
+ * Supported tensor rank: up to 8.
+ *
+ * Inputs:
+ * * 0: Input tensor of rank n.
+ * * 1: Axis tensor of type {@link OperandType::TENSOR_INT32} and shape [1],
+ * specifying which dimension of the input tensor is to be reversed. The dimension
+ * must be in the range [0, n).
+ *
+ * Outputs:
+ * * 0: The reversed tensor.
+ * For {@link OperandType::TENSOR_QUANT8_ASYMM} and
+ * {@link OperandType::TENSOR_QUANT8_ASYMM_SIGNED} tensors,
+ * the scales and zeroPoint must be the same as input0.
+ */
+ REVERSE = 105,
}
diff --git a/neuralnetworks/aidl/utils/Android.bp b/neuralnetworks/aidl/utils/Android.bp
index 1a4cd9a..e356104 100644
--- a/neuralnetworks/aidl/utils/Android.bp
+++ b/neuralnetworks/aidl/utils/Android.bp
@@ -56,13 +56,21 @@
}
cc_library_static {
- name: "neuralnetworks_utils_hal_aidl",
+ name: "neuralnetworks_utils_hal_aidl_v2",
defaults: ["neuralnetworks_utils_hal_aidl_defaults"],
shared_libs: [
"android.hardware.neuralnetworks-V2-ndk",
],
}
+cc_library_static {
+ name: "neuralnetworks_utils_hal_aidl",
+ defaults: ["neuralnetworks_utils_hal_aidl_defaults"],
+ shared_libs: [
+ "android.hardware.neuralnetworks-V3-ndk",
+ ],
+}
+
// A cc_defaults that includes the latest non-experimental AIDL utilities and other AIDL libraries
// that are commonly used together. Modules that always depend on the latest non-experimental
// AIDL features can include this cc_defaults to avoid managing dependency versions explicitly.
@@ -71,7 +79,7 @@
static_libs: [
"android.hardware.common-V2-ndk",
"android.hardware.graphics.common-V3-ndk",
- "android.hardware.neuralnetworks-V2-ndk",
+ "android.hardware.neuralnetworks-V3-ndk",
"neuralnetworks_utils_hal_aidl",
],
}
diff --git a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
index b4e747e..a27487e 100644
--- a/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
+++ b/neuralnetworks/aidl/utils/include/nnapi/hal/aidl/Utils.h
@@ -36,6 +36,8 @@
return nn::kVersionFeatureLevel5;
case 2:
return nn::kVersionFeatureLevel6;
+ case 3:
+ return nn::kVersionFeatureLevel7;
default:
return std::nullopt;
}
diff --git a/neuralnetworks/aidl/utils/test/DeviceTest.cpp b/neuralnetworks/aidl/utils/test/DeviceTest.cpp
index 4e9fc46..0366e7d 100644
--- a/neuralnetworks/aidl/utils/test/DeviceTest.cpp
+++ b/neuralnetworks/aidl/utils/test/DeviceTest.cpp
@@ -159,6 +159,8 @@
return "v1";
case nn::Version::Level::FEATURE_LEVEL_6:
return "v2";
+ case nn::Version::Level::FEATURE_LEVEL_7:
+ return "v3";
default:
LOG(FATAL) << "Invalid AIDL version: " << version;
return "invalid";
@@ -893,7 +895,8 @@
}
INSTANTIATE_TEST_SUITE_P(TestDevice, DeviceTest,
- ::testing::Values(nn::kVersionFeatureLevel5, nn::kVersionFeatureLevel6),
+ ::testing::Values(nn::kVersionFeatureLevel5, nn::kVersionFeatureLevel6,
+ nn::kVersionFeatureLevel7),
printDeviceTest);
} // namespace aidl::android::hardware::neuralnetworks::utils
diff --git a/tv/tuner/aidl/vts/functional/FilterTests.cpp b/tv/tuner/aidl/vts/functional/FilterTests.cpp
index c53adb2..a5acdc1 100644
--- a/tv/tuner/aidl/vts/functional/FilterTests.cpp
+++ b/tv/tuner/aidl/vts/functional/FilterTests.cpp
@@ -23,6 +23,33 @@
using ::aidl::android::hardware::common::NativeHandle;
+::ndk::ScopedAStatus FilterCallback::onFilterEvent(const vector<DemuxFilterEvent>& events) {
+ android::Mutex::Autolock autoLock(mMsgLock);
+ // Temprarily we treat the first coming back filter data on the matching pid a success
+ // once all of the MQ are cleared, means we got all the expected output
+ readFilterEventsData(events);
+ mPidFilterOutputCount++;
+ mMsgCondition.signal();
+
+ // HACK: we need to cast the const away as DemuxFilterEvent contains a ScopedFileDescriptor
+ // that cannot be copied.
+ for (auto&& e : const_cast<std::vector<DemuxFilterEvent>&>(events)) {
+ auto it = mFilterEventPromises.find(e.getTag());
+ if (it != mFilterEventPromises.cend()) {
+ it->second.set_value(std::move(e));
+ mFilterEventPromises.erase(it);
+ }
+ }
+
+ return ::ndk::ScopedAStatus::ok();
+}
+
+std::future<DemuxFilterEvent> FilterCallback::getNextFilterEventWithTag(DemuxFilterEvent::Tag tag) {
+ // Note: this currently only supports one future per DemuxFilterEvent::Tag.
+ mFilterEventPromises[tag] = std::promise<DemuxFilterEvent>();
+ return mFilterEventPromises[tag].get_future();
+}
+
void FilterCallback::testFilterDataOutput() {
android::Mutex::Autolock autoLock(mMsgLock);
while (mPidFilterOutputCount < 1) {
diff --git a/tv/tuner/aidl/vts/functional/FilterTests.h b/tv/tuner/aidl/vts/functional/FilterTests.h
index c965d95..6258bac 100644
--- a/tv/tuner/aidl/vts/functional/FilterTests.h
+++ b/tv/tuner/aidl/vts/functional/FilterTests.h
@@ -24,7 +24,9 @@
#include <log/log.h>
#include <utils/Condition.h>
#include <utils/Mutex.h>
+#include <future>
#include <map>
+#include <unordered_map>
#include <fmq/AidlMessageQueue.h>
@@ -58,15 +60,9 @@
class FilterCallback : public BnFilterCallback {
public:
- virtual ::ndk::ScopedAStatus onFilterEvent(const vector<DemuxFilterEvent>& events) override {
- android::Mutex::Autolock autoLock(mMsgLock);
- // Temprarily we treat the first coming back filter data on the matching pid a success
- // once all of the MQ are cleared, means we got all the expected output
- readFilterEventsData(events);
- mPidFilterOutputCount++;
- mMsgCondition.signal();
- return ::ndk::ScopedAStatus::ok();
- }
+ virtual ::ndk::ScopedAStatus onFilterEvent(const vector<DemuxFilterEvent>& events) override;
+
+ std::future<DemuxFilterEvent> getNextFilterEventWithTag(DemuxFilterEvent::Tag tag);
virtual ::ndk::ScopedAStatus onFilterStatus(const DemuxFilterStatus /*status*/) override {
return ::ndk::ScopedAStatus::ok();
@@ -89,6 +85,7 @@
int32_t mFilterId;
std::shared_ptr<IFilter> mFilter;
+ std::unordered_map<DemuxFilterEvent::Tag, std::promise<DemuxFilterEvent>> mFilterEventPromises;
native_handle_t* mAvSharedHandle = nullptr;
uint64_t mAvSharedMemSize = -1;
diff --git a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
index 85e5c68..88890e4 100644
--- a/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
+++ b/tv/tuner/aidl/vts/functional/VtsHalTvTunerTargetTest.cpp
@@ -640,6 +640,57 @@
testTimeFilter(timeFilterMap[timeFilter.timeFilterId]);
}
+// TODO: move boilerplate into text fixture
+TEST_P(TunerFilterAidlTest, FilterTimeDelayHintTest) {
+ description("Test filter delay hint.");
+
+ int32_t feId;
+ int32_t demuxId;
+ std::shared_ptr<IDemux> demux;
+ int64_t filterId;
+
+ mFrontendTests.getFrontendIdByType(frontendMap[live.frontendId].type, feId);
+ ASSERT_TRUE(feId != INVALID_ID);
+ ASSERT_TRUE(mFrontendTests.openFrontendById(feId));
+ ASSERT_TRUE(mFrontendTests.setFrontendCallback());
+ ASSERT_TRUE(mDemuxTests.openDemux(demux, demuxId));
+ ASSERT_TRUE(mDemuxTests.setDemuxFrontendDataSource(feId));
+ mFilterTests.setDemux(demux);
+
+ const auto& filterConf = filterMap[live.ipFilterId];
+ ASSERT_TRUE(mFilterTests.openFilterInDemux(filterConf.type, filterConf.bufferSize));
+ ASSERT_TRUE(mFilterTests.getNewlyOpenedFilterId_64bit(filterId));
+ ASSERT_TRUE(mFilterTests.configFilter(filterConf.settings, filterId));
+ ASSERT_TRUE(mFilterTests.configIpFilterCid(filterConf.ipCid, filterId));
+
+ auto filter = mFilterTests.getFilterById(filterId);
+
+ auto delayValue = std::chrono::milliseconds(5000);
+ FilterDelayHint delayHint;
+ delayHint.hintType = FilterDelayHintType::TIME_DELAY_IN_MS;
+ delayHint.hintValue = delayValue.count();
+
+ auto status = filter->setDelayHint(delayHint);
+ ASSERT_TRUE(status.isOk());
+
+ auto startTime = std::chrono::steady_clock::now();
+ ASSERT_TRUE(mFilterTests.startFilter(filterId));
+
+ auto cb = mFilterTests.getFilterCallbacks().at(filterId);
+ auto future = cb->getNextFilterEventWithTag(DemuxFilterEvent::Tag::ipPayload);
+
+ // block and wait for callback to be received.
+ ASSERT_EQ(future.wait_for(std::chrono::seconds(10)), std::future_status::ready);
+ auto duration = std::chrono::steady_clock::now() - startTime;
+ ASSERT_GE(duration, delayValue);
+
+ // cleanup
+ ASSERT_TRUE(mFilterTests.stopFilter(filterId));
+ ASSERT_TRUE(mFilterTests.closeFilter(filterId));
+ ASSERT_TRUE(mDemuxTests.closeDemux());
+ ASSERT_TRUE(mFrontendTests.closeFrontend());
+}
+
TEST_P(TunerPlaybackAidlTest, PlaybackDataFlowWithTsSectionFilterTest) {
description("Feed ts data from playback and configure Ts section filter to get output");
if (!playback.support || playback.sectionFilterId.compare(emptyHardwareId) == 0) {