1 /*
2  * Copyright (c) 2024 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 "unlock_event_helper.h"
17 
18 #include <unistd.h>
19 
20 #include "datetime_ex.h"
21 #include "log.h"
22 
23 #ifdef SCREENLOCK_MANAGER_ENABLED
24 #include "screenlock_manager.h"
25 #endif
26 
27 namespace OHOS {
28 namespace Security {
29 namespace CodeSign {
30 constexpr int32_t SEELP_TIME_FOR_COMMON_EVENT_MGR = 500 * 1000; // 500 ms
31 constexpr int32_t SEELP_TIME_FOR_COMMON_EVENT_MGR_TIME_OUT = 10 * 60; // 10 min
32 constexpr int32_t COMMON_EVENT_MANAGER_ID = 3299;
33 
OnReceiveEvent(const EventFwk::CommonEventData & event)34 void UnlockEventHelper::UnlockEventSubscriber::OnReceiveEvent(const EventFwk::CommonEventData& event)
35 {
36     const auto want = event.GetWant();
37     const auto action = want.GetAction();
38     if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED) {
39         LOG_INFO(LABEL, "receive unlocked event");
40         UnlockEventHelper::GetInstance().FinishWaiting();
41         return;
42     }
43 }
44 
GetInstance()45 UnlockEventHelper &UnlockEventHelper::GetInstance()
46 {
47     static UnlockEventHelper singleUnlockEventHelper;
48     return singleUnlockEventHelper;
49 }
50 
CheckUserUnlockByScreenLockManager()51 bool UnlockEventHelper::CheckUserUnlockByScreenLockManager()
52 {
53     std::lock_guard<std::mutex> lock(unlockMutex_);
54 #ifdef SCREENLOCK_MANAGER_ENABLED
55     if (hasUnLocked_) {
56         return true;
57     }
58     bool lockStatus = false;
59     if (ScreenLock::ScreenLockManager::GetInstance()->IsLocked(lockStatus) == ScreenLock::E_SCREENLOCK_OK) {
60         LOG_INFO(LABEL, "screen locked status = %{private}d", lockStatus);
61         hasUnLocked_ = !lockStatus;
62     } else {
63         LOG_ERROR(LABEL, "unable get lock screen status");
64     }
65 #endif
66     return hasUnLocked_;
67 }
68 
InitUnlockEventSubscriber()69 void UnlockEventHelper::InitUnlockEventSubscriber()
70 {
71     if (hasInited_) {
72         return;
73     }
74     EventFwk::MatchingSkills matchingSkill;
75     // use COMMON_EVENT_USER_UNLOCKED if only for device with PIN
76     matchingSkill.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED);
77     EventFwk::CommonEventSubscribeInfo eventInfo(matchingSkill);
78     unlockEventSubscriber_ = std::make_shared<UnlockEventSubscriber>(eventInfo);
79     hasInited_ = true;
80     LOG_INFO(LABEL, "Init subscriber success.");
81 }
82 
RegisterEvent()83 bool UnlockEventHelper::RegisterEvent()
84 {
85     LOG_INFO(LABEL, "RegisterEvent start");
86     if (hasRegistered_) {
87         LOG_DEBUG(LABEL, "status observer already registered");
88         return false;
89     }
90     InitUnlockEventSubscriber();
91     const auto result = EventFwk::CommonEventManager::SubscribeCommonEvent(
92         unlockEventSubscriber_);
93     if (!result) {
94         LOG_ERROR(LABEL, "RegisterEvent result is err");
95         return false;
96     }
97     hasRegistered_ = true;
98     return true;
99 }
100 
UnregisterEvent()101 void UnlockEventHelper::UnregisterEvent()
102 {
103     LOG_INFO(LABEL, "UnregisterEvent start");
104     const auto result = EventFwk::CommonEventManager::UnSubscribeCommonEvent(
105         unlockEventSubscriber_);
106     if (!result) {
107         LOG_ERROR(LABEL, "UnregisterEvent result is err");
108         return;
109     }
110     hasRegistered_ = false;
111 }
112 
WaitForCommonEventManager()113 bool UnlockEventHelper::WaitForCommonEventManager()
114 {
115     struct tm doingTime = {0};
116     struct tm startTime = {0};
117     int64_t seconds = 0;
118     bool ret = false;
119     if (!OHOS::GetSystemCurrentTime(&startTime)) {
120         return false;
121     }
122     while (seconds <= SEELP_TIME_FOR_COMMON_EVENT_MGR_TIME_OUT) {
123         sptr<ISystemAbilityManager> samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
124         if (samgr != nullptr &&
125             samgr->CheckSystemAbility(COMMON_EVENT_MANAGER_ID) != nullptr) {
126             ret = true;
127             LOG_INFO(LABEL, "Common event manager is loaded.");
128             break;
129         }
130         LOG_DEBUG(LABEL, "Get common event manager failed.");
131         usleep(SEELP_TIME_FOR_COMMON_EVENT_MGR);
132         if (OHOS::GetSystemCurrentTime(&doingTime)) {
133             seconds = OHOS::GetSecondsBetween(startTime, doingTime);
134         }
135     }
136     return ret;
137 }
138 
StartWaitingUnlock()139 bool UnlockEventHelper::StartWaitingUnlock()
140 {
141     std::unique_lock<std::mutex> lock(unlockMutex_);
142     if (hasUnLocked_) {
143         return true;
144     }
145     if (!WaitForCommonEventManager()) {
146         return false;
147     }
148     if (!RegisterEvent()) {
149         return false;
150     }
151     unlockConVar_.wait(lock, [this]() { return this->hasUnLocked_; });
152     LOG_INFO(LABEL, "thread is wake up");
153     // only listening the first unlock event
154     UnregisterEvent();
155     return true;
156 }
157 
FinishWaiting()158 void UnlockEventHelper::FinishWaiting()
159 {
160     std::lock_guard<std::mutex> lock(unlockMutex_);
161     hasUnLocked_ = true;
162     unlockConVar_.notify_one();
163 }
164 }
165 }
166 }