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 "cj_sensor_impl.h"
17
18 #include "cj_lambda.h"
19 #include "geomagnetic_field.h"
20 #include "sensor_agent.h"
21 #include "sensor_algorithm.h"
22 #include "sensor_errors.h"
23
24 namespace OHOS {
25 namespace Sensors {
26 namespace {
27 constexpr int32_t ROTATION_VECTOR_LENGTH = 3;
28 constexpr int32_t QUATERNION_LENGTH = 4;
29 constexpr int32_t THREE_DIMENSIONAL_MATRIX_LENGTH = 9;
30 constexpr int32_t DATA_LENGTH = 16;
31 } // namespace
32
CJSensorImpl()33 CJSensorImpl::CJSensorImpl() {}
~CJSensorImpl()34 CJSensorImpl::~CJSensorImpl() {}
35
CJDataCallbackImpl(SensorEvent * event)36 void CJSensorImpl::CJDataCallbackImpl(SensorEvent *event)
37 {
38 CHKPV(event);
39 CJ_SENSOR_IMPL->EmitCallBack(event);
40 }
41
SubscribeSensorImpl(int32_t sensorId,int64_t interval)42 int32_t CJSensorImpl::SubscribeSensorImpl(int32_t sensorId, int64_t interval)
43 {
44 CALL_LOG_ENTER;
45 int32_t ret = SubscribeSensor(sensorId, &cjUser_);
46 if (ret != ERR_OK) {
47 SEN_HILOGE("SubscribeSensor failed");
48 return ret;
49 }
50 ret = SetBatch(sensorId, &cjUser_, interval, 0);
51 if (ret != ERR_OK) {
52 SEN_HILOGE("SetBatch failed");
53 return ret;
54 }
55
56 return ActivateSensor(sensorId, &cjUser_);
57 }
58
UnsubscribeSensorImpl(int32_t sensorTypeId)59 int32_t CJSensorImpl::UnsubscribeSensorImpl(int32_t sensorTypeId)
60 {
61 CALL_LOG_ENTER;
62 int32_t ret = DeactivateSensor(sensorTypeId, &cjUser_);
63 if (ret != ERR_OK) {
64 SEN_HILOGE("DeactivateSensor failed");
65 return ret;
66 }
67 return UnsubscribeSensor(sensorTypeId, &cjUser_);
68 }
69
MallocCString(const std::string origin)70 char *CJSensorImpl::MallocCString(const std::string origin)
71 {
72 if (origin.empty()) {
73 SEN_HILOGD("String is empty.");
74 return nullptr;
75 }
76 auto len = origin.length() + 1;
77 char *res = static_cast<char *>(malloc(sizeof(char) * len));
78 if (res == nullptr) {
79 SEN_HILOGE("Malloc failed.");
80 return nullptr;
81 }
82 return std::char_traits<char>::copy(res, origin.c_str(), len);
83 }
84
Transform2CSensor(const SensorInfo & in,CSensor & out)85 void CJSensorImpl::Transform2CSensor(const SensorInfo &in, CSensor &out)
86 {
87 out.sensorName = MallocCString(in.sensorName);
88 out.vendorName = MallocCString(in.vendorName);
89 out.firmwareVersion = MallocCString(in.firmwareVersion);
90 out.hardwareVersion = MallocCString(in.hardwareVersion);
91
92 out.sensorTypeId = in.sensorTypeId;
93 out.maxRange = in.maxRange;
94 out.minSamplePeriod = in.minSamplePeriod;
95 out.maxSamplePeriod = in.maxSamplePeriod;
96 out.precision = in.precision;
97 out.power = in.power;
98 }
99
ConvertCArr2Vector(const CArrFloat32 & in)100 std::vector<float> CJSensorImpl::ConvertCArr2Vector(const CArrFloat32 &in)
101 {
102 std::vector<float> res;
103 if (in.head == nullptr || in.size <= 0) {
104 SEN_HILOGD("head is nullptr or size is zero.");
105 return res;
106 }
107
108 for (int64_t i = 0; i < in.size; i++) {
109 res.push_back(in.head[i]);
110 }
111
112 return res;
113 }
114
ConvertVector2CArr(const std::vector<float> & in)115 CArrFloat32 CJSensorImpl::ConvertVector2CArr(const std::vector<float> &in)
116 {
117 CArrFloat32 res = {NULL, 0};
118 if (in.empty()) {
119 SEN_HILOGD("vector is empty.");
120 return res;
121 }
122
123 res.head = static_cast<float *>(malloc(sizeof(float) * in.size()));
124 if (res.head == nullptr) {
125 SEN_HILOGE("Malloc failed.");
126 return res;
127 }
128 size_t i = 0;
129 for (; i < in.size(); ++i) {
130 res.head[i] = in[i];
131 }
132 res.size = static_cast<int64_t>(i);
133 return res;
134 }
135
OnSensorChange(int32_t sensorId,int64_t interval,void (* callback)(SensorEvent * event))136 int32_t CJSensorImpl::OnSensorChange(int32_t sensorId, int64_t interval, void (*callback)(SensorEvent *event))
137 {
138 CALL_LOG_ENTER;
139 int32_t ret = SubscribeSensorImpl(sensorId, interval);
140 if (ret != ERR_OK) {
141 SEN_HILOGE("subscribe sensor failed, %{public}d.", sensorId);
142 return ret;
143 }
144
145 AddCallback2Map(sensorId, CJLambda::Create(callback));
146 return ERR_OK;
147 }
148
OffSensorChange(int32_t sensorId)149 int32_t CJSensorImpl::OffSensorChange(int32_t sensorId)
150 {
151 CALL_LOG_ENTER;
152 int32_t ret = UnsubscribeSensorImpl(sensorId);
153 if (ret != ERR_OK) {
154 SEN_HILOGE("unsubscribe sensor failed, %{public}d.", sensorId);
155 return ret;
156 }
157
158 DelCallback(sensorId);
159 return ERR_OK;
160 }
161
EmitCallBack(SensorEvent * event)162 void CJSensorImpl::EmitCallBack(SensorEvent *event)
163 {
164 auto callback = FindCallback(event->sensorTypeId);
165 if (callback == std::nullopt) {
166 SEN_HILOGE("EmitCallBack failed, %{public}d not find.", event->sensorTypeId);
167 return;
168 }
169
170 callback.value()(event);
171 }
172
AddCallback2Map(int32_t type,SensorCallbackType callback)173 void CJSensorImpl::AddCallback2Map(int32_t type, SensorCallbackType callback)
174 {
175 std::lock_guard<std::mutex> mutex(mutex_);
176 eventMap_[type] = callback;
177 }
178
DelCallback(int32_t type)179 void CJSensorImpl::DelCallback(int32_t type)
180 {
181 std::lock_guard<std::mutex> mutex(mutex_);
182 eventMap_.erase(type);
183 }
184
FindCallback(int32_t type)185 std::optional<SensorCallbackType> CJSensorImpl::FindCallback(int32_t type)
186 {
187 std::lock_guard<std::mutex> mutex(mutex_);
188 auto iter = eventMap_.find(type);
189 if (iter != eventMap_.end()) {
190 return iter->second;
191 }
192
193 return std::nullopt;
194 }
195
GetGeomagneticInfo(CLocationOptions location,int64_t timeMillis)196 CGeomagneticData CJSensorImpl::GetGeomagneticInfo(CLocationOptions location, int64_t timeMillis)
197 {
198 GeomagneticField geomagneticField(location.latitude, location.longitude, location.altitude, timeMillis);
199 CGeomagneticData res = {
200 .x = geomagneticField.ObtainX(),
201 .y = geomagneticField.ObtainY(),
202 .z = geomagneticField.ObtainZ(),
203 .geomagneticDip = geomagneticField.ObtainGeomagneticDip(),
204 .deflectionAngle = geomagneticField.ObtainDeflectionAngle(),
205 .levelIntensity = geomagneticField.ObtainLevelIntensity(),
206 .totalIntensity = geomagneticField.ObtainTotalIntensity(),
207 };
208 return res;
209 }
210
GetAltitude(float seaPressure,float currentPressure,float * altitude)211 int32_t CJSensorImpl::GetAltitude(float seaPressure, float currentPressure, float *altitude)
212 {
213 SensorAlgorithm sensorAlgorithm;
214 int32_t ret = sensorAlgorithm.GetAltitude(seaPressure, currentPressure, altitude);
215 if (ret != ERR_OK) {
216 SEN_HILOGE("Get altitude failed, ret:%{public}d", ret);
217 }
218 return ret;
219 }
220
GetGeomagneticDip(CArrFloat32 inclinationMatrix,float * geomagneticDip)221 int32_t CJSensorImpl::GetGeomagneticDip(CArrFloat32 inclinationMatrix, float *geomagneticDip)
222 {
223 SensorAlgorithm sensorAlgorithm;
224 int32_t ret = sensorAlgorithm.GetGeomagneticDip(ConvertCArr2Vector(inclinationMatrix), geomagneticDip);
225 if (ret != ERR_OK) {
226 SEN_HILOGE("Get geomagnetic dip failed, ret:%{public}d", ret);
227 }
228
229 return ret;
230 }
231
GetAngleModify(const CArrFloat32 & curRotationMatrix,const CArrFloat32 & preRotationMatrix,CArrFloat32 * angleChangeOut)232 int32_t CJSensorImpl::GetAngleModify(const CArrFloat32 &curRotationMatrix, const CArrFloat32 &preRotationMatrix,
233 CArrFloat32 *angleChangeOut)
234 {
235 if (angleChangeOut == nullptr) {
236 SEN_HILOGE("Invalid parameter, angleChangeOut is nullptr!");
237 return PARAMETER_ERROR;
238 }
239 std::vector<float> angleChange(ROTATION_VECTOR_LENGTH);
240 SensorAlgorithm sensorAlgorithm;
241 int32_t ret = sensorAlgorithm.GetAngleModify(ConvertCArr2Vector(curRotationMatrix),
242 ConvertCArr2Vector(preRotationMatrix), angleChange);
243 if (ret != ERR_OK) {
244 SEN_HILOGE("Get angle change failed, ret:%{public}d", ret);
245 return ret;
246 }
247
248 *angleChangeOut = ConvertVector2CArr(angleChange);
249 return ret;
250 }
251
GetRotationMatrix(const CArrFloat32 & rotationCArr,CArrFloat32 & rotation)252 int32_t CJSensorImpl::GetRotationMatrix(const CArrFloat32 &rotationCArr, CArrFloat32 &rotation)
253 {
254 std::vector<float> rotationMatrix(THREE_DIMENSIONAL_MATRIX_LENGTH);
255 SensorAlgorithm sensorAlgorithm;
256 int32_t ret = sensorAlgorithm.CreateRotationMatrix(ConvertCArr2Vector(rotationCArr), rotationMatrix);
257 if (ret != ERR_OK) {
258 SEN_HILOGE("Get rotation matrix failed, ret:%{public}d", ret);
259 return ret;
260 }
261
262 rotation = ConvertVector2CArr(rotationMatrix);
263 return ret;
264 }
265
TransformRotationMatrix(const CArrFloat32 & rotationCArr,int32_t axisX,int32_t axisY,CArrFloat32 & outRotationMatrix)266 int32_t CJSensorImpl::TransformRotationMatrix(const CArrFloat32 &rotationCArr, int32_t axisX, int32_t axisY,
267 CArrFloat32 &outRotationMatrix)
268 {
269 int64_t length = rotationCArr.size;
270 if ((length != DATA_LENGTH) && (length != THREE_DIMENSIONAL_MATRIX_LENGTH)) {
271 SEN_HILOGE("Transform rotation mastrix failed, invalid parameter.");
272 return PARAMETER_ERROR;
273 }
274 std::vector<float> outRotationVector(length);
275 SensorAlgorithm sensorAlgorithm;
276 int32_t ret =
277 sensorAlgorithm.TransformCoordinateSystem(ConvertCArr2Vector(rotationCArr), axisX, axisY, outRotationVector);
278 if (ret != ERR_OK) {
279 SEN_HILOGE("Transform coordinate system failed, ret:%{public}d", ret);
280 return ret;
281 }
282
283 outRotationMatrix = ConvertVector2CArr(outRotationVector);
284 return ret;
285 }
286
GetQuaternion(const CArrFloat32 & rotationVector,CArrFloat32 & quaternionOut)287 int32_t CJSensorImpl::GetQuaternion(const CArrFloat32 &rotationVector, CArrFloat32 &quaternionOut)
288 {
289 std::vector<float> quaternion(QUATERNION_LENGTH);
290 SensorAlgorithm sensorAlgorithm;
291 int32_t ret = sensorAlgorithm.CreateQuaternion(ConvertCArr2Vector(rotationVector), quaternion);
292 if (ret != ERR_OK) {
293 SEN_HILOGE("Get quaternion failed, ret:%{public}d", ret);
294 return ret;
295 }
296
297 quaternionOut = ConvertVector2CArr(quaternion);
298 return ret;
299 }
300
GetOrientation(const CArrFloat32 & rotationMatrix,CArrFloat32 & rotationAngleOut)301 int32_t CJSensorImpl::GetOrientation(const CArrFloat32 &rotationMatrix, CArrFloat32 &rotationAngleOut)
302 {
303 std::vector<float> rotationAngle(ROTATION_VECTOR_LENGTH);
304 SensorAlgorithm sensorAlgorithm;
305 int32_t ret = sensorAlgorithm.GetDirection(ConvertCArr2Vector(rotationMatrix), rotationAngle);
306 if (ret != OHOS::ERR_OK) {
307 SEN_HILOGE("Get direction failed, ret:%{public}d", ret);
308 return ret;
309 }
310
311 rotationAngleOut = ConvertVector2CArr(rotationAngle);
312 return ret;
313 }
314
GetRotationMatrixByGraityAndGeomagnetic(const CArrFloat32 gravity,const CArrFloat32 geomagnetic,CArrFloat32 & rotationMatrix,CArrFloat32 & inclinationMatrix)315 int32_t CJSensorImpl::GetRotationMatrixByGraityAndGeomagnetic(const CArrFloat32 gravity, const CArrFloat32 geomagnetic,
316 CArrFloat32 &rotationMatrix,
317 CArrFloat32 &inclinationMatrix)
318 {
319 std::vector<float> rotation(THREE_DIMENSIONAL_MATRIX_LENGTH);
320 std::vector<float> inclination(THREE_DIMENSIONAL_MATRIX_LENGTH);
321 SensorAlgorithm sensorAlgorithm;
322 int32_t ret = sensorAlgorithm.CreateRotationAndInclination(ConvertCArr2Vector(gravity),
323 ConvertCArr2Vector(geomagnetic), rotation, inclination);
324 if (ret != OHOS::ERR_OK) {
325 SEN_HILOGE("Create rotation and inclination failed, ret:%{public}d", ret);
326 return ret;
327 }
328
329 rotationMatrix = ConvertVector2CArr(rotation);
330 inclinationMatrix = ConvertVector2CArr(inclination);
331
332 return ret;
333 }
334
GetAllSensorList(CSensorArray & sensorList)335 int32_t CJSensorImpl::GetAllSensorList(CSensorArray &sensorList)
336 {
337 SensorInfo *sensorInfos = nullptr;
338 int32_t count = 0;
339 int32_t ret = GetAllSensors(&sensorInfos, &count);
340 if (ret != OHOS::ERR_OK) {
341 SEN_HILOGE("Get all sensors failed, ret:%{public}d", ret);
342 return ret;
343 }
344
345 if (count == 0) {
346 return ERR_OK;
347 }
348
349 sensorList.head = static_cast<CSensor *>(malloc(sizeof(CSensor) * count));
350 if (sensorList.head == nullptr) {
351 SEN_HILOGE("Malloc failed.");
352 return ERR_OK;
353 }
354
355 int32_t size = 0;
356 for (int32_t i = 0; i < count; ++i) {
357 if ((sensorInfos[i].sensorTypeId == SENSOR_TYPE_ID_AMBIENT_LIGHT1) ||
358 (sensorInfos[i].sensorTypeId == SENSOR_TYPE_ID_PROXIMITY1) ||
359 (sensorInfos[i].sensorTypeId > GL_SENSOR_TYPE_PRIVATE_MIN_VALUE)) {
360 SEN_HILOGD("This sensor is secondary ambient light");
361 continue;
362 }
363 Transform2CSensor(sensorInfos[i], sensorList.head[size]);
364 ++size;
365 }
366 sensorList.size = size;
367
368 return ERR_OK;
369 }
370 } // namespace Sensors
371 } // namespace OHOS