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 #include "context_appstate_observer.h"
16
17 #include <sstream>
18
19 #include "context_pool.h"
20 #include "iam_check.h"
21 #include "iam_logger.h"
22 #include "iam_para2str.h"
23 #include "system_ability_definition.h"
24
25 #define LOG_TAG "USER_AUTH_SA"
26 namespace OHOS {
27 namespace UserIam {
28 namespace UserAuth {
29 using namespace OHOS::AppExecFwk;
30 namespace {
31 constexpr std::uint32_t CONVERT_UID_TO_USERID = 200000;
32 }
33
GetAppManagerInstance()34 sptr<IAppMgr> ContextAppStateObserverManager::GetAppManagerInstance()
35 {
36 IAM_LOGI("start");
37 sptr<ISystemAbilityManager> systemAbilityManager =
38 SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
39 if (systemAbilityManager == nullptr) {
40 IAM_LOGE("systemAbilityManager is nullptr");
41 return nullptr;
42 }
43
44 sptr<IRemoteObject> object = systemAbilityManager->GetSystemAbility(APP_MGR_SERVICE_ID);
45 if (object == nullptr) {
46 IAM_LOGE("systemAbilityManager remote object is nullptr");
47 return nullptr;
48 }
49
50 return iface_cast<IAppMgr>(object);
51 }
52
SubscribeAppState(const std::shared_ptr<ContextCallback> & callback,const uint64_t contextId)53 void ContextAppStateObserverManager::SubscribeAppState(const std::shared_ptr<ContextCallback> &callback,
54 const uint64_t contextId)
55 {
56 IAM_LOGI("start");
57 IF_FALSE_LOGE_AND_RETURN(callback != nullptr);
58
59 const std::string bundleName = callback->GetCallerName();
60 if (bundleName.empty()) {
61 IAM_LOGE("bundleName is null");
62 return;
63 }
64
65 sptr<IAppMgr> appManager = GetAppManagerInstance();
66 if (appManager == nullptr) {
67 IAM_LOGE("GetAppManagerInstance failed");
68 return;
69 }
70
71 appStateObserver_ = new (std::nothrow) ContextAppStateObserver(contextId, bundleName);
72 if (appStateObserver_ == nullptr) {
73 IAM_LOGE("get appStateObserver failed");
74 return;
75 }
76
77 std::vector<std::string> bundleNameList;
78 bundleNameList.emplace_back(bundleName);
79 int32_t result = appManager->RegisterApplicationStateObserver(appStateObserver_, bundleNameList);
80 if (result != SUCCESS) {
81 IAM_LOGE("RegistApplicationStateObserver failed");
82 appStateObserver_ = nullptr;
83 return;
84 }
85
86 IAM_LOGI("SubscribeAppState success, contextId:****%{public}hx, bundleName:%{public}s",
87 static_cast<uint16_t>(contextId), bundleName.c_str());
88 return;
89 }
90
UnSubscribeAppState()91 void ContextAppStateObserverManager::UnSubscribeAppState()
92 {
93 IAM_LOGI("start");
94 if (appStateObserver_ == nullptr) {
95 IAM_LOGE("appStateObserver_ is nullptr");
96 return;
97 }
98
99 sptr<IAppMgr> appManager = GetAppManagerInstance();
100 if (appManager == nullptr) {
101 IAM_LOGE("GetAppManagerInstance failed");
102 return;
103 }
104
105 int32_t result = appManager->UnregisterApplicationStateObserver(appStateObserver_);
106 if (result != SUCCESS) {
107 IAM_LOGE("UnregisterApplicationStateObserver failed");
108 return;
109 }
110
111 appStateObserver_ = nullptr;
112 IAM_LOGI("UnSubscribeAppState success");
113 return;
114 }
115
GetInstance()116 ContextAppStateObserverManager &ContextAppStateObserverManager::GetInstance()
117 {
118 static ContextAppStateObserverManager instance;
119 return instance;
120 }
121
SetScreenLockState(bool screenLockState,int32_t userId)122 void ContextAppStateObserverManager::SetScreenLockState(bool screenLockState, int32_t userId)
123 {
124 std::lock_guard<std::mutex> guard(mutex_);
125 IAM_LOGI("setScreenLockState: %{public}d, userId: %{public}d", screenLockState, userId);
126 screenLockedMap_.insert_or_assign(userId, screenLockState);
127 }
128
GetScreenLockState(int32_t userId)129 bool ContextAppStateObserverManager::GetScreenLockState(int32_t userId)
130 {
131 std::lock_guard<std::mutex> guard(mutex_);
132 bool screenLockState = false;
133 auto iter = screenLockedMap_.find(userId);
134 if (iter != screenLockedMap_.end()) {
135 screenLockState = iter->second;
136 }
137 IAM_LOGI("getScreenLockState: %{public}d, userId: %{public}d", screenLockState, userId);
138 return screenLockState;
139 }
140
RemoveScreenLockState(int32_t userId)141 void ContextAppStateObserverManager::RemoveScreenLockState(int32_t userId)
142 {
143 std::lock_guard<std::mutex> guard(mutex_);
144 IAM_LOGI("RemoveScreenLockState userId: %{public}d", userId);
145 screenLockedMap_.erase(userId);
146 }
147
ContextAppStateObserver(const uint64_t contextId,const std::string bundleName)148 ContextAppStateObserver::ContextAppStateObserver(const uint64_t contextId,
149 const std::string bundleName) : contextId_(contextId), bundleName_(bundleName)
150 {
151 IAM_LOGI("start");
152 }
153
ProcAppStateChanged(int32_t userId)154 void ContextAppStateObserver::ProcAppStateChanged(int32_t userId)
155 {
156 IAM_LOGI("start");
157 auto context = ContextPool::Instance().Select(contextId_).lock();
158 if (context == nullptr) {
159 IAM_LOGE("context is nullptr");
160 return;
161 }
162 if (context->GetUserId() != userId) {
163 IAM_LOGI("context userId is %{public}d, appStateChanged userId is %{public}d", context->GetUserId(), userId);
164 return;
165 }
166 if (ContextAppStateObserverManager::GetInstance().GetScreenLockState(userId)) {
167 IAM_LOGI("the screen is currently locked, skip auth cancel");
168 return;
169 }
170 if (!context->Stop()) {
171 IAM_LOGE("failed to cancel enroll or auth");
172 return;
173 }
174 return;
175 }
176
OnAppStateChanged(const AppStateData & appStateData)177 void ContextAppStateObserver::OnAppStateChanged(const AppStateData &appStateData)
178 {
179 IAM_LOGI("start, contextId: ****%{public}hx", static_cast<uint16_t>(contextId_));
180 auto bundleName = appStateData.bundleName;
181 auto state = static_cast<ApplicationState>(appStateData.state);
182 int32_t userId = appStateData.uid / CONVERT_UID_TO_USERID;
183 IAM_LOGI("OnAppStateChanged, userId:%{public}d, bundleName:%{public}s, state:%{public}d", userId,
184 bundleName.c_str(), state);
185
186 if (bundleName.compare(bundleName_) == 0 && state == ApplicationState::APP_STATE_BACKGROUND) {
187 ProcAppStateChanged(userId);
188 }
189 return;
190 }
191
OnForegroundApplicationChanged(const AppStateData & appStateData)192 void ContextAppStateObserver::OnForegroundApplicationChanged(const AppStateData &appStateData)
193 {
194 IAM_LOGI("start, contextId: ****%{public}hx", static_cast<uint16_t>(contextId_));
195 auto bundleName = appStateData.bundleName;
196 auto state = static_cast<ApplicationState>(appStateData.state);
197 int32_t userId = appStateData.uid / CONVERT_UID_TO_USERID;
198 IAM_LOGI("OnForegroundApplicationChanged, userId:%{public}d, bundleName:%{public}s, state:%{public}d", userId,
199 bundleName.c_str(), state);
200
201 if (bundleName.compare(bundleName_) == 0 && state == ApplicationState::APP_STATE_BACKGROUND) {
202 ProcAppStateChanged(userId);
203 }
204 return;
205 }
206 } // namespace UserAuth
207 } // namespace UserIam
208 } // namespace OHOS
209