• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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