/* * Copyright (c) 2021-2023 Huawei Device Co., Ltd. * 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 "sensor_impl.h" #include <cinttypes> #include <unordered_map> #include <mutex> #include <iproxy_broker.h> #include "sensor_uhdf_log.h" #include "hitrace_meter.h" #include "sensor_dump.h" #define HDF_LOG_TAG uhdf_sensor_service #define DEFAULT_SDC_SENSOR_INFO_SIZE 2 namespace OHOS { namespace HDI { namespace Sensor { namespace V1_1 { namespace { constexpr int32_t CALLBACK_CTOUNT_THRESHOLD = 1; using GroupIdCallBackMap = std::unordered_map<int32_t, std::vector<sptr<ISensorCallbackVdi>>>; GroupIdCallBackMap g_groupIdCallBackMap; std::mutex g_mutex; } // namespace int32_t ReportSensorEventsData(int32_t sensorType, const struct SensorEvents *event) { std::lock_guard<std::mutex> lock(g_mutex); auto groupCallBackIter = g_groupIdCallBackMap.find(sensorType); if (groupCallBackIter == g_groupIdCallBackMap.end()) { return SENSOR_SUCCESS; } HdfSensorEventsVdi hdfSensorEvents; hdfSensorEvents.sensorId = event->sensorId; hdfSensorEvents.version = event->version; hdfSensorEvents.timestamp = event->timestamp; hdfSensorEvents.option = event->option; hdfSensorEvents.mode = event->mode; hdfSensorEvents.dataLen = event->dataLen; uint32_t len = event->dataLen; uint8_t *tmp = event->data; while ((len--) != 0) { hdfSensorEvents.data.push_back(*tmp); tmp++; } for (auto callBack : g_groupIdCallBackMap[sensorType]) { callBack->OnDataEventVdi(hdfSensorEvents); } return SENSOR_SUCCESS; } int32_t TradtionalSensorDataCallback(const struct SensorEvents *event) { if (event == nullptr || event->data == nullptr) { HDF_LOGE("%{public}s failed, event or event.data is nullptr", __func__); return SENSOR_FAILURE; } (void)ReportSensorEventsData(TRADITIONAL_SENSOR_TYPE, event); return SENSOR_SUCCESS; } int32_t MedicalSensorDataCallback(const struct SensorEvents *event) { if (event == nullptr || event->data == nullptr) { HDF_LOGE("%{public}s failed, event or event.data is nullptr", __func__); return SENSOR_FAILURE; } (void)ReportSensorEventsData(MEDICAL_SENSOR_TYPE, event); return SENSOR_SUCCESS; } SensorImpl::~SensorImpl() { FreeSensorInterfaceInstance(); } int32_t SensorImpl::Init() { sensorInterface = NewSensorInterfaceInstance(); if (sensorInterface == nullptr) { HDF_LOGE("%{public}s: get sensor Module instance failed", __func__); return HDF_FAILURE; } SensorDevRegisterDump(); return HDF_SUCCESS; } int32_t SensorImpl::GetAllSensorInfo(std::vector<HdfSensorInformationVdi> &info) { HDF_LOGI("%{public}s: Enter the GetAllSensorInfo function.", __func__); if (sensorInterface == nullptr || sensorInterface->GetAllSensors == nullptr) { HDF_LOGE("%{public}s: get sensor Module instance failed", __func__); return HDF_FAILURE; } struct SensorInformation *sensorInfo = nullptr; struct SensorInformation *tmp = nullptr; int32_t count = 0; StartTrace(HITRACE_TAG_SENSORS, "GetAllSensorInfo"); int32_t ret = sensorInterface->GetAllSensors(&sensorInfo, &count); FinishTrace(HITRACE_TAG_SENSORS); if (ret != SENSOR_SUCCESS) { HDF_LOGE("%{public}s failed, error code is %{public}d", __func__, ret); return ret; } if (count <= 0) { HDF_LOGE("%{public}s failed, count<=0", __func__); return HDF_FAILURE; } tmp = sensorInfo; while (count--) { HdfSensorInformationVdi hdfSensorInfo; std::string sensorName(tmp->sensorName); hdfSensorInfo.sensorName = sensorName; std::string vendorName(tmp->vendorName); hdfSensorInfo.vendorName = vendorName; std::string firmwareVersion(tmp->firmwareVersion); hdfSensorInfo.firmwareVersion = firmwareVersion; std::string hardwareVersion(tmp->hardwareVersion); hdfSensorInfo.hardwareVersion = hardwareVersion; hdfSensorInfo.sensorTypeId = tmp->sensorTypeId; hdfSensorInfo.sensorId = tmp->sensorId; hdfSensorInfo.maxRange = tmp->maxRange; hdfSensorInfo.accuracy = tmp->accuracy; hdfSensorInfo.power = tmp->power; hdfSensorInfo.minDelay = tmp->minDelay; hdfSensorInfo.maxDelay = tmp->maxDelay; hdfSensorInfo.fifoMaxEventCount = tmp->fifoMaxEventCount; info.push_back(std::move(hdfSensorInfo)); tmp++; } return HDF_SUCCESS; } int32_t SensorImpl::Enable(int32_t sensorId) { HDF_LOGI("%{public}s: Enter the Enable function, sensorId is %{public}d", __func__, sensorId); if (sensorInterface == nullptr || sensorInterface->Enable == nullptr) { HDF_LOGE("%{public}s: get sensor Module instance failed", __func__); return HDF_FAILURE; } StartTrace(HITRACE_TAG_SENSORS, "Enable"); int32_t ret = sensorInterface->Enable(sensorId); FinishTrace(HITRACE_TAG_SENSORS); if (ret != SENSOR_SUCCESS) { HDF_LOGE("%{public}s failed, error code is %{public}d", __func__, ret); } return ret; } int32_t SensorImpl::Disable(int32_t sensorId) { HDF_LOGI("%{public}s: Enter the Disable function, sensorId is %{public}d", __func__, sensorId); if (sensorInterface == nullptr || sensorInterface->Disable == nullptr) { HDF_LOGE("%{public}s: get sensor Module instance failed", __func__); return HDF_FAILURE; } StartTrace(HITRACE_TAG_SENSORS, "Disable"); int32_t ret = sensorInterface->Disable(sensorId); FinishTrace(HITRACE_TAG_SENSORS); if (ret != SENSOR_SUCCESS) { HDF_LOGE("%{public}s failed, error code is %{public}d", __func__, ret); } return ret; } int32_t SensorImpl::SetBatch(int32_t sensorId, int64_t samplingInterval, int64_t reportInterval) { HDF_LOGI("%{public}s: sensorId is %{public}d, samplingInterval is [%{public}" PRId64 "], \ reportInterval is [%{public}" PRId64 "].", __func__, sensorId, samplingInterval, reportInterval); if (sensorInterface == nullptr || sensorInterface->SetBatch == nullptr) { HDF_LOGE("%{public}s: get sensor Module instance failed", __func__); return HDF_FAILURE; } StartTrace(HITRACE_TAG_SENSORS, "SetBatch"); int32_t ret = sensorInterface->SetBatch(sensorId, samplingInterval, reportInterval); FinishTrace(HITRACE_TAG_SENSORS); if (ret != SENSOR_SUCCESS) { HDF_LOGE("%{public}s failed, error code is %{public}d", __func__, ret); } return ret; } int32_t SensorImpl::SetMode(int32_t sensorId, int32_t mode) { HDF_LOGI("%{public}s: Enter the SetMode function, sensorId is %{public}d, mode is %{public}d", __func__, sensorId, mode); if (sensorInterface == nullptr || sensorInterface->SetMode == nullptr) { HDF_LOGE("%{public}s: get sensor Module instance failed", __func__); return HDF_FAILURE; } StartTrace(HITRACE_TAG_SENSORS, "SetMode"); int32_t ret = sensorInterface->SetMode(sensorId, mode); FinishTrace(HITRACE_TAG_SENSORS); if (ret != SENSOR_SUCCESS) { HDF_LOGE("%{public}s SetMode failed, error code is %{public}d", __func__, ret); } return ret; } int32_t SensorImpl::SetOption(int32_t sensorId, uint32_t option) { HDF_LOGI("%{public}s: Enter the SetOption function, sensorId is %{public}d, option is %{public}u", __func__, sensorId, option); if (sensorInterface == nullptr || sensorInterface->SetOption == nullptr) { HDF_LOGE("%{public}s: get sensor Module instance failed", __func__); return HDF_FAILURE; } StartTrace(HITRACE_TAG_SENSORS, "SetOption"); int32_t ret = sensorInterface->SetOption(sensorId, option); FinishTrace(HITRACE_TAG_SENSORS); if (ret != SENSOR_SUCCESS) { HDF_LOGE("%{public}s failed, error code is %{public}d", __func__, ret); } return ret; } int32_t SensorImpl::Register(int32_t groupId, const sptr<ISensorCallbackVdi> &callbackObj) { HDF_LOGI("%{public}s: Enter the Register function, groupId is %{public}d", __func__, groupId); if (sensorInterface == nullptr || sensorInterface->Register == nullptr) { HDF_LOGE("%{public}s: get sensor Module instance failed", __func__); return HDF_FAILURE; } if (groupId < TRADITIONAL_SENSOR_TYPE || groupId > MEDICAL_SENSOR_TYPE) { HDF_LOGE("%{public}s: groupId [%{public}d] out of range", __func__, groupId); return SENSOR_INVALID_PARAM; } std::lock_guard<std::mutex> lock(g_mutex); auto groupCallBackIter = g_groupIdCallBackMap.find(groupId); if (groupCallBackIter != g_groupIdCallBackMap.end()) { auto callBackIter = find_if(g_groupIdCallBackMap[groupId].begin(), g_groupIdCallBackMap[groupId].end(), [&callbackObj](const sptr<ISensorCallbackVdi> &callbackRegistered) { const sptr<IRemoteObject> &lhs = callbackObj->HandleCallbackDeath(); const sptr<IRemoteObject> &rhs = callbackRegistered->HandleCallbackDeath(); return lhs == rhs; }); if (callBackIter == g_groupIdCallBackMap[groupId].end()) { g_groupIdCallBackMap[groupId].push_back(callbackObj); } return SENSOR_SUCCESS; } int32_t ret = HDF_FAILURE; StartTrace(HITRACE_TAG_SENSORS, "Register"); if (groupId == TRADITIONAL_SENSOR_TYPE) { ret = sensorInterface->Register(groupId, TradtionalSensorDataCallback); } else if (groupId == MEDICAL_SENSOR_TYPE) { ret = sensorInterface->Register(groupId, MedicalSensorDataCallback); } FinishTrace(HITRACE_TAG_SENSORS); if (ret != SENSOR_SUCCESS) { HDF_LOGE("%{public}s: Register fail, groupId[%{public}d]", __func__, groupId); return ret; } std::vector<sptr<ISensorCallbackVdi>> remoteVec; remoteVec.push_back(callbackObj); g_groupIdCallBackMap[groupId] = remoteVec; return ret; } int32_t SensorImpl::Unregister(int32_t groupId, const sptr<ISensorCallbackVdi> &callbackObj) { HDF_LOGI("%{public}s: Enter the Unregister function, groupId is %{public}d", __func__, groupId); if (sensorInterface == nullptr || sensorInterface->Unregister == nullptr) { HDF_LOGE("%{public}s: get sensor Module instance failed", __func__); return HDF_FAILURE; } std::lock_guard<std::mutex> lock(g_mutex); const sptr<IRemoteObject> &remote = callbackObj->HandleCallbackDeath(); StartTrace(HITRACE_TAG_SENSORS, "Unregister"); int32_t ret = UnregisterImpl(groupId, remote.GetRefPtr()); FinishTrace(HITRACE_TAG_SENSORS); if (ret != SENSOR_SUCCESS) { HDF_LOGE("%{public}s: Unregister failed groupId[%{public}d]", __func__, groupId); } return ret; } int32_t SensorImpl::GetSdcSensorInfo(std::vector<SdcSensorInfoVdi> &sdcSensorInfoVdi) { HDF_LOGI("%{public}s: Enter the GetSdcSensorInfo function", __func__); if (sensorInterface == nullptr || sensorInterface->GetSdcSensorInfo == nullptr) { HDF_LOGE("%{public}s: get sensor Module instance failed", __func__); return HDF_FAILURE; } StartTrace(HITRACE_TAG_SENSORS, "GetSdcSensorInfo"); struct SdcSensorInfo sdcSensorInfo[DEFAULT_SDC_SENSOR_INFO_SIZE]; int32_t ret = sensorInterface->GetSdcSensorInfo(sdcSensorInfo); FinishTrace(HITRACE_TAG_SENSORS); if (ret != SENSOR_SUCCESS) { HDF_LOGE("%{public}s failed, error code is %{public}d", __func__, ret); } for (auto info : sdcSensorInfo) { SdcSensorInfoVdi infoVdi; infoVdi.offset = info.offset; infoVdi.sensorId = info.sensorId; infoVdi.ddrSize = info.ddrSize; infoVdi.minRateLevel = info.minRateLevel; infoVdi.maxRateLevel = info.maxRateLevel; infoVdi.memAddr = info.memAddr; infoVdi.reserved = info.reserved; sdcSensorInfoVdi.push_back(std::move(infoVdi)); } return ret; } int32_t SensorImpl::UnregisterImpl(int32_t groupId, IRemoteObject *callbackObj) { if (groupId < TRADITIONAL_SENSOR_TYPE || groupId > MEDICAL_SENSOR_TYPE) { HDF_LOGE("%{public}s: groupId [%{public}d] out of range", __func__, groupId); return SENSOR_INVALID_PARAM; } auto groupIdCallBackIter = g_groupIdCallBackMap.find(groupId); if (groupIdCallBackIter == g_groupIdCallBackMap.end()) { HDF_LOGE("%{public}s: groupId [%{public}d] callbackObj not registered", __func__, groupId); return HDF_FAILURE; } auto callBackIter = find_if(g_groupIdCallBackMap[groupId].begin(), g_groupIdCallBackMap[groupId].end(), [&callbackObj](const sptr<ISensorCallbackVdi> &callbackRegistered) { return callbackObj == (callbackRegistered->HandleCallbackDeath()).GetRefPtr(); }); if (callBackIter == g_groupIdCallBackMap[groupId].end()) { HDF_LOGE("%{public}s: groupId [%{public}d] callbackObj not registered", __func__, groupId); return HDF_FAILURE; } /** * when there is only one item in the vector,can call the Unregister function. * when there is more than one item in the vector, only need to remove the callbackObj * from the vector */ if (g_groupIdCallBackMap[groupId].size() > CALLBACK_CTOUNT_THRESHOLD) { g_groupIdCallBackMap[groupId].erase(callBackIter); return SENSOR_SUCCESS; } int32_t ret = HDF_FAILURE; if (groupId == TRADITIONAL_SENSOR_TYPE) { ret = sensorInterface->Unregister(groupId, TradtionalSensorDataCallback); } else if (groupId == MEDICAL_SENSOR_TYPE) { ret = sensorInterface->Unregister(groupId, MedicalSensorDataCallback); } if (ret != SENSOR_SUCCESS) { HDF_LOGE("%{public}s failed, error code is %{public}d", __func__, ret); return ret; } g_groupIdCallBackMap.erase(groupId); return ret; } static int32_t CreateSensorVdiInstance(struct HdfVdiBase *vdiBase) { HDF_LOGI("%{public}s", __func__); if (vdiBase == nullptr) { HDF_LOGI("%{public}s: parameter vdiBase is NULL", __func__); return HDF_FAILURE; } struct WrapperSensorVdi *sensorVdi = reinterpret_cast<struct WrapperSensorVdi *>(vdiBase); sensorVdi->sensorModule = new SensorImpl(); if (sensorVdi->sensorModule == nullptr) { HDF_LOGI("%{public}s: new sensorModule failed!", __func__); return HDF_FAILURE; } return HDF_SUCCESS; } static int32_t DestorySensorVdiInstance(struct HdfVdiBase *vdiBase) { HDF_LOGI("%{public}s", __func__); if (vdiBase == nullptr) { HDF_LOGI("%{public}s: parameter vdiBase is NULL", __func__); return HDF_FAILURE; } struct WrapperSensorVdi *sensorVdi = reinterpret_cast<struct WrapperSensorVdi *>(vdiBase); SensorImpl *impl = reinterpret_cast<SensorImpl *>(sensorVdi->sensorModule); if (impl != nullptr) { delete impl; sensorVdi->sensorModule = nullptr; } return HDF_SUCCESS; } static struct WrapperSensorVdi g_sensorVdi = { .base = { .moduleVersion = 1, .moduleName = "sensor_Service", .CreateVdiInstance = CreateSensorVdiInstance, .DestoryVdiInstance = DestorySensorVdiInstance, }, .sensorModule = nullptr, }; extern "C" HDF_VDI_INIT(g_sensorVdi); } // namespace V1_1 } // namespace Sensor } // namespace HDI } // namespace OHOS