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)122 void ContextAppStateObserverManager::SetScreenLockState(bool screenLockState)
123 {
124 IAM_LOGI("setScreenLockState: %{public}d", screenLockState);
125 isScreenLocked_ = screenLockState;
126 }
127
GetScreenLockState()128 bool ContextAppStateObserverManager::GetScreenLockState()
129 {
130 return isScreenLocked_;
131 }
132
ContextAppStateObserver(const uint64_t contextId,const std::string bundleName)133 ContextAppStateObserver::ContextAppStateObserver(const uint64_t contextId,
134 const std::string bundleName) : contextId_(contextId), bundleName_(bundleName)
135 {
136 IAM_LOGI("start");
137 }
138
ProcAppStateChanged(int32_t userId)139 void ContextAppStateObserver::ProcAppStateChanged(int32_t userId)
140 {
141 IAM_LOGI("start");
142 auto context = ContextPool::Instance().Select(contextId_).lock();
143 if (context == nullptr) {
144 IAM_LOGE("context is nullptr");
145 return;
146 }
147 if (context->GetUserId() != userId) {
148 IAM_LOGI("context userId is %{public}d, appStateChanged userId is %{public}d", context->GetUserId(), userId);
149 return;
150 }
151 if (ContextAppStateObserverManager::GetInstance().GetScreenLockState()) {
152 IAM_LOGI("the screen is currently locked, skip auth cancel");
153 return;
154 }
155 if (!context->Stop()) {
156 IAM_LOGE("failed to cancel enroll or auth");
157 return;
158 }
159 return;
160 }
161
OnAppStateChanged(const AppStateData & appStateData)162 void ContextAppStateObserver::OnAppStateChanged(const AppStateData &appStateData)
163 {
164 IAM_LOGI("start, contextId: ****%{public}hx", static_cast<uint16_t>(contextId_));
165 auto bundleName = appStateData.bundleName;
166 auto state = static_cast<ApplicationState>(appStateData.state);
167 int32_t userId = appStateData.uid / CONVERT_UID_TO_USERID;
168 IAM_LOGI("OnAppStateChanged, userId:%{public}d, bundleName:%{public}s, state:%{public}d", userId,
169 bundleName.c_str(), state);
170
171 if (bundleName.compare(bundleName_) == 0 && state == ApplicationState::APP_STATE_BACKGROUND) {
172 ProcAppStateChanged(userId);
173 }
174 return;
175 }
176
OnForegroundApplicationChanged(const AppStateData & appStateData)177 void ContextAppStateObserver::OnForegroundApplicationChanged(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("OnForegroundApplicationChanged, 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
OnAbilityStateChanged(const AbilityStateData & abilityStateData)192 void ContextAppStateObserver::OnAbilityStateChanged(const AbilityStateData &abilityStateData)
193 {
194 IAM_LOGI("start, contextId: ****%{public}hx", static_cast<uint16_t>(contextId_));
195 auto bundleName = abilityStateData.bundleName;
196 auto state = static_cast<AbilityState>(abilityStateData.abilityState);
197 int32_t userId = abilityStateData.uid / CONVERT_UID_TO_USERID;
198 IAM_LOGI("OnAbilityStateChanged, userId:%{public}d, bundleName:%{public}s, state:%{public}d", userId,
199 bundleName.c_str(), state);
200
201 if (bundleName.compare(bundleName_) == 0 && state == AbilityState::ABILITY_STATE_BACKGROUND) {
202 ProcAppStateChanged(userId);
203 }
204 return;
205 }
206 } // namespace UserAuth
207 } // namespace UserIam
208 } // namespace OHOS
209