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