1686862fbSopenharmony_ci/*
2686862fbSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3686862fbSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4686862fbSopenharmony_ci * you may not use this file except in compliance with the License.
5686862fbSopenharmony_ci * You may obtain a copy of the License at
6686862fbSopenharmony_ci *
7686862fbSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8686862fbSopenharmony_ci *
9686862fbSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10686862fbSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11686862fbSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12686862fbSopenharmony_ci * See the License for the specific language governing permissions and
13686862fbSopenharmony_ci * limitations under the License.
14686862fbSopenharmony_ci */
15686862fbSopenharmony_ci
16686862fbSopenharmony_ci#include "distributed_sched_permission.h"
17686862fbSopenharmony_ci
18686862fbSopenharmony_ci#include "accesstoken_kit.h"
19686862fbSopenharmony_ci#include "datetime_ex.h"
20686862fbSopenharmony_ci#include "device_auth_defines.h"
21686862fbSopenharmony_ci#include "device_manager.h"
22686862fbSopenharmony_ci#include "device_security_defines.h"
23686862fbSopenharmony_ci#include "device_security_info.h"
24686862fbSopenharmony_ci#include "ipc_skeleton.h"
25686862fbSopenharmony_ci#include "ohos_account_kits.h"
26686862fbSopenharmony_ci#include "os_account_manager.h"
27686862fbSopenharmony_ci#include "string_wrapper.h"
28686862fbSopenharmony_ci
29686862fbSopenharmony_ci#include "adapter/dnetwork_adapter.h"
30686862fbSopenharmony_ci#include "bundle/bundle_manager_internal.h"
31686862fbSopenharmony_ci#include "caller_info.h"
32686862fbSopenharmony_ci#include "distributed_sched_adapter.h"
33686862fbSopenharmony_ci#include "distributed_sched_utils.h"
34686862fbSopenharmony_ci#include "dtbschedmgr_device_info_storage.h"
35686862fbSopenharmony_ci#include "dtbschedmgr_log.h"
36686862fbSopenharmony_ci#include "json_util.h"
37686862fbSopenharmony_ci
38686862fbSopenharmony_cinamespace OHOS {
39686862fbSopenharmony_cinamespace DistributedSchedule {
40686862fbSopenharmony_ciusing namespace OHOS::Security;
41686862fbSopenharmony_ciusing namespace AAFwk;
42686862fbSopenharmony_ciusing namespace DistributedHardware;
43686862fbSopenharmony_cinamespace {
44686862fbSopenharmony_ciconst std::string FOUNDATION_PROCESS_NAME = "foundation";
45686862fbSopenharmony_ciconst std::string DMS_API_VERSION = "dmsApiVersion";
46686862fbSopenharmony_ciconst std::string DMS_IS_CALLER_BACKGROUND = "dmsIsCallerBackGround";
47686862fbSopenharmony_ciconst std::string DMS_MISSION_ID = "dmsMissionId";
48686862fbSopenharmony_ciconst std::string DMS_VERSION_ID = "dmsVersion";
49686862fbSopenharmony_ciconst std::string PARAMS_URI = "ability.verify.uri";
50686862fbSopenharmony_ciconst std::string PARAMS_STREAM = "ability.params.stream";
51686862fbSopenharmony_ciconst std::string PERMISSION_START_ABILIIES_FROM_BACKGROUND = "ohos.permission.START_ABILIIES_FROM_BACKGROUND";
52686862fbSopenharmony_ciconst std::string PERMISSION_START_ABILITIES_FROM_BACKGROUND = "ohos.permission.START_ABILITIES_FROM_BACKGROUND";
53686862fbSopenharmony_ciconst std::string PERMISSION_START_INVISIBLE_ABILITY = "ohos.permission.START_INVISIBLE_ABILITY";
54686862fbSopenharmony_ciconst std::string DISTRIBUTED_FILES_PATH = "/data/storage/el2/distributedfiles/";
55686862fbSopenharmony_ciconst std::string BUNDLE_NAME_SCENEBOARD = "com.ohos.sceneboard";
56686862fbSopenharmony_ciconstexpr int32_t DEFAULT_DMS_API_VERSION = 9;
57686862fbSopenharmony_ciconst int DEFAULT_DMS_MISSION_ID = -1;
58686862fbSopenharmony_ciconst int FA_MODULE_ALLOW_MIN_API_VERSION = 8;
59686862fbSopenharmony_ciconst int DEFAULT_DEVICE_SECURITY_LEVEL = -1;
60686862fbSopenharmony_ci}
61686862fbSopenharmony_ci
62686862fbSopenharmony_ciIMPLEMENT_SINGLE_INSTANCE(DistributedSchedPermission);
63686862fbSopenharmony_ci
64686862fbSopenharmony_civoid from_json(const nlohmann::json& jsonObject, GroupInfo& groupInfo)
65686862fbSopenharmony_ci{
66686862fbSopenharmony_ci    const auto &jsonObjectEnd = jsonObject.end();
67686862fbSopenharmony_ci    int32_t parseResult = ERR_OK;
68686862fbSopenharmony_ci    GetValueIfFindKey<std::string>(jsonObject,
69686862fbSopenharmony_ci        jsonObjectEnd,
70686862fbSopenharmony_ci        FIELD_GROUP_NAME,
71686862fbSopenharmony_ci        groupInfo.groupName,
72686862fbSopenharmony_ci        JsonType::STRING,
73686862fbSopenharmony_ci        false,
74686862fbSopenharmony_ci        parseResult,
75686862fbSopenharmony_ci        ArrayType::NOT_ARRAY);
76686862fbSopenharmony_ci    GetValueIfFindKey<std::string>(jsonObject,
77686862fbSopenharmony_ci        jsonObjectEnd,
78686862fbSopenharmony_ci        FIELD_GROUP_ID,
79686862fbSopenharmony_ci        groupInfo.groupId,
80686862fbSopenharmony_ci        JsonType::STRING,
81686862fbSopenharmony_ci        false,
82686862fbSopenharmony_ci        parseResult,
83686862fbSopenharmony_ci        ArrayType::NOT_ARRAY);
84686862fbSopenharmony_ci    GetValueIfFindKey<std::string>(jsonObject,
85686862fbSopenharmony_ci        jsonObjectEnd,
86686862fbSopenharmony_ci        FIELD_GROUP_OWNER,
87686862fbSopenharmony_ci        groupInfo.groupOwner,
88686862fbSopenharmony_ci        JsonType::STRING,
89686862fbSopenharmony_ci        false,
90686862fbSopenharmony_ci        parseResult,
91686862fbSopenharmony_ci        ArrayType::NOT_ARRAY);
92686862fbSopenharmony_ci    GetValueIfFindKey<int32_t>(jsonObject,
93686862fbSopenharmony_ci        jsonObjectEnd,
94686862fbSopenharmony_ci        FIELD_GROUP_TYPE,
95686862fbSopenharmony_ci        groupInfo.groupType,
96686862fbSopenharmony_ci        JsonType::NUMBER,
97686862fbSopenharmony_ci        false,
98686862fbSopenharmony_ci        parseResult,
99686862fbSopenharmony_ci        ArrayType::NOT_ARRAY);
100686862fbSopenharmony_ci    GetValueIfFindKey<int32_t>(jsonObject,
101686862fbSopenharmony_ci        jsonObjectEnd,
102686862fbSopenharmony_ci        FIELD_GROUP_VISIBILITY,
103686862fbSopenharmony_ci        groupInfo.groupVisibility,
104686862fbSopenharmony_ci        JsonType::NUMBER,
105686862fbSopenharmony_ci        false,
106686862fbSopenharmony_ci        parseResult,
107686862fbSopenharmony_ci        ArrayType::NOT_ARRAY);
108686862fbSopenharmony_ci}
109686862fbSopenharmony_ci
110686862fbSopenharmony_ciint32_t DistributedSchedPermission::CheckSendResultPermission(const AAFwk::Want& want, const CallerInfo& callerInfo,
111686862fbSopenharmony_ci    const AccountInfo& accountInfo, AppExecFwk::AbilityInfo& targetAbility)
112686862fbSopenharmony_ci{
113686862fbSopenharmony_ci    // 1.check account access permission in no account networking environment.
114686862fbSopenharmony_ci    if (!CheckAccountAccessPermission(callerInfo, accountInfo, targetAbility.bundleName)) {
115686862fbSopenharmony_ci        HILOGE("CheckAccountAccessPermission denied or failed!");
116686862fbSopenharmony_ci        return DMS_ACCOUNT_ACCESS_PERMISSION_DENIED;
117686862fbSopenharmony_ci    }
118686862fbSopenharmony_ci    // 2.check component access permission, when the ability is not visible.
119686862fbSopenharmony_ci    if (!CheckComponentAccessPermission(targetAbility, callerInfo, accountInfo, want)) {
120686862fbSopenharmony_ci        HILOGE("CheckComponentAccessPermission denied or failed! the callee component do not have permission");
121686862fbSopenharmony_ci        return DMS_COMPONENT_ACCESS_PERMISSION_DENIED;
122686862fbSopenharmony_ci    }
123686862fbSopenharmony_ci    HILOGI("CheckSendResultPermission success!!");
124686862fbSopenharmony_ci    return ERR_OK;
125686862fbSopenharmony_ci}
126686862fbSopenharmony_ci
127686862fbSopenharmony_ciint32_t DistributedSchedPermission::CheckStartPermission(const AAFwk::Want& want, const CallerInfo& callerInfo,
128686862fbSopenharmony_ci    const AccountInfo& accountInfo, AppExecFwk::AbilityInfo& targetAbility, bool isSameBundle)
129686862fbSopenharmony_ci{
130686862fbSopenharmony_ci    // 1.check account access permission in no account networking environment.
131686862fbSopenharmony_ci    if (!CheckAccountAccessPermission(callerInfo, accountInfo, targetAbility.bundleName)) {
132686862fbSopenharmony_ci        HILOGE("CheckAccountAccessPermission denied or failed!");
133686862fbSopenharmony_ci        return DMS_ACCOUNT_ACCESS_PERMISSION_DENIED;
134686862fbSopenharmony_ci    }
135686862fbSopenharmony_ci    // 2.check start control permissions.
136686862fbSopenharmony_ci    if (!CheckStartControlPermission(targetAbility, callerInfo, want, isSameBundle)) {
137686862fbSopenharmony_ci        HILOGE("CheckStartControlPermission denied or failed! the callee component do not have permission");
138686862fbSopenharmony_ci        return DMS_START_CONTROL_PERMISSION_DENIED;
139686862fbSopenharmony_ci    }
140686862fbSopenharmony_ci    HILOGI("CheckDistributedPermission success!");
141686862fbSopenharmony_ci    return ERR_OK;
142686862fbSopenharmony_ci}
143686862fbSopenharmony_ci
144686862fbSopenharmony_ciint32_t DistributedSchedPermission::GetAccountInfo(const std::string& remoteNetworkId,
145686862fbSopenharmony_ci    const CallerInfo& callerInfo, AccountInfo& accountInfo)
146686862fbSopenharmony_ci{
147686862fbSopenharmony_ci    if (remoteNetworkId.empty()) {
148686862fbSopenharmony_ci        HILOGE("remoteNetworkId is empty");
149686862fbSopenharmony_ci        return ERR_NULL_OBJECT;
150686862fbSopenharmony_ci    }
151686862fbSopenharmony_ci    std::string udid = DnetworkAdapter::GetInstance()->GetUdidByNetworkId(remoteNetworkId);
152686862fbSopenharmony_ci    if (udid.empty()) {
153686862fbSopenharmony_ci        HILOGE("udid is empty");
154686862fbSopenharmony_ci        return ERR_NULL_OBJECT;
155686862fbSopenharmony_ci    }
156686862fbSopenharmony_ci    if (!GetOsAccountData(accountInfo)) {
157686862fbSopenharmony_ci        HILOGE("Get Os accountId and userId fail.");
158686862fbSopenharmony_ci        return INVALID_PARAMETERS_ERR;
159686862fbSopenharmony_ci    }
160686862fbSopenharmony_ci
161686862fbSopenharmony_ci#ifdef DMSFWK_SAME_ACCOUNT
162686862fbSopenharmony_ci    if (CheckDstSameAccount(remoteNetworkId, accountInfo, callerInfo)) {
163686862fbSopenharmony_ci        return ERR_OK;
164686862fbSopenharmony_ci    }
165686862fbSopenharmony_ci    HILOGI("check same account by DM fail, will try check access Group by hichain");
166686862fbSopenharmony_ci#endif // DMSFWK_SAME_ACCOUNT
167686862fbSopenharmony_ci
168686862fbSopenharmony_ci    if (GetRelatedGroups(udid, callerInfo.bundleNames, accountInfo)) {
169686862fbSopenharmony_ci        return ERR_OK;
170686862fbSopenharmony_ci    }
171686862fbSopenharmony_ci
172686862fbSopenharmony_ci    HILOGI("Check access Group by hichain fail, will try check different account ACL by DM.");
173686862fbSopenharmony_ci    if (CheckAclList(remoteNetworkId, accountInfo, callerInfo)) {
174686862fbSopenharmony_ci        return ERR_OK;
175686862fbSopenharmony_ci    }
176686862fbSopenharmony_ci    HILOGE("Check different account ACL by DM fail.");
177686862fbSopenharmony_ci    return  INVALID_PARAMETERS_ERR;
178686862fbSopenharmony_ci}
179686862fbSopenharmony_ci
180686862fbSopenharmony_cibool DistributedSchedPermission::GetOsAccountData(AccountInfo& dmsAccountInfo)
181686862fbSopenharmony_ci{
182686862fbSopenharmony_ci#ifdef OS_ACCOUNT_PART
183686862fbSopenharmony_ci    std::vector<int32_t> ids;
184686862fbSopenharmony_ci    ErrCode ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
185686862fbSopenharmony_ci    if (ret != ERR_OK || ids.empty()) {
186686862fbSopenharmony_ci        HILOGE("Get userId from active Os AccountIds fail, ret : %{public}d", ret);
187686862fbSopenharmony_ci        return false;
188686862fbSopenharmony_ci    }
189686862fbSopenharmony_ci    dmsAccountInfo.userId = ids[0];
190686862fbSopenharmony_ci
191686862fbSopenharmony_ci    AccountSA::OhosAccountInfo osAccountInfo;
192686862fbSopenharmony_ci    ret = AccountSA::OhosAccountKits::GetInstance().GetOhosAccountInfo(osAccountInfo);
193686862fbSopenharmony_ci    if (ret != 0 || osAccountInfo.uid_ == "") {
194686862fbSopenharmony_ci        HILOGE("Get accountId from Ohos account info fail, ret: %{public}d.", ret);
195686862fbSopenharmony_ci        return false;
196686862fbSopenharmony_ci    }
197686862fbSopenharmony_ci    dmsAccountInfo.activeAccountId = osAccountInfo.uid_;
198686862fbSopenharmony_ci    HILOGI("Get caller dmsAccountInfo OK, accountId %{public}s, userId %{public}s.",
199686862fbSopenharmony_ci        GetAnonymStr(dmsAccountInfo.activeAccountId).c_str(), GetAnonymInt32(dmsAccountInfo.userId).c_str());
200686862fbSopenharmony_ci#endif
201686862fbSopenharmony_ci    return true;
202686862fbSopenharmony_ci}
203686862fbSopenharmony_ci
204686862fbSopenharmony_cibool DistributedSchedPermission::CheckDstSameAccount(const std::string& dstNetworkId,
205686862fbSopenharmony_ci    const AccountInfo& dmsAccountInfo, const CallerInfo& callerInfo)
206686862fbSopenharmony_ci{
207686862fbSopenharmony_ci#ifdef DMSFWK_SAME_ACCOUNT
208686862fbSopenharmony_ci    DmAccessCaller dmSrcCaller = {
209686862fbSopenharmony_ci        .accountId = dmsAccountInfo.activeAccountId,
210686862fbSopenharmony_ci        .networkId = callerInfo.sourceDeviceId,
211686862fbSopenharmony_ci        .userId = dmsAccountInfo.userId,
212686862fbSopenharmony_ci        .tokenId = callerInfo.accessToken,
213686862fbSopenharmony_ci    };
214686862fbSopenharmony_ci    DmAccessCallee dmDstCallee = {
215686862fbSopenharmony_ci        .networkId = dstNetworkId,
216686862fbSopenharmony_ci        .peerId = "",
217686862fbSopenharmony_ci    };
218686862fbSopenharmony_ci    for (const auto& bundleName : callerInfo.bundleNames) {
219686862fbSopenharmony_ci        dmSrcCaller.pkgName = bundleName;
220686862fbSopenharmony_ci        HILOGI("dmSrcCaller networkId %{public}s, accountId %{public}s, userId %{public}s, pkgName %{public}s; "
221686862fbSopenharmony_ci            "dmDstCallee networkId %{public}s.", GetAnonymStr(dmSrcCaller.networkId).c_str(),
222686862fbSopenharmony_ci            GetAnonymStr(dmSrcCaller.accountId).c_str(), GetAnonymInt32(dmSrcCaller.userId).c_str(),
223686862fbSopenharmony_ci            dmSrcCaller.pkgName.c_str(), GetAnonymStr(dmDstCallee.networkId).c_str());
224686862fbSopenharmony_ci        if (!DeviceManager::GetInstance().CheckIsSameAccount(dmSrcCaller, dmDstCallee)) {
225686862fbSopenharmony_ci            continue;
226686862fbSopenharmony_ci        }
227686862fbSopenharmony_ci        return true;
228686862fbSopenharmony_ci    }
229686862fbSopenharmony_ci    return false;
230686862fbSopenharmony_ci#else // DMSFWK_SAME_ACCOUNT
231686862fbSopenharmony_ci    HILOGI("Not support remote same account check.");
232686862fbSopenharmony_ci    return false;
233686862fbSopenharmony_ci#endif // DMSFWK_SAME_ACCOUNT
234686862fbSopenharmony_ci}
235686862fbSopenharmony_ci
236686862fbSopenharmony_cibool DistributedSchedPermission::CheckAclList(const std::string& dstNetworkId,
237686862fbSopenharmony_ci    const AccountInfo& dmsAccountInfo, const CallerInfo& callerInfo)
238686862fbSopenharmony_ci{
239686862fbSopenharmony_ci    DmAccessCaller dmSrcCaller = {
240686862fbSopenharmony_ci        .accountId = dmsAccountInfo.activeAccountId,
241686862fbSopenharmony_ci        .networkId = callerInfo.sourceDeviceId,
242686862fbSopenharmony_ci        .userId = dmsAccountInfo.userId,
243686862fbSopenharmony_ci        .tokenId = callerInfo.accessToken,
244686862fbSopenharmony_ci    };
245686862fbSopenharmony_ci    DmAccessCallee dmDstCallee = {
246686862fbSopenharmony_ci        .networkId = dstNetworkId,
247686862fbSopenharmony_ci        .peerId = "",
248686862fbSopenharmony_ci    };
249686862fbSopenharmony_ci    for (const auto& bundleName : callerInfo.bundleNames) {
250686862fbSopenharmony_ci        dmSrcCaller.pkgName = bundleName;
251686862fbSopenharmony_ci        HILOGI("dmSrcCaller networkId %{public}s, accountId %{public}s, userId %{public}s, pkgName %{public}s; "
252686862fbSopenharmony_ci            "dmDstCallee networkId %{public}s.", GetAnonymStr(dmSrcCaller.networkId).c_str(),
253686862fbSopenharmony_ci            GetAnonymStr(dmSrcCaller.accountId).c_str(), GetAnonymInt32(dmSrcCaller.userId).c_str(),
254686862fbSopenharmony_ci            dmSrcCaller.pkgName.c_str(), GetAnonymStr(dmDstCallee.networkId).c_str());
255686862fbSopenharmony_ci        if (!DeviceManager::GetInstance().CheckAccessControl(dmSrcCaller, dmDstCallee)) {
256686862fbSopenharmony_ci            continue;
257686862fbSopenharmony_ci        }
258686862fbSopenharmony_ci        return true;
259686862fbSopenharmony_ci    }
260686862fbSopenharmony_ci    return false;
261686862fbSopenharmony_ci}
262686862fbSopenharmony_ci
263686862fbSopenharmony_cibool DistributedSchedPermission::GetRelatedGroups(const std::string& udid,
264686862fbSopenharmony_ci    const std::vector<std::string>& bundleNames, AccountInfo& accountInfo)
265686862fbSopenharmony_ci{
266686862fbSopenharmony_ci    for (const auto& bundleName : bundleNames) {
267686862fbSopenharmony_ci        std::string returnGroups;
268686862fbSopenharmony_ci        if (!DistributedSchedAdapter::GetInstance().GetRelatedGroups(udid, bundleName, returnGroups)) {
269686862fbSopenharmony_ci            continue;
270686862fbSopenharmony_ci        }
271686862fbSopenharmony_ci        std::vector<GroupInfo> groupInfos;
272686862fbSopenharmony_ci        if (!ParseGroupInfos(returnGroups, groupInfos)) {
273686862fbSopenharmony_ci            continue;
274686862fbSopenharmony_ci        }
275686862fbSopenharmony_ci        for (const auto& groupInfo : groupInfos) {
276686862fbSopenharmony_ci            // check group type is whether (same count or point to point) or not
277686862fbSopenharmony_ci            if (groupInfo.groupType != GroupType::IDENTICAL_ACCOUNT_GROUP
278686862fbSopenharmony_ci                && groupInfo.groupType != GroupType::PEER_TO_PEER_GROUP) {
279686862fbSopenharmony_ci                continue;
280686862fbSopenharmony_ci            }
281686862fbSopenharmony_ci            accountInfo.groupIdList.push_back(groupInfo.groupId);
282686862fbSopenharmony_ci            if (groupInfo.groupType == GroupType::IDENTICAL_ACCOUNT_GROUP
283686862fbSopenharmony_ci                && accountInfo.accountType != IDistributedSched::SAME_ACCOUNT_TYPE) {
284686862fbSopenharmony_ci                accountInfo.accountType = IDistributedSched::SAME_ACCOUNT_TYPE;
285686862fbSopenharmony_ci            }
286686862fbSopenharmony_ci        }
287686862fbSopenharmony_ci    }
288686862fbSopenharmony_ci    if (accountInfo.groupIdList.empty()) {
289686862fbSopenharmony_ci        HILOGE("groupIdList is empty");
290686862fbSopenharmony_ci        return false;
291686862fbSopenharmony_ci    }
292686862fbSopenharmony_ci    return true;
293686862fbSopenharmony_ci}
294686862fbSopenharmony_ci
295686862fbSopenharmony_cibool DistributedSchedPermission::ParseGroupInfos(const std::string& returnGroupStr, std::vector<GroupInfo>& groupInfos)
296686862fbSopenharmony_ci{
297686862fbSopenharmony_ci    nlohmann::json groupInfoJson = nlohmann::json::parse(returnGroupStr, nullptr, false);
298686862fbSopenharmony_ci    if (groupInfoJson.is_discarded()) {
299686862fbSopenharmony_ci        HILOGE("returnGroupStr parse failed");
300686862fbSopenharmony_ci        return false;
301686862fbSopenharmony_ci    }
302686862fbSopenharmony_ci    HILOGD("groupInfoJson:%{public}s", groupInfoJson.dump().c_str());
303686862fbSopenharmony_ci    groupInfos = groupInfoJson.get<std::vector<GroupInfo>>();
304686862fbSopenharmony_ci    if (groupInfos.empty()) {
305686862fbSopenharmony_ci        HILOGE("groupInfos is empty");
306686862fbSopenharmony_ci        return false;
307686862fbSopenharmony_ci    }
308686862fbSopenharmony_ci    return true;
309686862fbSopenharmony_ci}
310686862fbSopenharmony_ci
311686862fbSopenharmony_cibool DistributedSchedPermission::GetTargetAbility(const AAFwk::Want& want,
312686862fbSopenharmony_ci    AppExecFwk::AbilityInfo& targetAbility, bool needQueryExtension) const
313686862fbSopenharmony_ci{
314686862fbSopenharmony_ci    if (BundleManagerInternal::QueryAbilityInfo(want, targetAbility)) {
315686862fbSopenharmony_ci        if (want.GetIntParam(DMS_MISSION_ID, DEFAULT_DMS_MISSION_ID) != DEFAULT_DMS_MISSION_ID &&
316686862fbSopenharmony_ci            (targetAbility.type == AppExecFwk::AbilityType::SERVICE ||
317686862fbSopenharmony_ci            targetAbility.type == AppExecFwk::AbilityType::EXTENSION)) {
318686862fbSopenharmony_ci            HILOGE("StartAbilityForResult can not start service and extension ability");
319686862fbSopenharmony_ci            return false;
320686862fbSopenharmony_ci        }
321686862fbSopenharmony_ci        return true;
322686862fbSopenharmony_ci    }
323686862fbSopenharmony_ci    if (needQueryExtension) {
324686862fbSopenharmony_ci        HILOGI("QueryAbilityInfo failed, try to QueryExtensionAbilityInfo");
325686862fbSopenharmony_ci        // try to find extension
326686862fbSopenharmony_ci        AppExecFwk::ExtensionAbilityInfo extensionAbility;
327686862fbSopenharmony_ci        if (BundleManagerInternal::QueryExtensionAbilityInfo(want, extensionAbility)) {
328686862fbSopenharmony_ci            // extensionAbilityInfo translates to abilityInfo
329686862fbSopenharmony_ci            BundleManagerInternal::InitAbilityInfoFromExtension(extensionAbility, targetAbility);
330686862fbSopenharmony_ci            return true;
331686862fbSopenharmony_ci        }
332686862fbSopenharmony_ci    }
333686862fbSopenharmony_ci    HILOGE("QueryAbilityInfo failed, want bundle name=%{public}s, ability name=%{public}s.",
334686862fbSopenharmony_ci        want.GetElement().GetBundleName().c_str(), want.GetElement().GetAbilityName().c_str());
335686862fbSopenharmony_ci    return false;
336686862fbSopenharmony_ci}
337686862fbSopenharmony_ci
338686862fbSopenharmony_ciint32_t DistributedSchedPermission::CheckGetCallerPermission(const AAFwk::Want& want, const CallerInfo& callerInfo,
339686862fbSopenharmony_ci    const AccountInfo& accountInfo, AppExecFwk::AbilityInfo& targetAbility)
340686862fbSopenharmony_ci{
341686862fbSopenharmony_ci    // 1.check account access permission in no account networking environment.
342686862fbSopenharmony_ci    if (!CheckAccountAccessPermission(callerInfo, accountInfo, targetAbility.bundleName)) {
343686862fbSopenharmony_ci        HILOGE("CheckAccountAccessPermission denied or failed!");
344686862fbSopenharmony_ci        return DMS_ACCOUNT_ACCESS_PERMISSION_DENIED;
345686862fbSopenharmony_ci    }
346686862fbSopenharmony_ci    // 2. check call with same appid
347686862fbSopenharmony_ci    if (!BundleManagerInternal::IsSameAppId(callerInfo.callerAppId, targetAbility.bundleName)) {
348686862fbSopenharmony_ci        HILOGE("the appId is different, check permission denied!");
349686862fbSopenharmony_ci        return CALL_PERMISSION_DENIED;
350686862fbSopenharmony_ci    }
351686862fbSopenharmony_ci    // 3. check background permission
352686862fbSopenharmony_ci    if (!CheckBackgroundPermission(targetAbility, callerInfo, want, false)) {
353686862fbSopenharmony_ci        HILOGE("Check background permission failed!");
354686862fbSopenharmony_ci        return DMS_BACKGROUND_PERMISSION_DENIED;
355686862fbSopenharmony_ci    }
356686862fbSopenharmony_ci    // 4. check device security level
357686862fbSopenharmony_ci    if (!targetAbility.visible &&
358686862fbSopenharmony_ci        !CheckDeviceSecurityLevel(callerInfo.sourceDeviceId, want.GetElement().GetDeviceID())) {
359686862fbSopenharmony_ci        HILOGE("check device security level failed!");
360686862fbSopenharmony_ci        return CALL_PERMISSION_DENIED;
361686862fbSopenharmony_ci    }
362686862fbSopenharmony_ci    HILOGI("CheckGetCallerPermission success!!");
363686862fbSopenharmony_ci    return ERR_OK;
364686862fbSopenharmony_ci}
365686862fbSopenharmony_ci
366686862fbSopenharmony_cibool DistributedSchedPermission::IsFoundationCall() const
367686862fbSopenharmony_ci{
368686862fbSopenharmony_ci    uint32_t accessToken = IPCSkeleton::GetCallingTokenID();
369686862fbSopenharmony_ci    AccessToken::NativeTokenInfo nativeTokenInfo;
370686862fbSopenharmony_ci    int32_t result = AccessToken::AccessTokenKit::GetNativeTokenInfo(accessToken, nativeTokenInfo);
371686862fbSopenharmony_ci    if (result == ERR_OK && nativeTokenInfo.processName == FOUNDATION_PROCESS_NAME) {
372686862fbSopenharmony_ci        return true;
373686862fbSopenharmony_ci    }
374686862fbSopenharmony_ci    HILOGE("not foundation called, processName:%{private}s", nativeTokenInfo.processName.c_str());
375686862fbSopenharmony_ci    return false;
376686862fbSopenharmony_ci}
377686862fbSopenharmony_ci
378686862fbSopenharmony_cibool DistributedSchedPermission::IsSceneBoardCall() const
379686862fbSopenharmony_ci{
380686862fbSopenharmony_ci    int32_t activeAccountId = 0;
381686862fbSopenharmony_ci#ifdef OS_ACCOUNT_PART
382686862fbSopenharmony_ci    std::vector<int32_t> ids;
383686862fbSopenharmony_ci    int32_t errCode = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
384686862fbSopenharmony_ci    if (errCode != ERR_OK || ids.empty()) {
385686862fbSopenharmony_ci        HILOGE("QueryActiveOsAccountIds failed.");
386686862fbSopenharmony_ci        return false;
387686862fbSopenharmony_ci    }
388686862fbSopenharmony_ci    activeAccountId = ids[0];
389686862fbSopenharmony_ci#endif
390686862fbSopenharmony_ci    AppExecFwk::ApplicationInfo appInfo;
391686862fbSopenharmony_ci    if (BundleManagerInternal::GetApplicationInfoFromBms(BUNDLE_NAME_SCENEBOARD,
392686862fbSopenharmony_ci        AppExecFwk::BundleFlag::GET_BUNDLE_DEFAULT, activeAccountId, appInfo) != ERR_OK) {
393686862fbSopenharmony_ci        HILOGE("get applicationInfo failed.");
394686862fbSopenharmony_ci        return false;
395686862fbSopenharmony_ci    }
396686862fbSopenharmony_ci    auto accessTokenId = IPCSkeleton::GetCallingTokenID();
397686862fbSopenharmony_ci    if (accessTokenId != appInfo.accessTokenId) {
398686862fbSopenharmony_ci        HILOGE("not sceneBoard called.");
399686862fbSopenharmony_ci        return false;
400686862fbSopenharmony_ci    }
401686862fbSopenharmony_ci    return true;
402686862fbSopenharmony_ci}
403686862fbSopenharmony_ci
404686862fbSopenharmony_ciint32_t DistributedSchedPermission::CheckPermission(uint32_t accessToken, const std::string& permissionName) const
405686862fbSopenharmony_ci{
406686862fbSopenharmony_ci    HILOGI("CheckPermission called.");
407686862fbSopenharmony_ci    if (VerifyPermission(accessToken, permissionName)) {
408686862fbSopenharmony_ci        return ERR_OK;
409686862fbSopenharmony_ci    }
410686862fbSopenharmony_ci    return DMS_PERMISSION_DENIED;
411686862fbSopenharmony_ci}
412686862fbSopenharmony_ci
413686862fbSopenharmony_ciint32_t DistributedSchedPermission::CheckPermissionAll(uint32_t accessToken, const std::string& permissionName) const
414686862fbSopenharmony_ci{
415686862fbSopenharmony_ci    HILOGI("CheckPermissionAll called.");
416686862fbSopenharmony_ci    if (VerifyPermission(accessToken, permissionName)) {
417686862fbSopenharmony_ci        return ERR_OK;
418686862fbSopenharmony_ci    }
419686862fbSopenharmony_ci    return DMS_PERMISSION_DENIED;
420686862fbSopenharmony_ci}
421686862fbSopenharmony_ci
422686862fbSopenharmony_civoid DistributedSchedPermission::MarkUriPermission(OHOS::AAFwk::Want& want, uint32_t accessToken)
423686862fbSopenharmony_ci{
424686862fbSopenharmony_ci    if ((want.GetFlags() & (Want::FLAG_AUTH_READ_URI_PERMISSION | Want::FLAG_AUTH_WRITE_URI_PERMISSION)) == 0) {
425686862fbSopenharmony_ci        return;
426686862fbSopenharmony_ci    }
427686862fbSopenharmony_ci    auto bms = BundleManagerInternal::GetBundleManager();
428686862fbSopenharmony_ci    if (bms == nullptr) {
429686862fbSopenharmony_ci        HILOGW("Failed to get bms.");
430686862fbSopenharmony_ci        return;
431686862fbSopenharmony_ci    }
432686862fbSopenharmony_ci    std::vector<std::string> uriVec = want.GetStringArrayParam(PARAMS_STREAM);
433686862fbSopenharmony_ci    std::string uriStr = want.GetUri().ToString();
434686862fbSopenharmony_ci    uriVec.emplace_back(uriStr);
435686862fbSopenharmony_ci    std::vector<std::string> uriVecPermission;
436686862fbSopenharmony_ci    HILOGI("GrantUriPermission uriVec size: %{public}zu", uriVec.size());
437686862fbSopenharmony_ci    for (std::string str : uriVec) {
438686862fbSopenharmony_ci        Uri uri(str);
439686862fbSopenharmony_ci        if (!IsDistributedFile(uri.GetPath())) {
440686862fbSopenharmony_ci            continue;
441686862fbSopenharmony_ci        }
442686862fbSopenharmony_ci        std::string authority = uri.GetAuthority();
443686862fbSopenharmony_ci        HILOGI("uri authority is %{public}s.", authority.c_str());
444686862fbSopenharmony_ci        AppExecFwk::BundleInfo bundleInfo;
445686862fbSopenharmony_ci        int32_t activeAccountId = 0;
446686862fbSopenharmony_ci#ifdef OS_ACCOUNT_PART
447686862fbSopenharmony_ci        std::vector<int32_t> ids;
448686862fbSopenharmony_ci        int32_t errCode = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
449686862fbSopenharmony_ci        if (errCode != ERR_OK || ids.empty()) {
450686862fbSopenharmony_ci            return;
451686862fbSopenharmony_ci        }
452686862fbSopenharmony_ci        activeAccountId = ids[0];
453686862fbSopenharmony_ci#endif
454686862fbSopenharmony_ci        if (!bms->GetBundleInfo(authority,
455686862fbSopenharmony_ci            AppExecFwk::BundleFlag::GET_BUNDLE_WITH_EXTENSION_INFO, bundleInfo, activeAccountId)) {
456686862fbSopenharmony_ci            HILOGW("To fail to get bundle info according to uri.");
457686862fbSopenharmony_ci            continue;
458686862fbSopenharmony_ci        }
459686862fbSopenharmony_ci        if (bundleInfo.applicationInfo.accessTokenId == accessToken) {
460686862fbSopenharmony_ci            HILOGI("uri token is true.");
461686862fbSopenharmony_ci            uriVecPermission.emplace_back(str);
462686862fbSopenharmony_ci        }
463686862fbSopenharmony_ci    }
464686862fbSopenharmony_ci    want.SetParam(PARAMS_URI, uriVecPermission);
465686862fbSopenharmony_ci}
466686862fbSopenharmony_ci
467686862fbSopenharmony_cibool DistributedSchedPermission::IsDistributedFile(const std::string& path) const
468686862fbSopenharmony_ci{
469686862fbSopenharmony_ci    if (path.compare(0, DISTRIBUTED_FILES_PATH.size(), DISTRIBUTED_FILES_PATH) == 0) {
470686862fbSopenharmony_ci        return true;
471686862fbSopenharmony_ci    }
472686862fbSopenharmony_ci    HILOGE("uri path is false.");
473686862fbSopenharmony_ci    return false;
474686862fbSopenharmony_ci}
475686862fbSopenharmony_ci
476686862fbSopenharmony_cibool DistributedSchedPermission::VerifyPermission(uint32_t accessToken, const std::string& permissionName) const
477686862fbSopenharmony_ci{
478686862fbSopenharmony_ci    int32_t result = AccessToken::AccessTokenKit::VerifyAccessToken(accessToken, permissionName);
479686862fbSopenharmony_ci    if (result == AccessToken::PermissionState::PERMISSION_DENIED) {
480686862fbSopenharmony_ci        HILOGE("permission denied, permissionName:%{public}s", permissionName.c_str());
481686862fbSopenharmony_ci        return false;
482686862fbSopenharmony_ci    }
483686862fbSopenharmony_ci    HILOGD("permission matched.");
484686862fbSopenharmony_ci    return true;
485686862fbSopenharmony_ci}
486686862fbSopenharmony_ci
487686862fbSopenharmony_cibool DistributedSchedPermission::CheckAccountAccessPermission(const CallerInfo& callerInfo,
488686862fbSopenharmony_ci    const AccountInfo& accountInfo, const std::string& targetBundleName)
489686862fbSopenharmony_ci{
490686862fbSopenharmony_ci    std::string udid = DnetworkAdapter::GetInstance()->GetUdidByNetworkId(callerInfo.sourceDeviceId);
491686862fbSopenharmony_ci    std::string dstNetworkId;
492686862fbSopenharmony_ci    if (!DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalDeviceId(dstNetworkId)) {
493686862fbSopenharmony_ci        HILOGE("GetLocalDeviceId failed");
494686862fbSopenharmony_ci        return false;
495686862fbSopenharmony_ci    }
496686862fbSopenharmony_ci    DmAccessCaller dmSrcCaller = {
497686862fbSopenharmony_ci        .accountId = accountInfo.activeAccountId,
498686862fbSopenharmony_ci        .pkgName = targetBundleName,
499686862fbSopenharmony_ci        .networkId = callerInfo.sourceDeviceId,
500686862fbSopenharmony_ci        .userId = accountInfo.userId,
501686862fbSopenharmony_ci        .tokenId = callerInfo.accessToken,
502686862fbSopenharmony_ci    };
503686862fbSopenharmony_ci    DmAccessCallee dmDstCallee = {
504686862fbSopenharmony_ci        .networkId = dstNetworkId,
505686862fbSopenharmony_ci        .peerId = "",
506686862fbSopenharmony_ci    };
507686862fbSopenharmony_ci    HILOGI("dmSrcCaller netWorkId %{public}s, accountId %{public}s, userId %{public}s, pkgName %{public}s; "
508686862fbSopenharmony_ci        "dmDstCallee networkId %{public}s.", GetAnonymStr(dmSrcCaller.networkId).c_str(),
509686862fbSopenharmony_ci        GetAnonymStr(dmSrcCaller.accountId).c_str(), GetAnonymInt32(dmSrcCaller.userId).c_str(),
510686862fbSopenharmony_ci        dmSrcCaller.pkgName.c_str(), GetAnonymStr(dmDstCallee.networkId).c_str());
511686862fbSopenharmony_ci
512686862fbSopenharmony_ci#ifdef DMSFWK_SAME_ACCOUNT
513686862fbSopenharmony_ci    if (DeviceManager::GetInstance().CheckIsSameAccount(dmSrcCaller, dmDstCallee)) {
514686862fbSopenharmony_ci        return true;
515686862fbSopenharmony_ci    }
516686862fbSopenharmony_ci    HILOGI("check same account by DM fail, will try check access Group by hichain");
517686862fbSopenharmony_ci#endif
518686862fbSopenharmony_ci
519686862fbSopenharmony_ci    if (DistributedSchedAdapter::GetInstance().CheckAccessToGroup(udid, targetBundleName)) {
520686862fbSopenharmony_ci        return true;
521686862fbSopenharmony_ci    }
522686862fbSopenharmony_ci
523686862fbSopenharmony_ci    HILOGI("Check access Group by hichain fail, will try check different account ACL by DM.");
524686862fbSopenharmony_ci    if (DeviceManager::GetInstance().CheckAccessControl(dmSrcCaller, dmDstCallee)) {
525686862fbSopenharmony_ci        return true;
526686862fbSopenharmony_ci    }
527686862fbSopenharmony_ci
528686862fbSopenharmony_ci    HILOGE("Check different account ACL by DM fail.");
529686862fbSopenharmony_ci    return false;
530686862fbSopenharmony_ci}
531686862fbSopenharmony_ci
532686862fbSopenharmony_cibool DistributedSchedPermission::CheckComponentAccessPermission(const AppExecFwk::AbilityInfo& targetAbility,
533686862fbSopenharmony_ci    const CallerInfo& callerInfo, const AccountInfo& accountInfo, const AAFwk::Want& want) const
534686862fbSopenharmony_ci{
535686862fbSopenharmony_ci    // reject directly when in no account networking environment and target ability is not visible,
536686862fbSopenharmony_ci    if (!targetAbility.visible) {
537686862fbSopenharmony_ci        HILOGE("target ability is not visible, permission denied!");
538686862fbSopenharmony_ci        return false;
539686862fbSopenharmony_ci    }
540686862fbSopenharmony_ci    HILOGD("check component permission success");
541686862fbSopenharmony_ci    return true;
542686862fbSopenharmony_ci}
543686862fbSopenharmony_ci
544686862fbSopenharmony_cibool DistributedSchedPermission::CheckMigrateStartCtrlPer(const AppExecFwk::AbilityInfo& targetAbility,
545686862fbSopenharmony_ci    const CallerInfo& callerInfo, const AAFwk::Want& want, bool isSameBundle)
546686862fbSopenharmony_ci{
547686862fbSopenharmony_ci    std::string bundleName = want.GetBundle();
548686862fbSopenharmony_ci    // check if continuation with same appid
549686862fbSopenharmony_ci    HILOGI("Check migration start control permission with same appid enter.");
550686862fbSopenharmony_ci    if (!targetAbility.visible &&
551686862fbSopenharmony_ci        !CheckDeviceSecurityLevel(callerInfo.sourceDeviceId, want.GetElement().GetDeviceID())) {
552686862fbSopenharmony_ci        HILOGE("check device security level failed!");
553686862fbSopenharmony_ci        return false;
554686862fbSopenharmony_ci        }
555686862fbSopenharmony_ci    if (!isSameBundle) {
556686862fbSopenharmony_ci        return true;
557686862fbSopenharmony_ci    }
558686862fbSopenharmony_ci    if (BundleManagerInternal::IsSameAppId(callerInfo.callerAppId, targetAbility.bundleName)) {
559686862fbSopenharmony_ci        HILOGD("the appId is the same, check migration start control permission success!");
560686862fbSopenharmony_ci        return true;
561686862fbSopenharmony_ci    }
562686862fbSopenharmony_ci    HILOGE("the appId is different in the migration scenario, permission denied!");
563686862fbSopenharmony_ci    return false;
564686862fbSopenharmony_ci}
565686862fbSopenharmony_ci
566686862fbSopenharmony_cibool DistributedSchedPermission::CheckCollaborateStartCtrlPer(const AppExecFwk::AbilityInfo& targetAbility,
567686862fbSopenharmony_ci    const CallerInfo& callerInfo, const AAFwk::Want& want) const
568686862fbSopenharmony_ci{
569686862fbSopenharmony_ci    HILOGI("Check collaboration start control permission enter.");
570686862fbSopenharmony_ci    // 1. check background permission
571686862fbSopenharmony_ci    if (!CheckBackgroundPermission(targetAbility, callerInfo, want, true)) {
572686862fbSopenharmony_ci        HILOGE("Check background permission failed!");
573686862fbSopenharmony_ci        return false;
574686862fbSopenharmony_ci    }
575686862fbSopenharmony_ci    // 2. check device security level
576686862fbSopenharmony_ci    if (!targetAbility.visible &&
577686862fbSopenharmony_ci        !CheckDeviceSecurityLevel(callerInfo.sourceDeviceId, want.GetElement().GetDeviceID())) {
578686862fbSopenharmony_ci        HILOGE("check device security level failed!");
579686862fbSopenharmony_ci        return false;
580686862fbSopenharmony_ci    }
581686862fbSopenharmony_ci    // 3. check start or connect ability with same appid
582686862fbSopenharmony_ci    if (BundleManagerInternal::IsSameAppId(callerInfo.callerAppId, targetAbility.bundleName)) {
583686862fbSopenharmony_ci        HILOGD("the appId is the same, check permission success!");
584686862fbSopenharmony_ci        return true;
585686862fbSopenharmony_ci    }
586686862fbSopenharmony_ci    // 4. check if target ability is not visible and without PERMISSION_START_INVISIBLE_ABILITY
587686862fbSopenharmony_ci    if (!CheckTargetAbilityVisible(targetAbility, callerInfo)) {
588686862fbSopenharmony_ci        HILOGE("target ability is not visible and has no PERMISSION_START_INVISIBLE_ABILITY, permission denied!");
589686862fbSopenharmony_ci        return false;
590686862fbSopenharmony_ci    }
591686862fbSopenharmony_ci    // 5. check if service of fa mode can associatedWakeUp
592686862fbSopenharmony_ci    if (!targetAbility.isStageBasedModel && targetAbility.type == AppExecFwk::AbilityType::SERVICE &&
593686862fbSopenharmony_ci        !targetAbility.applicationInfo.associatedWakeUp) {
594686862fbSopenharmony_ci        HILOGE("target ability is service ability(FA) and associatedWakeUp is false, permission denied!");
595686862fbSopenharmony_ci        return false;
596686862fbSopenharmony_ci    }
597686862fbSopenharmony_ci    HILOGD("Check collaboration start control permission success");
598686862fbSopenharmony_ci    return true;
599686862fbSopenharmony_ci}
600686862fbSopenharmony_ci
601686862fbSopenharmony_cibool DistributedSchedPermission::CheckStartControlPermission(const AppExecFwk::AbilityInfo& targetAbility,
602686862fbSopenharmony_ci    const CallerInfo& callerInfo, const AAFwk::Want& want, bool isSameBundle)
603686862fbSopenharmony_ci{
604686862fbSopenharmony_ci    HILOGD("Check start control permission enter");
605686862fbSopenharmony_ci    return ((want.GetFlags() & AAFwk::Want::FLAG_ABILITY_CONTINUATION) != 0) ?
606686862fbSopenharmony_ci        CheckMigrateStartCtrlPer(targetAbility, callerInfo, want, isSameBundle) :
607686862fbSopenharmony_ci        CheckCollaborateStartCtrlPer(targetAbility, callerInfo, want);
608686862fbSopenharmony_ci}
609686862fbSopenharmony_ci
610686862fbSopenharmony_cibool DistributedSchedPermission::CheckBackgroundPermission(const AppExecFwk::AbilityInfo& targetAbility,
611686862fbSopenharmony_ci    const CallerInfo& callerInfo, const AAFwk::Want& want, bool needCheckApiVersion) const
612686862fbSopenharmony_ci{
613686862fbSopenharmony_ci    if (callerInfo.extraInfoJson.empty() ||
614686862fbSopenharmony_ci        callerInfo.extraInfoJson.find(DMS_VERSION_ID) == callerInfo.extraInfoJson.end()) {
615686862fbSopenharmony_ci        HILOGD("the version is low");
616686862fbSopenharmony_ci        return true;
617686862fbSopenharmony_ci    }
618686862fbSopenharmony_ci    AAFwk::Want* remoteWant = const_cast<Want*>(&want);
619686862fbSopenharmony_ci    bool isCallerBackGround = remoteWant->GetBoolParam(DMS_IS_CALLER_BACKGROUND, true);
620686862fbSopenharmony_ci    remoteWant->RemoveParam(DMS_IS_CALLER_BACKGROUND);
621686862fbSopenharmony_ci    if (!isCallerBackGround) {
622686862fbSopenharmony_ci        HILOGD("the app is foreground");
623686862fbSopenharmony_ci        return true;
624686862fbSopenharmony_ci    }
625686862fbSopenharmony_ci    int apiVersion = remoteWant->GetIntParam(DMS_API_VERSION, DEFAULT_DMS_API_VERSION);
626686862fbSopenharmony_ci    remoteWant->RemoveParam(DMS_API_VERSION);
627686862fbSopenharmony_ci    // service in fa mode(API 8) do not need check
628686862fbSopenharmony_ci    if (needCheckApiVersion && CheckMinApiVersion(targetAbility, apiVersion)) {
629686862fbSopenharmony_ci        HILOGD("the app is service ability of fa mode and is under api 8");
630686862fbSopenharmony_ci        return true;
631686862fbSopenharmony_ci    }
632686862fbSopenharmony_ci    uint32_t dAccessToken = AccessToken::AccessTokenKit::AllocLocalTokenID(callerInfo.sourceDeviceId,
633686862fbSopenharmony_ci        callerInfo.accessToken);
634686862fbSopenharmony_ci    if (dAccessToken == 0) {
635686862fbSopenharmony_ci        HILOGE("dAccessTokenID is invalid!");
636686862fbSopenharmony_ci        return false;
637686862fbSopenharmony_ci    }
638686862fbSopenharmony_ci    // check if background's ability has PERMISSION_START_ABILITIES_FROM_BACKGROUND
639686862fbSopenharmony_ci    if (CheckPermission(dAccessToken, PERMISSION_START_ABILITIES_FROM_BACKGROUND) == ERR_OK ||
640686862fbSopenharmony_ci        CheckPermission(dAccessToken, PERMISSION_START_ABILIIES_FROM_BACKGROUND) == ERR_OK) {
641686862fbSopenharmony_ci        HILOGD("the app has PERMISSION_START_ABILITIES_FROM_BACKGROUND");
642686862fbSopenharmony_ci        return true;
643686862fbSopenharmony_ci    }
644686862fbSopenharmony_ci    HILOGE("CheckBackgroundPermission failed!");
645686862fbSopenharmony_ci    return false;
646686862fbSopenharmony_ci}
647686862fbSopenharmony_ci
648686862fbSopenharmony_cibool DistributedSchedPermission::CheckMinApiVersion(const AppExecFwk::AbilityInfo& targetAbility,
649686862fbSopenharmony_ci    int32_t apiVersion) const
650686862fbSopenharmony_ci{
651686862fbSopenharmony_ci    if (!targetAbility.isStageBasedModel && targetAbility.type == AppExecFwk::AbilityType::SERVICE &&
652686862fbSopenharmony_ci        apiVersion <= FA_MODULE_ALLOW_MIN_API_VERSION) {
653686862fbSopenharmony_ci        HILOGD("CheckMinApiVersion pass");
654686862fbSopenharmony_ci        return true;
655686862fbSopenharmony_ci    }
656686862fbSopenharmony_ci    return false;
657686862fbSopenharmony_ci}
658686862fbSopenharmony_ci
659686862fbSopenharmony_cibool DistributedSchedPermission::CheckDeviceSecurityLevel(const std::string& srcDeviceId,
660686862fbSopenharmony_ci    const std::string& dstDeviceId) const
661686862fbSopenharmony_ci{
662686862fbSopenharmony_ci    std::string srcUdid = DnetworkAdapter::GetInstance()->GetUdidByNetworkId(srcDeviceId);
663686862fbSopenharmony_ci    if (srcUdid.empty()) {
664686862fbSopenharmony_ci        HILOGE("src udid is empty");
665686862fbSopenharmony_ci        return false;
666686862fbSopenharmony_ci    }
667686862fbSopenharmony_ci    std::string dstUdid = DnetworkAdapter::GetInstance()->GetUdidByNetworkId(dstDeviceId);
668686862fbSopenharmony_ci    if (dstUdid.empty()) {
669686862fbSopenharmony_ci        HILOGE("dst udid is empty");
670686862fbSopenharmony_ci        return false;
671686862fbSopenharmony_ci    }
672686862fbSopenharmony_ci    int32_t srcDeviceSecurityLevel = GetDeviceSecurityLevel(srcUdid);
673686862fbSopenharmony_ci    int32_t dstDeviceSecurityLevel = GetDeviceSecurityLevel(dstUdid);
674686862fbSopenharmony_ci    if (srcDeviceSecurityLevel == DEFAULT_DEVICE_SECURITY_LEVEL ||
675686862fbSopenharmony_ci        srcDeviceSecurityLevel < dstDeviceSecurityLevel) {
676686862fbSopenharmony_ci        HILOGE("the device security of source device is lower");
677686862fbSopenharmony_ci        return false;
678686862fbSopenharmony_ci    }
679686862fbSopenharmony_ci    return true;
680686862fbSopenharmony_ci}
681686862fbSopenharmony_ci
682686862fbSopenharmony_ciint32_t DistributedSchedPermission::GetDeviceSecurityLevel(const std::string& udid) const
683686862fbSopenharmony_ci{
684686862fbSopenharmony_ci    DeviceIdentify devIdentify;
685686862fbSopenharmony_ci    devIdentify.length = DEVICE_ID_MAX_LEN;
686686862fbSopenharmony_ci    int32_t ret = memcpy_s(devIdentify.identity, DEVICE_ID_MAX_LEN, udid.c_str(), udid.length());
687686862fbSopenharmony_ci    if (ret != 0) {
688686862fbSopenharmony_ci        HILOGE("str copy failed %{public}d", ret);
689686862fbSopenharmony_ci        return DEFAULT_DEVICE_SECURITY_LEVEL;
690686862fbSopenharmony_ci    }
691686862fbSopenharmony_ci    DeviceSecurityInfo *info = nullptr;
692686862fbSopenharmony_ci    ret = RequestDeviceSecurityInfo(&devIdentify, nullptr, &info);
693686862fbSopenharmony_ci    if (ret != SUCCESS) {
694686862fbSopenharmony_ci        HILOGE("request device security info failed %{public}d", ret);
695686862fbSopenharmony_ci        FreeDeviceSecurityInfo(info);
696686862fbSopenharmony_ci        info = nullptr;
697686862fbSopenharmony_ci        return DEFAULT_DEVICE_SECURITY_LEVEL;
698686862fbSopenharmony_ci    }
699686862fbSopenharmony_ci    int32_t level = 0;
700686862fbSopenharmony_ci    ret = GetDeviceSecurityLevelValue(info, &level);
701686862fbSopenharmony_ci    HILOGD("get device security level, level is %{public}d", level);
702686862fbSopenharmony_ci    FreeDeviceSecurityInfo(info);
703686862fbSopenharmony_ci    info = nullptr;
704686862fbSopenharmony_ci    if (ret != SUCCESS) {
705686862fbSopenharmony_ci        HILOGE("get device security level failed %{public}d", ret);
706686862fbSopenharmony_ci        return DEFAULT_DEVICE_SECURITY_LEVEL;
707686862fbSopenharmony_ci    }
708686862fbSopenharmony_ci    return level;
709686862fbSopenharmony_ci}
710686862fbSopenharmony_ci
711686862fbSopenharmony_cibool DistributedSchedPermission::CheckTargetAbilityVisible(const AppExecFwk::AbilityInfo& targetAbility,
712686862fbSopenharmony_ci    const CallerInfo& callerInfo) const
713686862fbSopenharmony_ci{
714686862fbSopenharmony_ci    if (targetAbility.visible) {
715686862fbSopenharmony_ci        HILOGD("Target ability is visible.");
716686862fbSopenharmony_ci        return true;
717686862fbSopenharmony_ci    }
718686862fbSopenharmony_ci    uint32_t dAccessToken = AccessToken::AccessTokenKit::AllocLocalTokenID(callerInfo.sourceDeviceId,
719686862fbSopenharmony_ci        callerInfo.accessToken);
720686862fbSopenharmony_ci    if (dAccessToken == 0) {
721686862fbSopenharmony_ci        HILOGE("dAccessTokenID is invalid!");
722686862fbSopenharmony_ci        return false;
723686862fbSopenharmony_ci    }
724686862fbSopenharmony_ci    if (CheckPermissionAll(dAccessToken, PERMISSION_START_INVISIBLE_ABILITY) != ERR_OK) {
725686862fbSopenharmony_ci        HILOGE("CheckTargetAbilityVisible failed.");
726686862fbSopenharmony_ci        return false;
727686862fbSopenharmony_ci    }
728686862fbSopenharmony_ci    HILOGD("CheckTargetAbilityVisible passed.");
729686862fbSopenharmony_ci    return true;
730686862fbSopenharmony_ci}
731686862fbSopenharmony_ci
732686862fbSopenharmony_civoid DistributedSchedPermission::RemoveRemoteObjectFromWant(std::shared_ptr<AAFwk::Want> want) const
733686862fbSopenharmony_ci{
734686862fbSopenharmony_ci    if (want == nullptr) {
735686862fbSopenharmony_ci        return;
736686862fbSopenharmony_ci    }
737686862fbSopenharmony_ci    WantParams wantParams = want->GetParams();
738686862fbSopenharmony_ci    std::map<std::string, sptr<IInterface>> params = wantParams.GetParams();
739686862fbSopenharmony_ci    for (auto param : params) {
740686862fbSopenharmony_ci        sptr<IInterface> object = param.second;
741686862fbSopenharmony_ci        IWantParams *wp = IWantParams::Query(object);
742686862fbSopenharmony_ci        if (wp == nullptr) {
743686862fbSopenharmony_ci            continue;
744686862fbSopenharmony_ci        }
745686862fbSopenharmony_ci        WantParams value = WantParamWrapper::Unbox(wp);
746686862fbSopenharmony_ci        auto type = value.GetParam(TYPE_PROPERTY);
747686862fbSopenharmony_ci        AAFwk::IString *typeP = AAFwk::IString::Query(type);
748686862fbSopenharmony_ci        if (typeP == nullptr) {
749686862fbSopenharmony_ci            continue;
750686862fbSopenharmony_ci        }
751686862fbSopenharmony_ci        std::string typeValue = AAFwk::String::Unbox(typeP);
752686862fbSopenharmony_ci        if (typeValue == REMOTE_OBJECT) {
753686862fbSopenharmony_ci            wantParams.Remove(param.first);
754686862fbSopenharmony_ci        }
755686862fbSopenharmony_ci    }
756686862fbSopenharmony_ci    want->SetParams(wantParams);
757686862fbSopenharmony_ci}
758686862fbSopenharmony_ci}
759686862fbSopenharmony_ci}
760