1/*
2 * Copyright (c) 2023 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_uhdf_log.h"
17#include "sensor_clients_manager.h"
18#include <cinttypes>
19
20#define HDF_LOG_TAG uhdf_sensor_clients_manager
21
22namespace OHOS {
23namespace HDI {
24namespace Sensor {
25namespace V2_0 {
26
27namespace {
28    const std::vector<int32_t> continuesSensor = {HDF_SENSOR_TYPE_ACCELEROMETER, HDF_SENSOR_TYPE_GYROSCOPE,
29                                                  HDF_SENSOR_TYPE_MAGNETIC_FIELD, HDF_SENSOR_TYPE_SAR,
30                                                  HDF_SENSOR_TYPE_ORIENTATION, HDF_SENSOR_TYPE_GRAVITY,
31                                                  HDF_SENSOR_TYPE_LINEAR_ACCELERATION, HDF_SENSOR_TYPE_ROTATION_VECTOR,
32                                                  HDF_SENSOR_TYPE_MAGNETIC_FIELD_UNCALIBRATED,
33                                                  HDF_SENSOR_TYPE_GAME_ROTATION_VECTOR,
34                                                  HDF_SENSOR_TYPE_GYROSCOPE_UNCALIBRATED, HDF_SENSOR_TYPE_DROP_DETECT,
35                                                  HDF_SENSOR_TYPE_GEOMAGNETIC_ROTATION_VECTOR,
36                                                  HDF_SENSOR_TYPE_ACCELEROMETER_UNCALIBRATED,
37                                                  HDF_SENSOR_TYPE_BAROMETER};
38    constexpr int64_t ERROR_INTERVAL = 0;
39    constexpr int64_t STOP_INTERVAL = 0;
40    constexpr int32_t INIT_CUR_COUNT = 0;
41    constexpr int64_t INIT_REPORT_COUNT = 1;
42}
43
44std::mutex SensorClientsManager::instanceMutex_;
45
46SensorClientsManager::SensorClientsManager()
47{
48}
49
50SensorClientsManager::~SensorClientsManager()
51{
52    clients_.clear();
53    sensorUsed_.clear();
54    sensorConfig_.clear();
55    sdcSensorConfig_.clear();
56}
57
58void SensorClientsManager::CopySensorInfo(std::vector<HdfSensorInformation> &info, bool cFlag)
59{
60    std::unique_lock<std::mutex> lock(sensorInfoMutex_);
61    if (!cFlag) {
62        info = sensorInfo_;
63        return;
64    }
65    sensorInfo_ = info;
66    return;
67}
68
69void SensorClientsManager::GetEventData(struct SensorsDataPack &dataPack)
70{
71    std::unique_lock<std::mutex> lock(sensorsDataPackMutex_);
72    dataPack = listDump_;
73    return;
74}
75
76void SensorClientsManager::CopyEventData(const struct HdfSensorEvents event)
77{
78    std::unique_lock<std::mutex> lock(sensorsDataPackMutex_);
79    if (event.data.empty()) {
80        HDF_LOGE("%{public}s: event data is empty!", __func__);
81        return;
82    }
83
84    if (listDump_.count == MAX_DUMP_DATA_SIZE) {
85        listDump_.listDumpArray[listDump_.pos++] = event;
86        if (listDump_.pos == MAX_DUMP_DATA_SIZE) {
87            listDump_.pos = 0;
88        }
89    } else {
90        listDump_.listDumpArray[listDump_.count] = event;
91        listDump_.count++;
92    }
93    return;
94}
95
96int SensorClientsManager::GetServiceId(int groupId, const sptr<ISensorCallback> &callbackObj)
97{
98    SENSOR_TRACE_PID;
99    std::unique_lock<std::mutex> lock(clientsMutex_);
100    for (auto &iter : clients_[groupId]) {
101        if (iter.second.GetReportDataCb() == callbackObj) {
102            return iter.first;
103        }
104    }
105    return HDF_FAILURE;
106}
107
108void SensorClientsManager::ReportDataCbRegister(int groupId, int serviceId, const sptr<ISensorCallback> &callbackObj)
109{
110    SENSOR_TRACE_PID;
111    std::unique_lock<std::mutex> lock(clientsMutex_);
112    if (clients_.find(groupId) == clients_.end() || clients_[groupId].find(serviceId) == clients_[groupId].end()) {
113        if (callbackObj == nullptr) {
114            HDF_LOGE("%{public}s: the callback of service %{public}d is null", __func__, serviceId);
115            return;
116        }
117        clients_[groupId].emplace(serviceId, callbackObj);
118        HDF_LOGD("%{public}s: service %{public}d insert the callback", __func__, serviceId);
119        return;
120    }
121
122    auto it = clients_[groupId].find(serviceId);
123    it -> second.SetReportDataCb(callbackObj);
124    HDF_LOGD("%{public}s: service %{public}d update the callback", __func__, serviceId);
125
126    return;
127}
128
129void SensorClientsManager::ReportDataCbUnRegister(int groupId, int serviceId, const sptr<ISensorCallback> &callbackObj)
130{
131    SENSOR_TRACE_PID;
132    std::unique_lock<std::mutex> lock(clientsMutex_);
133    if (clients_.find(groupId) == clients_.end() || clients_[groupId].find(serviceId) == clients_[groupId].end()) {
134        HDF_LOGD("%{public}s: service %{public}d already UnRegister", __func__, serviceId);
135        return;
136    }
137
138    auto it = clients_[groupId].find(serviceId);
139    clients_[groupId].erase(it);
140    HDF_LOGD("%{public}s: service: %{public}d, UnRegisterCB Success", __func__, serviceId);
141    return;
142}
143
144void SensorClientsManager::UpdateSensorConfig(int sensorId, int64_t samplingInterval, int64_t reportInterval)
145{
146    SENSOR_TRACE_PID;
147    std::unique_lock<std::mutex> lock(sensorConfigMutex_);
148    auto it = sensorConfig_.find(sensorId);
149    if (it != sensorConfig_.end()) {
150        it->second.samplingInterval = samplingInterval <= it->second.samplingInterval ? samplingInterval
151         : it->second.samplingInterval;
152        it->second.reportInterval = reportInterval <= it->second.reportInterval ? reportInterval
153         : it->second.reportInterval;
154    } else {
155        BestSensorConfig config = {samplingInterval, reportInterval};
156        sensorConfig_.emplace(sensorId, config);
157    }
158}
159
160void SensorClientsManager::UpdateSdcSensorConfig(int sensorId, int64_t samplingInterval, int64_t reportInterval)
161{
162    SENSOR_TRACE_PID;
163    std::unique_lock<std::mutex> lock(sdcSensorConfigMutex_);
164    auto it = sdcSensorConfig_.find(sensorId);
165    if (it != sdcSensorConfig_.end()) {
166        it->second.samplingInterval = samplingInterval <= it->second.samplingInterval ? samplingInterval
167         : it->second.samplingInterval;
168        it->second.reportInterval = reportInterval <= it->second.reportInterval ? reportInterval
169         : it->second.reportInterval;
170    } else {
171        BestSensorConfig config = {samplingInterval, reportInterval};
172        sdcSensorConfig_.emplace(sensorId, config);
173    }
174}
175
176void SensorClientsManager::UpdateClientPeriodCount(int sensorId, int64_t samplingInterval, int64_t reportInterval)
177{
178    SENSOR_TRACE_PID;
179    HDF_LOGD("%{public}s: sensorId is %{public}d, samplingInterval is [%{public}" PRId64 "],"
180        "reportInterval is [%{public}" PRId64 "]", __func__, sensorId,
181        samplingInterval, reportInterval);
182    std::unique_lock<std::mutex> lock(clientsMutex_);
183    if (samplingInterval <= ERROR_INTERVAL || reportInterval < ERROR_INTERVAL) {
184        HDF_LOGE("%{public}s: samplingInterval or reportInterval error", __func__);
185        return;
186    }
187    int32_t groupId = HDF_TRADITIONAL_SENSOR_TYPE;
188    if (clients_.find(groupId) == clients_.end() || clients_[groupId].empty()) {
189        return;
190    }
191    std::string result = "";
192    for (auto &entry : clients_[groupId]) {
193        auto &client = entry.second;
194        if (client.curCountMap_.find(sensorId) == client.curCountMap_.end()) {
195            client.curCountMap_[sensorId] = INIT_CUR_COUNT;
196        }
197        if (client.sensorConfigMap_.find(sensorId) != client.sensorConfigMap_.end()) {
198            int32_t periodCount = client.sensorConfigMap_.find(sensorId)->second.samplingInterval / samplingInterval;
199            result += " serviceId=" + std::to_string(entry.first) + ", sensorId=" + std::to_string(sensorId) +
200                      ", periodCount=" + std::to_string(client.sensorConfigMap_.find(sensorId)->second.samplingInterval)
201                      + "/" + std::to_string(samplingInterval) + "=" + std::to_string(periodCount);
202            client.periodCountMap_[sensorId] = periodCount;
203        }
204    }
205    HDF_LOGI("%{public}s: %{public}s", __func__, result.c_str());
206}
207
208void SensorClientsManager::SetSensorBestConfig(int sensorId, int64_t &samplingInterval, int64_t &reportInterval)
209{
210    SENSOR_TRACE_PID;
211    std::unique_lock<std::mutex> lock(sensorConfigMutex_);
212    auto it = sensorConfig_.find(sensorId);
213    if (it == sensorConfig_.end()) {
214        HDF_LOGD("%{public}s: sensor: %{public}d is enabled first time", __func__, sensorId);
215        return;
216    }
217
218    samplingInterval = samplingInterval < it->second.samplingInterval ? samplingInterval : it->second.samplingInterval;
219    reportInterval = reportInterval < it->second.reportInterval ? reportInterval : it->second.reportInterval;
220    HDF_LOGD("%{public}s: sensorId is %{public}d, after SetSensorBestConfig, samplingInterval is %{public}s, "
221             "reportInterval is %{public}s", __func__, sensorId, std::to_string(samplingInterval).c_str(),
222             std::to_string(reportInterval).c_str());
223    return;
224}
225
226void SensorClientsManager::SetSdcSensorBestConfig(int sensorId, int64_t &samplingInterval, int64_t &reportInterval)
227{
228    SENSOR_TRACE_PID;
229    std::unique_lock<std::mutex> lock(sdcSensorConfigMutex_);
230    auto it = sdcSensorConfig_.find(sensorId);
231    if (it == sdcSensorConfig_.end()) {
232        HDF_LOGD("%{public}s: sensor: %{public}d is enabled by sdc first time", __func__, sensorId);
233        return;
234    }
235
236    samplingInterval = samplingInterval < it->second.samplingInterval ? samplingInterval : it->second.samplingInterval;
237    reportInterval = reportInterval < it->second.reportInterval ? reportInterval : it->second.reportInterval;
238    HDF_LOGD("%{public}s: sensorId is %{public}d, after SetSdcSensorBestConfig, samplingInterval is %{public}s, "
239             "reportInterval is %{public}s", __func__, sensorId, std::to_string(samplingInterval).c_str(),
240             std::to_string(reportInterval).c_str());
241    return;
242}
243
244
245void SensorClientsManager::GetSensorBestConfig(int sensorId, int64_t &samplingInterval, int64_t &reportInterval)
246{
247    SENSOR_TRACE_PID;
248    std::unique_lock<std::mutex> lock(sensorConfigMutex_);
249    auto it = sensorConfig_.find(sensorId);
250    if (it == sensorConfig_.end()) {
251        samplingInterval = STOP_INTERVAL;
252        reportInterval = STOP_INTERVAL;
253        HDF_LOGD("%{public}s: sensor: %{public}d has no best config", __func__, sensorId);
254        return;
255    }
256
257    samplingInterval = it->second.samplingInterval;
258    reportInterval = it->second.reportInterval;
259    HDF_LOGD("%{public}s: sensorId is %{public}d, after GetSensorBestConfig, samplingInterval is %{public}s, "
260             "reportInterval is %{public}s", __func__, sensorId, std::to_string(samplingInterval).c_str(),
261             std::to_string(reportInterval).c_str());
262    return;
263}
264
265void SensorClientsManager::EraseSdcSensorBestConfig(int sensorId)
266{
267    SENSOR_TRACE_PID;
268    std::unique_lock<std::mutex> lock(sdcSensorConfigMutex_);
269    auto it = sdcSensorConfig_.find(sensorId);
270    if (it == sdcSensorConfig_.end()) {
271        HDF_LOGD("%{public}s: sensor: %{public}d sdcSensorBestConfig not exist, not need erase", __func__, sensorId);
272        return;
273    }
274    sdcSensorConfig_.erase(it);
275    HDF_LOGD("%{public}s: sensor: %{public}d config has been erase from sdcSensorConfig_", __func__, sensorId);
276    return;
277}
278
279void SensorClientsManager::OpenSensor(int sensorId, int serviceId)
280{
281    SENSOR_TRACE_PID;
282    std::unique_lock<std::mutex> lock(sensorUsedMutex_);
283    std::set<int> service = {serviceId};
284    sensorUsed_.emplace(sensorId, service);
285    HDF_LOGD("%{public}s: service: %{public}d enabled sensor %{public}d", __func__,  serviceId, sensorId);
286}
287
288bool SensorClientsManager::IsNeedOpenSensor(int sensorId, int serviceId)
289{
290    SENSOR_TRACE_PID;
291    auto it = sensorUsed_.find(sensorId);
292    if (it == sensorUsed_.end()) {
293        HDF_LOGD("%{public}s: sensor %{public}d is enabled by service: %{public}d", __func__,  sensorId, serviceId);
294        return true;
295    }
296    auto service = sensorUsed_[sensorId].find(serviceId);
297    if (service == sensorUsed_[sensorId].end()) {
298        sensorUsed_[sensorId].insert(serviceId);
299        HDF_LOGD("%{public}s: service: %{public}d enabled sensor %{public}d", __func__,  serviceId, sensorId);
300    }
301    return false;
302}
303
304bool SensorClientsManager::IsNeedCloseSensor(int sensorId, int serviceId)
305{
306    SENSOR_TRACE_PID;
307    auto it = sensorUsed_.find(sensorId);
308    if (it == sensorUsed_.end()) {
309        HDF_LOGE("%{public}s: sensor %{public}d has been disabled  or not support", __func__, sensorId);
310        return true;
311    }
312    sensorUsed_[sensorId].erase(serviceId);
313    if (sensorUsed_[sensorId].empty()) {
314        sensorUsed_.erase(sensorId);
315        sensorConfig_.erase(sensorId);
316        HDF_LOGD("%{public}s: disabled sensor %{public}d", __func__, sensorId);
317        return true;
318    }
319    for (auto sid : sensorUsed_[sensorId]) {
320        HDF_LOGD("%{public}s: sensor %{public}d also is enable by service %{public}d", __func__, sensorId, sid);
321    }
322    return false;
323}
324
325bool SensorClientsManager::IsExistSdcSensorEnable(int sensorId)
326{
327    SENSOR_TRACE_PID;
328    std::unique_lock<std::mutex> lock(sdcSensorConfigMutex_);
329    auto it = sdcSensorConfig_.find(sensorId);
330    if (it == sdcSensorConfig_.end()) {
331        return false;
332    }
333    HDF_LOGE("%{public}s: sensor %{public}d has been enabled by sdc service %{public}d", __func__, sensorId, it->first);
334    return true;
335}
336
337bool SensorClientsManager::IsUpadateSensorState(int sensorId, int serviceId, bool isOpen)
338{
339    SENSOR_TRACE_PID;
340    std::unique_lock<std::mutex> lock(sensorUsedMutex_);
341    if (isOpen && IsNeedOpenSensor(sensorId, serviceId)) {
342        return true;
343    }
344    if (!isOpen && IsNeedCloseSensor(sensorId, serviceId)) {
345        return true;
346    }
347    return false;
348}
349
350bool SensorClientsManager::IsClientsEmpty(int groupId)
351{
352    SENSOR_TRACE_PID;
353    std::unique_lock<std::mutex> lock(clientsMutex_);
354    if (clients_.find(groupId) == clients_.end() || clients_[groupId].empty()) {
355        return true;
356    }
357    return false;
358}
359
360bool SensorClientsManager::IsNoSensorUsed()
361{
362    SENSOR_TRACE_PID;
363    std::unique_lock<std::mutex> lock(sensorUsedMutex_);
364    for (auto it = sensorUsed_.begin(); it != sensorUsed_.end(); ++it) {
365        if (!it->second.empty()) {
366            return false;
367        }
368    }
369    return true;
370}
371
372bool SensorClientsManager::GetClients(int groupId, std::unordered_map<int32_t, SensorClientInfo> &client)
373{
374    SENSOR_TRACE_PID;
375    std::unique_lock<std::mutex> lock(clientsMutex_);
376    auto it = clients_.find(groupId);
377    if (it == clients_.end() || it->second.empty()) {
378        return false;
379    }
380    client = it->second;
381    return true;
382}
383
384bool SensorClientsManager::GetBestSensorConfigMap(std::unordered_map<int32_t, struct BestSensorConfig> &map)
385{
386    SENSOR_TRACE_PID;
387    std::unique_lock<std::mutex> lock(sensorConfigMutex_);
388    map = sensorConfig_;
389    return true;
390}
391
392void SensorClientsManager::SetClientSenSorConfig(int32_t sensorId, int32_t serviceId, int64_t samplingInterval,
393                                                 int64_t &reportInterval)
394{
395    SENSOR_TRACE_PID;
396    std::unique_lock<std::mutex> lock(clientsMutex_);
397    HDF_LOGD("%{public}s: service %{public}d enter the SetClientSenSorConfig function, sensorId is %{public}d, "
398             "samplingInterval is %{public}s, reportInterval is %{public}s", __func__, serviceId, sensorId,
399             std::to_string(samplingInterval).c_str(), std::to_string(reportInterval).c_str());
400
401    int32_t groupId = HDF_TRADITIONAL_SENSOR_TYPE;
402    if (clients_.find(groupId) == clients_.end() || clients_[groupId].find(serviceId) == clients_[groupId].end()) {
403        HDF_LOGE("%{public}s: service %{public}d already UnRegister", __func__, serviceId);
404        return;
405    }
406
407    auto &client = clients_[groupId].find(serviceId)->second;
408    SensorConfig sensorConfig = {samplingInterval, reportInterval};
409    client.sensorConfigMap_[sensorId] = sensorConfig;
410}
411
412bool SensorClientsManager::IsSensorContinues(int32_t sensorId)
413{
414    return std::find(continuesSensor.begin(), continuesSensor.end(), sensorId) != continuesSensor.end();
415}
416
417bool SensorClientsManager::IsNotNeedReportData(SensorClientInfo &sensorClientInfo, const int32_t &sensorId,
418                                               const int32_t &serviceId)
419{
420    SENSOR_TRACE;
421    if (!SensorClientsManager::IsSensorContinues(sensorId)) {
422        return false;
423    }
424    if (sensorClientInfo.periodCountMap_.find(sensorId) == sensorClientInfo.periodCountMap_.end()) {
425        return false;
426    }
427    bool result = true;
428    sensorClientInfo.PrintClientMapInfo(serviceId, sensorId);
429    if (sensorClientInfo.curCountMap_[sensorId] == 0) {
430        result = false;
431    }
432    sensorClientInfo.curCountMap_[sensorId]++;
433    if (sensorClientInfo.curCountMap_[sensorId] >= sensorClientInfo.periodCountMap_[sensorId]) {
434        sensorClientInfo.curCountMap_[sensorId] = 0;
435    }
436    return result;
437}
438
439std::set<int32_t> SensorClientsManager::GetServiceIds(int32_t &sensorId)
440{
441    SENSOR_TRACE;
442    std::unique_lock<std::mutex> lock(sensorUsedMutex_);
443    if (sensorUsed_.find(sensorId) == sensorUsed_.end()) {
444        HDF_LOGD("%{public}s sensor %{public}d is not enabled by anyone", __func__, sensorId);
445        return std::set<int32_t>();
446    }
447    return sensorUsed_.find(sensorId)->second;
448}
449
450std::string SensorClientsManager::ReportEachClient(const V2_0::HdfSensorEvents& event)
451{
452    SENSOR_TRACE;
453    std::string result = "services=";
454    int32_t sensorId = event.sensorId;
455    const std::set<int32_t> services = GetServiceIds(sensorId);
456    int32_t groupId = HDF_TRADITIONAL_SENSOR_TYPE;
457    {
458        std::unique_lock<std::mutex> lock(clientsMutex_);
459        if (clients_.find(groupId) == clients_.end() || clients_.find(groupId)->second.empty()) {
460            HDF_LOGE("%{public}s groupId %{public}d is not enabled by anyone", __func__, sensorId);
461            return result;
462        }
463    }
464    for (auto it = services.begin(); it != services.end(); ++it) {
465        int32_t serviceId = *it;
466        sptr<ISensorCallback> callback;
467        {
468            std::unique_lock<std::mutex> lock(clientsMutex_);
469            if (clients_.find(groupId)->second.find(serviceId) == clients_.find(groupId)->second.end()) {
470                continue;
471            }
472            SensorClientInfo &sensorClientInfo = clients_.find(groupId)->second.find(serviceId)->second;
473            if (IsNotNeedReportData(sensorClientInfo, sensorId, serviceId)) {
474                continue;
475            }
476            callback = sensorClientInfo.GetReportDataCb();
477            if (callback == nullptr) {
478                HDF_LOGD("%{public}s the callback of %{public}d is nullptr", __func__, serviceId);
479                continue;
480            }
481        }
482        SENSOR_TRACE_MSG("serviceId=" + std::to_string(serviceId) + ",sensorId=" + std::to_string(event.sensorId));
483        int32_t ret = callback->OnDataEvent(event);
484        if (ret != HDF_SUCCESS) {
485            HDF_LOGD("%{public}s Sensor OnDataEvent failed, error code is %{public}d", __func__, ret);
486        } else {
487            static std::unordered_map<int32_t, std::unordered_map<int32_t, int64_t>> sensorReportCountMap;
488            auto it = sensorReportCountMap[sensorId].find(serviceId);
489            int64_t reportCount = INIT_REPORT_COUNT;
490            if (it == sensorReportCountMap[sensorId].end()) {
491                sensorReportCountMap[sensorId][serviceId] = INIT_REPORT_COUNT;
492            } else {
493                it->second++;
494                reportCount = it->second;
495            }
496            result += std::to_string(serviceId) + "-" + std::to_string(reportCount) + " ";
497        }
498    }
499    return result;
500}
501
502std::unordered_map<int32_t, std::set<int32_t>> SensorClientsManager::GetSensorUsed()
503{
504    std::unique_lock<std::mutex> lock(sensorUsedMutex_);
505    return sensorUsed_;
506}
507
508SensorClientsManager* SensorClientsManager::GetInstance()
509{
510    static SensorClientsManager *instance = new SensorClientsManager();
511    return instance;
512}
513
514} // V2_0
515} // Sensor
516} // HDI
517} // OHOS