aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Stange <stange@google.com>2019-03-26 12:40:53 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-03-26 12:40:53 +0000
commit0b73c038efd96f7dd1b0a71797a515d43f711dda (patch)
tree4e63c1da987f1c64fef9587805a7945f3db9e4be
parentef3a17263d11ac90a6a22fd249c6112ebb920e19 (diff)
parent2667bf2aa4423ff6d5b694e960c157967fe80a39 (diff)
downloadchre-0b73c038efd96f7dd1b0a71797a515d43f711dda.tar.gz
Merge changes from topic "sensor_status_updates"
* changes: Add store method to atomic.h Delay checking SMGR sensor status updates
-rw-r--r--core/include/chre/core/event_loop_common.h1
-rw-r--r--core/include/chre/core/sensor_request_manager.h4
-rw-r--r--platform/include/chre/platform/atomic.h14
-rw-r--r--platform/include/chre/platform/platform_sensor.h3
-rw-r--r--platform/linux/include/chre/target_platform/atomic_base_impl.h8
-rw-r--r--platform/slpi/include/chre/platform/slpi/smgr/smr_helper.h129
-rw-r--r--platform/slpi/include/chre/target_platform/atomic_base_impl.h8
-rw-r--r--platform/slpi/smgr/include/chre/target_platform/platform_sensor_base.h8
-rw-r--r--platform/slpi/smgr/platform_sensor.cc178
-rw-r--r--platform/slpi/smgr/smr_helper.cc28
10 files changed, 331 insertions, 50 deletions
diff --git a/core/include/chre/core/event_loop_common.h b/core/include/chre/core/event_loop_common.h
index df989775..c871d7bc 100644
--- a/core/include/chre/core/event_loop_common.h
+++ b/core/include/chre/core/event_loop_common.h
@@ -44,6 +44,7 @@ enum class SystemCallbackType : uint16_t {
AudioHandleHostAwake,
SensorFlushComplete,
SensorFlushTimeout,
+ SensorStatusInfoResponse,
};
//! The function signature of a system callback mirrors the CHRE event free
diff --git a/core/include/chre/core/sensor_request_manager.h b/core/include/chre/core/sensor_request_manager.h
index 621421a4..950b7947 100644
--- a/core/include/chre/core/sensor_request_manager.h
+++ b/core/include/chre/core/sensor_request_manager.h
@@ -93,6 +93,10 @@ class SensorRequestManager : public NonCopyable {
/**
* Obtains a pointer to the Sensor of the specified sensorType.
*
+ * NOTE: Some platform implementations invoke this method from different
+ * threads assuming the underlying list of sensors doesn't change after
+ * initialization.
+ *
* @param sensorType The SensorType of the sensor.
* @return A pointer to the Sensor of sensorType, or nullptr if sensorType is
* invalid or the requested SensorType is not supported on the current
diff --git a/platform/include/chre/platform/atomic.h b/platform/include/chre/platform/atomic.h
index b01fd811..7244b75b 100644
--- a/platform/include/chre/platform/atomic.h
+++ b/platform/include/chre/platform/atomic.h
@@ -44,6 +44,13 @@ class AtomicBool : public AtomicBoolBase,
bool load();
/**
+ * Atomically replaces the current value of the atomic object.
+ *
+ * @param The value the object will be replaced with.
+ */
+ void store(bool desired);
+
+ /**
* Atomically replaces the value of the atomic object.
*
* @param The value the object should have when the method returns.
@@ -75,6 +82,13 @@ class AtomicUint32 : public AtomicUint32Base,
uint32_t load();
/**
+ * Atomically replaces the current value of the atomic object.
+ *
+ * @param The value the object will be replaced with.
+ */
+ void store(uint32_t desired);
+
+ /**
* Atomically replaces the value of the atomic object.
*
* @param The value the object should have when the method returns.
diff --git a/platform/include/chre/platform/platform_sensor.h b/platform/include/chre/platform/platform_sensor.h
index a430b376..82a18e96 100644
--- a/platform/include/chre/platform/platform_sensor.h
+++ b/platform/include/chre/platform/platform_sensor.h
@@ -53,6 +53,9 @@ class PlatformSensor : public PlatformSensorBase,
* and puts them in the supplied DynamicVector, which should be empty when
* passed in. If this method returns false the vector may be partially filled.
*
+ * NOTE: Some platform implementations depend on this list only being
+ * constructed during initialization so it must remain fixed afterwards.
+ *
* @param sensors A non-null pointer to a DynamicVector to populate with the
* list of sensors.
* @return true if the query was successful.
diff --git a/platform/linux/include/chre/target_platform/atomic_base_impl.h b/platform/linux/include/chre/target_platform/atomic_base_impl.h
index 850085d5..9d925d1f 100644
--- a/platform/linux/include/chre/target_platform/atomic_base_impl.h
+++ b/platform/linux/include/chre/target_platform/atomic_base_impl.h
@@ -29,6 +29,10 @@ inline bool AtomicBool::load() {
return mAtomic.load();
}
+inline void AtomicBool::store(bool desired) {
+ mAtomic.store(desired);
+}
+
inline bool AtomicBool::exchange(bool desired) {
return mAtomic.exchange(desired);
}
@@ -41,6 +45,10 @@ inline uint32_t AtomicUint32::load() {
return mAtomic.load();
}
+inline void AtomicUint32::store(uint32_t desired) {
+ mAtomic.store(desired);
+}
+
inline uint32_t AtomicUint32::exchange(uint32_t desired) {
return mAtomic.exchange(desired);
}
diff --git a/platform/slpi/include/chre/platform/slpi/smgr/smr_helper.h b/platform/slpi/include/chre/platform/slpi/smgr/smr_helper.h
index f80bf397..66289f09 100644
--- a/platform/slpi/include/chre/platform/slpi/smgr/smr_helper.h
+++ b/platform/slpi/include/chre/platform/slpi/smgr/smr_helper.h
@@ -28,6 +28,7 @@ extern "C" {
#include "chre/platform/condition_variable.h"
#include "chre/platform/mutex.h"
+#include "chre/platform/slpi/power_control_util.h"
#include "chre/util/non_copyable.h"
#include "chre/util/time.h"
#include "chre/util/unique_ptr.h"
@@ -41,6 +42,10 @@ constexpr Nanoseconds kDefaultSmrTimeout = Seconds(2);
//! external dependencies blocking SMGR initialization.
constexpr Nanoseconds kDefaultSmrWaitTimeout = Seconds(5);
+template<typename RespStruct>
+using SmrReqCallback = void (*)(UniquePtr<RespStruct> resp, void *callbackData,
+ smr_err transpErr);
+
/**
* A helper class for making synchronous requests to SMR (Sensors Message
* Router). Not safe to use from multiple threads.
@@ -60,6 +65,57 @@ class SmrHelper : public NonCopyable {
Nanoseconds timeout = kDefaultSmrTimeout);
/**
+ * Wrapper to send the async smr_client_send_req() call.
+ *
+ * @param ReqStruct QMI IDL-generated request structure
+ * @param RespStruct QMI IDL-generated response structure
+ * @param clientHandle SMR handle previously given by smr_client_init()
+ * @param msgId QMI message ID of the request to send
+ * @param req Pointer to populated request structure
+ * @param resp Pointer to structure to receive the response.
+ * @param callback Callback to be invoked upon completion of the request.
+ * NOTE: This callback will be invoked on the CHRE thread.
+ * @param callbackData Data to be sent to the callback when invoked.
+ *
+ * @return Result code returned by smr_client_send_req()
+ */
+ template<typename ReqStruct, typename RespStruct>
+ smr_err sendReqAsync(
+ smr_client_hndl clientHandle, unsigned int msgId,
+ UniquePtr<ReqStruct> *req, UniquePtr<RespStruct> *resp,
+ SmrReqCallback<RespStruct> callback, void *callbackData) {
+ // Try to catch copy/paste errors at compile time - QMI always has a
+ // different struct definition for request and response
+ static_assert(!std::is_same<ReqStruct, RespStruct>::value,
+ "Request and response structures must be different");
+
+ smr_err result;
+ auto reqData = MakeUnique<AsyncCallbackData<ReqStruct, RespStruct>>();
+ if (reqData.isNull()) {
+ LOG_OOM();
+ result = SMR_OUT_OF_MEMORY;
+ } else {
+ reqData->callback = callback;
+ reqData->reqCStruct = std::move(*req);
+ reqData->respCStruct = std::move(*resp);
+ reqData->data = callbackData;
+
+ result = sendReqAsyncUntyped(
+ clientHandle, msgId, reqData->reqCStruct.get(), sizeof(ReqStruct),
+ reqData->respCStruct.get(), sizeof(RespStruct), reqData.get(),
+ SmrHelper::smrAsyncRespCb<ReqStruct, RespStruct>);
+
+ if (result == SMR_NO_ERR) {
+ // Release ownership of the request callback data since it will be used
+ // by SMGR and the async callback after this function returns.
+ reqData.release();
+ }
+ }
+
+ return result;
+ }
+
+ /**
* Wrapper to convert the async smr_client_send_req() to a synchronous call.
*
* Only one request can be pending at a time per instance of SmrHelper.
@@ -138,6 +194,43 @@ class SmrHelper : public NonCopyable {
};
/**
+ * Struct used to store data needed once smr_client_send_req invokes the async
+ * request callback.
+ */
+ template<typename ReqStruct, typename RespStruct>
+ struct AsyncCallbackData {
+ //! Callback given by the client issuing the request.
+ SmrReqCallback<RespStruct> callback;
+
+ //! Error received from the SMGR response callback.
+ smr_err transpErr;
+
+ //! Arbitrary data to be given to the callback.
+ void *data;
+
+ //! ReqStruct info from the initial SMGR request.
+ UniquePtr<ReqStruct> reqCStruct;
+
+ //! RespStruct info from the SMGR response callback.
+ UniquePtr<RespStruct> respCStruct;
+ };
+
+ /**
+ * Implements sendReqAsync(), but accepts untyped (void*) buffers.
+ * snake_case parameters exactly match those given to smr_client_send_req().
+ *
+ * @return The error code returned by smr_client_send_req().
+ *
+ * @see sendReqAsync()
+ * @see smr_client_send_req()
+ */
+ static smr_err sendReqAsyncUntyped(
+ smr_client_hndl client_handle, unsigned int msg_id,
+ void *req_c_struct, unsigned int req_c_struct_len,
+ void *resp_c_struct, unsigned int resp_c_struct_len,
+ void *resp_cb_data, smr_client_resp_cb resp_cb);
+
+ /**
* Implements sendReqSync(), but with accepting untyped (void*) buffers.
* snake_case parameters exactly match those given to smr_client_send_req().
*
@@ -180,13 +273,43 @@ class SmrHelper : public NonCopyable {
static void smrReleaseCb(void *release_cb_data);
/**
+ * Posts the asynchronous response back to the CHRE thread and then invokes
+ * the callback given by the client when the request was made with the
+ * appropriate parameters from the response.
+ *
+ * @see smr_client_resp_cb
+ */
+ template<typename ReqStruct, typename RespStruct>
+ static void smrAsyncRespCb(smr_client_hndl client_handle,
+ unsigned int msg_id, void *resp_c_struct,
+ unsigned int resp_c_struct_len,
+ void *resp_cb_data, smr_err transp_err) {
+ auto callback = [](uint16_t /* type */, void *data) {
+ UniquePtr<AsyncCallbackData<ReqStruct, RespStruct>> cbData(
+ static_cast<AsyncCallbackData<ReqStruct, RespStruct> *>(data));
+ cbData->callback(std::move(cbData->respCStruct), cbData->data,
+ cbData->transpErr);
+ };
+
+ auto *cbData =
+ static_cast<AsyncCallbackData<ReqStruct, RespStruct> *>(resp_cb_data);
+ cbData->transpErr = transp_err;
+
+ // Schedule a deferred callback to handle sensor status change on the
+ // main thread.
+ EventLoopManagerSingleton::get()->deferCallback(
+ SystemCallbackType::SensorStatusInfoResponse, resp_cb_data, callback);
+ }
+
+ /**
* Extracts "this" from resp_cb_data and calls through to handleResp()
*
* @see smr_client_resp_cb
*/
- static void smrRespCb(smr_client_hndl client_handle, unsigned int msg_id,
- void *resp_c_struct, unsigned int resp_c_struct_len,
- void *resp_cb_data, smr_err transp_err);
+ static void smrSyncRespCb(smr_client_hndl client_handle,
+ unsigned int msg_id, void *resp_c_struct,
+ unsigned int resp_c_struct_len,
+ void *resp_cb_data, smr_err transp_err);
/**
* SMR wait for service callback used with waitForService()
diff --git a/platform/slpi/include/chre/target_platform/atomic_base_impl.h b/platform/slpi/include/chre/target_platform/atomic_base_impl.h
index 6b734ef8..02576e07 100644
--- a/platform/slpi/include/chre/target_platform/atomic_base_impl.h
+++ b/platform/slpi/include/chre/target_platform/atomic_base_impl.h
@@ -36,6 +36,10 @@ inline bool AtomicBool::load() {
return mValue;
}
+inline void AtomicBool::store(bool desired) {
+ exchange(desired);
+}
+
inline bool AtomicBool::exchange(bool desired) {
qurt_atomic_barrier();
return qurt_atomic_set(&mValue,
@@ -51,6 +55,10 @@ inline uint32_t AtomicUint32::load() {
return mValue;
}
+inline void AtomicUint32::store(uint32_t desired) {
+ exchange(desired);
+}
+
inline uint32_t AtomicUint32::exchange(uint32_t desired) {
qurt_atomic_barrier();
return qurt_atomic_set(&mValue, desired);
diff --git a/platform/slpi/smgr/include/chre/target_platform/platform_sensor_base.h b/platform/slpi/smgr/include/chre/target_platform/platform_sensor_base.h
index fb264d71..b0071496 100644
--- a/platform/slpi/smgr/include/chre/target_platform/platform_sensor_base.h
+++ b/platform/slpi/smgr/include/chre/target_platform/platform_sensor_base.h
@@ -24,6 +24,8 @@ extern "C" {
} // extern "C"
#include "chre/core/sensor_request.h"
+#include "chre/core/timer_pool.h"
+#include "chre/platform/atomic.h"
namespace chre {
@@ -32,6 +34,8 @@ namespace chre {
*/
class PlatformSensorBase {
public:
+ PlatformSensorBase() : timerHandle(CHRE_TIMER_INVALID) {}
+
/**
* Copies the supplied event to the sensor's last event and marks last event
* valid.
@@ -62,6 +66,10 @@ class PlatformSensorBase {
//! non-null if this is an on-change sensor.
ChreSensorData *lastEvent = nullptr;
+ //! The timer that is used to determine whether CHRE should issue passive
+ //! requests or not to avoid checking for every sensor status callback.
+ AtomicUint32 timerHandle;
+
//! The amount of memory we've allocated in lastEvent (this varies depending
//! on the sensor type)
size_t lastEventSize = 0;
diff --git a/platform/slpi/smgr/platform_sensor.cc b/platform/slpi/smgr/platform_sensor.cc
index 944301af..d24ece31 100644
--- a/platform/slpi/smgr/platform_sensor.cc
+++ b/platform/slpi/smgr/platform_sensor.cc
@@ -32,6 +32,7 @@ extern "C" {
#include "chre_api/chre/sensor.h"
#include "chre/core/event_loop_manager.h"
#include "chre/core/sensor.h"
+#include "chre/core/timer_pool.h"
#include "chre/platform/assert.h"
#include "chre/platform/fatal_error.h"
#include "chre/platform/log.h"
@@ -68,9 +69,12 @@ extern "C" {
// transition.
// 3) The merged mode of a sensor is the strongest mode of all sensor
// requests of the same sensor ID, with active > passive > off.
-// 3. When SNS_SMGR_SENSOR_STATUS_MONITOR_IND_V02 from SMGR is received, a
-// SNS_SMGR_CLIENT_REQUEST_INFO_REQ_V01 message is sent to query SMGR on the
-// existence of other clients.
+// 3. When SNS_SMGR_SENSOR_STATUS_MONITOR_IND_V02 from SMGR is received, a new
+// timer is set for kStatusDelayIntervalNanos in the future for each
+// sensorId. Any future updates that occur before the timer fires are
+// ignored.
+// 4. Once the timer fires, an asynchronous SNS_SMGR_CLIENT_REQUEST_INFO_REQ_V01
+// message is sent to query SMGR on the existence of other clients.
// - If a transition from absence-to-presence of other clients is detected,
// all pending passive requests are made.
// - If a transition from presence-to-absence of other clients is deteted,
@@ -98,6 +102,10 @@ constexpr uint64_t kDefaultInterval = Seconds(1).toRawNanoseconds();
constexpr uint64_t kTickRolloverOffset =
((1ULL << 32) * Seconds(1).toRawNanoseconds()) / TIMETICK_NOMINAL_FREQ_HZ;
+//! The delay in nanoseconds between receiving a sensor status change
+//! and updating the sensor status.
+constexpr Nanoseconds kStatusDelayIntervalNanos = Milliseconds(10);
+
smr_client_hndl gPlatformSensorServiceSmrClientHandle;
smr_client_hndl gPlatformSensorInternalServiceSmrClientHandle;
@@ -733,47 +741,114 @@ void onOtherClientPresenceChange(uint8_t sensorId, bool otherClientPresent) {
}
/**
- * Processes sensor status monitor indication message.
+ * Retrieves first valid sensor that has the given sensor ID. Can be
+ * invoked from any thread.
+ *
+ * @param sensorID The sensor handle that should be used to search
+ * the current list of sensors.
+ * @return The first non-null Sensor that matches the given sensor handle or
+ * nullptr if no match is found.
+ */
+Sensor *getFirstValidSensor(uint8_t sensorId) {
+ SensorType sensorTypes[kMaxNumSensorsPerSensorId];
+ size_t numSensorTypes = populateSensorTypeArrayFromSensorId(
+ sensorId, sensorTypes);
+
+ Sensor *sensor = nullptr;
+ for (size_t i = 0; i < numSensorTypes; i++) {
+ sensor = EventLoopManagerSingleton::get()
+ ->getSensorRequestManager().getSensor(sensorTypes[i]);
+ if (sensor != nullptr) {
+ break;
+ }
+ }
+ return sensor;
+}
+
+/**
+ * Processes the latest client request info response for the given sensor ID.
+ * Must be invoked from the CHRE thread.
+ *
+ * @param resp The SMGR client request info response.
+ * @param sensorId The sensor ID the response is for.
+ * @param transpErr The error related to the request.
+ */
+void onClientRequestInfoResponse(
+ const sns_smgr_client_request_info_resp_msg_v01& resp,
+ uint8_t sensorId,
+ smr_err transpErr) {
+ size_t index = getSensorMonitorIndex(sensorId);
+ if (transpErr != SMR_NO_ERR) {
+ LOGE("Error receiving client request info: %" PRIu8, transpErr);
+ } else if (resp.resp.sns_result_t != SNS_RESULT_SUCCESS_V01) {
+ LOGE("Client request info failed with error: %" PRIu8 ", id %" PRIu8,
+ resp.resp.sns_err_t, sensorId);
+ } else if (index == gSensorMonitors.size()) {
+ LOGE("Sensor status monitor update of invalid sensor ID %" PRIu8, sensorId);
+ } else {
+ bool otherClientPresent = resp.other_client_present;
+ if (gSensorMonitors[index].otherClientPresent != otherClientPresent) {
+ onOtherClientPresenceChange(sensorId, otherClientPresent);
+ gSensorMonitors[index].otherClientPresent = otherClientPresent;
+ }
+ }
+}
+
+/**
+ * Makes an asynchronous request to SMGR to receive the latest client
+ * request info.
*
- * @param status The new sensor status indication from SMGR
+ * @param sensorId The handle to the sensor whose status has changed.
*/
-void onStatusChange(const sns_smgr_sensor_status_monitor_ind_msg_v02& status) {
- size_t index = getSensorMonitorIndex(status.sensor_id);
+void onStatusChange(uint8_t sensorId) {
+ // Sensor already verified to be valid before onStatusChange is called.
+ Sensor *sensor = getFirstValidSensor(sensorId);
+ // Invalidate timer first so a status update isn't potentially
+ // missed.
+ sensor->timerHandle.store(CHRE_TIMER_INVALID);
+
+ size_t index = getSensorMonitorIndex(sensorId);
if (index == gSensorMonitors.size()) {
- LOGE("Sensor status monitor update of invalid sensor ID %" PRIu64,
- status.sensor_id);
+ LOGE("Sensor status monitor update of invalid sensor ID %" PRIu8, sensorId);
} else {
- // Use asynchronous sensor status monitor indication message as a cue to
- // query and obtain the synchronous client request info.
- // As the info conveyed in the indication is asynchronous from current
- // status and is insufficient to determine other clients' status, relying on
- // it to enable/disable passive sensors may put the system in an incorrect
- // state or lead to a request loop.
+ // Use the asynchronous sensor status monitor indication message as a cue
+ // to query and obtain the latest client request info. Since the status
+ // changes are processed on a delay, the current client status is out of
+ // date so query the latest status asynchronously to avoid holding up the
+ // CHRE thread.
auto infoRequest =
MakeUniqueZeroFill<sns_smgr_client_request_info_req_msg_v01>();
auto infoResponse = MakeUnique<sns_smgr_client_request_info_resp_msg_v01>();
if (infoRequest.isNull() || infoResponse.isNull()) {
- LOGE("Failed to allocate client request info message");
+ LOG_OOM();
} else {
- infoRequest->sensor_id = status.sensor_id;
-
- smr_err smrStatus = getSmrHelper()->sendReqSync(
+ // Enables passing the sensor ID through the event data pointer to avoid
+ // allocating memory
+ union NestedSensorId {
+ void *eventData;
+ uint8_t sensorId;
+ };
+ NestedSensorId nestedId = {};
+ nestedId.sensorId = sensorId;
+
+ SmrReqCallback<sns_smgr_client_request_info_resp_msg_v01> callback =
+ [](UniquePtr<sns_smgr_client_request_info_resp_msg_v01> resp,
+ void *data,
+ smr_err transpErr) {
+ NestedSensorId nestedIdCb;
+ nestedIdCb.eventData = data;
+ onClientRequestInfoResponse(*resp.get(),
+ nestedIdCb.sensorId, transpErr);
+ };
+
+ infoRequest->sensor_id = sensorId;
+ smr_err smrStatus = getSmrHelper()->sendReqAsync(
gPlatformSensorServiceSmrClientHandle,
SNS_SMGR_CLIENT_REQUEST_INFO_REQ_V01,
- &infoRequest, &infoResponse);
-
+ &infoRequest, &infoResponse, callback, nestedId.eventData);
if (smrStatus != SMR_NO_ERR) {
LOGE("Error requesting client request info: %d", smrStatus);
- } else if (infoResponse->resp.sns_result_t != SNS_RESULT_SUCCESS_V01) {
- LOGE("Client request info failed with error: %" PRIu8 ", id %" PRIu8,
- infoResponse->resp.sns_err_t, infoRequest->sensor_id);
- } else {
- bool otherClientPresent = infoResponse->other_client_present;
- if (gSensorMonitors[index].otherClientPresent != otherClientPresent) {
- onOtherClientPresenceChange(status.sensor_id, otherClientPresent);
- gSensorMonitors[index].otherClientPresent = otherClientPresent;
- }
}
}
}
@@ -851,23 +926,40 @@ void updateSamplingStatus(Sensor *sensor, const SensorRequest& request) {
*/
void handleSensorStatusMonitorIndication(
const sns_smgr_sensor_status_monitor_ind_msg_v02& smgrMonitorIndMsg) {
- auto *callbackData =
- memoryAlloc<sns_smgr_sensor_status_monitor_ind_msg_v02>();
- if (callbackData == nullptr) {
- LOGE("Failed to allocate status update deferred callback memory");
- } else {
- *callbackData = smgrMonitorIndMsg;
+ uint8_t sensorId = smgrMonitorIndMsg.sensor_id;
+
+ // Only use one Sensor to avoid multiple timers per sensorId.
+ Sensor *sensor = getFirstValidSensor(sensorId);
+ if (sensor == nullptr) {
+ LOGE("Sensor ID: %" PRIu8 " in status update doesn't correspond to "
+ "valid sensor.", sensorId);
+ // SMGR should send all callbacks back on the same thread which
+ // means the following code won't result in any timers overriding one
+ // another.
+ } else if (sensor->timerHandle.load() == CHRE_TIMER_INVALID) {
+ // Enables passing the sensor ID through the event data pointer to avoid
+ // allocating memory
+ union NestedSensorId {
+ void *eventData;
+ uint8_t sensorId;
+ };
+ NestedSensorId nestedId = {};
+ nestedId.sensorId = sensorId;
+
auto callback = [](uint16_t /* type */, void *data) {
- auto *cbData =
- static_cast<sns_smgr_sensor_status_monitor_ind_msg_v02 *>(data);
- onStatusChange(*cbData);
- memoryFree(cbData);
+ NestedSensorId nestedIdCb;
+ nestedIdCb.eventData = data;
+ onStatusChange(nestedIdCb.sensorId);
};
- // Schedule a deferred callback to handle sensor status change in the main
+ // Schedule a delayed callback to handle sensor status change on the main
// thread.
- EventLoopManagerSingleton::get()->deferCallback(
- SystemCallbackType::SensorStatusUpdate, callbackData, callback);
+ TimerHandle timer = EventLoopManagerSingleton::get()->setDelayedCallback(
+ SystemCallbackType::SensorStatusUpdate,
+ nestedId.eventData,
+ callback,
+ kStatusDelayIntervalNanos);
+ sensor->timerHandle.store(timer);
}
}
diff --git a/platform/slpi/smgr/smr_helper.cc b/platform/slpi/smgr/smr_helper.cc
index a4a68375..022b31a5 100644
--- a/platform/slpi/smgr/smr_helper.cc
+++ b/platform/slpi/smgr/smr_helper.cc
@@ -89,6 +89,26 @@ smr_err SmrHelper::waitForService(qmi_idl_service_object_type serviceObj,
return result;
}
+smr_err SmrHelper::sendReqAsyncUntyped(
+ smr_client_hndl client_handle, unsigned int msg_id,
+ void *req_c_struct, unsigned int req_c_struct_len,
+ void *resp_c_struct, unsigned int resp_c_struct_len,
+ void *resp_cb_data, smr_client_resp_cb resp_cb) {
+ // Force big image since smr_client_send_req is not supported in micro-image
+ slpiForceBigImage();
+
+ smr_err result = smr_client_send_req(client_handle, msg_id, req_c_struct,
+ req_c_struct_len, resp_c_struct,
+ resp_c_struct_len, resp_cb, resp_cb_data,
+ nullptr /* txn_handle */);
+
+ if (result != SMR_NO_ERR) {
+ LOGE("Failed to send request (msg_id 0x%02x): %d", msg_id, result);
+ }
+
+ return result;
+}
+
bool SmrHelper::sendReqSyncUntyped(
smr_client_hndl client_handle, unsigned int msg_id,
void *req_c_struct, unsigned int req_c_struct_len,
@@ -119,7 +139,7 @@ bool SmrHelper::sendReqSyncUntyped(
// SMR itself does not support canceling transactions made to SMR services.
*result = smr_client_send_req(
client_handle, msg_id, req_c_struct, req_c_struct_len, resp_c_struct,
- resp_c_struct_len, SmrHelper::smrRespCb, txn.get(),
+ resp_c_struct_len, SmrHelper::smrSyncRespCb, txn.get(),
nullptr /* txn_handle */);
if (*result != SMR_NO_ERR) {
LOGE("Failed to send request (msg_id 0x%02x): %d", msg_id, *result);
@@ -189,9 +209,9 @@ void SmrHelper::smrReleaseCb(void *release_cb_data) {
obj->mCond.notify_one();
}
-void SmrHelper::smrRespCb(smr_client_hndl client_handle, unsigned int msg_id,
- void *resp_c_struct, unsigned int resp_c_struct_len,
- void *resp_cb_data, smr_err transp_err) {
+void SmrHelper::smrSyncRespCb(
+ smr_client_hndl client_handle, unsigned int msg_id, void *resp_c_struct,
+ unsigned int resp_c_struct_len, void *resp_cb_data, smr_err transp_err) {
auto *txn = static_cast<SmrTransaction *>(resp_cb_data);
txn->parent->handleResp(
client_handle, msg_id, resp_c_struct, resp_c_struct_len, transp_err, txn);