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 }