1686862fbSopenharmony_ci/*
2686862fbSopenharmony_ci * Copyright (c) 2022 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 "dms_token_callback.h"
17686862fbSopenharmony_ci
18686862fbSopenharmony_ci#include "accesstoken_kit.h"
19686862fbSopenharmony_ci#include "bundle/bundle_manager_internal.h"
20686862fbSopenharmony_ci#include "distributed_sched_permission.h"
21686862fbSopenharmony_ci#include "distributed_sched_service.h"
22686862fbSopenharmony_ci#include "distributed_sched_utils.h"
23686862fbSopenharmony_ci#include "dtbschedmgr_device_info_storage.h"
24686862fbSopenharmony_ci#include "dtbschedmgr_log.h"
25686862fbSopenharmony_ci#include "ipc_skeleton.h"
26686862fbSopenharmony_ci#include "iservice_registry.h"
27686862fbSopenharmony_ci#include "parcel_helper.h"
28686862fbSopenharmony_ci#include "system_ability.h"
29686862fbSopenharmony_ci#include "system_ability_definition.h"
30686862fbSopenharmony_ci
31686862fbSopenharmony_ciusing namespace OHOS::Security;
32686862fbSopenharmony_ci
33686862fbSopenharmony_cinamespace OHOS {
34686862fbSopenharmony_cinamespace DistributedSchedule {
35686862fbSopenharmony_ciconst std::string TAG = "DmsTokenCallback";
36686862fbSopenharmony_ciconst std::string FOUNDATION_PROCESS_NAME = "foundation";
37686862fbSopenharmony_ciconst std::string DMS_SRC_NETWORK_ID = "dmsSrcNetworkId";
38686862fbSopenharmony_ci
39686862fbSopenharmony_ciint32_t DmsTokenCallback::SendResult(OHOS::AAFwk::Want& want, int32_t callerUid,
40686862fbSopenharmony_ci    int32_t requestCode, uint32_t accessToken, int32_t resultCode)
41686862fbSopenharmony_ci{
42686862fbSopenharmony_ci    AccessToken::NativeTokenInfo nativeTokenInfo;
43686862fbSopenharmony_ci    int32_t ret = AccessToken::AccessTokenKit::GetNativeTokenInfo(IPCSkeleton::GetCallingTokenID(),
44686862fbSopenharmony_ci        nativeTokenInfo);
45686862fbSopenharmony_ci    if (ret != ERR_OK || nativeTokenInfo.processName != FOUNDATION_PROCESS_NAME) {
46686862fbSopenharmony_ci        HILOGE("check foundation call failed");
47686862fbSopenharmony_ci        return INVALID_PARAMETERS_ERR;
48686862fbSopenharmony_ci    }
49686862fbSopenharmony_ci    std::string localDeviceId;
50686862fbSopenharmony_ci    std::string deviceId = want.GetStringParam(DMS_SRC_NETWORK_ID);
51686862fbSopenharmony_ci    if (!GetLocalDeviceId(localDeviceId) || !CheckDeviceId(localDeviceId, deviceId)) {
52686862fbSopenharmony_ci        HILOGE("check deviceId failed");
53686862fbSopenharmony_ci        return INVALID_PARAMETERS_ERR;
54686862fbSopenharmony_ci    }
55686862fbSopenharmony_ci    sptr<IDistributedSched> remoteDms = GetRemoteDms(deviceId);
56686862fbSopenharmony_ci    if (remoteDms == nullptr) {
57686862fbSopenharmony_ci        HILOGE("get remoteDms failed");
58686862fbSopenharmony_ci        return INVALID_PARAMETERS_ERR;
59686862fbSopenharmony_ci    }
60686862fbSopenharmony_ci    nlohmann::json extraInfoJson;
61686862fbSopenharmony_ci    CallerInfo callerInfo = {.uid = callerUid, .sourceDeviceId = localDeviceId, .accessToken = accessToken,
62686862fbSopenharmony_ci        .extraInfoJson = extraInfoJson};
63686862fbSopenharmony_ci    if (!BundleManagerInternal::GetCallerAppIdFromBms(callerInfo.uid, callerInfo.callerAppId)) {
64686862fbSopenharmony_ci        HILOGE("GetCallerAppIdFromBms failed");
65686862fbSopenharmony_ci        return INVALID_PARAMETERS_ERR;
66686862fbSopenharmony_ci    }
67686862fbSopenharmony_ci    if (!BundleManagerInternal::GetBundleNameListFromBms(callerInfo.uid, callerInfo.bundleNames)) {
68686862fbSopenharmony_ci        HILOGE("GetBundleNameListFromBms failed");
69686862fbSopenharmony_ci        return INVALID_PARAMETERS_ERR;
70686862fbSopenharmony_ci    }
71686862fbSopenharmony_ci    AccountInfo accountInfo;
72686862fbSopenharmony_ci    ret = DistributedSchedPermission::GetInstance().GetAccountInfo(deviceId, callerInfo, accountInfo);
73686862fbSopenharmony_ci    if (ret != ERR_OK) {
74686862fbSopenharmony_ci        HILOGE("GetAccountInfo failed");
75686862fbSopenharmony_ci        return ret;
76686862fbSopenharmony_ci    }
77686862fbSopenharmony_ci    HILOGI("[PerformanceTest] SendResult transact begin");
78686862fbSopenharmony_ci    int32_t result = remoteDms->SendResultFromRemote(want, requestCode, callerInfo, accountInfo, resultCode);
79686862fbSopenharmony_ci    HILOGI("[PerformanceTest] SendResult transact end");
80686862fbSopenharmony_ci    return result;
81686862fbSopenharmony_ci}
82686862fbSopenharmony_ci
83686862fbSopenharmony_cibool DmsTokenCallback::GetLocalDeviceId(std::string& localDeviceId)
84686862fbSopenharmony_ci{
85686862fbSopenharmony_ci    if (!DtbschedmgrDeviceInfoStorage::GetInstance().GetLocalDeviceId(localDeviceId)) {
86686862fbSopenharmony_ci        HILOGE("GetLocalDeviceId failed");
87686862fbSopenharmony_ci        return false;
88686862fbSopenharmony_ci    }
89686862fbSopenharmony_ci    return true;
90686862fbSopenharmony_ci}
91686862fbSopenharmony_ci
92686862fbSopenharmony_cibool DmsTokenCallback::CheckDeviceId(const std::string& localDeviceId, const std::string& remoteDeviceId)
93686862fbSopenharmony_ci{
94686862fbSopenharmony_ci    // remoteDeviceId must not same with localDeviceId
95686862fbSopenharmony_ci    if (localDeviceId.empty() || remoteDeviceId.empty() || localDeviceId == remoteDeviceId) {
96686862fbSopenharmony_ci        HILOGE("check deviceId failed");
97686862fbSopenharmony_ci        return false;
98686862fbSopenharmony_ci    }
99686862fbSopenharmony_ci    return true;
100686862fbSopenharmony_ci}
101686862fbSopenharmony_ci
102686862fbSopenharmony_cisptr<IDistributedSched> DmsTokenCallback::GetRemoteDms(const std::string& remoteDeviceId)
103686862fbSopenharmony_ci{
104686862fbSopenharmony_ci    if (remoteDeviceId.empty()) {
105686862fbSopenharmony_ci        HILOGE("GetRemoteDms remoteDeviceId is empty");
106686862fbSopenharmony_ci        return nullptr;
107686862fbSopenharmony_ci    }
108686862fbSopenharmony_ci    HILOGD("GetRemoteDms connect deviceid is %s", GetAnonymStr(remoteDeviceId).c_str());
109686862fbSopenharmony_ci    auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
110686862fbSopenharmony_ci    if (samgr == nullptr) {
111686862fbSopenharmony_ci        HILOGE("GetRemoteDms failed to connect to systemAbilityMgr!");
112686862fbSopenharmony_ci        return nullptr;
113686862fbSopenharmony_ci    }
114686862fbSopenharmony_ci    HILOGD("[PerformanceTest] GetRemoteDms begin");
115686862fbSopenharmony_ci    auto object = samgr->CheckSystemAbility(DISTRIBUTED_SCHED_SA_ID, remoteDeviceId);
116686862fbSopenharmony_ci    HILOGD("[PerformanceTest] GetRemoteDms end");
117686862fbSopenharmony_ci    if (object == nullptr) {
118686862fbSopenharmony_ci        HILOGE("GetRemoteDms failed to get remote DistributedSched %{private}s", GetAnonymStr(remoteDeviceId).c_str());
119686862fbSopenharmony_ci        return nullptr;
120686862fbSopenharmony_ci    }
121686862fbSopenharmony_ci    return iface_cast<IDistributedSched>(object);
122686862fbSopenharmony_ci}
123686862fbSopenharmony_ci} // namespace Distributedschedule
124686862fbSopenharmony_ci} // namespace OHOS