• 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 "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