1/*
2 * Copyright (c) 2021-2022 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_manager.h"
17
18#include <cinttypes>
19
20#include "iservice_registry.h"
21
22#include "sensor.h"
23#include "sensor_data_event.h"
24#include "sensor_errors.h"
25
26#undef LOG_TAG
27#define LOG_TAG "SensorManager"
28
29namespace OHOS {
30namespace Sensors {
31using namespace OHOS::HiviewDFX;
32namespace {
33#ifdef HDF_DRIVERS_INTERFACE_SENSOR
34constexpr int32_t INVALID_SENSOR_ID = -1;
35#endif // HDF_DRIVERS_INTERFACE_SENSOR
36constexpr uint32_t PROXIMITY_SENSOR_ID = 50331904;
37constexpr float PROXIMITY_FAR = 5.0;
38} // namespace
39
40#ifdef HDF_DRIVERS_INTERFACE_SENSOR
41void SensorManager::InitSensorMap(const std::unordered_map<int32_t, Sensor> &sensorMap,
42                                  sptr<SensorDataProcesser> dataProcesser, sptr<ReportDataCallback> dataCallback)
43{
44    std::lock_guard<std::mutex> sensorLock(sensorMapMutex_);
45    sensorMap_.insert(sensorMap.begin(), sensorMap.end());
46    sensorDataProcesser_ = dataProcesser;
47    reportDataCallback_ = dataCallback;
48    SEN_HILOGD("Begin sensorMap_.size:%{public}zu", sensorMap_.size());
49}
50
51bool SensorManager::SetBestSensorParams(int32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs)
52{
53    CALL_LOG_ENTER;
54    if (sensorId == INVALID_SENSOR_ID) {
55        SEN_HILOGE("sensorId is invalid");
56        return false;
57    }
58    SensorBasicInfo sensorInfo = clientInfo_.GetBestSensorInfo(sensorId);
59    int64_t bestSamplingPeriodNs = sensorInfo.GetSamplingPeriodNs();
60    int64_t bestReportDelayNs = sensorInfo.GetMaxReportDelayNs();
61    if ((samplingPeriodNs > bestSamplingPeriodNs) && (maxReportDelayNs > bestReportDelayNs)) {
62        SEN_HILOGD("No need to reset sensor params");
63        return true;
64    }
65    bestSamplingPeriodNs = (samplingPeriodNs < bestSamplingPeriodNs) ? samplingPeriodNs : bestSamplingPeriodNs;
66    bestReportDelayNs = (maxReportDelayNs < bestReportDelayNs) ? maxReportDelayNs : bestReportDelayNs;
67    SEN_HILOGD("bestSamplingPeriodNs : %{public}" PRId64, bestSamplingPeriodNs);
68    auto ret = sensorHdiConnection_.SetBatch(sensorId, bestSamplingPeriodNs, bestReportDelayNs);
69    if (ret != ERR_OK) {
70        SEN_HILOGE("SetBatch is failed");
71        return false;
72    }
73    return true;
74}
75
76bool SensorManager::ResetBestSensorParams(int32_t sensorId)
77{
78    CALL_LOG_ENTER;
79    if (sensorId == INVALID_SENSOR_ID) {
80        SEN_HILOGE("sensorId is invalid");
81        return false;
82    }
83    SensorBasicInfo sensorInfo = clientInfo_.GetBestSensorInfo(sensorId);
84    auto ret = sensorHdiConnection_.SetBatch(sensorId,
85        sensorInfo.GetSamplingPeriodNs(), sensorInfo.GetMaxReportDelayNs());
86    if (ret != ERR_OK) {
87        SEN_HILOGE("SetBatch is failed");
88        return false;
89    }
90    return true;
91}
92
93void SensorManager::StartDataReportThread()
94{
95    CALL_LOG_ENTER;
96    if (!dataThread_.joinable()) {
97        SEN_HILOGW("dataThread_ started");
98        std::thread dataProcessThread(SensorDataProcesser::DataThread, sensorDataProcesser_, reportDataCallback_);
99        dataThread_ = std::move(dataProcessThread);
100    }
101}
102#else
103void SensorManager::InitSensorMap(const std::unordered_map<int32_t, Sensor> &sensorMap)
104{
105    std::lock_guard<std::mutex> sensorLock(sensorMapMutex_);
106    sensorMap_ = sensorMap;
107    SEN_HILOGD("Begin sensorMap_.size:%{public}zu", sensorMap_.size());
108}
109#endif // HDF_DRIVERS_INTERFACE_SENSOR
110
111bool SensorManager::SaveSubscriber(int32_t sensorId, uint32_t pid, int64_t samplingPeriodNs,
112    int64_t maxReportDelayNs)
113{
114    SensorBasicInfo sensorInfo = GetSensorInfo(sensorId, samplingPeriodNs, maxReportDelayNs);
115    if (!clientInfo_.UpdateSensorInfo(sensorId, pid, sensorInfo)) {
116        SEN_HILOGE("UpdateSensorInfo is failed");
117        return false;
118    }
119    return true;
120}
121
122SensorBasicInfo SensorManager::GetSensorInfo(int32_t sensorId, int64_t samplingPeriodNs, int64_t maxReportDelayNs)
123{
124    CALL_LOG_ENTER;
125    SensorBasicInfo sensorInfo;
126    std::lock_guard<std::mutex> sensorMapLock(sensorMapMutex_);
127    auto it = sensorMap_.find(sensorId);
128    if (it == sensorMap_.end()) {
129        sensorInfo.SetSamplingPeriodNs(samplingPeriodNs);
130        sensorInfo.SetMaxReportDelayNs(maxReportDelayNs);
131        sensorInfo.SetSensorState(true);
132        SEN_HILOGE("sensorId is invalid");
133        return sensorInfo;
134    }
135    int64_t curSamplingPeriodNs =
136        (samplingPeriodNs < it->second.GetMinSamplePeriodNs()) ? it->second.GetMinSamplePeriodNs() : samplingPeriodNs;
137    int32_t maxEventCount = it->second.GetFifoMaxEventCount();
138    if ((samplingPeriodNs == 0) || (maxEventCount > (INT64_MAX / samplingPeriodNs))) {
139        SEN_HILOGE("Failed, samplingPeriodNs overflow");
140        return sensorInfo;
141    }
142    int64_t supportDelay = samplingPeriodNs * maxEventCount;
143    int64_t curReportDelayNs = (maxReportDelayNs > supportDelay) ? supportDelay : maxReportDelayNs;
144    sensorInfo.SetSamplingPeriodNs(curSamplingPeriodNs);
145    sensorInfo.SetMaxReportDelayNs(curReportDelayNs);
146    sensorInfo.SetSensorState(true);
147    return sensorInfo;
148}
149
150bool SensorManager::IsOtherClientUsingSensor(int32_t sensorId, int32_t clientPid)
151{
152    CALL_LOG_ENTER;
153    if (clientInfo_.OnlyCurPidSensorEnabled(sensorId, clientPid)) {
154        SEN_HILOGD("Only current client using this sensor");
155        return false;
156    }
157    clientInfo_.ClearCurPidSensorInfo(sensorId, clientPid);
158#ifdef HDF_DRIVERS_INTERFACE_SENSOR
159    if (!ResetBestSensorParams(sensorId)) {
160        SEN_HILOGW("ResetBestSensorParams is failed");
161    }
162#endif // HDF_DRIVERS_INTERFACE_SENSOR
163    SEN_HILOGD("Other client is using this sensor");
164    return true;
165}
166
167ErrCode SensorManager::AfterDisableSensor(int32_t sensorId)
168{
169    CALL_LOG_ENTER;
170    clientInfo_.ClearSensorInfo(sensorId);
171    if (sensorId == PROXIMITY_SENSOR_ID) {
172        SensorData sensorData;
173        auto ret = clientInfo_.GetStoreEvent(sensorId, sensorData);
174        if (ret == ERR_OK) {
175            SEN_HILOGD("Change the default state is far");
176            sensorData.data[0] = PROXIMITY_FAR;
177            clientInfo_.StoreEvent(sensorData);
178        }
179    }
180    return ERR_OK;
181}
182
183void SensorManager::GetPackageName(AccessTokenID tokenId, std::string &packageName)
184{
185    CALL_LOG_ENTER;
186    int32_t tokenType = AccessTokenKit::GetTokenTypeFlag(tokenId);
187    switch (tokenType) {
188        case ATokenTypeEnum::TOKEN_HAP: {
189            HapTokenInfo hapInfo;
190            if (AccessTokenKit::GetHapTokenInfo(tokenId, hapInfo) != 0) {
191                SEN_HILOGE("Get hap token info fail");
192                return;
193            }
194            packageName = hapInfo.bundleName;
195            break;
196        }
197        case ATokenTypeEnum::TOKEN_NATIVE:
198        case ATokenTypeEnum::TOKEN_SHELL: {
199            NativeTokenInfo tokenInfo;
200            if (AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) != 0) {
201                SEN_HILOGE("Get native token info fail");
202                return;
203            }
204            packageName = tokenInfo.processName;
205            break;
206        }
207        default: {
208            SEN_HILOGW("Token type not match");
209            break;
210        }
211    }
212}
213} // namespace Sensors
214} // namespace OHOS
215