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
16 #include "sensor_agent_proxy.h"
17
18 #include <cstring>
19
20 #include "securec.h"
21 #include "sensor_catalog.h"
22 #include "sensor_service_client.h"
23 #include "sensors_errors.h"
24 #include "sensors_log_domain.h"
25
26 using namespace OHOS::HiviewDFX;
27 namespace OHOS {
28 namespace Sensors {
29 namespace {
30 constexpr HiLogLabel LABEL = { LOG_CORE, OHOS::SensorsLogDomain::SENSORS_IMPLEMENT, "SensorAgentProxy" };
31
32 using OHOS::ERR_OK;
33 using OHOS::Sensors::BODY;
34 using OHOS::Sensors::DEVICE_MOTION;
35 using OHOS::Sensors::ENVIRONMENT;
36 using OHOS::Sensors::INVALID_POINTER;
37 using OHOS::Sensors::LIGHT;
38 using OHOS::Sensors::ORIENTATION;
39 using OHOS::Sensors::OTHER;
40 using OHOS::Sensors::SENSOR_TYPE_6DOF_ATTITUDE;
41 using OHOS::Sensors::SENSOR_TYPE_ACCELEROMETER;
42 using OHOS::Sensors::SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED;
43 using OHOS::Sensors::SENSOR_TYPE_AMBIENT_LIGHT;
44 using OHOS::Sensors::SENSOR_TYPE_AMBIENT_TEMPERATURE;
45 using OHOS::Sensors::SENSOR_TYPE_BAROMETER;
46 using OHOS::Sensors::SENSOR_TYPE_DEVICE_ORIENTATION;
47 using OHOS::Sensors::SENSOR_TYPE_GAME_ROTATION_VECTOR;
48 using OHOS::Sensors::SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR;
49 using OHOS::Sensors::SENSOR_TYPE_GRAVITY;
50 using OHOS::Sensors::SENSOR_TYPE_GYROSCOPE;
51 using OHOS::Sensors::SENSOR_TYPE_GYROSCOPE_UNCALIBRATED;
52 using OHOS::Sensors::SENSOR_TYPE_HEART_RATE_DETECTOR;
53 using OHOS::Sensors::SENSOR_TYPE_HUMIDITY;
54 using OHOS::Sensors::SENSOR_TYPE_LINEAR_ACCELERATION;
55 using OHOS::Sensors::SENSOR_TYPE_MAGNETIC_FIELD;
56 using OHOS::Sensors::SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED;
57 using OHOS::Sensors::SENSOR_TYPE_ORIENTATION;
58 using OHOS::Sensors::SENSOR_TYPE_PRESSURE_DETECTOR;
59 using OHOS::Sensors::SENSOR_TYPE_PROXIMITY;
60 using OHOS::Sensors::SENSOR_TYPE_ROTATION_VECTOR;
61 using OHOS::Sensors::SENSOR_TYPE_SIGNIFICANT_MOTION;
62 using OHOS::Sensors::SENSOR_TYPE_STEP_COUNTER;
63 using OHOS::Sensors::SENSOR_TYPE_STEP_DETECTOR;
64 using OHOS::Sensors::SENSOR_TYPE_WEAR_DETECTOR;
65 using OHOS::Sensors::SensorDataChannel;
66 using OHOS::Sensors::SensorServiceClient;
67 } // namespace
68
69 OHOS::sptr<SensorAgentProxy> SensorAgentProxy::sensorObj_ = nullptr;
70 bool SensorAgentProxy::g_isChannelCreated;
71 int64_t SensorAgentProxy::g_samplingInterval;
72 int64_t SensorAgentProxy::g_reportInterval;
73 std::mutex SensorAgentProxy::subscribeMutex_;
74 std::mutex SensorAgentProxy::chanelMutex_;
75 std::map<int32_t, const SensorUser *> SensorAgentProxy::g_subscribeMap;
76 std::map<int32_t, const SensorUser *> SensorAgentProxy::g_unsubscribeMap;
77
SensorAgentProxy()78 SensorAgentProxy::SensorAgentProxy()
79 : dataChannel_(new (std::nothrow) SensorDataChannel())
80 {}
81
GetSensorsObj()82 const SensorAgentProxy *SensorAgentProxy::GetSensorsObj()
83 {
84 HiLog::Debug(LABEL, "%{public}s", __func__);
85
86 if (sensorObj_ == nullptr) {
87 HiLog::Debug(LABEL, "%{public}s sensorObj_ new object", __func__);
88 sensorObj_ = new (std::nothrow) SensorAgentProxy();
89 }
90 return sensorObj_;
91 }
92
HandleSensorData(struct SensorEvent * events,int32_t num,void * data)93 void SensorAgentProxy::HandleSensorData(struct SensorEvent *events, int32_t num, void *data)
94 {
95 if (events == nullptr || num <= 0) {
96 HiLog::Error(LABEL, "%{public}s events is null or num is invalid", __func__);
97 return;
98 }
99 struct SensorEvent eventStream;
100 for (int32_t i = 0; i < num; ++i) {
101 eventStream = events[i];
102 if (eventStream.data == nullptr || g_subscribeMap[eventStream.sensorTypeId] == nullptr) {
103 HiLog::Error(LABEL, "%{public}s data or sensorUser is nullptr", __func__);
104 return;
105 }
106 if (g_subscribeMap.find(eventStream.sensorTypeId) == g_subscribeMap.end()) {
107 HiLog::Error(LABEL, "%{public}s sensorTypeId not in g_subscribeMap", __func__);
108 return;
109 }
110 g_subscribeMap[eventStream.sensorTypeId]->callback(&eventStream);
111 }
112 }
113
CreateSensorDataChannel() const114 int32_t SensorAgentProxy::CreateSensorDataChannel() const
115 {
116 HiLog::Debug(LABEL, "%{public}s", __func__);
117 std::lock_guard<std::mutex> chanelLock(chanelMutex_);
118 if (g_isChannelCreated) {
119 HiLog::Info(LABEL, "%{public}s the channel has already been created", __func__);
120 return ERR_OK;
121 }
122 if (dataChannel_ == nullptr) {
123 HiLog::Error(LABEL, "%{public}s data channel cannot be null", __func__);
124 return INVALID_POINTER;
125 }
126 auto ret = dataChannel_->CreateSensorDataChannel(HandleSensorData, nullptr);
127 if (ret != ERR_OK) {
128 HiLog::Error(LABEL, "%{public}s create data channel failed, ret : %{public}d", __func__, ret);
129 return ret;
130 }
131 auto &client = SensorServiceClient::GetInstance();
132 ret = client.TransferDataChannel(dataChannel_);
133 if (ret != ERR_OK) {
134 auto destoryRet = dataChannel_->DestroySensorDataChannel();
135 HiLog::Error(LABEL, "%{public}s transfer data channel failed, ret : %{public}d, destoryRet : %{public}d",
136 __func__, ret, destoryRet);
137 return ret;
138 }
139 g_isChannelCreated = true;
140 return ERR_OK;
141 }
142
DestroySensorDataChannel() const143 int32_t SensorAgentProxy::DestroySensorDataChannel() const
144 {
145 HiLog::Debug(LABEL, "%{public}s", __func__);
146 std::lock_guard<std::mutex> chanelLock(chanelMutex_);
147 if (!g_isChannelCreated) {
148 HiLog::Info(LABEL, "%{public}s channel has been destroyed", __func__);
149 return ERR_OK;
150 }
151 if (dataChannel_ == nullptr) {
152 HiLog::Error(LABEL, "%{public}s data channel cannot be null", __func__);
153 return INVALID_POINTER;
154 }
155 int32_t ret = dataChannel_->DestroySensorDataChannel();
156 if (ret != ERR_OK) {
157 HiLog::Error(LABEL, "%{public}s destory data channel failed, ret : %{public}d", __func__, ret);
158 return ret;
159 }
160 SensorServiceClient &client = SensorServiceClient::GetInstance();
161 ret = client.DestroyDataChannel();
162 if (ret != ERR_OK) {
163 HiLog::Error(LABEL, "%{public}s destory service data channel fail, ret : %{public}d", __func__, ret);
164 return ret;
165 }
166 g_isChannelCreated = false;
167 return ERR_OK;
168 }
169
ActivateSensor(int32_t sensorId,const SensorUser * user) const170 int32_t SensorAgentProxy::ActivateSensor(int32_t sensorId, const SensorUser *user) const
171 {
172 if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
173 HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
174 return OHOS::Sensors::ERROR;
175 }
176 if (g_samplingInterval < 0 || g_reportInterval < 0) {
177 HiLog::Error(LABEL, "%{public}s samplingPeroid or g_reportInterval is invalid", __func__);
178 return OHOS::Sensors::ERROR;
179 }
180 std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
181 if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) {
182 HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__);
183 return OHOS::Sensors::ERROR;
184 }
185 SensorServiceClient &client = SensorServiceClient::GetInstance();
186 int32_t ret = client.EnableSensor(sensorId, g_samplingInterval, g_reportInterval);
187 g_samplingInterval = -1;
188 g_reportInterval = -1;
189 if (ret != 0) {
190 HiLog::Error(LABEL, "%{public}s enable sensor failed, ret: %{public}d", __func__, ret);
191 g_subscribeMap.erase(sensorId);
192 return OHOS::Sensors::ERROR;
193 }
194 return OHOS::Sensors::SUCCESS;
195 }
196
DeactivateSensor(int32_t sensorId,const SensorUser * user) const197 int32_t SensorAgentProxy::DeactivateSensor(int32_t sensorId, const SensorUser *user) const
198 {
199 if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
200 HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
201 return OHOS::Sensors::ERROR;
202 }
203 std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
204 if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap[sensorId] != user)) {
205 HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__);
206 return OHOS::Sensors::ERROR;
207 }
208 g_subscribeMap.erase(sensorId);
209 g_unsubscribeMap[sensorId] = user;
210 SensorServiceClient &client = SensorServiceClient::GetInstance();
211 int32_t ret = client.DisableSensor(sensorId);
212 if (ret != 0) {
213 HiLog::Error(LABEL, "%{public}s disable sensor failed, ret: %{public}d", __func__, ret);
214 return OHOS::Sensors::ERROR;
215 }
216 return OHOS::Sensors::SUCCESS;
217 }
218
SetBatch(int32_t sensorId,const SensorUser * user,int64_t samplingInterval,int64_t reportInterval) const219 int32_t SensorAgentProxy::SetBatch(int32_t sensorId, const SensorUser *user, int64_t samplingInterval,
220 int64_t reportInterval) const
221 {
222 if (user == nullptr || sensorId < 0) {
223 HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
224 return OHOS::Sensors::ERROR;
225 }
226 if (samplingInterval < 0 || reportInterval < 0) {
227 HiLog::Error(LABEL, "%{public}s samplingInterval or reportInterval is invalid", __func__);
228 return OHOS::Sensors::ERROR;
229 }
230 std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
231 if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) {
232 HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__);
233 return OHOS::Sensors::ERROR;
234 }
235 g_samplingInterval = samplingInterval;
236 g_reportInterval = reportInterval;
237 return OHOS::Sensors::SUCCESS;
238 }
239
SubscribeSensor(int32_t sensorId,const SensorUser * user) const240 int32_t SensorAgentProxy::SubscribeSensor(int32_t sensorId, const SensorUser *user) const
241 {
242 HiLog::Info(LABEL, "%{public}s in, sensorId: %{public}d", __func__, sensorId);
243 if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
244 HiLog::Error(LABEL, "%{public}s user or sensorId is invalid", __func__);
245 return OHOS::Sensors::ERROR;
246 }
247 int32_t ret = CreateSensorDataChannel();
248 if (ret != ERR_OK) {
249 HiLog::Error(LABEL, "%{public}s create sensor data chanel failed", __func__);
250 return OHOS::Sensors::ERROR;
251 }
252 std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
253 g_subscribeMap[sensorId] = user;
254 return OHOS::Sensors::SUCCESS;
255 }
256
UnsubscribeSensor(int32_t sensorId,const SensorUser * user) const257 int32_t SensorAgentProxy::UnsubscribeSensor(int32_t sensorId, const SensorUser *user) const
258 {
259 HiLog::Info(LABEL, "%{public}s in, sensorId: %{public}d", __func__, sensorId);
260 if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
261 HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
262 return OHOS::Sensors::ERROR;
263 }
264 std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
265 if (g_unsubscribeMap.find(sensorId) == g_unsubscribeMap.end() || g_unsubscribeMap[sensorId] != user) {
266 HiLog::Error(LABEL, "%{public}s deactivate sensorId first", __func__);
267 return OHOS::Sensors::ERROR;
268 }
269 if (g_subscribeMap.empty()) {
270 int32_t ret = DestroySensorDataChannel();
271 if (ret != ERR_OK) {
272 HiLog::Error(LABEL, "%{public}s destory data channel fail, ret : %{public}d", __func__, ret);
273 return ret;
274 }
275 }
276 g_unsubscribeMap.erase(sensorId);
277 return OHOS::Sensors::SUCCESS;
278 }
279
SetMode(int32_t sensorId,const SensorUser * user,int32_t mode) const280 int32_t SensorAgentProxy::SetMode(int32_t sensorId, const SensorUser *user, int32_t mode) const
281 {
282 if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
283 HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
284 return OHOS::Sensors::ERROR;
285 }
286 std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
287 if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) {
288 HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__);
289 return OHOS::Sensors::ERROR;
290 }
291 return OHOS::Sensors::SUCCESS;
292 }
293
SetOption(int32_t sensorId,const SensorUser * user,int32_t option) const294 int32_t SensorAgentProxy::SetOption(int32_t sensorId, const SensorUser *user, int32_t option) const
295 {
296 if (user == nullptr || sensorId < 0 || user->callback == nullptr) {
297 HiLog::Error(LABEL, "%{public}s user is null or sensorId is invalid", __func__);
298 return OHOS::Sensors::ERROR;
299 }
300 std::lock_guard<std::mutex> subscribeLock(subscribeMutex_);
301 if ((g_subscribeMap.find(sensorId) == g_subscribeMap.end()) || (g_subscribeMap.at(sensorId) != user)) {
302 HiLog::Error(LABEL, "%{public}s subscribe sensorId first", __func__);
303 return OHOS::Sensors::ERROR;
304 }
305 return OHOS::Sensors::SUCCESS;
306 }
307
GetAllSensors(SensorInfo ** sensorInfo,int32_t * count) const308 int32_t SensorAgentProxy::GetAllSensors(SensorInfo **sensorInfo, int32_t *count) const
309 {
310 if (sensorInfo == nullptr || count == nullptr) {
311 HiLog::Error(LABEL, "%{public}s sensorInfo or count is null", __func__);
312 return OHOS::Sensors::ERROR;
313 }
314 SensorServiceClient &client = SensorServiceClient::GetInstance();
315 std::vector<OHOS::Sensors::Sensor> sensorList_ = client.GetSensorList();
316 if (sensorList_.empty()) {
317 HiLog::Error(LABEL, "%{public}s get sensor lists failed", __func__);
318 return OHOS::Sensors::ERROR;
319 }
320 *count = sensorList_.size();
321 *sensorInfo = (SensorInfo *)malloc(sizeof(SensorInfo) * (*count));
322 if (*sensorInfo == nullptr) {
323 HiLog::Error(LABEL, "%{public}s malloc sensorInfo failed", __func__);
324 return OHOS::Sensors::ERROR;
325 }
326 for (int32_t index = 0; index < *count; ++index) {
327 errno_t ret = strcpy_s((*sensorInfo + index)->sensorName, NAME_MAX_LEN,
328 sensorList_[index].GetSensorName().c_str());
329 if (ret != EOK) {
330 HiLog::Error(LABEL, "%{public}s strcpy sensorName failed", __func__);
331 return OHOS::Sensors::ERROR;
332 }
333 ret = strcpy_s((*sensorInfo + index)->vendorName, NAME_MAX_LEN,
334 sensorList_[index].GetVendorName().c_str());
335 if (ret != EOK) {
336 HiLog::Error(LABEL, "%{public}s strcpy vendorName failed", __func__);
337 return OHOS::Sensors::ERROR;
338 }
339 ret = strcpy_s((*sensorInfo + index)->hardwareVersion, VERSION_MAX_LEN,
340 sensorList_[index].GetHardwareVersion().c_str());
341 if (ret != EOK) {
342 HiLog::Error(LABEL, "%{public}s strcpy hardwareVersion failed", __func__);
343 return OHOS::Sensors::ERROR;
344 }
345 ret = strcpy_s((*sensorInfo + index)->firmwareVersion, VERSION_MAX_LEN,
346 sensorList_[index].GetFirmwareVersion().c_str());
347 if (ret != EOK) {
348 HiLog::Error(LABEL, "%{public}s strcpy hardwareVersion failed", __func__);
349 return OHOS::Sensors::ERROR;
350 }
351 (*sensorInfo + index)->sensorId = static_cast<int32_t>(sensorList_[index].GetSensorId());
352 (*sensorInfo + index)->sensorTypeId = static_cast<int32_t>(sensorList_[index].GetSensorTypeId());
353 (*sensorInfo + index)->maxRange = sensorList_[index].GetMaxRange();
354 (*sensorInfo + index)->precision = sensorList_[index].GetResolution();
355 (*sensorInfo + index)->power = sensorList_[index].GetPower();
356 }
357 return OHOS::Sensors::SUCCESS;
358 }
359 } // namespace Sensors
360 } // namespace OHOS