1686862fbSopenharmony_ci/*
2686862fbSopenharmony_ci * Copyright (c) 2022-2023 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_ability_manager_stub.h"
17686862fbSopenharmony_ci
18686862fbSopenharmony_ci#include <iosfwd>
19686862fbSopenharmony_ci#include <memory>
20686862fbSopenharmony_ci#include <string>
21686862fbSopenharmony_ci#include <utility>
22686862fbSopenharmony_ci
23686862fbSopenharmony_ci#include "accesstoken_kit.h"
24686862fbSopenharmony_ci#include "base/continuationmgr_log.h"
25686862fbSopenharmony_ci#include "base/parcel_helper.h"
26686862fbSopenharmony_ci#include "continuation_extra_params.h"
27686862fbSopenharmony_ci#include "device_connect_status.h"
28686862fbSopenharmony_ci#include "iremote_object.h"
29686862fbSopenharmony_ci#include "ipc_skeleton.h"
30686862fbSopenharmony_ci
31686862fbSopenharmony_cinamespace OHOS {
32686862fbSopenharmony_cinamespace DistributedSchedule {
33686862fbSopenharmony_ciusing namespace OHOS::Security;
34686862fbSopenharmony_cinamespace {
35686862fbSopenharmony_ciconst std::string TAG = "ContinuationManagerStub";
36686862fbSopenharmony_ciconst std::string PERMISSION_DISTRIBUTED_DATASYNC = "ohos.permission.DISTRIBUTED_DATASYNC";
37686862fbSopenharmony_ci}
38686862fbSopenharmony_ci
39686862fbSopenharmony_ciDistributedAbilityManagerStub::DistributedAbilityManagerStub()
40686862fbSopenharmony_ci{
41686862fbSopenharmony_ci    funcsMap_[static_cast<uint32_t>(IDAbilityManagerInterfaceCode::REGISTER)] =
42686862fbSopenharmony_ci        &DistributedAbilityManagerStub::RegisterInner;
43686862fbSopenharmony_ci    funcsMap_[static_cast<uint32_t>(IDAbilityManagerInterfaceCode::UNREGISTER)] =
44686862fbSopenharmony_ci        &DistributedAbilityManagerStub::UnregisterInner;
45686862fbSopenharmony_ci    funcsMap_[static_cast<uint32_t>(IDAbilityManagerInterfaceCode::REGISTER_DEVICE_SELECTION_CALLBACK)] =
46686862fbSopenharmony_ci        &DistributedAbilityManagerStub::RegisterDeviceSelectionCallbackInner;
47686862fbSopenharmony_ci    funcsMap_[static_cast<uint32_t>(IDAbilityManagerInterfaceCode::UNREGISTER_DEVICE_SELECTION_CALLBACK)] =
48686862fbSopenharmony_ci        &DistributedAbilityManagerStub::UnregisterDeviceSelectionCallbackInner;
49686862fbSopenharmony_ci    funcsMap_[static_cast<uint32_t>(IDAbilityManagerInterfaceCode::UPDATE_CONNECT_STATUS)] =
50686862fbSopenharmony_ci        &DistributedAbilityManagerStub::UpdateConnectStatusInner;
51686862fbSopenharmony_ci    funcsMap_[static_cast<uint32_t>(IDAbilityManagerInterfaceCode::START_DEVICE_MANAGER)] =
52686862fbSopenharmony_ci        &DistributedAbilityManagerStub::StartDeviceManagerInner;
53686862fbSopenharmony_ci}
54686862fbSopenharmony_ci
55686862fbSopenharmony_ciDistributedAbilityManagerStub::~DistributedAbilityManagerStub()
56686862fbSopenharmony_ci{
57686862fbSopenharmony_ci    funcsMap_.clear();
58686862fbSopenharmony_ci}
59686862fbSopenharmony_ci
60686862fbSopenharmony_ciint32_t DistributedAbilityManagerStub::OnRemoteRequest(uint32_t code, MessageParcel& data,
61686862fbSopenharmony_ci    MessageParcel& reply, MessageOption& option)
62686862fbSopenharmony_ci{
63686862fbSopenharmony_ci    HILOGI("code = %{public}u", code);
64686862fbSopenharmony_ci    auto iter = funcsMap_.find(code);
65686862fbSopenharmony_ci    if (iter != funcsMap_.end()) {
66686862fbSopenharmony_ci        auto func = iter->second;
67686862fbSopenharmony_ci        if (!EnforceInterfaceToken(data)) {
68686862fbSopenharmony_ci            HILOGE("interface token check failed!");
69686862fbSopenharmony_ci            return DMS_PERMISSION_DENIED;
70686862fbSopenharmony_ci        }
71686862fbSopenharmony_ci        uint32_t accessToken = IPCSkeleton::GetCallingTokenID();
72686862fbSopenharmony_ci        if (!VerifyPermission(accessToken, PERMISSION_DISTRIBUTED_DATASYNC)) {
73686862fbSopenharmony_ci            HILOGE("DISTRIBUTED_DATASYNC permission check failed!");
74686862fbSopenharmony_ci            return DMS_PERMISSION_DENIED;
75686862fbSopenharmony_ci        }
76686862fbSopenharmony_ci        if (func != nullptr) {
77686862fbSopenharmony_ci            return (this->*func)(data, reply);
78686862fbSopenharmony_ci        } else {
79686862fbSopenharmony_ci            HILOGE("func is nullptr");
80686862fbSopenharmony_ci            return ERR_NULL_OBJECT;
81686862fbSopenharmony_ci        }
82686862fbSopenharmony_ci    }
83686862fbSopenharmony_ci    return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
84686862fbSopenharmony_ci}
85686862fbSopenharmony_ci
86686862fbSopenharmony_cibool DistributedAbilityManagerStub::EnforceInterfaceToken(MessageParcel& data)
87686862fbSopenharmony_ci{
88686862fbSopenharmony_ci    std::u16string interfaceToken = data.ReadInterfaceToken();
89686862fbSopenharmony_ci    return interfaceToken == IDistributedAbilityManager::GetDescriptor();
90686862fbSopenharmony_ci}
91686862fbSopenharmony_ci
92686862fbSopenharmony_ciint32_t DistributedAbilityManagerStub::RegisterInner(MessageParcel& data, MessageParcel& reply)
93686862fbSopenharmony_ci{
94686862fbSopenharmony_ci    int32_t flag = VALUE_NULL;
95686862fbSopenharmony_ci    PARCEL_READ_HELPER(data, Int32, flag);
96686862fbSopenharmony_ci    int32_t token = -1;
97686862fbSopenharmony_ci    ContinuationExtraParams* continuationExtraParams = nullptr;
98686862fbSopenharmony_ci    if (flag == VALUE_OBJECT) {
99686862fbSopenharmony_ci        continuationExtraParams = data.ReadParcelable<ContinuationExtraParams>();
100686862fbSopenharmony_ci        if (continuationExtraParams == nullptr) {
101686862fbSopenharmony_ci            HILOGE("ContinuationExtraParams readParcelable failed!");
102686862fbSopenharmony_ci            return ERR_NULL_OBJECT;
103686862fbSopenharmony_ci        }
104686862fbSopenharmony_ci    }
105686862fbSopenharmony_ci    std::shared_ptr<ContinuationExtraParams> continuationExtraParamsPtr(continuationExtraParams);
106686862fbSopenharmony_ci    int32_t result = Register(continuationExtraParamsPtr, token);
107686862fbSopenharmony_ci    HILOGI("result = %{public}d", result);
108686862fbSopenharmony_ci    PARCEL_WRITE_HELPER(reply, Int32, result);
109686862fbSopenharmony_ci    PARCEL_WRITE_HELPER(reply, Int32, token);
110686862fbSopenharmony_ci    return ERR_NONE;
111686862fbSopenharmony_ci}
112686862fbSopenharmony_ci
113686862fbSopenharmony_ciint32_t DistributedAbilityManagerStub::UnregisterInner(MessageParcel& data, MessageParcel& reply)
114686862fbSopenharmony_ci{
115686862fbSopenharmony_ci    int32_t token = -1;
116686862fbSopenharmony_ci    PARCEL_READ_HELPER(data, Int32, token);
117686862fbSopenharmony_ci    int32_t result = Unregister(token);
118686862fbSopenharmony_ci    HILOGI("result = %{public}d", result);
119686862fbSopenharmony_ci    PARCEL_WRITE_HELPER(reply, Int32, result);
120686862fbSopenharmony_ci    return ERR_NONE;
121686862fbSopenharmony_ci}
122686862fbSopenharmony_ci
123686862fbSopenharmony_ciint32_t DistributedAbilityManagerStub::RegisterDeviceSelectionCallbackInner(MessageParcel& data, MessageParcel& reply)
124686862fbSopenharmony_ci{
125686862fbSopenharmony_ci    int32_t token = -1;
126686862fbSopenharmony_ci    PARCEL_READ_HELPER(data, Int32, token);
127686862fbSopenharmony_ci    std::string cbType;
128686862fbSopenharmony_ci    PARCEL_READ_HELPER(data, String, cbType);
129686862fbSopenharmony_ci    if (cbType.empty()) {
130686862fbSopenharmony_ci        HILOGE("cbType unmarshalling failed!");
131686862fbSopenharmony_ci        return ERR_NULL_OBJECT;
132686862fbSopenharmony_ci    }
133686862fbSopenharmony_ci    sptr<IRemoteObject> notifier = data.ReadRemoteObject();
134686862fbSopenharmony_ci    if (notifier == nullptr) {
135686862fbSopenharmony_ci        HILOGE("notifier unmarshalling failed!");
136686862fbSopenharmony_ci        return ERR_NULL_OBJECT;
137686862fbSopenharmony_ci    }
138686862fbSopenharmony_ci    int32_t result = RegisterDeviceSelectionCallback(token, cbType, notifier);
139686862fbSopenharmony_ci    HILOGI("result = %{public}d", result);
140686862fbSopenharmony_ci    PARCEL_WRITE_HELPER(reply, Int32, result);
141686862fbSopenharmony_ci    return ERR_NONE;
142686862fbSopenharmony_ci}
143686862fbSopenharmony_ci
144686862fbSopenharmony_ciint32_t DistributedAbilityManagerStub::UnregisterDeviceSelectionCallbackInner(MessageParcel& data,
145686862fbSopenharmony_ci    MessageParcel& reply)
146686862fbSopenharmony_ci{
147686862fbSopenharmony_ci    int32_t token = -1;
148686862fbSopenharmony_ci    PARCEL_READ_HELPER(data, Int32, token);
149686862fbSopenharmony_ci    std::string cbType;
150686862fbSopenharmony_ci    PARCEL_READ_HELPER(data, String, cbType);
151686862fbSopenharmony_ci    if (cbType.empty()) {
152686862fbSopenharmony_ci        HILOGE("cbType unmarshalling failed!");
153686862fbSopenharmony_ci        return ERR_NULL_OBJECT;
154686862fbSopenharmony_ci    }
155686862fbSopenharmony_ci    int32_t result = UnregisterDeviceSelectionCallback(token, cbType);
156686862fbSopenharmony_ci    HILOGI("result = %{public}d", result);
157686862fbSopenharmony_ci    PARCEL_WRITE_HELPER(reply, Int32, result);
158686862fbSopenharmony_ci    return ERR_NONE;
159686862fbSopenharmony_ci}
160686862fbSopenharmony_ci
161686862fbSopenharmony_ciint32_t DistributedAbilityManagerStub::UpdateConnectStatusInner(MessageParcel& data, MessageParcel& reply)
162686862fbSopenharmony_ci{
163686862fbSopenharmony_ci    int32_t token = -1;
164686862fbSopenharmony_ci    PARCEL_READ_HELPER(data, Int32, token);
165686862fbSopenharmony_ci    std::string deviceId;
166686862fbSopenharmony_ci    PARCEL_READ_HELPER(data, String, deviceId);
167686862fbSopenharmony_ci    DeviceConnectStatus deviceConnectStatus = static_cast<DeviceConnectStatus>(data.ReadInt32());
168686862fbSopenharmony_ci    int32_t result = UpdateConnectStatus(token, deviceId, deviceConnectStatus);
169686862fbSopenharmony_ci    HILOGI("result = %{public}d", result);
170686862fbSopenharmony_ci    PARCEL_WRITE_HELPER(reply, Int32, result);
171686862fbSopenharmony_ci    return ERR_NONE;
172686862fbSopenharmony_ci}
173686862fbSopenharmony_ci
174686862fbSopenharmony_ciint32_t DistributedAbilityManagerStub::StartDeviceManagerInner(MessageParcel& data, MessageParcel& reply)
175686862fbSopenharmony_ci{
176686862fbSopenharmony_ci    int32_t token = -1;
177686862fbSopenharmony_ci    PARCEL_READ_HELPER(data, Int32, token);
178686862fbSopenharmony_ci    int32_t flag = VALUE_NULL;
179686862fbSopenharmony_ci    PARCEL_READ_HELPER(data, Int32, flag);
180686862fbSopenharmony_ci    ContinuationExtraParams* continuationExtraParams = nullptr;
181686862fbSopenharmony_ci    if (flag == VALUE_OBJECT) {
182686862fbSopenharmony_ci        continuationExtraParams = data.ReadParcelable<ContinuationExtraParams>();
183686862fbSopenharmony_ci        if (continuationExtraParams == nullptr) {
184686862fbSopenharmony_ci            HILOGE("ContinuationExtraParams readParcelable failed!");
185686862fbSopenharmony_ci            return ERR_NULL_OBJECT;
186686862fbSopenharmony_ci        }
187686862fbSopenharmony_ci    }
188686862fbSopenharmony_ci    std::shared_ptr<ContinuationExtraParams> continuationExtraParamsPtr(continuationExtraParams);
189686862fbSopenharmony_ci    int32_t result = StartDeviceManager(token, continuationExtraParamsPtr);
190686862fbSopenharmony_ci    HILOGI("result = %{public}d", result);
191686862fbSopenharmony_ci    PARCEL_WRITE_HELPER(reply, Int32, result);
192686862fbSopenharmony_ci    return ERR_NONE;
193686862fbSopenharmony_ci}
194686862fbSopenharmony_ci
195686862fbSopenharmony_cibool DistributedAbilityManagerStub::VerifyPermission(uint32_t accessToken, const std::string& permissionName) const
196686862fbSopenharmony_ci{
197686862fbSopenharmony_ci    int32_t result = AccessToken::AccessTokenKit::VerifyAccessToken(accessToken, permissionName);
198686862fbSopenharmony_ci    if (result == AccessToken::PermissionState::PERMISSION_DENIED) {
199686862fbSopenharmony_ci        HILOGE("permission denied, permissionName:%{public}s", permissionName.c_str());
200686862fbSopenharmony_ci        return false;
201686862fbSopenharmony_ci    }
202686862fbSopenharmony_ci    HILOGD("permission matched.");
203686862fbSopenharmony_ci    return true;
204686862fbSopenharmony_ci}
205686862fbSopenharmony_ci
206686862fbSopenharmony_ci} // namespace DistributedSchedule
207686862fbSopenharmony_ci} // namespace OHOS