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