1 /*
2  * Copyright (c) 2021-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_power_policy.h"
17 
18 #include "sensor.h"
19 #include "sensor_agent_type.h"
20 #ifdef OHOS_BUILD_ENABLE_RUST
21 #include "rust_binding.h"
22 #endif // OHOS_BUILD_ENABLE_RUST
23 #undef LOG_TAG
24 #define LOG_TAG "SensorPowerPolicy"
25 
26 namespace OHOS {
27 namespace Sensors {
28 using namespace OHOS::HiviewDFX;
29 
30 namespace {
31 constexpr int32_t INVALID_SENSOR_ID = -1;
32 constexpr int64_t MAX_EVENT_COUNT = 1000;
33 ClientInfo &clientInfo_ = ClientInfo::GetInstance();
34 SensorManager &sensorManager_ = SensorManager::GetInstance();
35 #ifdef HDF_DRIVERS_INTERFACE_SENSOR
36 SensorHdiConnection &sensorHdiConnection_ = SensorHdiConnection::GetInstance();
37 #endif // HDF_DRIVERS_INTERFACE_SENSOR
38 }  // namespace
39 
CheckFreezingSensor(int32_t sensorId)40 bool SensorPowerPolicy::CheckFreezingSensor(int32_t sensorId)
41 {
42     return ((sensorId == SENSOR_TYPE_ID_PEDOMETER_DETECTION) || (sensorId == SENSOR_TYPE_ID_PEDOMETER));
43 }
44 
SuspendSensors(int32_t pid)45 ErrCode SensorPowerPolicy::SuspendSensors(int32_t pid)
46 {
47     CALL_LOG_ENTER;
48     std::vector<int32_t> sensorIdList = clientInfo_.GetSensorIdByPid(pid);
49     if (sensorIdList.empty()) {
50         SEN_HILOGD("Suspend sensors failed, sensorIdList is empty, pid:%{public}d", pid);
51         return SUSPEND_ERR;
52     }
53     std::lock_guard<std::mutex> pidSensorInfoLock(pidSensorInfoMutex_);
54     auto pidSensorInfoIt = pidSensorInfoMap_.find(pid);
55     if (pidSensorInfoIt != pidSensorInfoMap_.end()) {
56         std::unordered_map<int32_t, SensorBasicInfo> sensorInfoMap = pidSensorInfoIt->second;
57         if (!Suspend(pid, sensorIdList, sensorInfoMap)) {
58             SEN_HILOGE("Suspend part sensors, but some failed, pid:%{public}d", pid);
59             return SUSPEND_ERR;
60         }
61         SEN_HILOGI("Suspend sensors success, pid:%{public}d", pid);
62         return ERR_OK;
63     }
64     std::unordered_map<int32_t, SensorBasicInfo> sensorInfoMap;
65     auto isAllSuspend = Suspend(pid, sensorIdList, sensorInfoMap);
66     pidSensorInfoMap_.insert(std::make_pair(pid, sensorInfoMap));
67     if (!isAllSuspend) {
68         SEN_HILOGE("Suspend all sensors, but some failed, pid:%{public}d", pid);
69         return SUSPEND_ERR;
70     }
71     SEN_HILOGI("Suspend sensors success, pid:%{public}d", pid);
72     return ERR_OK;
73 }
74 
Suspend(int32_t pid,const std::vector<int32_t> & sensorIdList,std::unordered_map<int32_t,SensorBasicInfo> & sensorInfoMap)75 bool SensorPowerPolicy::Suspend(int32_t pid, const std::vector<int32_t> &sensorIdList,
76     std::unordered_map<int32_t, SensorBasicInfo> &sensorInfoMap)
77 {
78     CALL_LOG_ENTER;
79     bool isAllSuspend = true;
80     for (const auto &sensorId : sensorIdList) {
81         if (CheckFreezingSensor(sensorId)) {
82             SEN_HILOGD("Current sensor is pedometer detection or pedometer, can not suspend");
83             continue;
84         }
85         auto sensorInfo = clientInfo_.GetCurPidSensorInfo(sensorId, pid);
86         if (sensorManager_.IsOtherClientUsingSensor(sensorId, pid)) {
87             SEN_HILOGD("Other client is using this sensor now, cannot suspend, sensorId:%{public}d", sensorId);
88             sensorInfoMap.insert(std::make_pair(sensorId, sensorInfo));
89             continue;
90         }
91 #ifdef HDF_DRIVERS_INTERFACE_SENSOR
92         auto ret = sensorHdiConnection_.DisableSensor(sensorId);
93         if (ret != ERR_OK) {
94             isAllSuspend = false;
95             SEN_HILOGE("Hdi disable sensor failed, sensorId:%{public}d, ret:%{public}d", sensorId, ret);
96         }
97 #endif // HDF_DRIVERS_INTERFACE_SENSOR
98         sensorInfoMap.insert(std::make_pair(sensorId, sensorInfo));
99         sensorManager_.AfterDisableSensor(sensorId);
100     }
101     return isAllSuspend;
102 }
103 
ResumeSensors(int32_t pid)104 ErrCode SensorPowerPolicy::ResumeSensors(int32_t pid)
105 {
106     CALL_LOG_ENTER;
107     std::lock_guard<std::mutex> pidSensorInfoLock(pidSensorInfoMutex_);
108     auto pidSensorInfoIt = pidSensorInfoMap_.find(pid);
109     if (pidSensorInfoIt == pidSensorInfoMap_.end()) {
110         SEN_HILOGD("Resume sensors failed, please suspend sensors first, pid:%{public}d", pid);
111         return RESUME_ERR;
112     }
113     bool isAllResume = true;
114     std::unordered_map<int32_t, SensorBasicInfo> sensorInfoMap = pidSensorInfoIt->second;
115     for (auto sensorIt = sensorInfoMap.begin(); sensorIt != sensorInfoMap.end();) {
116         int32_t sensorId = sensorIt->first;
117         int64_t samplingPeriodNs = sensorIt->second.GetSamplingPeriodNs();
118         int64_t maxReportDelayNs = sensorIt->second.GetMaxReportDelayNs();
119         if (!Resume(pid, sensorId, samplingPeriodNs, maxReportDelayNs)) {
120             SEN_HILOGE("Resume sensor failed, sensorId:%{public}d", sensorId);
121             isAllResume = false;
122             ++sensorIt;
123         } else {
124             sensorIt = sensorInfoMap.erase(sensorIt);
125         }
126     }
127     if (!isAllResume) {
128         SEN_HILOGE("Resume all sensors, but some failed, pid:%{public}d", pid);
129         return RESUME_ERR;
130     }
131     pidSensorInfoMap_.erase(pidSensorInfoIt);
132     SEN_HILOGI("Resume sensors success, pid:%{public}d", pid);
133     return ERR_OK;
134 }
135 
Resume(int32_t pid,int32_t sensorId,int64_t samplingPeriodNs,int64_t maxReportDelayNs)136 bool SensorPowerPolicy::Resume(int32_t pid, int32_t sensorId, int64_t samplingPeriodNs,
137     int64_t maxReportDelayNs)
138 {
139     CALL_LOG_ENTER;
140     if ((sensorId == INVALID_SENSOR_ID) || (samplingPeriodNs <= 0) ||
141         ((samplingPeriodNs != 0L) && (maxReportDelayNs / samplingPeriodNs > MAX_EVENT_COUNT))) {
142         SEN_HILOGE("sensorId is invalid or maxReportDelayNs exceed the maximum value");
143         return false;
144     }
145     if (clientInfo_.GetSensorState(sensorId)) {
146         SEN_HILOGD("Sensor is enable, sensorId:%{public}d", sensorId);
147         auto ret = RestoreSensorInfo(pid, sensorId, samplingPeriodNs, maxReportDelayNs);
148         if (ret != ERR_OK) {
149             SEN_HILOGE("Restore sensor info failed, ret:%{public}d", ret);
150             return false;
151         }
152         return true;
153     }
154     auto ret = RestoreSensorInfo(pid, sensorId, samplingPeriodNs, maxReportDelayNs);
155     if (ret != ERR_OK) {
156         SEN_HILOGE("Restore sensor info failed, ret:%{public}d", ret);
157         return false;
158     }
159 #ifdef HDF_DRIVERS_INTERFACE_SENSOR
160     ret = sensorHdiConnection_.EnableSensor(sensorId);
161     if (ret != ERR_OK) {
162         SEN_HILOGE("Hdi enable sensor failed, sensorId:%{public}d, ret:%{public}d", sensorId, ret);
163         clientInfo_.RemoveSubscriber(sensorId, pid);
164         return false;
165     }
166 #endif // HDF_DRIVERS_INTERFACE_SENSOR
167     return true;
168 }
169 
RestoreSensorInfo(int32_t pid,int32_t sensorId,int64_t samplingPeriodNs,int64_t maxReportDelayNs)170 ErrCode SensorPowerPolicy::RestoreSensorInfo(int32_t pid, int32_t sensorId, int64_t samplingPeriodNs,
171     int64_t maxReportDelayNs)
172 {
173     CALL_LOG_ENTER;
174     if (!sensorManager_.SaveSubscriber(sensorId, pid, samplingPeriodNs, maxReportDelayNs)) {
175         SEN_HILOGE("SaveSubscriber failed");
176         return UPDATE_SENSOR_INFO_ERR;
177     }
178 #ifdef HDF_DRIVERS_INTERFACE_SENSOR
179     sensorManager_.StartDataReportThread();
180     if (!sensorManager_.SetBestSensorParams(sensorId, samplingPeriodNs, maxReportDelayNs)) {
181         SEN_HILOGE("SetBestSensorParams failed");
182         clientInfo_.RemoveSubscriber(sensorId, pid);
183         return SET_SENSOR_CONFIG_ERR;
184     }
185 #endif // HDF_DRIVERS_INTERFACE_SENSOR
186     return ERR_OK;
187 }
188 
GetSuspendPidList()189 std::vector<int32_t> SensorPowerPolicy::GetSuspendPidList()
190 {
191     CALL_LOG_ENTER;
192     std::vector<int32_t> suspendPidList;
193     std::lock_guard<std::mutex> pidSensorInfoLock(pidSensorInfoMutex_);
194     for (const auto &pidSensorInfo : pidSensorInfoMap_) {
195         int32_t pid = pidSensorInfo.first;
196         suspendPidList.push_back(pid);
197     }
198     return suspendPidList;
199 }
200 
ResetSensors()201 ErrCode SensorPowerPolicy::ResetSensors()
202 {
203     CALL_LOG_ENTER;
204     std::vector<int32_t> suspendPidList = GetSuspendPidList();
205     bool resetStatus = true;
206     for (const auto &pid : suspendPidList) {
207         if (ResumeSensors(pid) != ERR_OK) {
208             SEN_HILOGE("Reset pid sensors failed, pid:%{public}d", pid);
209             resetStatus = false;
210         }
211     }
212     if (resetStatus) {
213         SEN_HILOGI("Reset sensors success");
214     }
215     return resetStatus ? ERR_OK : RESET_ERR;
216 }
217 
218 
GetActiveInfoList(int32_t pid)219 std::vector<ActiveInfo> SensorPowerPolicy::GetActiveInfoList(int32_t pid)
220 {
221     CALL_LOG_ENTER;
222     std::vector<ActiveInfo> activeInfoList;
223     std::vector<int32_t> sensorIdList = clientInfo_.GetSensorIdByPid(pid);
224     for (const auto &sensorId : sensorIdList) {
225         auto sensorInfo = clientInfo_.GetCurPidSensorInfo(sensorId, pid);
226         ActiveInfo activeInfo(pid, sensorId, sensorInfo.GetSamplingPeriodNs(),
227             sensorInfo.GetMaxReportDelayNs());
228         activeInfoList.push_back(activeInfo);
229     }
230     if (activeInfoList.size() > 0) {
231         SEN_HILOGI("Get active info list success, pid:%{public}d", pid);
232     } else {
233         SEN_HILOGW("activeInfoList is empty");
234     }
235     return activeInfoList;
236 }
237 
ReportActiveInfo(const ActiveInfo & activeInfo,const std::vector<SessionPtr> & sessionList)238 void SensorPowerPolicy::ReportActiveInfo(const ActiveInfo &activeInfo,
239     const std::vector<SessionPtr> &sessionList)
240 {
241     CALL_LOG_ENTER;
242     if (activeInfo.GetPid() < 0 || activeInfo.GetSensorId() < 0) {
243         SEN_HILOGE("Invalid activeInfo");
244         return;
245     }
246     NetPacket pkt(MessageId::ACTIVE_INFO);
247     pkt << activeInfo.GetPid() << activeInfo.GetSensorId() <<
248         activeInfo.GetSamplingPeriodNs() << activeInfo.GetMaxReportDelayNs();
249 #ifdef OHOS_BUILD_ENABLE_RUST
250     if (StreamBufferChkRWError(pkt.streamBufferPtr_.get())) {
251 #else
252     if (pkt.ChkRWError()) {
253 #endif // OHOS_BUILD_ENABLE_RUST
254         SEN_HILOGE("Packet write data failed");
255         return;
256     }
257     for (const auto &sess : sessionList) {
258         if (!sess->SendMsg(pkt)) {
259             SEN_HILOGE("Packet send failed");
260             continue;
261         }
262     }
263 }
264 }  // namespace Sensors
265 }  // namespace OHOS