1 /*
2 * Copyright (c) 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 "running_lock_impl.h"
17
18 #include "hdf_base.h"
19 #include "hdf_log.h"
20
21 namespace OHOS {
22 namespace HDI {
23 namespace Power {
24 namespace V1_1 {
25 namespace {
26 const std::string RUNNINGLOCK_TAG_BACKGROUND_INVALID = "OHOS.RunningLock.Background.Invalid";
27 const std::string RUNNINGLOCK_TAG_BACKGROUND_PHONE = "OHOS.RunningLock.Background.Phone";
28 const std::string RUNNINGLOCK_TAG_BACKGROUND_NOTIFICATION = "OHOS.RunningLock.Background.Notification";
29 const std::string RUNNINGLOCK_TAG_BACKGROUND_AUDIO = "OHOS.RunningLock.Background.Audio";
30 const std::string RUNNINGLOCK_TAG_BACKGROUND_SPORT = "OHOS.RunningLock.Background.Sport";
31 const std::string RUNNINGLOCK_TAG_BACKGROUND_NAVIGATION = "OHOS.RunningLock.Background.Navigation";
32 const std::string RUNNINGLOCK_TAG_BACKGROUND_TASK = "OHOS.RunningLock.Background.Task";
33 constexpr int32_t DEFAULT_TIMEOUT = 3000;
34 } // namespace
35 std::mutex RunningLockImpl::mutex_;
36 int32_t RunningLockImpl::defaultTimeOutMs_ = DEFAULT_TIMEOUT;
37 std::unique_ptr<RunningLockTimerHandler> RunningLockImpl::timerHandler_ = nullptr;
38 std::map<RunningLockType, std::shared_ptr<RunningLockCounter>> RunningLockImpl::lockCounters_ = {};
39
Hold(const RunningLockInfo & info,PowerHdfState state)40 int32_t RunningLockImpl::Hold(const RunningLockInfo &info, PowerHdfState state)
41 {
42 std::lock_guard<std::mutex> lock(mutex_);
43 if (info.name.empty()) {
44 HDF_LOGW("Runninglock hold failed, name is empty");
45 return HDF_ERR_INVALID_PARAM;
46 }
47 RunningLockInfo filledInfo = FillRunningLockInfo(info);
48 if (!IsValidType(filledInfo.type, state)) {
49 HDF_LOGW("Runninglock hold failed, type=%{public}d or state=%{public}d is invalid", filledInfo.type, state);
50 return HDF_ERR_INVALID_PARAM;
51 }
52 auto iterator = lockCounters_.find(filledInfo.type);
53 if (iterator == lockCounters_.end()) {
54 auto pair = lockCounters_.emplace(filledInfo.type,
55 std::make_shared<RunningLockCounter>(filledInfo.type, GetRunningLockTag(filledInfo.type)));
56 if (pair.second == false) {
57 HDF_LOGW("Runninglock hold failed, type=%{public}d is not in lockCounters", filledInfo.type);
58 return HDF_FAILURE;
59 }
60 iterator = pair.first;
61 }
62 std::shared_ptr<RunningLockCounter> lockCounter = iterator->second;
63 if (lockCounter->Increase(filledInfo) != HDF_SUCCESS) {
64 return HDF_FAILURE;
65 }
66 if (filledInfo.timeoutMs > 0) {
67 if (timerHandler_ == nullptr) {
68 timerHandler_ = std::make_unique<RunningLockTimerHandler>();
69 }
70 std::function<void()> unholdFunc = std::bind(&RunningLockImpl::Unhold, filledInfo);
71 timerHandler_->RegisterRunningLockTimer(filledInfo, unholdFunc);
72 }
73 return HDF_SUCCESS;
74 }
75
Unhold(const RunningLockInfo & info)76 int32_t RunningLockImpl::Unhold(const RunningLockInfo &info)
77 {
78 std::lock_guard<std::mutex> lock(mutex_);
79 if (info.name.empty()) {
80 HDF_LOGW("Runninglock unhold failed, name is empty");
81 return HDF_ERR_INVALID_PARAM;
82 }
83 RunningLockInfo filledInfo = FillRunningLockInfo(info);
84 if (!IsValidType(filledInfo.type)) {
85 HDF_LOGW("Runninglock unhold failed, type=%{public}d is invalid", filledInfo.type);
86 return HDF_ERR_INVALID_PARAM;
87 }
88 auto iterator = lockCounters_.find(filledInfo.type);
89 if (iterator == lockCounters_.end()) {
90 HDF_LOGW("type=%{public}d is not in lockCounters, no need to unhold", filledInfo.type);
91 return HDF_ERR_NOT_SUPPORT;
92 }
93 if (timerHandler_ != nullptr) {
94 timerHandler_->UnregisterRunningLockTimer(filledInfo);
95 }
96 std::shared_ptr<RunningLockCounter> lockCounter = iterator->second;
97 int32_t status = lockCounter->Decrease(filledInfo);
98 return status;
99 }
100
GetCount(RunningLockType type)101 uint32_t RunningLockImpl::GetCount(RunningLockType type)
102 {
103 std::lock_guard<std::mutex> lock(mutex_);
104 int32_t count = 0;
105 auto iterator = lockCounters_.find(type);
106 if (iterator != lockCounters_.end()) {
107 count = iterator->second->GetCount();
108 }
109 return count;
110 }
111
SetDefaultTimeOutMs(int32_t timeOutMs)112 void RunningLockImpl::SetDefaultTimeOutMs(int32_t timeOutMs)
113 {
114 std::lock_guard<std::mutex> lock(mutex_);
115 if (timeOutMs > 0) {
116 defaultTimeOutMs_ = timeOutMs;
117 }
118 }
119
IsValidType(RunningLockType type,PowerHdfState state)120 bool RunningLockImpl::IsValidType(RunningLockType type, PowerHdfState state)
121 {
122 switch (state) {
123 case PowerHdfState::SLEEP:
124 return false;
125 case PowerHdfState::INACTIVE:
126 return type == RUNNINGLOCK_BACKGROUND_PHONE || type == RUNNINGLOCK_BACKGROUND_NOTIFICATION;
127 case PowerHdfState::AWAKE:
128 return type == RUNNINGLOCK_BACKGROUND_PHONE || type == RUNNINGLOCK_BACKGROUND_NOTIFICATION ||
129 type == RUNNINGLOCK_BACKGROUND_AUDIO || type == RUNNINGLOCK_BACKGROUND_SPORT ||
130 type == RUNNINGLOCK_BACKGROUND_NAVIGATION || type == RUNNINGLOCK_BACKGROUND_TASK;
131 default:
132 break;
133 }
134 return false;
135 }
136
FillRunningLockInfo(const RunningLockInfo & info)137 RunningLockInfo RunningLockImpl::FillRunningLockInfo(const RunningLockInfo &info)
138 {
139 struct RunningLockInfo filledInfo {
140 .name = info.name,
141 .type = info.type,
142 .timeoutMs = info.timeoutMs,
143 .pid = info.pid,
144 .uid = info.uid,
145 };
146 if (static_cast<uint32_t>(filledInfo.type) == 0) {
147 filledInfo.type = RunningLockType::RUNNINGLOCK_BACKGROUND_TASK;
148 }
149 if (filledInfo.timeoutMs == 0) {
150 filledInfo.timeoutMs = defaultTimeOutMs_;
151 }
152 return filledInfo;
153 }
154
GetRunningLockTag(RunningLockType type)155 std::string RunningLockImpl::GetRunningLockTag(RunningLockType type)
156 {
157 switch (type) {
158 case RunningLockType::RUNNINGLOCK_BACKGROUND_PHONE:
159 return RUNNINGLOCK_TAG_BACKGROUND_PHONE;
160 case RunningLockType::RUNNINGLOCK_BACKGROUND_NOTIFICATION:
161 return RUNNINGLOCK_TAG_BACKGROUND_NOTIFICATION;
162 case RunningLockType::RUNNINGLOCK_BACKGROUND_AUDIO:
163 return RUNNINGLOCK_TAG_BACKGROUND_AUDIO;
164 case RunningLockType::RUNNINGLOCK_BACKGROUND_SPORT:
165 return RUNNINGLOCK_TAG_BACKGROUND_SPORT;
166 case RunningLockType::RUNNINGLOCK_BACKGROUND_NAVIGATION:
167 return RUNNINGLOCK_TAG_BACKGROUND_NAVIGATION;
168 case RunningLockType::RUNNINGLOCK_BACKGROUND_TASK:
169 return RUNNINGLOCK_TAG_BACKGROUND_TASK;
170 default: {
171 HDF_LOGE("type=%{public}d is invalid, there is no corresponding tag", type);
172 return RUNNINGLOCK_TAG_BACKGROUND_INVALID;
173 }
174 }
175 }
176 } // namespace V1_1
177 } // namespace Power
178 } // namespace HDI
179 } // namespace OHOS