• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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