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