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 sensorId)38 bool SensorPowerPolicy::CheckFreezingSensor(int32_t sensorId)
39 {
40 return ((sensorId == SENSOR_TYPE_ID_PEDOMETER_DETECTION) || (sensorId == 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<int32_t> sensorIdList = clientInfo_.GetSensorIdByPid(pid);
47 if (sensorIdList.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<int32_t, SensorBasicInfo> sensorInfoMap = pidSensorInfoIt->second;
55 if (!Suspend(pid, sensorIdList, 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<int32_t, SensorBasicInfo> sensorInfoMap;
63 auto isAllSuspend = Suspend(pid, sensorIdList, 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<int32_t> & sensorIdList,std::unordered_map<int32_t,SensorBasicInfo> & sensorInfoMap)73 bool SensorPowerPolicy::Suspend(int32_t pid, const std::vector<int32_t> &sensorIdList,
74 std::unordered_map<int32_t, SensorBasicInfo> &sensorInfoMap)
75 {
76 CALL_LOG_ENTER;
77 bool isAllSuspend = true;
78 for (const auto &sensorId : sensorIdList) {
79 if (CheckFreezingSensor(sensorId)) {
80 SEN_HILOGD("Current sensor is pedometer detection or pedometer, can not suspend");
81 continue;
82 }
83 auto sensorInfo = clientInfo_.GetCurPidSensorInfo(sensorId, pid);
84 if (sensorManager_.IsOtherClientUsingSensor(sensorId, pid)) {
85 SEN_HILOGD("Other client is using this sensor now, cannot suspend, sensorId:%{public}d", sensorId);
86 sensorInfoMap.insert(std::make_pair(sensorId, sensorInfo));
87 continue;
88 }
89 #ifdef HDF_DRIVERS_INTERFACE_SENSOR
90 auto ret = sensorHdiConnection_.DisableSensor(sensorId);
91 if (ret != ERR_OK) {
92 isAllSuspend = false;
93 SEN_HILOGE("Hdi disable sensor failed, sensorId:%{public}d, ret:%{public}d", sensorId, ret);
94 }
95 #endif // HDF_DRIVERS_INTERFACE_SENSOR
96 sensorInfoMap.insert(std::make_pair(sensorId, sensorInfo));
97 sensorManager_.AfterDisableSensor(sensorId);
98 }
99 return isAllSuspend;
100 }
101
ResumeSensors(int32_t pid)102 ErrCode SensorPowerPolicy::ResumeSensors(int32_t pid)
103 {
104 CALL_LOG_ENTER;
105 std::lock_guard<std::mutex> pidSensorInfoLock(pidSensorInfoMutex_);
106 auto pidSensorInfoIt = pidSensorInfoMap_.find(pid);
107 if (pidSensorInfoIt == pidSensorInfoMap_.end()) {
108 SEN_HILOGD("Resume sensors failed, please suspend sensors first, pid:%{public}d", pid);
109 return RESUME_ERR;
110 }
111 bool isAllResume = true;
112 std::unordered_map<int32_t, SensorBasicInfo> sensorInfoMap = pidSensorInfoIt->second;
113 for (auto sensorIt = sensorInfoMap.begin(); sensorIt != sensorInfoMap.end();) {
114 int32_t sensorId = sensorIt->first;
115 int64_t samplingPeriodNs = sensorIt->second.GetSamplingPeriodNs();
116 int64_t maxReportDelayNs = sensorIt->second.GetMaxReportDelayNs();
117 if (!Resume(pid, sensorId, samplingPeriodNs, maxReportDelayNs)) {
118 SEN_HILOGE("Resume sensor failed, sensorId:%{public}d", sensorId);
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,int32_t sensorId,int64_t samplingPeriodNs,int64_t maxReportDelayNs)134 bool SensorPowerPolicy::Resume(int32_t pid, int32_t sensorId, int64_t samplingPeriodNs,
135 int64_t maxReportDelayNs)
136 {
137 CALL_LOG_ENTER;
138 if ((sensorId == INVALID_SENSOR_ID) || (samplingPeriodNs <= 0) ||
139 ((samplingPeriodNs != 0L) && (maxReportDelayNs / samplingPeriodNs > MAX_EVENT_COUNT))) {
140 SEN_HILOGE("sensorId is invalid or maxReportDelayNs exceed the maximum value");
141 return false;
142 }
143 if (clientInfo_.GetSensorState(sensorId)) {
144 SEN_HILOGD("Sensor is enable, sensorId:%{public}d", sensorId);
145 auto ret = RestoreSensorInfo(pid, sensorId, 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, sensorId, 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(sensorId);
159 if (ret != ERR_OK) {
160 SEN_HILOGE("Hdi enable sensor failed, sensorId:%{public}d, ret:%{public}d", sensorId, ret);
161 clientInfo_.RemoveSubscriber(sensorId, pid);
162 return false;
163 }
164 #endif // HDF_DRIVERS_INTERFACE_SENSOR
165 return true;
166 }
167
RestoreSensorInfo(int32_t pid,int32_t sensorId,int64_t samplingPeriodNs,int64_t maxReportDelayNs)168 ErrCode SensorPowerPolicy::RestoreSensorInfo(int32_t pid, int32_t sensorId, int64_t samplingPeriodNs,
169 int64_t maxReportDelayNs)
170 {
171 CALL_LOG_ENTER;
172 if (!sensorManager_.SaveSubscriber(sensorId, 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(sensorId, samplingPeriodNs, maxReportDelayNs)) {
179 SEN_HILOGE("SetBestSensorParams failed");
180 clientInfo_.RemoveSubscriber(sensorId, 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<int32_t> sensorIdList = clientInfo_.GetSensorIdByPid(pid);
222 for (const auto &sensorId : sensorIdList) {
223 auto sensorInfo = clientInfo_.GetCurPidSensorInfo(sensorId, pid);
224 ActiveInfo activeInfo(pid, sensorId, sensorInfo.GetSamplingPeriodNs(),
225 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