1 /*
2 * Copyright (c) 2021-2024 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_hardware_stub.h"
17
18 #include <cinttypes>
19
20 #include "accesstoken_kit.h"
21 #include "ipc_skeleton.h"
22 #include "tokenid_kit.h"
23
24 #include "device_manager.h"
25
26 #include "anonymous_string.h"
27 #include "constants.h"
28 #include "dhardware_ipc_interface_code.h"
29 #include "dh_context.h"
30 #include "dh_utils_tool.h"
31 #include "distributed_hardware_errno.h"
32 #include "distributed_hardware_log.h"
33 #include "publisher_listener_proxy.h"
34
35 namespace OHOS {
36 namespace DistributedHardware {
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)37 int32_t DistributedHardwareStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
38 MessageOption &option)
39 {
40 if (data.ReadInterfaceToken() != GetDescriptor()) {
41 DHLOGE("IPC Token valid fail!");
42 return ERR_INVALID_DATA;
43 }
44 switch (code) {
45 case static_cast<uint32_t>(DHMsgInterfaceCode::REG_PUBLISHER_LISTNER): {
46 return RegisterPublisherListenerInner(data, reply);
47 }
48 case static_cast<uint32_t>(DHMsgInterfaceCode::UNREG_PUBLISHER_LISTENER): {
49 return UnregisterPublisherListenerInner(data, reply);
50 }
51 case static_cast<uint32_t>(DHMsgInterfaceCode::PUBLISH_MESSAGE): {
52 return PublishMessageInner(data, reply);
53 }
54 case static_cast<uint32_t>(DHMsgInterfaceCode::INIT_CTL_CEN): {
55 return InitializeAVCenterInner(data, reply);
56 }
57 case static_cast<uint32_t>(DHMsgInterfaceCode::RELEASE_CTL_CEN): {
58 return ReleaseAVCenterInner(data, reply);
59 }
60 case static_cast<uint32_t>(DHMsgInterfaceCode::CREATE_CTL_CEN_CHANNEL): {
61 return CreateControlChannelInner(data, reply);
62 }
63 case static_cast<uint32_t>(DHMsgInterfaceCode::NOTIFY_AV_EVENT): {
64 return NotifyAVCenterInner(data, reply);
65 }
66 case static_cast<uint32_t>(DHMsgInterfaceCode::REGISTER_CTL_CEN_CALLBACK): {
67 return RegisterControlCenterCallbackInner(data, reply);
68 }
69 case static_cast<uint32_t>(DHMsgInterfaceCode::QUERY_LOCAL_SYS_SPEC): {
70 return QueryLocalSysSpecInner(data, reply);
71 }
72 case static_cast<uint32_t>(DHMsgInterfaceCode::NOTIFY_SOURCE_DEVICE_REMOTE_DMSDP_STARTED): {
73 return HandleNotifySourceRemoteSinkStarted(data, reply);
74 }
75 case static_cast<uint32_t>(DHMsgInterfaceCode::PAUSE_DISTRIBUTED_HARDWARE): {
76 return PauseDistributedHardwareInner(data, reply);
77 }
78 case static_cast<uint32_t>(DHMsgInterfaceCode::RESUME_DISTRIBUTED_HARDWARE): {
79 return ResumeDistributedHardwareInner(data, reply);
80 }
81 case static_cast<uint32_t>(DHMsgInterfaceCode::STOP_DISTRIBUTED_HARDWARE): {
82 return StopDistributedHardwareInner(data, reply);
83 }
84 default:
85 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
86 }
87 return DH_FWK_SUCCESS;
88 }
89
RegisterPublisherListenerInner(MessageParcel & data,MessageParcel & reply)90 int32_t DistributedHardwareStub::RegisterPublisherListenerInner(MessageParcel &data, MessageParcel &reply)
91 {
92 if (!HasAccessDHPermission()) {
93 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
94 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
95 }
96
97 uint32_t topicInt = data.ReadUint32();
98 if (!ValidTopic(topicInt)) {
99 DHLOGE("Topic invalid: %{public}" PRIu32, topicInt);
100 reply.WriteInt32(ERR_DH_FWK_PARA_INVALID);
101 return ERR_DH_FWK_PARA_INVALID;
102 }
103
104 DHTopic topic = (DHTopic)topicInt;
105 sptr<IPublisherListener> listener = iface_cast<IPublisherListener>(data.ReadRemoteObject());
106 if (listener == nullptr) {
107 DHLOGE("Register publisher listener is null");
108 reply.WriteInt32(ERR_DH_FWK_PARA_INVALID);
109 return ERR_DH_FWK_PARA_INVALID;
110 }
111 DHLOGI("Register listener, topic: %{public}" PRIu32, (uint32_t)topic);
112 RegisterPublisherListener(topic, listener);
113 reply.WriteInt32(DH_FWK_SUCCESS);
114 return DH_FWK_SUCCESS;
115 }
116
UnregisterPublisherListenerInner(MessageParcel & data,MessageParcel & reply)117 int32_t DistributedHardwareStub::UnregisterPublisherListenerInner(MessageParcel &data, MessageParcel &reply)
118 {
119 if (!HasAccessDHPermission()) {
120 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
121 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
122 }
123
124 uint32_t topicInt = data.ReadUint32();
125 if (!ValidTopic(topicInt)) {
126 DHLOGE("Topic invalid: %{public}" PRIu32, topicInt);
127 reply.WriteInt32(ERR_DH_FWK_PARA_INVALID);
128 return ERR_DH_FWK_PARA_INVALID;
129 }
130
131 DHTopic topic = (DHTopic)topicInt;
132 sptr<IPublisherListener> listener = iface_cast<IPublisherListener>(data.ReadRemoteObject());
133 if (listener == nullptr) {
134 DHLOGE("Unregister publisher listener is null");
135 reply.WriteInt32(ERR_DH_FWK_PARA_INVALID);
136 return ERR_DH_FWK_PARA_INVALID;
137 }
138 DHLOGI("Unregister listener, topic: %{public}" PRIu32, (uint32_t)topic);
139 UnregisterPublisherListener(topic, listener);
140 reply.WriteInt32(DH_FWK_SUCCESS);
141 return DH_FWK_SUCCESS;
142 }
143
PublishMessageInner(MessageParcel & data,MessageParcel & reply)144 int32_t DistributedHardwareStub::PublishMessageInner(MessageParcel &data, MessageParcel &reply)
145 {
146 if (!HasAccessDHPermission()) {
147 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
148 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
149 }
150
151 uint32_t topicInt = data.ReadUint32();
152 if (!ValidTopic(topicInt)) {
153 DHLOGE("Topic invalid: %{public}" PRIu32, topicInt);
154 reply.WriteInt32(ERR_DH_FWK_PARA_INVALID);
155 return ERR_DH_FWK_PARA_INVALID;
156 }
157
158 DHTopic topic = (DHTopic)topicInt;
159 std::string message = data.ReadString();
160 DHLOGI("Publish message, topic: %{public}" PRIu32, (uint32_t)topic);
161 PublishMessage(topic, message);
162 reply.WriteInt32(DH_FWK_SUCCESS);
163 return DH_FWK_SUCCESS;
164 }
165
QueryLocalSysSpecInner(MessageParcel & data,MessageParcel & reply)166 int32_t DistributedHardwareStub::QueryLocalSysSpecInner(MessageParcel &data, MessageParcel &reply)
167 {
168 if (!HasAccessDHPermission()) {
169 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
170 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
171 }
172
173 uint32_t specInt = data.ReadUint32();
174 if (!ValidQueryLocalSpec(specInt)) {
175 DHLOGE("Spec invalid: %{public}" PRIu32, specInt);
176 reply.WriteInt32(ERR_DH_FWK_PARA_INVALID);
177 return ERR_DH_FWK_PARA_INVALID;
178 }
179
180 QueryLocalSysSpecType spec = (QueryLocalSysSpecType)specInt;
181 DHLOGI("Query Local Sys Spec: %{public}" PRIu32, (uint32_t)spec);
182 std::string res = QueryLocalSysSpec(spec);
183 DHLOGI("Get Local spec: %{public}s", res.c_str());
184 reply.WriteString(res);
185 return DH_FWK_SUCCESS;
186 }
187
InitializeAVCenterInner(MessageParcel & data,MessageParcel & reply)188 int32_t DistributedHardwareStub::InitializeAVCenterInner(MessageParcel &data, MessageParcel &reply)
189 {
190 if (!HasAccessDHPermission()) {
191 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
192 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
193 }
194
195 TransRole transRole = (TransRole)(data.ReadUint32());
196 int32_t engineId = 0;
197 int32_t ret = InitializeAVCenter(transRole, engineId);
198 if (!reply.WriteInt32(engineId)) {
199 DHLOGE("Write engine id failed");
200 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
201 }
202 if (!reply.WriteInt32(ret)) {
203 DHLOGE("Write ret code failed");
204 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
205 }
206 return DH_FWK_SUCCESS;
207 }
208
ReleaseAVCenterInner(MessageParcel & data,MessageParcel & reply)209 int32_t DistributedHardwareStub::ReleaseAVCenterInner(MessageParcel &data, MessageParcel &reply)
210 {
211 if (!HasAccessDHPermission()) {
212 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
213 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
214 }
215
216 int32_t engineId = data.ReadInt32();
217 int32_t ret = ReleaseAVCenter(engineId);
218 if (!reply.WriteInt32(ret)) {
219 DHLOGE("Write ret code failed");
220 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
221 }
222 return DH_FWK_SUCCESS;
223 }
224
CreateControlChannelInner(MessageParcel & data,MessageParcel & reply)225 int32_t DistributedHardwareStub::CreateControlChannelInner(MessageParcel &data, MessageParcel &reply)
226 {
227 if (!HasAccessDHPermission()) {
228 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
229 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
230 }
231
232 int32_t engineId = data.ReadInt32();
233 std::string peerDevId = data.ReadString();
234 int32_t ret = CreateControlChannel(engineId, peerDevId);
235 if (!reply.WriteInt32(ret)) {
236 DHLOGE("Write ret code failed");
237 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
238 }
239 return DH_FWK_SUCCESS;
240 }
241
NotifyAVCenterInner(MessageParcel & data,MessageParcel & reply)242 int32_t DistributedHardwareStub::NotifyAVCenterInner(MessageParcel &data, MessageParcel &reply)
243 {
244 if (!HasAccessDHPermission()) {
245 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
246 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
247 }
248
249 int32_t engineId = data.ReadInt32();
250 uint32_t type = data.ReadUint32();
251 std::string content = data.ReadString();
252 std::string peerDevId = data.ReadString();
253 int32_t ret = NotifyAVCenter(engineId, AVTransEvent{ (EventType)type, content, peerDevId });
254 if (!reply.WriteInt32(ret)) {
255 DHLOGE("Write ret code failed");
256 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
257 }
258 return DH_FWK_SUCCESS;
259 }
260
RegisterControlCenterCallbackInner(MessageParcel & data,MessageParcel & reply)261 int32_t DistributedHardwareStub::RegisterControlCenterCallbackInner(MessageParcel &data, MessageParcel &reply)
262 {
263 if (!HasAccessDHPermission()) {
264 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
265 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
266 }
267
268 int32_t engineId = data.ReadInt32();
269 sptr<IAVTransControlCenterCallback> callback = iface_cast<IAVTransControlCenterCallback>(data.ReadRemoteObject());
270 if (callback == nullptr) {
271 DHLOGE("Input av control center callback is null");
272 return ERR_DH_FWK_PARA_INVALID;
273 }
274
275 int32_t ret = RegisterCtlCenterCallback(engineId, callback);
276 if (!reply.WriteInt32(ret)) {
277 DHLOGE("Write ret code failed");
278 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
279 }
280 return DH_FWK_SUCCESS;
281 }
282
HandleNotifySourceRemoteSinkStarted(MessageParcel & data,MessageParcel & reply)283 int32_t OHOS::DistributedHardware::DistributedHardwareStub::HandleNotifySourceRemoteSinkStarted(MessageParcel &data,
284 MessageParcel &reply)
285 {
286 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
287 std::string udid = data.ReadString();
288 if (!IsIdLengthValid(udid)) {
289 DHLOGE("the udid is invalid, %{public}s", GetAnonyString(udid).c_str());
290 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
291 }
292 std::string networkId = "";
293 DeviceManager::GetInstance().GetNetworkIdByUdid(DH_FWK_PKG_NAME, udid, networkId);
294 if (!IsIdLengthValid(networkId)) {
295 DHLOGE("the networkId is invalid, %{public}s", GetAnonyString(networkId).c_str());
296 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
297 }
298 uint32_t dAccessToken = Security::AccessToken::AccessTokenKit::AllocLocalTokenID(networkId, callerToken);
299 const std::string permissionName = "ohos.permission.ACCESS_DISTRIBUTED_HARDWARE";
300 int32_t result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(dAccessToken, permissionName);
301 if (result != Security::AccessToken::PERMISSION_GRANTED) {
302 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
303 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
304 }
305
306 DHLOGI("DistributedHardwareStub HandleNotifySourceRemoteSinkStarted Start.");
307 int32_t ret = NotifySourceRemoteSinkStarted(udid);
308 if (!reply.WriteInt32(ret)) {
309 DHLOGE("write ret failed.");
310 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
311 }
312 DHLOGI("DistributedHardwareStub HandleNotifySourceRemoteSinkStarted End.");
313 return DH_FWK_SUCCESS;
314 }
315
ValidTopic(uint32_t topic)316 bool DistributedHardwareStub::ValidTopic(uint32_t topic)
317 {
318 if (topic <= (uint32_t)DHTopic::TOPIC_MIN || topic >= (uint32_t)DHTopic::TOPIC_MAX) {
319 return false;
320 }
321 return true;
322 }
323
ValidQueryLocalSpec(uint32_t spec)324 bool DistributedHardwareStub::ValidQueryLocalSpec(uint32_t spec)
325 {
326 if (spec <= (uint32_t)QueryLocalSysSpecType::MIN || spec >= (uint32_t)QueryLocalSysSpecType::MAX) {
327 return false;
328 }
329 return true;
330 }
331
PauseDistributedHardwareInner(MessageParcel & data,MessageParcel & reply)332 int32_t DistributedHardwareStub::PauseDistributedHardwareInner(MessageParcel &data, MessageParcel &reply)
333 {
334 if (!IsSystemHap()) {
335 DHLOGE("GetCallerProcessName not system hap.");
336 return ERR_DH_FWK_IS_SYSTEM_HAP_CHECK_FAIL;
337 }
338 if (!HasAccessDHPermission()) {
339 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
340 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
341 }
342 DHType dhType = static_cast<DHType>(data.ReadInt32());
343 std::string networkId = data.ReadString();
344 int32_t ret = PauseDistributedHardware(dhType, networkId);
345 if (!reply.WriteInt32(ret)) {
346 DHLOGE("Write ret code failed");
347 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
348 }
349 return DH_FWK_SUCCESS;
350 }
351
ResumeDistributedHardwareInner(MessageParcel & data,MessageParcel & reply)352 int32_t DistributedHardwareStub::ResumeDistributedHardwareInner(MessageParcel &data, MessageParcel &reply)
353 {
354 if (!IsSystemHap()) {
355 DHLOGE("GetCallerProcessName not system hap.");
356 return ERR_DH_FWK_IS_SYSTEM_HAP_CHECK_FAIL;
357 }
358 if (!HasAccessDHPermission()) {
359 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
360 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
361 }
362 DHType dhType = static_cast<DHType>(data.ReadInt32());
363 std::string networkId = data.ReadString();
364 int32_t ret = ResumeDistributedHardware(dhType, networkId);
365 if (!reply.WriteInt32(ret)) {
366 DHLOGE("Write ret code failed");
367 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
368 }
369 return DH_FWK_SUCCESS;
370 }
371
StopDistributedHardwareInner(MessageParcel & data,MessageParcel & reply)372 int32_t DistributedHardwareStub::StopDistributedHardwareInner(MessageParcel &data, MessageParcel &reply)
373 {
374 if (!IsSystemHap()) {
375 DHLOGE("GetCallerProcessName not system hap.");
376 return ERR_DH_FWK_IS_SYSTEM_HAP_CHECK_FAIL;
377 }
378 if (!HasAccessDHPermission()) {
379 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
380 return ERR_DH_FWK_ACCESS_PERMISSION_CHECK_FAIL;
381 }
382 DHType dhType = static_cast<DHType>(data.ReadInt32());
383 std::string networkId = data.ReadString();
384 int32_t ret = StopDistributedHardware(dhType, networkId);
385 if (!reply.WriteInt32(ret)) {
386 DHLOGE("Write ret code failed");
387 return ERR_DH_FWK_SERVICE_WRITE_INFO_FAIL;
388 }
389 return DH_FWK_SUCCESS;
390 }
391
HasAccessDHPermission()392 bool DistributedHardwareStub::HasAccessDHPermission()
393 {
394 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
395 const std::string permissionName = "ohos.permission.ACCESS_DISTRIBUTED_HARDWARE";
396 int32_t result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken,
397 permissionName);
398 return (result == Security::AccessToken::PERMISSION_GRANTED);
399 }
400
IsSystemHap()401 bool DistributedHardwareStub::IsSystemHap()
402 {
403 uint64_t fullTokenId = IPCSkeleton::GetCallingFullTokenID();
404 if (!OHOS::Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(fullTokenId)) {
405 return false;
406 }
407 return true;
408 }
409 } // namespace DistributedHardware
410 } // namespace OHOS
411