1 /*
2  * Copyright (c) 2021-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 "accesstoken_kit.h"
17 #include "dcamera_ipc_interface_code.h"
18 #include "distributed_camera_sink_stub.h"
19 #include "distributed_camera_errno.h"
20 #include "distributed_hardware_log.h"
21 #include "ipc_skeleton.h"
22 #include "dcamera_sink_callback_proxy.h"
23 
24 namespace OHOS {
25 namespace DistributedHardware {
DistributedCameraSinkStub()26 DistributedCameraSinkStub::DistributedCameraSinkStub() : IRemoteStub(true)
27 {
28     memberFuncMap_[static_cast<uint32_t>(IDCameraSinkInterfaceCode::INIT_SINK)] =
29         &DistributedCameraSinkStub::InitSinkInner;
30     memberFuncMap_[static_cast<uint32_t>(IDCameraSinkInterfaceCode::RELEASE_SINK)] =
31         &DistributedCameraSinkStub::ReleaseSinkInner;
32     memberFuncMap_[static_cast<uint32_t>(IDCameraSinkInterfaceCode::SUBSCRIBE_LOCAL_HARDWARE)] =
33         &DistributedCameraSinkStub::SubscribeLocalHardwareInner;
34     memberFuncMap_[static_cast<uint32_t>(IDCameraSinkInterfaceCode::UNSUBSCRIBE_LOCAL_HARDWARE)] =
35         &DistributedCameraSinkStub::UnsubscribeLocalHardwareInner;
36     memberFuncMap_[static_cast<uint32_t>(IDCameraSinkInterfaceCode::STOP_CAPTURE)] =
37         &DistributedCameraSinkStub::StopCaptureInner;
38     memberFuncMap_[static_cast<uint32_t>(IDCameraSinkInterfaceCode::CHANNEL_NEG)] =
39         &DistributedCameraSinkStub::ChannelNegInner;
40     memberFuncMap_[static_cast<uint32_t>(IDCameraSinkInterfaceCode::GET_CAMERA_INFO)] =
41         &DistributedCameraSinkStub::GetCameraInfoInner;
42     memberFuncMap_[static_cast<uint32_t>(IDCameraSinkInterfaceCode::OPEN_CHANNEL)] =
43         &DistributedCameraSinkStub::OpenChannelInner;
44     memberFuncMap_[static_cast<uint32_t>(IDCameraSinkInterfaceCode::CLOSE_CHANNEL)] =
45         &DistributedCameraSinkStub::CloseChannelInner;
46     memberFuncMap_[static_cast<uint32_t>(IDCameraSinkInterfaceCode::PAUSE_DISTRIBUTED_HARDWARE)] =
47         &DistributedCameraSinkStub::PauseDistributedHardwareInner;
48     memberFuncMap_[static_cast<uint32_t>(IDCameraSinkInterfaceCode::RESUME_DISTRIBUTED_HARDWARE)] =
49         &DistributedCameraSinkStub::ResumeDistributedHardwareInner;
50     memberFuncMap_[static_cast<uint32_t>(IDCameraSinkInterfaceCode::STOP_DISTRIBUTED_HARDWARE)] =
51         &DistributedCameraSinkStub::StopDistributedHardwareInner;
52 }
53 
~DistributedCameraSinkStub()54 DistributedCameraSinkStub::~DistributedCameraSinkStub()
55 {}
56 
HasEnableDHPermission()57 bool DistributedCameraSinkStub::HasEnableDHPermission()
58 {
59     Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
60     const std::string permissionName = "ohos.permission.ENABLE_DISTRIBUTED_HARDWARE";
61     int32_t result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken,
62         permissionName);
63     return (result == Security::AccessToken::PERMISSION_GRANTED);
64 }
65 
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)66 int32_t DistributedCameraSinkStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
67     MessageOption &option)
68 {
69     DHLOGD("remote request code: %{public}d", code);
70     std::u16string desc = DistributedCameraSinkStub::GetDescriptor();
71     std::u16string remoteDesc = data.ReadInterfaceToken();
72     if (desc != remoteDesc) {
73         DHLOGE("remoteDesc is invalid!");
74         return ERR_INVALID_DATA;
75     }
76 
77     switch (code) {
78         case static_cast<uint32_t>(IDCameraSinkInterfaceCode::INIT_SINK):
79             return InitSinkInner(data, reply);
80         case static_cast<uint32_t>(IDCameraSinkInterfaceCode::RELEASE_SINK):
81             return ReleaseSinkInner(data, reply);
82         case static_cast<uint32_t>(IDCameraSinkInterfaceCode::SUBSCRIBE_LOCAL_HARDWARE):
83             return SubscribeLocalHardwareInner(data, reply);
84         case static_cast<uint32_t>(IDCameraSinkInterfaceCode::UNSUBSCRIBE_LOCAL_HARDWARE):
85             return UnsubscribeLocalHardwareInner(data, reply);
86         case static_cast<uint32_t>(IDCameraSinkInterfaceCode::STOP_CAPTURE):
87             return StopCaptureInner(data, reply);
88         case static_cast<uint32_t>(IDCameraSinkInterfaceCode::CHANNEL_NEG):
89             return ChannelNegInner(data, reply);
90         case static_cast<uint32_t>(IDCameraSinkInterfaceCode::GET_CAMERA_INFO):
91             return GetCameraInfoInner(data, reply);
92         case static_cast<uint32_t>(IDCameraSinkInterfaceCode::OPEN_CHANNEL):
93             return OpenChannelInner(data, reply);
94         case static_cast<uint32_t>(IDCameraSinkInterfaceCode::CLOSE_CHANNEL):
95             return CloseChannelInner(data, reply);
96         case static_cast<uint32_t>(IDCameraSinkInterfaceCode::PAUSE_DISTRIBUTED_HARDWARE):
97             return PauseDistributedHardwareInner(data, reply);
98         case static_cast<uint32_t>(IDCameraSinkInterfaceCode::RESUME_DISTRIBUTED_HARDWARE):
99             return ResumeDistributedHardwareInner(data, reply);
100         case static_cast<uint32_t>(IDCameraSinkInterfaceCode::STOP_DISTRIBUTED_HARDWARE):
101             return StopDistributedHardwareInner(data, reply);
102         default:
103             DHLOGE("Invalid OnRemoteRequest code=%{public}d", code);
104             return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
105     }
106     return DCAMERA_NOT_FOUND;
107 }
108 
InitSinkInner(MessageParcel & data,MessageParcel & reply)109 int32_t DistributedCameraSinkStub::InitSinkInner(MessageParcel &data, MessageParcel &reply)
110 {
111     DHLOGD("enter");
112     int32_t ret = DCAMERA_OK;
113     do {
114         if (!HasEnableDHPermission()) {
115             DHLOGE("The caller has no ENABLE_DISTRIBUTED_HARDWARE permission.");
116             ret = DCAMERA_BAD_VALUE;
117             break;
118         }
119         std::string params = data.ReadString();
120         if (params.empty() || params.size() > PARAM_MAX_SIZE) {
121             DHLOGE("params is invalid");
122             ret = DCAMERA_BAD_VALUE;
123             break;
124         }
125         sptr<IRemoteObject> remoteObject = data.ReadRemoteObject();
126         if (remoteObject == nullptr) {
127             DHLOGE("Read ReadRemoteObject failed.");
128             ret = DCAMERA_BAD_VALUE;
129             break;
130         }
131 
132         sptr<DCameraSinkCallbackProxy> dCameraSinkCallbackProxy(new DCameraSinkCallbackProxy(remoteObject));
133         ret = InitSink(params, dCameraSinkCallbackProxy);
134     } while (0);
135     reply.WriteInt32(ret);
136     return DCAMERA_OK;
137 }
138 
ReleaseSinkInner(MessageParcel & data,MessageParcel & reply)139 int32_t DistributedCameraSinkStub::ReleaseSinkInner(MessageParcel &data, MessageParcel &reply)
140 {
141     DHLOGD("enter");
142     int32_t ret = DCAMERA_OK;
143     do {
144         if (!HasEnableDHPermission()) {
145             DHLOGE("The caller has no ENABLE_DISTRIBUTED_HARDWARE permission.");
146             ret = DCAMERA_BAD_VALUE;
147             break;
148         }
149         ret = ReleaseSink();
150     } while (0);
151     reply.WriteInt32(ret);
152     return DCAMERA_OK;
153 }
154 
SubscribeLocalHardwareInner(MessageParcel & data,MessageParcel & reply)155 int32_t DistributedCameraSinkStub::SubscribeLocalHardwareInner(MessageParcel &data, MessageParcel &reply)
156 {
157     DHLOGD("enter");
158     int32_t ret = DCAMERA_OK;
159     do {
160         std::string dhId = data.ReadString();
161         std::string parameters = data.ReadString();
162         if (parameters.empty() || parameters.size() > PARAM_MAX_SIZE || dhId.empty() ||
163             dhId.size() > DID_MAX_SIZE) {
164             DHLOGE("params is invalid");
165             ret = DCAMERA_BAD_VALUE;
166             break;
167         }
168         ret = SubscribeLocalHardware(dhId, parameters);
169     } while (0);
170     reply.WriteInt32(ret);
171     return DCAMERA_OK;
172 }
173 
UnsubscribeLocalHardwareInner(MessageParcel & data,MessageParcel & reply)174 int32_t DistributedCameraSinkStub::UnsubscribeLocalHardwareInner(MessageParcel &data, MessageParcel &reply)
175 {
176     DHLOGD("enter");
177     int32_t ret = DCAMERA_OK;
178     do {
179         std::string dhId = data.ReadString();
180         if (dhId.empty() || dhId.size() > DID_MAX_SIZE) {
181             DHLOGE("params is invalid");
182             ret = DCAMERA_BAD_VALUE;
183             break;
184         }
185         ret = UnsubscribeLocalHardware(dhId);
186     } while (0);
187     reply.WriteInt32(ret);
188     return DCAMERA_OK;
189 }
190 
StopCaptureInner(MessageParcel & data,MessageParcel & reply)191 int32_t DistributedCameraSinkStub::StopCaptureInner(MessageParcel &data, MessageParcel &reply)
192 {
193     DHLOGD("enter");
194     int32_t ret = DCAMERA_OK;
195     do {
196         std::string dhId = data.ReadString();
197         if (dhId.empty() || dhId.size() > DID_MAX_SIZE) {
198             DHLOGE("params is invalid");
199             ret = DCAMERA_BAD_VALUE;
200             break;
201         }
202         ret = StopCapture(dhId);
203     } while (0);
204     reply.WriteInt32(ret);
205     return DCAMERA_OK;
206 }
207 
ChannelNegInner(MessageParcel & data,MessageParcel & reply)208 int32_t DistributedCameraSinkStub::ChannelNegInner(MessageParcel &data, MessageParcel &reply)
209 {
210     DHLOGD("enter");
211     int32_t ret = DCAMERA_OK;
212     do {
213         std::string dhId = data.ReadString();
214         std::string channelInfo = data.ReadString();
215         if (dhId.empty() || dhId.size() > DID_MAX_SIZE || channelInfo.empty() ||
216             channelInfo.size() > PARAM_MAX_SIZE) {
217             DHLOGE("params is invalid");
218             ret = DCAMERA_BAD_VALUE;
219             break;
220         }
221         ret = ChannelNeg(dhId, channelInfo);
222     } while (0);
223     reply.WriteInt32(ret);
224     return DCAMERA_OK;
225 }
226 
GetCameraInfoInner(MessageParcel & data,MessageParcel & reply)227 int32_t DistributedCameraSinkStub::GetCameraInfoInner(MessageParcel &data, MessageParcel &reply)
228 {
229     DHLOGD("enter");
230     int32_t ret = DCAMERA_OK;
231     do {
232         std::string dhId = data.ReadString();
233         std::string cameraInfo = data.ReadString();
234         if (dhId.empty() || dhId.size() > DID_MAX_SIZE) {
235             DHLOGE("params is invalid");
236             ret = DCAMERA_BAD_VALUE;
237             break;
238         }
239         ret = GetCameraInfo(dhId, cameraInfo);
240     } while (0);
241     reply.WriteInt32(ret);
242     return DCAMERA_OK;
243 }
244 
OpenChannelInner(MessageParcel & data,MessageParcel & reply)245 int32_t DistributedCameraSinkStub::OpenChannelInner(MessageParcel &data, MessageParcel &reply)
246 {
247     DHLOGD("DistributedCameraSinkStub OpenChannelInner Begin");
248     int32_t ret = DCAMERA_OK;
249     do {
250         std::string dhId = data.ReadString();
251         std::string openInfo = data.ReadString();
252         if (dhId.empty() || dhId.size() > DID_MAX_SIZE || openInfo.empty()||
253             openInfo.size() > PARAM_MAX_SIZE) {
254             DHLOGE("params is invalid");
255             ret = DCAMERA_BAD_VALUE;
256             break;
257         }
258         ret = OpenChannel(dhId, openInfo);
259     } while (0);
260     reply.WriteInt32(ret);
261     DHLOGD("DistributedCameraSinkStub OpenChannelInner End");
262     return DCAMERA_OK;
263 }
264 
CloseChannelInner(MessageParcel & data,MessageParcel & reply)265 int32_t DistributedCameraSinkStub::CloseChannelInner(MessageParcel &data, MessageParcel &reply)
266 {
267     DHLOGD("enter");
268     int32_t ret = DCAMERA_OK;
269     do {
270         std::string dhId = data.ReadString();
271         if (dhId.empty() || dhId.size() > DID_MAX_SIZE) {
272             DHLOGE("params is invalid");
273             ret = DCAMERA_BAD_VALUE;
274             break;
275         }
276         ret = CloseChannel(dhId);
277     } while (0);
278     reply.WriteInt32(ret);
279     return DCAMERA_OK;
280 }
281 
HasAccessDHPermission()282 bool DistributedCameraSinkStub::HasAccessDHPermission()
283 {
284     Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
285     const std::string permissionName = "ohos.permission.ACCESS_DISTRIBUTED_HARDWARE";
286     int32_t result = Security::AccessToken::AccessTokenKit::VerifyAccessToken(callerToken,
287         permissionName);
288     return (result == Security::AccessToken::PERMISSION_GRANTED);
289 }
290 
PauseDistributedHardwareInner(MessageParcel & data,MessageParcel & reply)291 int32_t DistributedCameraSinkStub::PauseDistributedHardwareInner(MessageParcel &data, MessageParcel &reply)
292 {
293     DHLOGD("enter");
294     int32_t ret = DCAMERA_OK;
295     do {
296         if (!HasAccessDHPermission()) {
297             DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
298             ret = DCAMERA_BAD_VALUE;
299             break;
300         }
301         std::string networkId = data.ReadString();
302         if (networkId.empty() || networkId.size() > DID_MAX_SIZE) {
303             DHLOGE("params is invalid");
304             ret = DCAMERA_BAD_VALUE;
305             break;
306         }
307         ret = PauseDistributedHardware(networkId);
308     } while (0);
309     reply.WriteInt32(ret);
310     return DCAMERA_OK;
311 }
312 
ResumeDistributedHardwareInner(MessageParcel & data,MessageParcel & reply)313 int32_t DistributedCameraSinkStub::ResumeDistributedHardwareInner(MessageParcel &data, MessageParcel &reply)
314 {
315     DHLOGD("enter");
316     int32_t ret = DCAMERA_OK;
317     do {
318         if (!HasAccessDHPermission()) {
319             DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
320             ret = DCAMERA_BAD_VALUE;
321             break;
322         }
323         std::string networkId = data.ReadString();
324         if (networkId.empty() || networkId.size() > DID_MAX_SIZE) {
325             DHLOGE("params is invalid");
326             ret = DCAMERA_BAD_VALUE;
327             break;
328         }
329         ret = ResumeDistributedHardware(networkId);
330     } while (0);
331     reply.WriteInt32(ret);
332     return DCAMERA_OK;
333 }
334 
StopDistributedHardwareInner(MessageParcel & data,MessageParcel & reply)335 int32_t DistributedCameraSinkStub::StopDistributedHardwareInner(MessageParcel &data, MessageParcel &reply)
336 {
337     DHLOGD("enter");
338     int32_t ret = DCAMERA_OK;
339     do {
340         if (!HasAccessDHPermission()) {
341             DHLOGE("The caller has no ACCESS_DISTRIBUTED_HARDWARE permission.");
342             ret = DCAMERA_BAD_VALUE;
343             break;
344         }
345         std::string networkId = data.ReadString();
346         if (networkId.empty() || networkId.size() > DID_MAX_SIZE) {
347             DHLOGE("params is invalid");
348             ret = DCAMERA_BAD_VALUE;
349             break;
350         }
351         ret = StopDistributedHardware(networkId);
352     } while (0);
353     reply.WriteInt32(ret);
354     return DCAMERA_OK;
355 }
356 } // namespace DistributedHardware
357 } // namespace OHOS