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