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 CHKPR(g_sensorInterface, ERR_NO_INIT);
115 int32_t ret = g_sensorInterface->Enable(sensorId);
116 if (ret != 0) {
117 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SENSOR, "HDF_SERVICE_EXCEPTION",
118 HiSysEvent::EventType::FAULT, "PKG_NAME", "EnableSensor", "ERROR_CODE", ret);
119 SEN_HILOGE("Connect V2_0 hdi failed");
120 return ret;
121 }
122 SetSensorBasicInfoState(sensorId, true);
123 return ERR_OK;
124 }
125
DisableSensor(int32_t sensorId)126 int32_t HdiConnection::DisableSensor(int32_t sensorId)
127 {
128 CHKPR(g_sensorInterface, ERR_NO_INIT);
129 int32_t ret = g_sensorInterface->Disable(sensorId);
130 if (ret != 0) {
131 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SENSOR, "HDF_SERVICE_EXCEPTION",
132 HiSysEvent::EventType::FAULT, "PKG_NAME", "DisableSensor", "ERROR_CODE", ret);
133 SEN_HILOGE("Disable is failed");
134 return ret;
135 }
136 DeleteSensorBasicInfoState(sensorId);
137 return ERR_OK;
138 }
139
SetBatch(int32_t sensorId,int64_t samplingInterval,int64_t reportInterval)140 int32_t HdiConnection::SetBatch(int32_t sensorId, int64_t samplingInterval, int64_t reportInterval)
141 {
142 CHKPR(g_sensorInterface, ERR_NO_INIT);
143 int32_t ret = g_sensorInterface->SetBatch(sensorId, samplingInterval, reportInterval);
144 if (ret != 0) {
145 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SENSOR, "HDF_SERVICE_EXCEPTION",
146 HiSysEvent::EventType::FAULT, "PKG_NAME", "SetBatch", "ERROR_CODE", ret);
147 SEN_HILOGE("SetBatch is failed");
148 return ret;
149 }
150 UpdateSensorBasicInfo(sensorId, samplingInterval, reportInterval);
151 return ERR_OK;
152 }
153
SetMode(int32_t sensorId,int32_t mode)154 int32_t HdiConnection::SetMode(int32_t sensorId, int32_t mode)
155 {
156 CALL_LOG_ENTER;
157 CHKPR(g_sensorInterface, ERR_NO_INIT);
158 int32_t ret = g_sensorInterface->SetMode(sensorId, mode);
159 if (ret != 0) {
160 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SENSOR, "HDF_SERVICE_EXCEPTION",
161 HiSysEvent::EventType::FAULT, "PKG_NAME", "SetMode", "ERROR_CODE", ret);
162 SEN_HILOGE("SetMode is failed");
163 return ret;
164 }
165 return ERR_OK;
166 }
167
RegisterDataReport(ReportDataCb cb,sptr<ReportDataCallback> reportDataCallback)168 int32_t HdiConnection::RegisterDataReport(ReportDataCb cb, sptr<ReportDataCallback> reportDataCallback)
169 {
170 CALL_LOG_ENTER;
171 CHKPR(reportDataCallback, ERR_NO_INIT);
172 CHKPR(g_sensorInterface, ERR_NO_INIT);
173 int32_t ret = g_sensorInterface->Register(0, g_eventCallback);
174 if (ret != 0) {
175 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SENSOR, "HDF_SERVICE_EXCEPTION",
176 HiSysEvent::EventType::FAULT, "PKG_NAME", "RegisterDataReport", "ERROR_CODE", ret);
177 SEN_HILOGE("Register is failed");
178 return ret;
179 }
180 reportDataCb_ = cb;
181 reportDataCallback_ = reportDataCallback;
182 return ERR_OK;
183 }
184
DestroyHdiConnection()185 int32_t HdiConnection::DestroyHdiConnection()
186 {
187 CALL_LOG_ENTER;
188 CHKPR(g_sensorInterface, ERR_NO_INIT);
189 int32_t ret = g_sensorInterface->Unregister(0, g_eventCallback);
190 if (ret != 0) {
191 HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::SENSOR, "HDF_SERVICE_EXCEPTION",
192 HiSysEvent::EventType::FAULT, "PKG_NAME", "DestroyHdiConnection", "ERROR_CODE", ret);
193 SEN_HILOGE("Unregister is failed");
194 return ret;
195 }
196 g_eventCallback = nullptr;
197 UnregisterHdiDeathRecipient();
198 return ERR_OK;
199 }
200
GetReportDataCb()201 ReportDataCb HdiConnection::GetReportDataCb()
202 {
203 if (reportDataCb_ == nullptr) {
204 SEN_HILOGE("reportDataCb_ cannot be null");
205 }
206 return reportDataCb_;
207 }
208
GetReportDataCallback()209 sptr<ReportDataCallback> HdiConnection::GetReportDataCallback()
210 {
211 if (reportDataCallback_ == nullptr) {
212 SEN_HILOGE("reportDataCallback_ cannot be null");
213 }
214 return reportDataCallback_;
215 }
216
UpdateSensorBasicInfo(int32_t sensorId,int64_t samplingPeriodNs,int64_t maxReportDelayNs)217 void HdiConnection::UpdateSensorBasicInfo(int32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs)
218 {
219 std::lock_guard<std::mutex> sensorInfoLock(g_sensorBasicInfoMutex);
220 SensorBasicInfo sensorBasicInfo;
221 sensorBasicInfo.SetSamplingPeriodNs(samplingPeriodNs);
222 sensorBasicInfo.SetMaxReportDelayNs(maxReportDelayNs);
223 auto it = g_sensorBasicInfoMap.find(sensorId);
224 if (it != g_sensorBasicInfoMap.end()) {
225 if (g_sensorBasicInfoMap[sensorId].GetSensorState()) {
226 sensorBasicInfo.SetSensorState(true);
227 }
228 }
229 g_sensorBasicInfoMap[sensorId] = sensorBasicInfo;
230 }
231
SetSensorBasicInfoState(int32_t sensorId,bool state)232 void HdiConnection::SetSensorBasicInfoState(int32_t sensorId, bool state)
233 {
234 std::lock_guard<std::mutex> sensorInfoLock(g_sensorBasicInfoMutex);
235 auto it = g_sensorBasicInfoMap.find(sensorId);
236 if (it == g_sensorBasicInfoMap.end()) {
237 SEN_HILOGW("Should set batch first");
238 return;
239 }
240 g_sensorBasicInfoMap[sensorId].SetSensorState(state);
241 }
242
DeleteSensorBasicInfoState(int32_t sensorId)243 void HdiConnection::DeleteSensorBasicInfoState(int32_t sensorId)
244 {
245 std::lock_guard<std::mutex> sensorInfoLock(g_sensorBasicInfoMutex);
246 auto it = g_sensorBasicInfoMap.find(sensorId);
247 if (it != g_sensorBasicInfoMap.end()) {
248 g_sensorBasicInfoMap.erase(sensorId);
249 }
250 }
251
RegisterHdiDeathRecipient()252 void HdiConnection::RegisterHdiDeathRecipient()
253 {
254 CALL_LOG_ENTER;
255 CHKPV(g_sensorInterface);
256 if (hdiDeathObserver_ == nullptr) {
257 hdiDeathObserver_ = new (std::nothrow) DeathRecipientTemplate(*const_cast<HdiConnection *>(this));
258 CHKPV(hdiDeathObserver_);
259 }
260 OHOS::HDI::hdi_objcast<ISensorInterface>(g_sensorInterface)->AddDeathRecipient(hdiDeathObserver_);
261 }
262
UnregisterHdiDeathRecipient()263 void HdiConnection::UnregisterHdiDeathRecipient()
264 {
265 CALL_LOG_ENTER;
266 CHKPV(g_sensorInterface);
267 CHKPV(hdiDeathObserver_);
268 OHOS::HDI::hdi_objcast<ISensorInterface>(g_sensorInterface)->RemoveDeathRecipient(hdiDeathObserver_);
269 }
270
ProcessDeathObserver(const wptr<IRemoteObject> & object)271 void HdiConnection::ProcessDeathObserver(const wptr<IRemoteObject> &object)
272 {
273 CALL_LOG_ENTER;
274 sptr<IRemoteObject> hdiService = object.promote();
275 CHKPV(hdiService);
276 CHKPV(hdiDeathObserver_);
277 hdiService->RemoveDeathRecipient(hdiDeathObserver_);
278 g_eventCallback = nullptr;
279 Reconnect();
280 }
281
Reconnect()282 void HdiConnection::Reconnect()
283 {
284 CALL_LOG_ENTER;
285 int32_t ret = ConnectHdi();
286 if (ret != 0) {
287 SEN_HILOGE("Failed to get an instance of hdi service");
288 return;
289 }
290 ret = g_sensorInterface->Register(0, g_eventCallback);
291 if (ret != 0) {
292 SEN_HILOGE("Register callback fail");
293 return;
294 }
295 std::vector<Sensor> sensorList;
296 ret = GetSensorList(sensorList);
297 if (ret != 0) {
298 SEN_HILOGE("Get sensor list fail");
299 return;
300 }
301 std::lock_guard<std::mutex> sensorInfoLock(g_sensorBasicInfoMutex);
302 for (const auto &sensorInfo: g_sensorBasicInfoMap) {
303 int32_t sensorTypeId = sensorInfo.first;
304 SensorBasicInfo info = sensorInfo.second;
305 if (info.GetSensorState() != true) {
306 SEN_HILOGE("sensorTypeId:%{public}d don't need enable sensor", sensorTypeId);
307 continue;
308 }
309 ret = g_sensorInterface->SetBatch(sensorTypeId, info.GetSamplingPeriodNs(), info.GetMaxReportDelayNs());
310 if (ret != 0) {
311 SEN_HILOGE("sensorTypeId:%{public}d set batch fail, error:%{public}d", sensorTypeId, ret);
312 continue;
313 }
314 ret = g_sensorInterface->Enable(sensorTypeId);
315 if (ret != 0) {
316 SEN_HILOGE("Enable sensor fail, sensorTypeId:%{public}d, error:%{public}d", sensorTypeId, ret);
317 }
318 }
319 }
320 } // namespace Sensors
321 } // namespace OHOS
322