• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 
17 #include <algorithm>
18 
19 #include "ability_manager_errors.h"
20 #include "ability_manager_service.h"
21 #include "ability_record.h"
22 #include "ability_util.h"
23 #include "common_event.h"
24 #include "common_event_manager.h"
25 #include "common_event_support.h"
26 #include "hilog_tag_wrapper.h"
27 #include "interceptor/kiosk_interceptor.h"
28 #include "ipc_skeleton.h"
29 #include "kiosk_manager.h"
30 #include "permission_constants.h"
31 #include "session_manager_lite.h"
32 #include "singleton.h"
33 #include "utils/want_utils.h"
34 
35 namespace OHOS {
36 namespace AAFwk {
37 constexpr char KIOSK_MODE_ENABLED[] = "const.product.kioskmode.enabled";
38 
GetInstance()39 KioskManager &KioskManager::GetInstance()
40 {
41     static KioskManager manager;
42     return manager;
43 }
44 
OnAppStop(const AppInfo & info)45 void KioskManager::OnAppStop(const AppInfo &info)
46 {
47     if (info.state != AppState::TERMINATED && info.state != AppState::END) {
48         return;
49     }
50     TAG_LOGD(AAFwkTag::ABILITYMGR, "App stop, bundleName: %{public}s, state: %{public}d",
51         info.bundleName.c_str(), static_cast<int32_t>(info.state));
52     std::lock_guard<std::mutex> lock(kioskManagermutex_);
53     if (IsInKioskModeInner() && (info.bundleName == kioskStatus_.kioskBundleName_)) {
54         ExitKioskModeInner(info.bundleName, kioskStatus_.kioskToken_);
55     }
56 }
57 
UpdateKioskApplicationList(const std::vector<std::string> & appList)58 int32_t KioskManager::UpdateKioskApplicationList(const std::vector<std::string> &appList)
59 {
60     if (!system::GetBoolParameter(KIOSK_MODE_ENABLED, false)) {
61         TAG_LOGE(AAFwkTag::ABILITYMGR, "Disabled config");
62         return ERR_CAPABILITY_NOT_SUPPORT;
63     }
64 
65     if (!PermissionVerification::GetInstance()->IsSystemAppCall() &&
66         !PermissionVerification::GetInstance()->IsSACall()) {
67         TAG_LOGE(AAFwkTag::ABILITYMGR, "not system app");
68         return ERR_NOT_SYSTEM_APP;
69     }
70     if (!PermissionVerification::GetInstance()->VerifyCallingPermission(
71         PermissionConstants::PERMISSION_MANAGE_EDM_POLICY)) {
72         TAG_LOGE(AAFwkTag::ABILITYMGR, "not MANAGE_EDM_POLICY permission");
73         return CHECK_PERMISSION_FAILED;
74     }
75     std::lock_guard<std::mutex> lock(kioskManagermutex_);
76     if (IsInKioskModeInner()) {
77         auto it = std::find(appList.begin(), appList.end(), kioskStatus_.kioskBundleName_);
78         if (it == appList.end()) {
79             auto ret = ExitKioskModeInner(kioskStatus_.kioskBundleName_, kioskStatus_.kioskToken_);
80             if (ret != ERR_OK) {
81                 return ret;
82             }
83         }
84     }
85     whitelist_.clear();
86     for (const auto &app : appList) {
87         whitelist_.insert(app);
88     }
89     auto sceneSessionManager = Rosen::SessionManagerLite::GetInstance().GetSceneSessionManagerLiteProxy();
90     CHECK_POINTER_AND_RETURN_LOG(sceneSessionManager, INNER_ERR, "sceneSessionManager is nullptr");
91     sceneSessionManager->UpdateKioskAppList(appList);
92     return ERR_OK;
93 }
94 
EnterKioskMode(sptr<IRemoteObject> callerToken)95 int32_t KioskManager::EnterKioskMode(sptr<IRemoteObject> callerToken)
96 {
97     if (!system::GetBoolParameter(KIOSK_MODE_ENABLED, false)) {
98         TAG_LOGE(AAFwkTag::ABILITYMGR, "Disabled config");
99         return ERR_CAPABILITY_NOT_SUPPORT;
100     }
101     auto record = Token::GetAbilityRecordByToken(callerToken);
102     if (!record) {
103         TAG_LOGE(AAFwkTag::ABILITYMGR, "record null");
104         return INVALID_PARAMETERS_ERR;
105     }
106     std::string bundleName = record->GetAbilityInfo().bundleName;
107     if (!CheckCallerIsForeground(callerToken)) {
108         TAG_LOGE(AAFwkTag::ABILITYMGR, "The application is not in the foreground !");
109         return ERR_APP_NOT_IN_FOCUS;
110     }
111     std::lock_guard<std::mutex> lock(kioskManagermutex_);
112     if (!IsInWhiteListInner(bundleName)) {
113         return ERR_KIOSK_MODE_NOT_IN_WHITELIST;
114     }
115 
116     if (IsInKioskModeInner()) {
117         return ERR_ALREADY_IN_KIOSK_MODE;
118     }
119 
120     kioskStatus_.isKioskMode_ = true;
121     kioskStatus_.kioskBundleName_ = bundleName;
122     kioskStatus_.kioskBundleUid_ = IPCSkeleton::GetCallingUid();
123     kioskStatus_.kioskToken_ = callerToken;
124     GetEnterKioskModeCallback()();
125     NotifyKioskModeChanged(true);
126     auto sceneSessionManager = Rosen::SessionManagerLite::GetInstance().GetSceneSessionManagerLiteProxy();
127     CHECK_POINTER_AND_RETURN_LOG(sceneSessionManager, INNER_ERR, "sceneSessionManager is nullptr");
128     sceneSessionManager->EnterKioskMode(callerToken);
129     return ERR_OK;
130 }
131 
ExitKioskMode(sptr<IRemoteObject> callerToken)132 int32_t KioskManager::ExitKioskMode(sptr<IRemoteObject> callerToken)
133 {
134     if (!system::GetBoolParameter(KIOSK_MODE_ENABLED, false)) {
135         TAG_LOGE(AAFwkTag::ABILITYMGR, "Disabled config");
136         return ERR_CAPABILITY_NOT_SUPPORT;
137     }
138     auto record = Token::GetAbilityRecordByToken(callerToken);
139     if (!record) {
140         TAG_LOGE(AAFwkTag::ABILITYMGR, "record null");
141         return INVALID_PARAMETERS_ERR;
142     }
143     std::lock_guard<std::mutex> lock(kioskManagermutex_);
144     return ExitKioskModeInner(record->GetAbilityInfo().bundleName, callerToken);
145 }
146 
ExitKioskModeInner(const std::string & bundleName,sptr<IRemoteObject> callerToken)147 int32_t KioskManager::ExitKioskModeInner(const std::string &bundleName, sptr<IRemoteObject> callerToken)
148 {
149     if (!IsInWhiteListInner(bundleName)) {
150         return ERR_KIOSK_MODE_NOT_IN_WHITELIST;
151     }
152 
153     if (!IsInKioskModeInner()) {
154         return ERR_NOT_IN_KIOSK_MODE;
155     }
156     GetExitKioskModeCallback()();
157     NotifyKioskModeChanged(false);
158     kioskStatus_.Clear();
159     auto sceneSessionManager = Rosen::SessionManagerLite::GetInstance().GetSceneSessionManagerLiteProxy();
160     CHECK_POINTER_AND_RETURN_LOG(sceneSessionManager, INNER_ERR, "sceneSessionManager is nullptr");
161     sceneSessionManager->ExitKioskMode(callerToken);
162     return ERR_OK;
163 }
164 
GetKioskStatus(KioskStatus & kioskStatus)165 int32_t KioskManager::GetKioskStatus(KioskStatus &kioskStatus)
166 {
167     if (!system::GetBoolParameter(KIOSK_MODE_ENABLED, false)) {
168         TAG_LOGE(AAFwkTag::ABILITYMGR, "Disabled config");
169         return ERR_CAPABILITY_NOT_SUPPORT;
170     }
171     if (!PermissionVerification::GetInstance()->IsSystemAppCall() &&
172         !(PermissionVerification::GetInstance()->IsSACall() &&
173         PermissionVerification::GetInstance()->VerifyCallingPermission(
174             PermissionConstants::PERMISSION_GET_EDM_CONFIG))) {
175         TAG_LOGE(AAFwkTag::ABILITYMGR, "not system app or sa call without permission");
176         return ERR_NOT_SYSTEM_APP;
177     }
178     std::lock_guard<std::mutex> lock(kioskManagermutex_);
179     kioskStatus = kioskStatus_;
180     return ERR_OK;
181 }
182 
IsInKioskMode()183 bool KioskManager::IsInKioskMode()
184 {
185     std::lock_guard<std::mutex> lock(kioskManagermutex_);
186     return IsInKioskModeInner();
187 }
188 
IsInWhiteList(const std::string & bundleName)189 bool KioskManager::IsInWhiteList(const std::string &bundleName)
190 {
191     std::lock_guard<std::mutex> lock(kioskManagermutex_);
192     return IsInWhiteListInner(bundleName);
193 }
194 
IsInKioskModeInner()195 bool KioskManager::IsInKioskModeInner()
196 {
197     return kioskStatus_.isKioskMode_;
198 }
199 
NotifyKioskModeChanged(bool isInKioskMode)200 void KioskManager::NotifyKioskModeChanged(bool isInKioskMode)
201 {
202     std::string eventData = isInKioskMode
203                                 ? EventFwk::CommonEventSupport::COMMON_EVENT_KIOSK_MODE_ON
204                                 : EventFwk::CommonEventSupport::COMMON_EVENT_KIOSK_MODE_OFF;
205     Want want;
206     want.SetAction(eventData);
207     want.SetParam("bundleName", kioskStatus_.kioskBundleName_);
208     want.SetParam("uid", kioskStatus_.kioskBundleUid_);
209     want.SetParam("userId", kioskStatus_.kioskBundleUid_ / BASE_USER_RANGE);
210     EventFwk::CommonEventData commonData {want};
211     if (!IN_PROCESS_CALL(EventFwk::CommonEventManager::PublishCommonEvent(commonData))) {
212         TAG_LOGE(AAFwkTag::ABILITYMGR, "PublishCommonEvent failed, eventData: %{public}s", eventData.c_str());
213     }
214 }
215 
IsInWhiteListInner(const std::string & bundleName)216 bool KioskManager::IsInWhiteListInner(const std::string &bundleName)
217 {
218     return whitelist_.count(bundleName) != 0;
219 }
220 
GetEnterKioskModeCallback()221 std::function<void()> KioskManager::GetEnterKioskModeCallback()
222 {
223     auto enterKioskModeCallback = []() {
224         TAG_LOGI(AAFwkTag::ABILITYMGR, "EnterKioskMode");
225         KioskManager::GetInstance().AddKioskInterceptor();
226     };
227     return enterKioskModeCallback;
228 }
229 
GetExitKioskModeCallback()230 std::function<void()> KioskManager::GetExitKioskModeCallback()
231 {
232     auto exitKioskModeCallback = []() {
233         TAG_LOGI(AAFwkTag::ABILITYMGR, "ExitKioskMode");
234         KioskManager::GetInstance().RemoveKioskInterceptor();
235     };
236     return exitKioskModeCallback;
237 }
238 
AddKioskInterceptor()239 void KioskManager::AddKioskInterceptor()
240 {
241     auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
242     if (abilityMgr == nullptr) {
243         TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid abilityMgr pointer");
244         return;
245     }
246     auto interceptorExecuter = abilityMgr->GetAbilityInterceptorExecuter();
247     if (interceptorExecuter == nullptr) {
248         TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid interceptorExecuter pointer");
249         return;
250     }
251     interceptorExecuter->AddInterceptor("KioskWhitelist", std::make_shared<KioskInterceptor>());
252 }
253 
RemoveKioskInterceptor()254 void KioskManager::RemoveKioskInterceptor()
255 {
256     auto abilityMgr = DelayedSingleton<AbilityManagerService>::GetInstance();
257     if (abilityMgr == nullptr) {
258         TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid abilityMgr pointer");
259         return;
260     }
261     auto interceptorExecuter = abilityMgr->GetAbilityInterceptorExecuter();
262     if (interceptorExecuter == nullptr) {
263         TAG_LOGE(AAFwkTag::ABILITYMGR, "invalid interceptorExecuter pointer");
264         return;
265     }
266     interceptorExecuter->RemoveInterceptor("KioskWhitelist");
267 }
268 
CheckCallerIsForeground(sptr<IRemoteObject> callerToken)269 bool KioskManager::CheckCallerIsForeground(sptr<IRemoteObject> callerToken)
270 {
271     AppExecFwk::RunningProcessInfo processInfo;
272     DelayedSingleton<AppScheduler>::GetInstance()->GetRunningProcessInfoByToken(
273         callerToken, processInfo);
274 
275     return processInfo.state_ ==
276            AppExecFwk::AppProcessState::APP_STATE_FOREGROUND;
277 }
278 } // namespace AAFwk
279 } // namespace OHOS
280