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