1 /*
2 * Copyright (c) 2022 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 #include "distributed_ability_manager_stub.h"
17
18 #include <iosfwd>
19 #include <memory>
20 #include <string>
21 #include <utility>
22
23 #include "accesstoken_kit.h"
24 #include "continuation_extra_params.h"
25 #include "device_connect_status.h"
26 #include "dtbschedmgr_log.h"
27 #include "iremote_object.h"
28 #include "parcel_helper.h"
29 #include "ipc_skeleton.h"
30
31 namespace OHOS {
32 namespace DistributedSchedule {
33 using namespace OHOS::Security;
34 namespace {
35 const std::string TAG = "DistributedAbilityManagerStub";
36 const std::string PERMISSION_DISTRIBUTED_DATASYNC = "ohos.permission.DISTRIBUTED_DATASYNC";
37 const std::u16string DMS_STUB_INTERFACE_TOKEN = u"ohos.distributedschedule.accessToken";
38 constexpr int32_t GET_DISTRIBUTED_COMPONENT_LIST_REQUEST_CODE = 161;
39 }
40
DistributedAbilityManagerStub()41 DistributedAbilityManagerStub::DistributedAbilityManagerStub()
42 {
43 funcsMap_[REGISTER] = &DistributedAbilityManagerStub::RegisterInner;
44 funcsMap_[UNREGISTER] = &DistributedAbilityManagerStub::UnregisterInner;
45 funcsMap_[REGISTER_DEVICE_SELECTION_CALLBACK] =
46 &DistributedAbilityManagerStub::RegisterDeviceSelectionCallbackInner;
47 funcsMap_[UNREGISTER_DEVICE_SELECTION_CALLBACK] =
48 &DistributedAbilityManagerStub::UnregisterDeviceSelectionCallbackInner;
49 funcsMap_[UPDATE_CONNECT_STATUS] = &DistributedAbilityManagerStub::UpdateConnectStatusInner;
50 funcsMap_[START_DEVICE_MANAGER] = &DistributedAbilityManagerStub::StartDeviceManagerInner;
51
52 distributedFuncMap_[GET_DISTRIBUTED_COMPONENT_LIST_REQUEST_CODE] =
53 &DistributedAbilityManagerStub::GetDistributedComponentListInner;
54 }
55
~DistributedAbilityManagerStub()56 DistributedAbilityManagerStub::~DistributedAbilityManagerStub()
57 {
58 funcsMap_.clear();
59 distributedFuncMap_.clear();
60 }
61
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)62 int32_t DistributedAbilityManagerStub::OnRemoteRequest(uint32_t code, MessageParcel& data,
63 MessageParcel& reply, MessageOption& option)
64 {
65 HILOGI("code = %{public}u", code);
66 auto iter = funcsMap_.find(code);
67 if (iter != funcsMap_.end()) {
68 auto func = iter->second;
69 if (!EnforceInterfaceToken(data)) {
70 HILOGE("interface token check failed!");
71 return DMS_PERMISSION_DENIED;
72 }
73 uint32_t accessToken = IPCSkeleton::GetCallingTokenID();
74 if (!VerifyPermission(accessToken, PERMISSION_DISTRIBUTED_DATASYNC)) {
75 HILOGE("DISTRIBUTED_DATASYNC permission check failed!");
76 return DMS_PERMISSION_DENIED;
77 }
78 if (func != nullptr) {
79 return (this->*func)(data, reply);
80 } else {
81 HILOGE("func is nullptr");
82 return ERR_NULL_OBJECT;
83 }
84 }
85 auto distributedFuncIter = distributedFuncMap_.find(code);
86 if (distributedFuncIter != distributedFuncMap_.end()) {
87 auto func = distributedFuncIter->second;
88 if (func != nullptr) {
89 return (this->*func)(data, reply, option);
90 } else {
91 HILOGE("func is nullptr");
92 return ERR_NULL_OBJECT;
93 }
94 }
95 return SendRequestToImpl(code, data, reply, option);
96 }
97
EnforceInterfaceToken(MessageParcel & data)98 bool DistributedAbilityManagerStub::EnforceInterfaceToken(MessageParcel& data)
99 {
100 std::u16string interfaceToken = data.ReadInterfaceToken();
101 return interfaceToken == DMS_STUB_INTERFACE_TOKEN;
102 }
103
RegisterInner(MessageParcel & data,MessageParcel & reply)104 int32_t DistributedAbilityManagerStub::RegisterInner(MessageParcel& data, MessageParcel& reply)
105 {
106 int32_t flag = VALUE_NULL;
107 PARCEL_READ_HELPER(data, Int32, flag);
108 int32_t token = -1;
109 ContinuationExtraParams* continuationExtraParams = nullptr;
110 if (flag == VALUE_OBJECT) {
111 continuationExtraParams = data.ReadParcelable<ContinuationExtraParams>();
112 if (continuationExtraParams == nullptr) {
113 HILOGE("ContinuationExtraParams readParcelable failed!");
114 return ERR_NULL_OBJECT;
115 }
116 }
117 std::shared_ptr<ContinuationExtraParams> continuationExtraParamsPtr(continuationExtraParams);
118 int32_t result = Register(continuationExtraParamsPtr, token);
119 HILOGI("result = %{public}d", result);
120 PARCEL_WRITE_HELPER(reply, Int32, result);
121 PARCEL_WRITE_HELPER(reply, Int32, token);
122 return ERR_NONE;
123 }
124
UnregisterInner(MessageParcel & data,MessageParcel & reply)125 int32_t DistributedAbilityManagerStub::UnregisterInner(MessageParcel& data, MessageParcel& reply)
126 {
127 int32_t token = -1;
128 PARCEL_READ_HELPER(data, Int32, token);
129 int32_t result = Unregister(token);
130 HILOGI("result = %{public}d", result);
131 PARCEL_WRITE_HELPER(reply, Int32, result);
132 return ERR_NONE;
133 }
134
RegisterDeviceSelectionCallbackInner(MessageParcel & data,MessageParcel & reply)135 int32_t DistributedAbilityManagerStub::RegisterDeviceSelectionCallbackInner(MessageParcel& data, MessageParcel& reply)
136 {
137 int32_t token = -1;
138 PARCEL_READ_HELPER(data, Int32, token);
139 std::string cbType;
140 PARCEL_READ_HELPER(data, String, cbType);
141 if (cbType.empty()) {
142 HILOGE("cbType unmarshalling failed!");
143 return ERR_NULL_OBJECT;
144 }
145 sptr<IRemoteObject> notifier = data.ReadRemoteObject();
146 if (notifier == nullptr) {
147 HILOGE("notifier unmarshalling failed!");
148 return ERR_NULL_OBJECT;
149 }
150 int32_t result = RegisterDeviceSelectionCallback(token, cbType, notifier);
151 HILOGI("result = %{public}d", result);
152 PARCEL_WRITE_HELPER(reply, Int32, result);
153 return ERR_NONE;
154 }
155
UnregisterDeviceSelectionCallbackInner(MessageParcel & data,MessageParcel & reply)156 int32_t DistributedAbilityManagerStub::UnregisterDeviceSelectionCallbackInner(MessageParcel& data,
157 MessageParcel& reply)
158 {
159 int32_t token = -1;
160 PARCEL_READ_HELPER(data, Int32, token);
161 std::string cbType;
162 PARCEL_READ_HELPER(data, String, cbType);
163 if (cbType.empty()) {
164 HILOGE("cbType unmarshalling failed!");
165 return ERR_NULL_OBJECT;
166 }
167 int32_t result = UnregisterDeviceSelectionCallback(token, cbType);
168 HILOGI("result = %{public}d", result);
169 PARCEL_WRITE_HELPER(reply, Int32, result);
170 return ERR_NONE;
171 }
172
UpdateConnectStatusInner(MessageParcel & data,MessageParcel & reply)173 int32_t DistributedAbilityManagerStub::UpdateConnectStatusInner(MessageParcel& data, MessageParcel& reply)
174 {
175 int32_t token = -1;
176 PARCEL_READ_HELPER(data, Int32, token);
177 std::string deviceId;
178 PARCEL_READ_HELPER(data, String, deviceId);
179 DeviceConnectStatus deviceConnectStatus = static_cast<DeviceConnectStatus>(data.ReadInt32());
180 int32_t result = UpdateConnectStatus(token, deviceId, deviceConnectStatus);
181 HILOGI("result = %{public}d", result);
182 PARCEL_WRITE_HELPER(reply, Int32, result);
183 return ERR_NONE;
184 }
185
StartDeviceManagerInner(MessageParcel & data,MessageParcel & reply)186 int32_t DistributedAbilityManagerStub::StartDeviceManagerInner(MessageParcel& data, MessageParcel& reply)
187 {
188 int32_t token = -1;
189 PARCEL_READ_HELPER(data, Int32, token);
190 int32_t flag = VALUE_NULL;
191 PARCEL_READ_HELPER(data, Int32, flag);
192 ContinuationExtraParams* continuationExtraParams = nullptr;
193 if (flag == VALUE_OBJECT) {
194 continuationExtraParams = data.ReadParcelable<ContinuationExtraParams>();
195 if (continuationExtraParams == nullptr) {
196 HILOGE("ContinuationExtraParams readParcelable failed!");
197 return ERR_NULL_OBJECT;
198 }
199 }
200 std::shared_ptr<ContinuationExtraParams> continuationExtraParamsPtr(continuationExtraParams);
201 int32_t result = StartDeviceManager(token, continuationExtraParamsPtr);
202 HILOGI("result = %{public}d", result);
203 PARCEL_WRITE_HELPER(reply, Int32, result);
204 return ERR_NONE;
205 }
206
GetDistributedComponentListInner(MessageParcel & data,MessageParcel & reply,MessageOption & option)207 int32_t DistributedAbilityManagerStub::GetDistributedComponentListInner(MessageParcel& data,
208 MessageParcel& reply, MessageOption& option)
209 {
210 if (IsDistributedSchedLoaded()) {
211 return SendRequestToImpl(GET_DISTRIBUTED_COMPONENT_LIST_REQUEST_CODE, data, reply, option);
212 }
213 if (!EnforceInterfaceToken(data)) {
214 HILOGE("interface token check failed!");
215 return DMS_PERMISSION_DENIED;
216 }
217 HILOGI("DistributedSched is not loaded, return empty");
218 PARCEL_WRITE_HELPER(reply, Int32, ERR_NONE);
219 std::vector<std::string> distributedComponents;
220 PARCEL_WRITE_HELPER(reply, StringVector, distributedComponents);
221 return ERR_NONE;
222 }
223
VerifyPermission(uint32_t accessToken,const std::string & permissionName) const224 bool DistributedAbilityManagerStub::VerifyPermission(uint32_t accessToken, const std::string& permissionName) const
225 {
226 int32_t result = AccessToken::AccessTokenKit::VerifyAccessToken(accessToken, permissionName);
227 if (result == AccessToken::PermissionState::PERMISSION_DENIED) {
228 HILOGE("permission denied, permissionName:%{public}s", permissionName.c_str());
229 return false;
230 }
231 HILOGD("permission matched.");
232 return true;
233 }
234
235 } // namespace DistributedSchedule
236 } // namespace OHOS