1 /*
2 * Copyright (c) 2022-2023 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 "daudio_sink_stub.h"
17
18 #include "accesstoken_kit.h"
19 #include "ipc_skeleton.h"
20 #include "tokenid_kit.h"
21
22 #include "daudio_constants.h"
23 #include "daudio_errorcode.h"
24 #include "daudio_ipc_interface_code.h"
25 #include "daudio_log.h"
26 #include "daudio_sink_ipc_callback_proxy.h"
27
28 #undef DH_LOG_TAG
29 #define DH_LOG_TAG "DAudioSinkStub"
30
31 namespace OHOS {
32 namespace DistributedHardware {
DAudioSinkStub()33 DAudioSinkStub::DAudioSinkStub()
34 {
35 DHLOGD("Distributed audio sink stub constructed.");
36 memberFuncMap_[static_cast<uint32_t>(IDAudioSinkInterfaceCode::INIT_SINK)] =
37 &DAudioSinkStub::InitSinkInner;
38 memberFuncMap_[static_cast<uint32_t>(IDAudioSinkInterfaceCode::RELEASE_SINK)] =
39 &DAudioSinkStub::ReleaseSinkInner;
40 memberFuncMap_[static_cast<uint32_t>(IDAudioSinkInterfaceCode::SUBSCRIBE_LOCAL_HARDWARE)] =
41 &DAudioSinkStub::SubscribeLocalHardwareInner;
42 memberFuncMap_[static_cast<uint32_t>(IDAudioSinkInterfaceCode::UNSUBSCRIBE_LOCAL_HARDWARE)] =
43 &DAudioSinkStub::UnsubscribeLocalHardwareInner;
44 memberFuncMap_[static_cast<uint32_t>(IDAudioSinkInterfaceCode::DAUDIO_NOTIFY)] =
45 &DAudioSinkStub::DAudioNotifyInner;
46 memberFuncMap_[static_cast<uint32_t>(IDAudioSinkInterfaceCode::PAUSE_DISTRIBUTED_HARDWARE)] =
47 &DAudioSinkStub::PauseDistributedHardwareInner;
48 memberFuncMap_[static_cast<uint32_t>(IDAudioSinkInterfaceCode::RESUME_DISTRIBUTED_HARDWARE)] =
49 &DAudioSinkStub::ResumeDistributedHardwareInner;
50 memberFuncMap_[static_cast<uint32_t>(IDAudioSinkInterfaceCode::STOP_DISTRIBUTED_HARDWARE)] =
51 &DAudioSinkStub::StopDistributedHardwareInner;
52 }
53
~DAudioSinkStub()54 DAudioSinkStub::~DAudioSinkStub()
55 {
56 DHLOGD("Distributed audio sink stub deconstructed.");
57 }
58
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)59 int32_t DAudioSinkStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
60 {
61 DHLOGD("On remote request, code: %d.", code);
62 std::u16string desc = DAudioSinkStub::GetDescriptor();
63 std::u16string remoteDesc = data.ReadInterfaceToken();
64 if (desc != remoteDesc) {
65 DHLOGE("RemoteDesc is invalid.");
66 return ERR_DH_AUDIO_SA_INVALID_INTERFACE_TOKEN;
67 }
68
69 const auto &iter = memberFuncMap_.find(code);
70 if (iter == memberFuncMap_.end()) {
71 DHLOGE("Invalid request code.");
72 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
73 }
74 DAudioSinkServiceFunc &func = iter->second;
75 return (this->*func)(data, reply, option);
76 }
77
VerifyPermission()78 bool DAudioSinkStub::VerifyPermission()
79 {
80 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
81 int result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, AUDIO_PERMISSION_NAME);
82 if (result == Security::AccessToken::PERMISSION_GRANTED) {
83 return true;
84 }
85 return false;
86 }
87
InitSinkInner(MessageParcel & data,MessageParcel & reply,MessageOption & option)88 int32_t DAudioSinkStub::InitSinkInner(MessageParcel &data, MessageParcel &reply, MessageOption &option)
89 {
90 if (!VerifyPermission()) {
91 DHLOGE("Permission verification fail.");
92 return ERR_DH_AUDIO_SA_PERMISSION_FAIED;
93 }
94 std::string param = data.ReadString();
95 sptr<IRemoteObject> remoteObject = data.ReadRemoteObject();
96 CHECK_NULL_RETURN(remoteObject, ERR_DH_AUDIO_NULLPTR);
97 sptr<DAudioSinkIpcCallbackProxy> dAudioSinkIpcCallbackProxy(new DAudioSinkIpcCallbackProxy(remoteObject));
98 int32_t ret = InitSink(param, dAudioSinkIpcCallbackProxy);
99 reply.WriteInt32(ret);
100 return DH_SUCCESS;
101 }
102
ReleaseSinkInner(MessageParcel & data,MessageParcel & reply,MessageOption & option)103 int32_t DAudioSinkStub::ReleaseSinkInner(MessageParcel &data, MessageParcel &reply, MessageOption &option)
104 {
105 if (!VerifyPermission()) {
106 DHLOGE("Permission verification fail.");
107 return ERR_DH_AUDIO_SA_PERMISSION_FAIED;
108 }
109 int32_t ret = ReleaseSink();
110 reply.WriteInt32(ret);
111 return DH_SUCCESS;
112 }
113
SubscribeLocalHardwareInner(MessageParcel & data,MessageParcel & reply,MessageOption & option)114 int32_t DAudioSinkStub::SubscribeLocalHardwareInner(MessageParcel &data, MessageParcel &reply, MessageOption &option)
115 {
116 std::string dhId = data.ReadString();
117 std::string param = data.ReadString();
118 int32_t ret = SubscribeLocalHardware(dhId, param);
119 reply.WriteInt32(ret);
120 return DH_SUCCESS;
121 }
122
UnsubscribeLocalHardwareInner(MessageParcel & data,MessageParcel & reply,MessageOption & option)123 int32_t DAudioSinkStub::UnsubscribeLocalHardwareInner(MessageParcel &data, MessageParcel &reply, MessageOption &option)
124 {
125 std::string dhId = data.ReadString();
126 int32_t ret = UnsubscribeLocalHardware(dhId);
127 reply.WriteInt32(ret);
128 return DH_SUCCESS;
129 }
130
DAudioNotifyInner(MessageParcel & data,MessageParcel & reply,MessageOption & option)131 int32_t DAudioSinkStub::DAudioNotifyInner(MessageParcel &data, MessageParcel &reply, MessageOption &option)
132 {
133 std::string networkId = data.ReadString();
134 std::string dhId = data.ReadString();
135 int32_t eventType = data.ReadInt32();
136 std::string eventContent = data.ReadString();
137
138 DAudioNotify(networkId, dhId, eventType, eventContent);
139 return DH_SUCCESS;
140 }
141
PauseDistributedHardwareInner(MessageParcel & data,MessageParcel & reply,MessageOption & option)142 int32_t DAudioSinkStub::PauseDistributedHardwareInner(MessageParcel &data, MessageParcel &reply, MessageOption &option)
143 {
144 if (!HasAccessDHPermission()) {
145 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
146 return ERR_DH_AUDIO_ACCESS_PERMISSION_CHECK_FAIL;
147 }
148 std::string networkId = data.ReadString();
149 int32_t ret = PauseDistributedHardware(networkId);
150 reply.WriteInt32(ret);
151 return DH_SUCCESS;
152 }
153
ResumeDistributedHardwareInner(MessageParcel & data,MessageParcel & reply,MessageOption & option)154 int32_t DAudioSinkStub::ResumeDistributedHardwareInner(MessageParcel &data, MessageParcel &reply, MessageOption &option)
155 {
156 if (!HasAccessDHPermission()) {
157 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
158 return ERR_DH_AUDIO_ACCESS_PERMISSION_CHECK_FAIL;
159 }
160 std::string networkId = data.ReadString();
161 int32_t ret = ResumeDistributedHardware(networkId);
162 reply.WriteInt32(ret);
163 return DH_SUCCESS;
164 }
165
StopDistributedHardwareInner(MessageParcel & data,MessageParcel & reply,MessageOption & option)166 int32_t DAudioSinkStub::StopDistributedHardwareInner(MessageParcel &data, MessageParcel &reply, MessageOption &option)
167 {
168 if (!HasAccessDHPermission()) {
169 DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
170 return ERR_DH_AUDIO_ACCESS_PERMISSION_CHECK_FAIL;
171 }
172 std::string networkId = data.ReadString();
173 int32_t ret = StopDistributedHardware(networkId);
174 reply.WriteInt32(ret);
175 return DH_SUCCESS;
176 }
177
HasAccessDHPermission()178 bool DAudioSinkStub::HasAccessDHPermission()
179 {
180 Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
181 const std::string permissionName = "ohos.permission.ACCESS_DISTRIBUTED_HARDWARE";
182 int32_t result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken, permissionName);
183 return (result == Security::AccessToken::PERMISSION_GRANTED);
184 }
185 } // namespace DistributedHardware
186 } // namespace OHOS