1 /*
2  * Copyright (c) 2024 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 
16 #include "sensor_adapter_impl.h"
17 
18 #include <securec.h>
19 #include <map>
20 
21 #include "nweb_log.h"
22 
23 namespace OHOS::NWeb {
24 
25 std::unordered_map<int32_t, std::shared_ptr<SensorCallbackImpl>> SensorAdapterImpl::sensorCallbackMap;
26 std::mutex SensorAdapterImpl::sensorCallbackMapMutex_;
27 constexpr double NANOSECONDS_IN_SECOND = 1000000000.0;
28 constexpr double DEFAULT_SAMPLE_PERIOD = 200000000.0;
29 
SensorTypeToOhosSensorType(int sensorTypeId)30 SensorTypeId SensorTypeToOhosSensorType(int sensorTypeId)
31 {
32     SensorTypeId ohosSensorTypeId = SENSOR_TYPE_ID_NONE;
33     const static std::map<int32_t, SensorTypeId> TO_OHOS_SENSOR_TYPE_MAP = {
34         {2  /* ACCELEROMETER                     */, SENSOR_TYPE_ID_ACCELEROMETER },
35         {3  /* LINEAR_ACCELERATION               */, SENSOR_TYPE_ID_LINEAR_ACCELERATION },
36         {4  /* GRAVITY                           */, SENSOR_TYPE_ID_GRAVITY },
37         {5  /* GYROSCOPE                         */, SENSOR_TYPE_ID_GYROSCOPE },
38         {6  /* MAGNETOMETER                      */, SENSOR_TYPE_ID_MAGNETIC_FIELD },
39         {8  /* ABSOLUTE_ORIENTATION_EULER_ANGLES}*/, SENSOR_TYPE_ID_ORIENTATION },
40         {9  /* ABSOLUTE_ORIENTATION_QUATERNION}  */, SENSOR_TYPE_ID_ROTATION_VECTOR },
41         {11 /* RELATIVE_ORIENTATION_QUATERNION}  */, SENSOR_TYPE_ID_GAME_ROTATION_VECTOR }
42     };
43     auto checkIter = TO_OHOS_SENSOR_TYPE_MAP.find(sensorTypeId);
44     if (checkIter != TO_OHOS_SENSOR_TYPE_MAP.end()) {
45         ohosSensorTypeId = checkIter->second;
46     }
47     return ohosSensorTypeId;
48 }
49 
SensorTypeToSensorUserName(int sensorTypeId)50 std::string SensorTypeToSensorUserName(int sensorTypeId)
51 {
52     const static std::map<int32_t, std::string> TO_OHOS_SENSOR_USER_NAME_MAP = {
53         {2  /* ACCELEROMETER                     */, "OhosAccelerometerService" },
54         {3  /* LINEAR_ACCELERATION               */, "OhosLinearAccelerometerService" },
55         {4  /* GRAVITY                           */, "OhosGravityService" },
56         {5  /* GYROSCOPE                         */, "OhosCyroscopeService" },
57         {6  /* MAGNETOMETER                      */, "OhosMagnetometerService" },
58         {8  /* ABSOLUTE_ORIENTATION_EULER_ANGLES}*/, "OhosOrientationService" },
59         {9  /* ABSOLUTE_ORIENTATION_QUATERNION}  */, "OhosRotationVectorService"},
60         {11 /* RELATIVE_ORIENTATION_QUATERNION}  */, "OhosGameRotationVectorService" }
61     };
62     std::string userName = "OhosSensorService";
63     auto checkIter = TO_OHOS_SENSOR_USER_NAME_MAP.find(sensorTypeId);
64     if (checkIter != TO_OHOS_SENSOR_USER_NAME_MAP.end()) {
65         userName = checkIter->second;
66     }
67     return userName;
68 }
69 
SensorCallbackImpl(std::shared_ptr<SensorCallbackAdapter> callbackAdapter)70 SensorCallbackImpl::SensorCallbackImpl(
71     std::shared_ptr<SensorCallbackAdapter> callbackAdapter)
72     : callbackAdapter_(callbackAdapter)
73 {}
74 
UpdateOhosSensorData(double timestamp,double value1,double value2,double value3,double value4)75 void SensorCallbackImpl::UpdateOhosSensorData(double timestamp,
76     double value1, double value2, double value3, double value4)
77 {
78     if (callbackAdapter_) {
79         callbackAdapter_->UpdateOhosSensorData(timestamp, value1, value2, value3, value4);
80     }
81 }
82 
IsOhosSensorSupported(int32_t sensorTypeId)83 int32_t SensorAdapterImpl::IsOhosSensorSupported(int32_t sensorTypeId)
84 {
85     int32_t ohosSensorTypeId = SensorTypeToOhosSensorType(sensorTypeId);
86     if (ohosSensorTypeId != SENSOR_TYPE_ID_NONE) {
87         SensorInfo* sensorInfo = nullptr;
88         int32_t count;
89         int ret = GetAllSensors(&sensorInfo, &count);
90         if (ret != SENSOR_SUCCESS || sensorInfo == nullptr || count < 0) {
91             WVLOG_E("IsOhosSensorSupported Error, ret = %{public}d, count = %{public}d.", ret, count);
92             return SENSOR_ERROR;
93         }
94 
95         for (int i = 0; i < count; i++) {
96             if (sensorInfo[i].sensorId == ohosSensorTypeId) {
97                 WVLOG_I("IsOhosSensorSupported SUCCESS, sensorTypeId = %{public}d.", sensorTypeId);
98                 return SENSOR_SUCCESS;
99             }
100         }
101     }
102     WVLOG_E("IsOhosSensorSupported Error, sensorTypeId = %{public}d is invalid.", sensorTypeId);
103     return SENSOR_ERROR;
104 }
105 
GetOhosSensorReportingMode(int32_t sensorTypeId)106 int32_t SensorAdapterImpl::GetOhosSensorReportingMode(int32_t sensorTypeId)
107 {
108     int32_t ohosSensorTypeId = SensorTypeToOhosSensorType(sensorTypeId);
109     int32_t reportingMode = -1;
110     switch (ohosSensorTypeId) {
111         case SENSOR_TYPE_ID_ACCELEROMETER:
112         case SENSOR_TYPE_ID_GRAVITY:
113         case SENSOR_TYPE_ID_LINEAR_ACCELERATION:
114         case SENSOR_TYPE_ID_GYROSCOPE:
115         case SENSOR_TYPE_ID_MAGNETIC_FIELD:
116         case SENSOR_TYPE_ID_ORIENTATION:
117         case SENSOR_TYPE_ID_ROTATION_VECTOR:
118         case SENSOR_TYPE_ID_GAME_ROTATION_VECTOR:
119             reportingMode = SENSOR_DATA_REPORT_CONTINUOUS;
120             break;
121         default:
122             break;
123     }
124     return reportingMode;
125 }
126 
GetOhosSensorDefaultSupportedFrequency(int32_t sensorTypeId)127 double SensorAdapterImpl::GetOhosSensorDefaultSupportedFrequency(int32_t sensorTypeId)
128 {
129     int32_t ohosSensorTypeId = SensorTypeToOhosSensorType(sensorTypeId);
130     double defaultFrequency = 0.0;
131     if (ohosSensorTypeId != SENSOR_TYPE_ID_NONE) {
132         defaultFrequency = NANOSECONDS_IN_SECOND / DEFAULT_SAMPLE_PERIOD;
133     }
134     WVLOG_I("GetOhosSensorDefaultSupportedFrequency sensorTypeId: %{public}d, defaultFrequency: %{public}f",
135         sensorTypeId, defaultFrequency);
136     return defaultFrequency;
137 }
138 
GetOhosSensorMinSupportedFrequency(int32_t sensorTypeId)139 double SensorAdapterImpl::GetOhosSensorMinSupportedFrequency(int32_t sensorTypeId)
140 {
141     int32_t ohosSensorTypeId = SensorTypeToOhosSensorType(sensorTypeId);
142     double minFrequency = 0.0;
143     if (ohosSensorTypeId == SENSOR_TYPE_ID_NONE) {
144         WVLOG_E("GetOhosSensorMinSupportedFrequency Error, sensorTypeId = %{public}d is invalid.", sensorTypeId);
145         return minFrequency;
146     }
147     SensorInfo* sensorInfo = nullptr;
148     int32_t count;
149     int ret = GetAllSensors(&sensorInfo, &count);
150     if (ret != SENSOR_SUCCESS || sensorInfo == nullptr || count < 0) {
151         WVLOG_E("GetOhosSensorMinSupportedFrequency Error, ret = %{public}d, count = %{public}d.", ret, count);
152         return minFrequency;
153     }
154     for (int i = 0; i < count; i++) {
155         if (sensorInfo[i].sensorId == ohosSensorTypeId) {
156             int64_t maxSamplePeriod = sensorInfo[i].maxSamplePeriod;
157             if (maxSamplePeriod > 0) {
158                 minFrequency = NANOSECONDS_IN_SECOND / static_cast<double>(maxSamplePeriod);
159             }
160             break;
161         }
162     }
163     WVLOG_I("GetOhosSensorMinSupportedFrequency sensorTypeId: %{public}d, minFrequency: %{public}f",
164         sensorTypeId, minFrequency);
165     return minFrequency;
166 }
167 
GetOhosSensorMaxSupportedFrequency(int32_t sensorTypeId)168 double SensorAdapterImpl::GetOhosSensorMaxSupportedFrequency(int32_t sensorTypeId)
169 {
170     int32_t ohosSensorTypeId = SensorTypeToOhosSensorType(sensorTypeId);
171     double maxFrequency = 0.0;
172     if (ohosSensorTypeId == SENSOR_TYPE_ID_NONE) {
173         WVLOG_E("GetOhosSensorMaxSupportedFrequency Error, sensorTypeId = %{public}d is invalid.", sensorTypeId);
174         return maxFrequency;
175     }
176     SensorInfo* sensorInfo = nullptr;
177     int32_t count;
178     int ret = GetAllSensors(&sensorInfo, &count);
179     if (ret != SENSOR_SUCCESS || sensorInfo == nullptr || count < 0) {
180         WVLOG_E("GetOhosSensorMaxSupportedFrequency Error, ret = %{public}d, count = %{public}d.", ret, count);
181         return maxFrequency;
182     }
183     for (int i = 0; i < count; i++) {
184         if (sensorInfo[i].sensorId == ohosSensorTypeId) {
185             int64_t minSamplePeriod = sensorInfo[i].minSamplePeriod;
186             if (minSamplePeriod > 0) {
187                 maxFrequency = NANOSECONDS_IN_SECOND / static_cast<double>(minSamplePeriod);
188             }
189             break;
190         }
191     }
192     WVLOG_I("GetOhosSensorMaxSupportedFrequency sensorTypeId: %{public}d, maxFrequency: %{public}f",
193         sensorTypeId, maxFrequency);
194     return maxFrequency;
195 }
196 
handleAccelerometerData(std::shared_ptr<OHOS::NWeb::SensorCallbackImpl> callback,SensorEvent * event)197 void SensorAdapterImpl::handleAccelerometerData(std::shared_ptr<OHOS::NWeb::SensorCallbackImpl> callback,
198     SensorEvent* event)
199 {
200     if ((event == nullptr) || (callback == nullptr)) {
201         WVLOG_E("handleAccelerometerData Error.");
202         return;
203     }
204     AccelData* data = reinterpret_cast<AccelData*>(event->data);
205     if (data != nullptr) {
206         callback->UpdateOhosSensorData(event->timestamp, data->x, data->y, data->z, 0.0f);
207     }
208 }
209 
handleLinearAccelerometerData(std::shared_ptr<OHOS::NWeb::SensorCallbackImpl> callback,SensorEvent * event)210 void SensorAdapterImpl::handleLinearAccelerometerData(std::shared_ptr<OHOS::NWeb::SensorCallbackImpl> callback,
211     SensorEvent* event)
212 {
213     if ((event == nullptr) || (callback == nullptr)) {
214         WVLOG_E("handleLinearAccelerometerData Error.");
215         return;
216     }
217     LinearAccelData* data = reinterpret_cast<LinearAccelData*>(event->data);
218     if (data != nullptr) {
219         callback->UpdateOhosSensorData(event->timestamp, data->x, data->y, data->z, 0.0f);
220     }
221 }
222 
handleGravityData(std::shared_ptr<OHOS::NWeb::SensorCallbackImpl> callback,SensorEvent * event)223 void SensorAdapterImpl::handleGravityData(std::shared_ptr<OHOS::NWeb::SensorCallbackImpl> callback,
224     SensorEvent* event)
225 {
226     if ((event == nullptr) || (callback == nullptr)) {
227         WVLOG_E("handleGravityData Error.");
228         return;
229     }
230     GravityData* data = reinterpret_cast<GravityData*>(event->data);
231     if (data != nullptr) {
232         callback->UpdateOhosSensorData(event->timestamp, data->x, data->y, data->z, 0.0f);
233     }
234 }
235 
handleCyroscopeData(std::shared_ptr<OHOS::NWeb::SensorCallbackImpl> callback,SensorEvent * event)236 void SensorAdapterImpl::handleCyroscopeData(std::shared_ptr<OHOS::NWeb::SensorCallbackImpl> callback,
237     SensorEvent* event)
238 {
239     if ((event == nullptr) || (callback == nullptr)) {
240         WVLOG_E("handleCyroscopeData Error.");
241         return;
242     }
243     GyroscopeData* data = reinterpret_cast<GyroscopeData*>(event->data);
244     if (data != nullptr) {
245         callback->UpdateOhosSensorData(event->timestamp, data->x, data->y, data->z, 0.0f);
246     }
247 }
248 
handleMagnetometerData(std::shared_ptr<OHOS::NWeb::SensorCallbackImpl> callback,SensorEvent * event)249 void SensorAdapterImpl::handleMagnetometerData(std::shared_ptr<OHOS::NWeb::SensorCallbackImpl> callback,
250     SensorEvent* event)
251 {
252     if ((event == nullptr) || (callback == nullptr)) {
253         WVLOG_E("handleMagnetometerData Error.");
254         return;
255     }
256     MagneticFieldData* data = reinterpret_cast<MagneticFieldData*>(event->data);
257     if (data != nullptr) {
258         callback->UpdateOhosSensorData(event->timestamp, data->x, data->y, data->z, 0.0f);
259     }
260 }
261 
handleOrientationData(std::shared_ptr<OHOS::NWeb::SensorCallbackImpl> callback,SensorEvent * event)262 void SensorAdapterImpl::handleOrientationData(std::shared_ptr<OHOS::NWeb::SensorCallbackImpl> callback,
263     SensorEvent* event)
264 {
265     if ((event == nullptr) || (callback == nullptr)) {
266         WVLOG_E("handleOrientationData Error.");
267         return;
268     }
269     OrientationData* data = reinterpret_cast<OrientationData*>(event->data);
270     if (data != nullptr) {
271         callback->UpdateOhosSensorData(event->timestamp, data->beta, data->gamma, data->alpha, 0.0f);
272     }
273 }
274 
handleRotationVectorData(std::shared_ptr<OHOS::NWeb::SensorCallbackImpl> callback,SensorEvent * event)275 void SensorAdapterImpl::handleRotationVectorData(std::shared_ptr<OHOS::NWeb::SensorCallbackImpl> callback,
276     SensorEvent* event)
277 {
278     if ((event == nullptr) || (callback == nullptr)) {
279         WVLOG_E("handleRotationVectorData Error.");
280         return;
281     }
282     RotationVectorData* data = reinterpret_cast<RotationVectorData*>(event->data);
283     if (data != nullptr) {
284         callback->UpdateOhosSensorData(event->timestamp, data->x, data->y, data->z, data->w);
285     }
286 }
287 
handleGameRotationVectorData(std::shared_ptr<OHOS::NWeb::SensorCallbackImpl> callback,SensorEvent * event)288 void SensorAdapterImpl::handleGameRotationVectorData(std::shared_ptr<OHOS::NWeb::SensorCallbackImpl> callback,
289     SensorEvent* event)
290 {
291     if ((event == nullptr) || (callback == nullptr)) {
292         WVLOG_E("handleGameRotationVectorData Error.");
293         return;
294     }
295     GameRotationVectorData* data = reinterpret_cast<GameRotationVectorData*>(event->data);
296     if (data != nullptr) {
297         callback->UpdateOhosSensorData(event->timestamp, data->x, data->y, data->z, data->w);
298     }
299 }
300 
OhosSensorCallback(SensorEvent * event)301 void SensorAdapterImpl::OhosSensorCallback(SensorEvent* event)
302 {
303     if (event == nullptr) {
304         WVLOG_E("SensorEvent Error.");
305         return;
306     }
307     std::shared_ptr<OHOS::NWeb::SensorCallbackImpl> callback = nullptr;
308     {
309         std::lock_guard<std::mutex> lock(sensorCallbackMapMutex_);
310         auto findIter = sensorCallbackMap.find(event->sensorTypeId);
311         if (findIter != sensorCallbackMap.end()) {
312             callback = findIter->second;
313         }
314     }
315     if (callback == nullptr) {
316         WVLOG_E("OhosSensorCallback Error.");
317         return;
318     }
319     switch (event->sensorTypeId) {
320         case SENSOR_TYPE_ID_ACCELEROMETER:
321             handleAccelerometerData(callback, event);
322             break;
323 
324         case SENSOR_TYPE_ID_GRAVITY:
325             handleGravityData(callback, event);
326             break;
327 
328         case SENSOR_TYPE_ID_LINEAR_ACCELERATION:
329             handleLinearAccelerometerData(callback, event);
330             break;
331 
332         case SENSOR_TYPE_ID_GYROSCOPE:
333             handleCyroscopeData(callback, event);
334             break;
335 
336         case SENSOR_TYPE_ID_MAGNETIC_FIELD:
337             handleMagnetometerData(callback, event);
338             break;
339         case SENSOR_TYPE_ID_ORIENTATION:
340             handleOrientationData(callback, event);
341             break;
342         case SENSOR_TYPE_ID_ROTATION_VECTOR:
343             handleRotationVectorData(callback, event);
344             break;
345         case SENSOR_TYPE_ID_GAME_ROTATION_VECTOR:
346             handleGameRotationVectorData(callback, event);
347             break;
348 
349         default:
350             break;
351     }
352 }
353 
SubscribeOhosSensor(int32_t sensorTypeId,int64_t samplingInterval)354 int32_t SensorAdapterImpl::SubscribeOhosSensor(int32_t sensorTypeId, int64_t samplingInterval)
355 {
356     WVLOG_I("SubscribeOhosSensor sensorTypeId: %{public}d, samplingInterval: %{public}lld",
357         sensorTypeId, samplingInterval);
358     WVLOG_I("SubscribeOhosSensor sensorTypeId: %{public}d", sensorTypeId);
359     if (samplingInterval <= 0) {
360         WVLOG_E("SubscribeOhosSensor error, samplingInterval is invalid.");
361         return SENSOR_PARAMETER_ERROR;
362     }
363     int32_t ohosSensorTypeId = SensorTypeToOhosSensorType(sensorTypeId);
364     if (ohosSensorTypeId == SENSOR_TYPE_ID_NONE) {
365         WVLOG_E("SubscribeOhosSensor error, sensorTypeId is invalid.");
366         return SENSOR_PARAMETER_ERROR;
367     }
368 
369     std::string userName = SensorTypeToSensorUserName(sensorTypeId);
370     int cpyret = strcpy_s(mSensorUser.name, sizeof(mSensorUser.name), userName.c_str());
371     if (cpyret != 0) {
372         WVLOG_E("SubscribeOhosSensor error, call strcpy_s ret = %{public}d.", cpyret);
373     }
374     mSensorUser.userData = nullptr;
375     mSensorUser.callback = &OhosSensorCallback;
376     int32_t ret = SENSOR_SUCCESS;
377     ret = SubscribeSensor(ohosSensorTypeId, &mSensorUser);
378     if (ret != SENSOR_SUCCESS) {
379         WVLOG_E("SubscribeOhosSensor error, call SubscribeSensor ret = %{public}d.", ret);
380         return ret;
381     }
382     ret = SetBatch(ohosSensorTypeId, &mSensorUser, samplingInterval, samplingInterval);
383     if (ret != SENSOR_SUCCESS) {
384         WVLOG_E("SubscribeOhosSensor error, call SetBatch ret = %{public}d.", ret);
385         return ret;
386     }
387     ret = ActivateSensor(ohosSensorTypeId, &mSensorUser);
388     if (ret != SENSOR_SUCCESS) {
389         WVLOG_E("SubscribeOhosSensor error, call ActivateSensor ret = %{public}d.", ret);
390         return ret;
391     }
392     ret = SetMode(ohosSensorTypeId, &mSensorUser, SENSOR_REALTIME_MODE);
393     if (ret != SENSOR_SUCCESS) {
394         WVLOG_E("SubscribeOhosSensor error, call SetMode ret = %{public}d.", ret);
395         return ret;
396     }
397     return SENSOR_SUCCESS;
398 }
399 
RegistOhosSensorCallback(int32_t sensorTypeId,std::shared_ptr<SensorCallbackAdapter> callbackAdapter)400 int32_t SensorAdapterImpl::RegistOhosSensorCallback(int32_t sensorTypeId,
401     std::shared_ptr<SensorCallbackAdapter> callbackAdapter)
402 {
403     int32_t ohosSensorTypeId = SensorTypeToOhosSensorType(sensorTypeId);
404     if (ohosSensorTypeId != SENSOR_TYPE_ID_NONE) {
405         auto callback = std::make_shared<SensorCallbackImpl>(callbackAdapter);
406         std::lock_guard<std::mutex> lock(sensorCallbackMapMutex_);
407         sensorCallbackMap[ohosSensorTypeId] = callback;
408         return SENSOR_SUCCESS;
409     }
410     WVLOG_E("RegistOhosSensorCallback error, sensorTypeId is invalid.");
411     return SENSOR_PARAMETER_ERROR;
412 }
413 
UnsubscribeOhosSensor(int32_t sensorTypeId)414 int32_t SensorAdapterImpl::UnsubscribeOhosSensor(int32_t sensorTypeId)
415 {
416     WVLOG_I("UnsubscribeOhosSensor sensorTypeId: %{public}d.", sensorTypeId);
417     int32_t ohosSensorTypeId = SensorTypeToOhosSensorType(sensorTypeId);
418     if (ohosSensorTypeId != SENSOR_TYPE_ID_NONE) {
419         int32_t ret = DeactivateSensor(ohosSensorTypeId, &mSensorUser);
420         if (ret != SENSOR_SUCCESS) {
421             WVLOG_E("UnsubscribeOhosSensor error, call DeactivateSensor ret = %{public}d.", ret);
422             return ret;
423         }
424         ret = UnsubscribeSensor(ohosSensorTypeId, &mSensorUser);
425         if (ret != SENSOR_SUCCESS) {
426             WVLOG_E("UnsubscribeOhosSensor error, call UnsubscribeSensor ret = %{public}d.", ret);
427             return ret;
428         }
429         std::lock_guard<std::mutex> lock(sensorCallbackMapMutex_);
430         sensorCallbackMap.erase(ohosSensorTypeId);
431         return SENSOR_SUCCESS;
432     }
433     WVLOG_E("UnsubscribeOhosSensor error, sensorTypeId is invalid.");
434     return SENSOR_PARAMETER_ERROR;
435 }
436 } // namespace OHOS::NWeb