• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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