• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "hdi_connection.h"
16 
17 #include <map>
18 #include <thread>
19 
20 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
21 #include "hisysevent.h"
22 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
23 #include "iproxy_broker.h"
24 #include "v2_1/isensor_interface.h"
25 
26 #include "sensor_agent_type.h"
27 #include "sensor_errors.h"
28 #include "sensor_event_callback.h"
29 
30 #undef LOG_TAG
31 #define LOG_TAG "HdiConnection"
32 
33 namespace OHOS {
34 namespace Sensors {
35 using namespace OHOS::HiviewDFX;
36 using OHOS::HDI::Sensor::V2_1::ISensorInterface;
37 using OHOS::HDI::Sensor::V2_1::ISensorCallback;
38 using OHOS::HDI::Sensor::V2_1::HdfSensorInformation;
39 namespace {
40 sptr<ISensorInterface> g_sensorInterface = nullptr;
41 sptr<ISensorCallback> g_eventCallback = nullptr;
42 std::map<int32_t, SensorBasicInfo> g_sensorBasicInfoMap;
43 std::mutex g_sensorBasicInfoMutex;
44 constexpr int32_t GET_HDI_SERVICE_COUNT = 25;
45 constexpr uint32_t WAIT_MS = 200;
46 constexpr int32_t HEADPOSTURE_FIFO_COUNT = 5;
47 }  // namespace
48 
49 ReportDataCb HdiConnection::reportDataCb_ = nullptr;
50 sptr<ReportDataCallback> HdiConnection::reportDataCallback_ = nullptr;
51 
ConnectHdi()52 int32_t HdiConnection::ConnectHdi()
53 {
54     CALL_LOG_ENTER;
55     int32_t retry = 0;
56     while (retry < GET_HDI_SERVICE_COUNT) {
57         g_sensorInterface = ISensorInterface::Get();
58         if (g_sensorInterface != nullptr) {
59             SEN_HILOGI("Connect v2_1 hdi success");
60             g_eventCallback = new (std::nothrow) SensorEventCallback();
61             CHKPR(g_eventCallback, ERR_NO_INIT);
62             RegisterHdiDeathRecipient();
63             return ERR_OK;
64         }
65         retry++;
66         SEN_HILOGW("Connect hdi service failed, retry:%{public}d", retry);
67         std::this_thread::sleep_for(std::chrono::milliseconds(WAIT_MS));
68     }
69 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
70     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SENSOR, "HDF_SERVICE_EXCEPTION",
71         HiSysEvent::EventType::FAULT, "PKG_NAME", "ConnectHdi", "ERROR_CODE", CONNECT_SENSOR_HDF_ERR);
72 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
73     SEN_HILOGE("Connect v2_1 hdi failed");
74     return ERR_NO_INIT;
75 }
76 
GetSensorList(std::vector<Sensor> & sensorList)77 int32_t HdiConnection::GetSensorList(std::vector<Sensor> &sensorList)
78 {
79     CALL_LOG_ENTER;
80     CHKPR(g_sensorInterface, ERR_NO_INIT);
81     std::vector<HdfSensorInformation> sensorInfos;
82     int32_t ret = g_sensorInterface->GetAllSensorInfo(sensorInfos);
83     if (ret != 0) {
84 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
85         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SENSOR, "HDF_SERVICE_EXCEPTION",
86             HiSysEvent::EventType::FAULT, "PKG_NAME", "GetSensorList", "ERROR_CODE", ret);
87 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
88         SEN_HILOGE("Get sensor list failed");
89         return ret;
90     }
91     size_t count = sensorInfos.size();
92     if (count > MAX_SENSOR_COUNT) {
93         SEN_HILOGD("SensorInfos size:%{public}zu", count);
94         count = MAX_SENSOR_COUNT;
95     }
96     for (size_t i = 0; i < count; i++) {
97         Sensor sensor;
98         sensor.SetSensorId(sensorInfos[i].sensorId);
99         sensor.SetSensorTypeId(sensorInfos[i].sensorId);
100         sensor.SetFirmwareVersion(sensorInfos[i].firmwareVersion);
101         sensor.SetHardwareVersion(sensorInfos[i].hardwareVersion);
102         sensor.SetMaxRange(sensorInfos[i].maxRange);
103         sensor.SetSensorName(sensorInfos[i].sensorName);
104         sensor.SetVendorName(sensorInfos[i].vendorName);
105         sensor.SetResolution(sensorInfos[i].accuracy);
106         sensor.SetPower(sensorInfos[i].power);
107         sensor.SetMinSamplePeriodNs(sensorInfos[i].minDelay);
108         sensor.SetMaxSamplePeriodNs(sensorInfos[i].maxDelay);
109         if (sensorInfos[i].sensorId == SENSOR_TYPE_ID_HEADPOSTURE) {
110             sensor.SetFifoMaxEventCount(HEADPOSTURE_FIFO_COUNT);
111         }
112         sensorList.push_back(sensor);
113     }
114     return ERR_OK;
115 }
116 
EnableSensor(int32_t sensorId)117 int32_t HdiConnection::EnableSensor(int32_t sensorId)
118 {
119     SEN_HILOGI("In, sensorId:%{public}d", sensorId);
120     CHKPR(g_sensorInterface, ERR_NO_INIT);
121     int32_t ret = g_sensorInterface->Enable(sensorId);
122     if (ret != 0) {
123 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
124         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SENSOR, "HDF_SERVICE_EXCEPTION",
125             HiSysEvent::EventType::FAULT, "PKG_NAME", "EnableSensor", "ERROR_CODE", ret);
126 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
127         SEN_HILOGE("Connect v2_1 hdi failed");
128         return ret;
129     }
130     SetSensorBasicInfoState(sensorId, true);
131     SEN_HILOGI("Done, sensorId:%{public}d", sensorId);
132     return ERR_OK;
133 }
134 
DisableSensor(int32_t sensorId)135 int32_t HdiConnection::DisableSensor(int32_t sensorId)
136 {
137     SEN_HILOGI("In, sensorId:%{public}d", sensorId);
138     CHKPR(g_sensorInterface, ERR_NO_INIT);
139     int32_t ret = g_sensorInterface->Disable(sensorId);
140     if (ret != 0) {
141 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
142         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SENSOR, "HDF_SERVICE_EXCEPTION",
143             HiSysEvent::EventType::FAULT, "PKG_NAME", "DisableSensor", "ERROR_CODE", ret);
144 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
145         SEN_HILOGE("Disable is failed");
146         return ret;
147     }
148     DeleteSensorBasicInfoState(sensorId);
149     SEN_HILOGI("Done, sensorId:%{public}d", sensorId);
150     return ERR_OK;
151 }
152 
SetBatch(int32_t sensorId,int64_t samplingInterval,int64_t reportInterval)153 int32_t HdiConnection::SetBatch(int32_t sensorId, int64_t samplingInterval, int64_t reportInterval)
154 {
155     CHKPR(g_sensorInterface, ERR_NO_INIT);
156     int32_t ret = g_sensorInterface->SetBatch(sensorId, samplingInterval, reportInterval);
157     if (ret != 0) {
158 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
159         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SENSOR, "HDF_SERVICE_EXCEPTION",
160             HiSysEvent::EventType::FAULT, "PKG_NAME", "SetBatch", "ERROR_CODE", ret);
161 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
162         SEN_HILOGE("SetBatch is failed");
163         return ret;
164     }
165     UpdateSensorBasicInfo(sensorId, samplingInterval, reportInterval);
166     return ERR_OK;
167 }
168 
SetMode(int32_t sensorId,int32_t mode)169 int32_t HdiConnection::SetMode(int32_t sensorId, int32_t mode)
170 {
171     CALL_LOG_ENTER;
172     CHKPR(g_sensorInterface, ERR_NO_INIT);
173     int32_t ret = g_sensorInterface->SetMode(sensorId, mode);
174     if (ret != 0) {
175 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
176         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SENSOR, "HDF_SERVICE_EXCEPTION",
177             HiSysEvent::EventType::FAULT, "PKG_NAME", "SetMode", "ERROR_CODE", ret);
178 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
179         SEN_HILOGE("SetMode is failed");
180         return ret;
181     }
182     return ERR_OK;
183 }
184 
RegisterDataReport(ReportDataCb cb,sptr<ReportDataCallback> reportDataCallback)185 int32_t HdiConnection::RegisterDataReport(ReportDataCb cb, sptr<ReportDataCallback> reportDataCallback)
186 {
187     CALL_LOG_ENTER;
188     CHKPR(reportDataCallback, ERR_NO_INIT);
189     CHKPR(g_sensorInterface, ERR_NO_INIT);
190     int32_t ret = g_sensorInterface->RegisterAsync(0, g_eventCallback);
191     if (ret != 0) {
192 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
193         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SENSOR, "HDF_SERVICE_EXCEPTION",
194             HiSysEvent::EventType::FAULT, "PKG_NAME", "RegisterDataReport", "ERROR_CODE", ret);
195 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
196         SEN_HILOGE("RegisterAsync is failed");
197         return ret;
198     }
199     reportDataCb_ = cb;
200     reportDataCallback_ = reportDataCallback;
201     return ERR_OK;
202 }
203 
DestroyHdiConnection()204 int32_t HdiConnection::DestroyHdiConnection()
205 {
206     CALL_LOG_ENTER;
207     CHKPR(g_sensorInterface, ERR_NO_INIT);
208     int32_t ret = g_sensorInterface->UnregisterAsync(0, g_eventCallback);
209     if (ret != 0) {
210 #ifdef HIVIEWDFX_HISYSEVENT_ENABLE
211         HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SENSOR, "HDF_SERVICE_EXCEPTION",
212             HiSysEvent::EventType::FAULT, "PKG_NAME", "DestroyHdiConnection", "ERROR_CODE", ret);
213 #endif // HIVIEWDFX_HISYSEVENT_ENABLE
214         SEN_HILOGE("UnregisterAsync is failed");
215         return ret;
216     }
217     g_eventCallback = nullptr;
218     UnregisterHdiDeathRecipient();
219     return ERR_OK;
220 }
221 
GetReportDataCb()222 ReportDataCb HdiConnection::GetReportDataCb()
223 {
224     if (reportDataCb_ == nullptr) {
225         SEN_HILOGE("reportDataCb_ cannot be null");
226     }
227     return reportDataCb_;
228 }
229 
GetReportDataCallback()230 sptr<ReportDataCallback> HdiConnection::GetReportDataCallback()
231 {
232     if (reportDataCallback_ == nullptr) {
233         SEN_HILOGE("reportDataCallback_ cannot be null");
234     }
235     return reportDataCallback_;
236 }
237 
UpdateSensorBasicInfo(int32_t sensorId,int64_t samplingPeriodNs,int64_t maxReportDelayNs)238 void HdiConnection::UpdateSensorBasicInfo(int32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs)
239 {
240     std::lock_guard<std::mutex> sensorInfoLock(g_sensorBasicInfoMutex);
241     SensorBasicInfo sensorBasicInfo;
242     sensorBasicInfo.SetSamplingPeriodNs(samplingPeriodNs);
243     sensorBasicInfo.SetMaxReportDelayNs(maxReportDelayNs);
244     auto it = g_sensorBasicInfoMap.find(sensorId);
245     if (it != g_sensorBasicInfoMap.end()) {
246         if (g_sensorBasicInfoMap[sensorId].GetSensorState()) {
247             sensorBasicInfo.SetSensorState(true);
248         }
249     }
250     g_sensorBasicInfoMap[sensorId] = sensorBasicInfo;
251 }
252 
SetSensorBasicInfoState(int32_t sensorId,bool state)253 void HdiConnection::SetSensorBasicInfoState(int32_t sensorId, bool state)
254 {
255     SEN_HILOGI("In, sensorId:%{public}d", sensorId);
256     std::lock_guard<std::mutex> sensorInfoLock(g_sensorBasicInfoMutex);
257     auto it = g_sensorBasicInfoMap.find(sensorId);
258     if (it == g_sensorBasicInfoMap.end()) {
259         SEN_HILOGW("Should set batch first");
260         return;
261     }
262     g_sensorBasicInfoMap[sensorId].SetSensorState(state);
263     SEN_HILOGI("Done, sensorId:%{public}d", sensorId);
264 }
265 
DeleteSensorBasicInfoState(int32_t sensorId)266 void HdiConnection::DeleteSensorBasicInfoState(int32_t sensorId)
267 {
268     SEN_HILOGI("In, sensorId:%{public}d", sensorId);
269     std::lock_guard<std::mutex> sensorInfoLock(g_sensorBasicInfoMutex);
270     auto it = g_sensorBasicInfoMap.find(sensorId);
271     if (it != g_sensorBasicInfoMap.end()) {
272         g_sensorBasicInfoMap.erase(sensorId);
273     }
274     SEN_HILOGI("Done, sensorId:%{public}d", sensorId);
275 }
276 
RegisterHdiDeathRecipient()277 void HdiConnection::RegisterHdiDeathRecipient()
278 {
279     CALL_LOG_ENTER;
280     CHKPV(g_sensorInterface);
281     if (hdiDeathObserver_ == nullptr) {
282         hdiDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast<HdiConnection *>(this));
283         CHKPV(hdiDeathObserver_);
284     }
285     OHOS::HDI::hdi_objcast<ISensorInterface>(g_sensorInterface)->AddDeathRecipient(hdiDeathObserver_);
286 }
287 
UnregisterHdiDeathRecipient()288 void HdiConnection::UnregisterHdiDeathRecipient()
289 {
290     CALL_LOG_ENTER;
291     CHKPV(g_sensorInterface);
292     CHKPV(hdiDeathObserver_);
293     OHOS::HDI::hdi_objcast<ISensorInterface>(g_sensorInterface)->RemoveDeathRecipient(hdiDeathObserver_);
294 }
295 
ProcessDeathObserver(const wptr<IRemoteObject> & object)296 void HdiConnection::ProcessDeathObserver(const wptr<IRemoteObject> &object)
297 {
298     CALL_LOG_ENTER;
299     sptr<IRemoteObject> hdiService = object.promote();
300     CHKPV(hdiService);
301     CHKPV(hdiDeathObserver_);
302     hdiService->RemoveDeathRecipient(hdiDeathObserver_);
303     g_eventCallback = nullptr;
304     Reconnect();
305 }
306 
Reconnect()307 void HdiConnection::Reconnect()
308 {
309     CALL_LOG_ENTER;
310     int32_t ret = ConnectHdi();
311     if (ret != 0) {
312         SEN_HILOGE("Failed to get an instance of hdi service");
313         return;
314     }
315     ret = g_sensorInterface->Register(0, g_eventCallback);
316     if (ret != 0) {
317         SEN_HILOGE("Register callback fail");
318         return;
319     }
320     std::vector<Sensor> sensorList;
321     ret = GetSensorList(sensorList);
322     if (ret != 0) {
323         SEN_HILOGE("Get sensor list fail");
324         return;
325     }
326     std::lock_guard<std::mutex> sensorInfoLock(g_sensorBasicInfoMutex);
327     for (const auto &sensorInfo: g_sensorBasicInfoMap) {
328         int32_t sensorTypeId = sensorInfo.first;
329         SensorBasicInfo info = sensorInfo.second;
330         if (info.GetSensorState() != true) {
331             SEN_HILOGE("sensorTypeId:%{public}d don't need enable sensor", sensorTypeId);
332             continue;
333         }
334         ret = g_sensorInterface->SetBatch(sensorTypeId, info.GetSamplingPeriodNs(), info.GetMaxReportDelayNs());
335         if (ret != 0) {
336             SEN_HILOGE("sensorTypeId:%{public}d set batch fail, error:%{public}d", sensorTypeId, ret);
337             continue;
338         }
339         ret = g_sensorInterface->Enable(sensorTypeId);
340         if (ret != 0) {
341             SEN_HILOGE("Enable sensor fail, sensorTypeId:%{public}d, error:%{public}d", sensorTypeId, ret);
342         }
343     }
344 }
345 } // namespace Sensors
346 } // namespace OHOS
347