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 "dcamera_sink_controller.h"
17
18 #include <securec.h>
19 #include <thread>
20
21 #include "anonymous_string.h"
22 #include "dcamera_channel_sink_impl.h"
23 #include "dcamera_client.h"
24 #include "dcamera_metadata_setting_cmd.h"
25 #include "dcamera_protocol.h"
26 #include "dcamera_utils_tools.h"
27
28 #include "dcamera_sink_access_control.h"
29 #include "dcamera_sink_controller_channel_listener.h"
30 #include "dcamera_sink_controller_state_callback.h"
31 #include "dcamera_sink_output.h"
32 #include "dcamera_sink_service_ipc.h"
33
34 #include "distributed_camera_constants.h"
35 #include "distributed_camera_errno.h"
36 #include "distributed_hardware_log.h"
37 #ifdef DEVICE_SECURITY_LEVEL_ENABLE
38 #include "device_security_defines.h"
39 #include "device_security_info.h"
40 #endif
41 #include "ffrt_inner.h"
42 #include "idistributed_camera_source.h"
43 #include "ipc_skeleton.h"
44 #include "dcamera_low_latency.h"
45 #include <sys/prctl.h>
46
47 namespace OHOS {
48 namespace DistributedHardware {
49 const int DEFAULT_DEVICE_SECURITY_LEVEL = -1;
50 const std::string PAGE_SUBTYPE = "camera";
51
DCameraSinkController(std::shared_ptr<ICameraSinkAccessControl> & accessControl,const sptr<IDCameraSinkCallback> & sinkCallback)52 DCameraSinkController::DCameraSinkController(std::shared_ptr<ICameraSinkAccessControl>& accessControl,
53 const sptr<IDCameraSinkCallback> &sinkCallback)
54 : isInit_(false), sessionState_(DCAMERA_CHANNEL_STATE_DISCONNECTED), accessControl_(accessControl),
55 sinkCallback_(sinkCallback)
56 {
57 }
58
~DCameraSinkController()59 DCameraSinkController::~DCameraSinkController()
60 {
61 if (isInit_) {
62 UnInit();
63 }
64 }
65
StartCapture(std::vector<std::shared_ptr<DCameraCaptureInfo>> & captureInfos,int32_t sceneMode)66 int32_t DCameraSinkController::StartCapture(std::vector<std::shared_ptr<DCameraCaptureInfo>>& captureInfos,
67 int32_t sceneMode)
68 {
69 DHLOGI("StartCapture dhId: %{public}s, mode: %{public}d", GetAnonyString(dhId_).c_str(), sceneMode);
70 std::string accessType = "";
71 CHECK_AND_RETURN_RET_LOG(accessControl_ == nullptr, DCAMERA_BAD_VALUE, "accessControl_ is null.");
72 if ((accessControl_->IsSensitiveSrcAccess(SRC_TYPE)) &&
73 (accessControl_->GetAccessControlType(accessType) == DCAMERA_SAME_ACCOUNT)) {
74 int32_t ret = StartCaptureInner(captureInfos);
75 if (ret == DCAMERA_OK) {
76 accessControl_->NotifySensitiveSrc(SRC_TYPE);
77 }
78 return ret;
79 } else {
80 std::shared_ptr<std::string> param = std::make_shared<std::string>("");
81 std::shared_ptr<std::vector<std::shared_ptr<DCameraCaptureInfo>>> infos =
82 std::make_shared<std::vector<std::shared_ptr<DCameraCaptureInfo>>>(captureInfos);
83 CHECK_AND_RETURN_RET_LOG(sinkCotrEventHandler_ == nullptr, DCAMERA_BAD_VALUE, "sinkCotrEventHandler_ is null.");
84 AppExecFwk::InnerEvent::Pointer triggerEvent =
85 AppExecFwk::InnerEvent::Get(EVENT_FRAME_TRIGGER, param, 0);
86 AppExecFwk::InnerEvent::Pointer authorizationEvent =
87 AppExecFwk::InnerEvent::Get(EVENT_AUTHORIZATION, infos, 0);
88 sinkCotrEventHandler_->SendEvent(triggerEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
89 sinkCotrEventHandler_->SendEvent(authorizationEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
90 }
91 return DCAMERA_OK;
92 }
93
StopCapture()94 int32_t DCameraSinkController::StopCapture()
95 {
96 DHLOGI("StopCapture dhId: %{public}s", GetAnonyString(dhId_).c_str());
97 std::lock_guard<std::mutex> autoLock(captureLock_);
98 if (operator_ == nullptr) {
99 return DCAMERA_BAD_VALUE;
100 }
101 int32_t ret = operator_->StopCapture();
102 if (ret != DCAMERA_OK) {
103 DHLOGE("client stop capture failed, dhId: %{public}s, ret: %{public}d",
104 GetAnonyString(dhId_).c_str(), ret);
105 DCameraNotifyInner(DCAMERA_MESSAGE, DCAMERA_EVENT_DEVICE_ERROR, std::string("operator stop capture failed."));
106 return ret;
107 }
108 if (output_ == nullptr) {
109 return DCAMERA_BAD_VALUE;
110 }
111 ret = output_->StopCapture();
112 if (ret != DCAMERA_OK) {
113 DHLOGE("output stop capture failed, dhId: %{public}s, ret: %{public}d",
114 GetAnonyString(dhId_).c_str(), ret);
115 DCameraNotifyInner(DCAMERA_MESSAGE, DCAMERA_EVENT_DEVICE_ERROR, std::string("output stop capture failed"));
116 return ret;
117 }
118 DHLOGI("StopCapture %{public}s success", GetAnonyString(dhId_).c_str());
119 return DCAMERA_OK;
120 }
121
ChannelNeg(std::shared_ptr<DCameraChannelInfo> & info)122 int32_t DCameraSinkController::ChannelNeg(std::shared_ptr<DCameraChannelInfo>& info)
123 {
124 DHLOGI("ChannelNeg dhId: %{public}s", GetAnonyString(dhId_).c_str());
125 int32_t ret = output_->OpenChannel(info);
126 if (ret != DCAMERA_OK) {
127 DHLOGE("channel negotiate failed, dhId: %{public}s, ret: %{public}d", GetAnonyString(dhId_).c_str(), ret);
128 return ret;
129 }
130
131 DHLOGI("ChannelNeg %{public}s success", GetAnonyString(dhId_).c_str());
132 return DCAMERA_OK;
133 }
134
DCameraNotify(std::shared_ptr<DCameraEvent> & events)135 int32_t DCameraSinkController::DCameraNotify(std::shared_ptr<DCameraEvent>& events)
136 {
137 DHLOGI("DCameraNotify dhId: %{public}s", GetAnonyString(dhId_).c_str());
138 CHECK_AND_RETURN_RET_LOG(srcDevId_.empty(), DCAMERA_BAD_VALUE, "source deviceId is empty");
139
140 DCameraEventCmd eventCmd;
141 std::string jsonStr = "";
142 eventCmd.type_ = DCAMERA_PROTOCOL_TYPE_MESSAGE;
143 eventCmd.dhId_ = dhId_;
144 eventCmd.command_ = DCAMERA_PROTOCOL_CMD_STATE_NOTIFY;
145 eventCmd.value_ = events;
146 int32_t ret = eventCmd.Marshal(jsonStr);
147 if (ret != DCAMERA_OK) {
148 DHLOGE("DCameraEventCmd marshal failed, dhId: %{public}s, ret: %{public}d",
149 GetAnonyString(dhId_).c_str(), ret);
150 return ret;
151 }
152
153 if (ManageSelectChannel::GetInstance().GetSinkConnect()) {
154 std::shared_ptr<DataBuffer> buffer = std::make_shared<DataBuffer>(jsonStr.length() + 1);
155 ret = memcpy_s(buffer->Data(), buffer->Capacity(),
156 reinterpret_cast<uint8_t *>(const_cast<char *>(jsonStr.c_str())), jsonStr.length());
157 CHECK_AND_RETURN_RET_LOG(ret != EOK, DCAMERA_BAD_VALUE, "DCameraNotify memcpy_s failed, ret: %{public}d", ret);
158 ret = channel_->SendData(buffer);
159 if (ret != DCAMERA_OK) {
160 DHLOGE("DCameraNotify channel send data failed, dhId: %{public}s ret: %{public}d",
161 GetAnonyString(dhId_).c_str(), ret);
162 return DCAMERA_BAD_VALUE;
163 }
164 } else {
165 std::string sinkDevId;
166 ret = GetLocalDeviceNetworkId(sinkDevId);
167 if (ret != DCAMERA_OK) {
168 DHLOGE("GetLocalDeviceNetworkId failed, devId: %{public}s, dhId: %{public}s, ret: %{public}d",
169 GetAnonyString(sinkDevId).c_str(), GetAnonyString(dhId_).c_str(), ret);
170 return ret;
171 }
172
173 sptr<IDistributedCameraSource> sourceSA = DCameraSinkServiceIpc::GetInstance().GetSourceRemoteCamSrv(srcDevId_);
174 CHECK_AND_RETURN_RET_LOG(sourceSA == nullptr, DCAMERA_BAD_VALUE, "sourceSA is null");
175 ret = sourceSA->DCameraNotify(sinkDevId, dhId_, jsonStr);
176 if (ret != DCAMERA_OK) {
177 DHLOGE("SourceSA notify failed, srcId: %{public}s, sinkId: %{public}s, dhId: %{public}s, ret: %{public}d",
178 GetAnonyString(srcDevId_).c_str(), GetAnonyString(sinkDevId).c_str(),
179 GetAnonyString(dhId_).c_str(), ret);
180 return ret;
181 }
182 }
183
184 DHLOGI("DCameraNotify %{public}s success", GetAnonyString(dhId_).c_str());
185 return DCAMERA_OK;
186 }
187
UpdateSettings(std::vector<std::shared_ptr<DCameraSettings>> & settings)188 int32_t DCameraSinkController::UpdateSettings(std::vector<std::shared_ptr<DCameraSettings>>& settings)
189 {
190 DHLOGI("UpdateSettings dhId: %{public}s", GetAnonyString(dhId_).c_str());
191 if (!CheckPermission()) {
192 DHLOGE("DCameraSinkController UpdateSettings fail, CheckPermission fail");
193 return DCAMERA_WRONG_STATE;
194 }
195 int32_t ret = operator_->UpdateSettings(settings);
196 if (ret != DCAMERA_OK) {
197 DHLOGE("UpdateSettings failed, dhId: %{public}s, ret: %{public}d", GetAnonyString(dhId_).c_str(), ret);
198 return ret;
199 }
200
201 DHLOGI("UpdateSettings %{public}s success", GetAnonyString(dhId_).c_str());
202 return DCAMERA_OK;
203 }
204
GetCameraInfo(std::shared_ptr<DCameraInfo> & camInfo)205 int32_t DCameraSinkController::GetCameraInfo(std::shared_ptr<DCameraInfo>& camInfo)
206 {
207 DHLOGI("GetCameraInfo dhId: %{public}s, session state: %{public}d", GetAnonyString(dhId_).c_str(), sessionState_);
208 camInfo->state_ = sessionState_;
209 return DCAMERA_OK;
210 }
211
CheckSensitive()212 int32_t DCameraSinkController::CheckSensitive()
213 {
214 if (sinkCallback_ == nullptr) {
215 DHLOGE("check sensitive callback is nullptr.");
216 return DCAMERA_BAD_VALUE;
217 }
218 int32_t ret = sinkCallback_->OnNotifyResourceInfo(ResourceEventType::EVENT_TYPE_QUERY_RESOURCE, PAGE_SUBTYPE,
219 srcDevId_, isSensitive_, isSameAccount_);
220 CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, ret, "Query resource failed, ret: %{public}d", ret);
221 DHLOGI("OpenChannel isSensitive: %{public}d, isSameAccout: %{public}d", isSensitive_, isSameAccount_);
222 if (isSensitive_ && !isSameAccount_) {
223 DHLOGE("Privacy resource must be logged in with the same account.");
224 return DCAMERA_BAD_VALUE;
225 }
226
227 if (isCheckSecLevel_) {
228 std::string sinkDevId;
229 ret = GetLocalDeviceNetworkId(sinkDevId);
230 CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, ret, "GetLocalDeviceNetworkId failed, ret: %{public}d", ret);
231 if (isSensitive_ && !CheckDeviceSecurityLevel(srcDevId_, sinkDevId)) {
232 DHLOGE("Check device security level failed!");
233 return DCAMERA_BAD_VALUE;
234 }
235 }
236 return DCAMERA_OK;
237 }
238
OpenChannel(std::shared_ptr<DCameraOpenInfo> & openInfo)239 int32_t DCameraSinkController::OpenChannel(std::shared_ptr<DCameraOpenInfo>& openInfo)
240 {
241 DHLOGI("DCameraSinkController OpenChannel Start, dhId: %{public}s", GetAnonyString(dhId_).c_str());
242 ManageSelectChannel::GetInstance().SetSinkConnect(false);
243 if (!CheckPermission()) {
244 DHLOGE("DCameraSinkController OpenChannel fail, CheckPermission fail");
245 return DCAMERA_WRONG_STATE;
246 }
247 if (sessionState_ != DCAMERA_CHANNEL_STATE_DISCONNECTED) {
248 DHLOGE("wrong state, dhId: %{public}s, sessionState: %{public}d", GetAnonyString(dhId_).c_str(), sessionState_);
249 return DCAMERA_WRONG_STATE;
250 }
251 srcDevId_ = openInfo->sourceDevId_;
252 int32_t ret = CheckSensitive();
253 if (ret != DCAMERA_OK) {
254 DHLOGE("check sensitive error, ret %{public}d", ret);
255 return ret;
256 }
257 std::vector<DCameraIndex> indexs;
258 indexs.push_back(DCameraIndex(srcDevId_, dhId_));
259 auto controller = std::shared_ptr<DCameraSinkController>(shared_from_this());
260 std::shared_ptr<ICameraChannelListener> listener =
261 std::make_shared<DCameraSinkControllerChannelListener>(controller);
262 ret = channel_->CreateSession(indexs, SESSION_FLAG, DCAMERA_SESSION_MODE_CTRL, listener);
263 if (ret != DCAMERA_OK) {
264 DHLOGE("channel create session failed, dhId: %{public}s, ret: %{public}d", GetAnonyString(dhId_).c_str(), ret);
265 return ret;
266 }
267 ret = PullUpPage();
268 CHECK_AND_RETURN_RET_LOG(ret != DCAMERA_OK, ret, "PullUpPage failed");
269 DHLOGI("DCameraSinkController OpenChannel %{public}s success", GetAnonyString(dhId_).c_str());
270 return DCAMERA_OK;
271 }
272
PullUpPage()273 int32_t DCameraSinkController::PullUpPage()
274 {
275 if (isSensitive_) {
276 bool isSensitive = false;
277 bool isSameAccout = false;
278 int32_t ret = sinkCallback_->OnNotifyResourceInfo(ResourceEventType::EVENT_TYPE_PULL_UP_PAGE, PAGE_SUBTYPE,
279 srcDevId_, isSensitive, isSameAccout);
280 if (ret != DCAMERA_OK) {
281 DHLOGE("pull up page failed, ret %{public}d", ret);
282 return ret;
283 }
284 isPageStatus_.store(true);
285 }
286 return DCAMERA_OK;
287 }
288
CloseChannel()289 int32_t DCameraSinkController::CloseChannel()
290 {
291 DHLOGI("DCameraSinkController CloseChannel Start, dhId: %{public}s", GetAnonyString(dhId_).c_str());
292 std::lock_guard<std::mutex> autoLock(channelLock_);
293 if (!ManageSelectChannel::GetInstance().GetSinkConnect()) {
294 DCameraSinkServiceIpc::GetInstance().DeleteSourceRemoteCamSrv(srcDevId_);
295 if (channel_ == nullptr) {
296 DHLOGE("DCameraSinkController CloseChannel channel_ is nullptr");
297 return DCAMERA_BAD_VALUE;
298 }
299 int32_t ret = channel_->ReleaseSession();
300 if (ret != DCAMERA_OK) {
301 DHLOGE("DCameraSinkController release channel failed, dhId: %{public}s, ret: %{public}d",
302 GetAnonyString(dhId_).c_str(), ret);
303 }
304
305 ret = output_->CloseChannel();
306 if (ret != DCAMERA_OK) {
307 DHLOGE("DCameraSinkController CloseChannel failed, dhId: %{public}s, ret: %{public}d",
308 GetAnonyString(dhId_).c_str(), ret);
309 }
310 }
311 srcDevId_.clear();
312 sessionState_ = DCAMERA_CHANNEL_STATE_DISCONNECTED;
313 if (isPageStatus_.load()) {
314 bool isSensitive = false;
315 bool isSameAccout = false;
316 int32_t ret = sinkCallback_->OnNotifyResourceInfo(ResourceEventType::EVENT_TYPE_CLOSE_PAGE, PAGE_SUBTYPE,
317 srcDevId_, isSensitive, isSameAccout);
318 if (ret != DCAMERA_OK) {
319 DHLOGE("close page failed, ret: %{public}d", ret);
320 }
321 }
322 isPageStatus_.store(false);
323 DHLOGI("DCameraSinkController CloseChannel %{public}s success", GetAnonyString(dhId_).c_str());
324 return DCAMERA_OK;
325 }
326
Init(std::vector<DCameraIndex> & indexs)327 int32_t DCameraSinkController::Init(std::vector<DCameraIndex>& indexs)
328 {
329 DHLOGI("DCameraSinkController Init");
330 dhId_ = indexs[0].dhId_;
331 operator_ = std::make_shared<DCameraClient>(dhId_);
332 output_ = std::make_shared<DCameraSinkOutput>(dhId_, operator_);
333 int32_t ret = output_->Init();
334 if (ret != DCAMERA_OK) {
335 DHLOGE("output init failed, dhId: %{public}s, ret: %{public}d", GetAnonyString(dhId_).c_str(), ret);
336 return ret;
337 }
338
339 auto controller = std::shared_ptr<DCameraSinkController>(shared_from_this());
340 std::shared_ptr<StateCallback> stateCallback = std::make_shared<DCameraSinkControllerStateCallback>(controller);
341 operator_->SetStateCallback(stateCallback);
342 ret = operator_->Init();
343 if (ret != DCAMERA_OK) {
344 DHLOGE("operator init failed, dhId: %{public}s, ret: %{public}d", GetAnonyString(dhId_).c_str(), ret);
345 return ret;
346 }
347
348 channel_ = std::make_shared<DCameraChannelSinkImpl>();
349 std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create(true);
350 sinkCotrEventHandler_ =
351 std::make_shared<DCameraSinkController::DCameraSinkContrEventHandler>(runner, shared_from_this());
352 isInit_ = true;
353 initCallback_ = std::make_shared<DeviceInitCallback>();
354 ManageSelectChannel::GetInstance().SetSinkConnect(true);
355 ret = CreateCtrlSession();
356 if (ret != DCAMERA_OK) {
357 DHLOGE("CreateCtrlSessiion init failed, dhId: %{public}s, ret: %{public}d", GetAnonyString(dhId_).c_str(), ret);
358 return ret;
359 }
360 std::shared_ptr<DCameraChannelInfo> info = std::make_shared<DCameraChannelInfo>();
361 info->sourceDevId_ = "";
362 DCameraChannelDetail continueChInfo(CONTINUE_SESSION_FLAG, CONTINUOUS_FRAME);
363 DCameraChannelDetail snapShotChInfo(SNAP_SHOT_SESSION_FLAG, SNAPSHOT_FRAME);
364 info->detail_.push_back(continueChInfo);
365 info->detail_.push_back(snapShotChInfo);
366 ret = ChannelNeg(info);
367 if (ret != DCAMERA_OK) {
368 DHLOGE("ChannelNeg init failed, dhId: %{public}s, ret: %{public}d", GetAnonyString(dhId_).c_str(), ret);
369 return ret;
370 }
371 DHLOGI("DCameraSinkController Init %{public}s success", GetAnonyString(dhId_).c_str());
372 return DCAMERA_OK;
373 }
374
CreateCtrlSession()375 int32_t DCameraSinkController::CreateCtrlSession()
376 {
377 DHLOGI("DCameraSinkController CreateCtrlSessiion Start, dhId: %{public}s", GetAnonyString(dhId_).c_str());
378 if (sessionState_ != DCAMERA_CHANNEL_STATE_DISCONNECTED) {
379 DHLOGE("wrong state, dhId: %{public}s, sessionState: %{public}d", GetAnonyString(dhId_).c_str(), sessionState_);
380 return DCAMERA_WRONG_STATE;
381 }
382 DCameraLowLatency::GetInstance().EnableLowLatency();
383 std::vector<DCameraIndex> indexs;
384 indexs.push_back(DCameraIndex("", dhId_));
385 auto controller = std::shared_ptr<DCameraSinkController>(shared_from_this());
386 std::shared_ptr<ICameraChannelListener> listener =
387 std::make_shared<DCameraSinkControllerChannelListener>(controller);
388 int32_t ret = channel_->CreateSession(indexs, SESSION_FLAG, DCAMERA_SESSION_MODE_CTRL, listener);
389 if (ret != DCAMERA_OK) {
390 DHLOGE("channel create session failed, dhId: %{public}s, ret: %{public}d", GetAnonyString(dhId_).c_str(), ret);
391 return ret;
392 }
393 DHLOGI("DCameraSinkController CreateCtrlSessiion %{public}s success", GetAnonyString(dhId_).c_str());
394 return DCAMERA_OK;
395 }
396
UnInit()397 int32_t DCameraSinkController::UnInit()
398 {
399 DHLOGI("DCameraSinkController UnInit dhId: %{public}s", GetAnonyString(dhId_).c_str());
400 std::lock_guard<std::mutex> autoLock(autoLock_);
401 int32_t ret = StopCapture();
402 if (ret != DCAMERA_OK) {
403 DHLOGE("DCameraSinkController UnInit %{public}s stop capture failed, ret: %{public}d",
404 GetAnonyString(dhId_).c_str(), ret);
405 }
406
407 ret = CloseChannel();
408 if (ret != DCAMERA_OK) {
409 DHLOGE("DCameraSinkController UnInit %{public}s close channel failed, ret: %{public}d",
410 GetAnonyString(dhId_).c_str(), ret);
411 }
412
413 DCameraLowLatency::GetInstance().DisableLowLatency();
414 if (ManageSelectChannel::GetInstance().GetSinkConnect()) {
415 if (channel_ != nullptr) {
416 ret = channel_->ReleaseSession();
417 if (ret != DCAMERA_OK) {
418 DHLOGE("DCameraSinkController release channel failed, dhId: %{public}s, ret: %{public}d",
419 GetAnonyString(dhId_).c_str(), ret);
420 }
421 }
422 if (output_ != nullptr) {
423 ret = output_->CloseChannel();
424 if (ret != DCAMERA_OK) {
425 DHLOGE("DCameraSinkController output CloseChannel failed, dhId: %{public}s, ret: %{public}d",
426 GetAnonyString(dhId_).c_str(), ret);
427 }
428 }
429 }
430
431 if (output_ != nullptr) {
432 ret = output_->UnInit();
433 if (ret != DCAMERA_OK) {
434 DHLOGE("DCameraSinkController release output failed, dhId: %{public}s, ret: %{public}d",
435 GetAnonyString(dhId_).c_str(), ret);
436 }
437 }
438
439 if (operator_ != nullptr) {
440 ret = operator_->UnInit();
441 if (ret != DCAMERA_OK) {
442 DHLOGE("DCameraSinkController release operator failed, dhId: %{public}s, ret: %{public}d",
443 GetAnonyString(dhId_).c_str(), ret);
444 }
445 }
446
447 isInit_ = false;
448 ManageSelectChannel::GetInstance().SetSinkConnect(false);
449 DHLOGI("DCameraSinkController UnInit %{public}s success", GetAnonyString(dhId_).c_str());
450 return DCAMERA_OK;
451 }
452
DCameraSinkContrEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner,std::shared_ptr<DCameraSinkController> sinkContrPtr)453 DCameraSinkController::DCameraSinkContrEventHandler::DCameraSinkContrEventHandler(
454 const std::shared_ptr<AppExecFwk::EventRunner> &runner, std::shared_ptr<DCameraSinkController> sinkContrPtr)
455 : AppExecFwk::EventHandler(runner), sinkContrWPtr_(sinkContrPtr)
456 {
457 DHLOGI("Ctor DCameraSinkContrEventHandler.");
458 }
459
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)460 void DCameraSinkController::DCameraSinkContrEventHandler::ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event)
461 {
462 CHECK_AND_RETURN_LOG(event == nullptr, "event is nullptr.");
463 uint32_t eventId = event->GetInnerEventId();
464 auto sinkContr = sinkContrWPtr_.lock();
465 if (sinkContr == nullptr) {
466 DHLOGE("Can not get strong self ptr");
467 return;
468 }
469 switch (eventId) {
470 case EVENT_FRAME_TRIGGER:
471 sinkContr->ProcessFrameTrigger(event);
472 break;
473 case EVENT_AUTHORIZATION:
474 sinkContr->ProcessPostAuthorization(event);
475 break;
476 default:
477 DHLOGE("event is undefined, id is %d", eventId);
478 break;
479 }
480 }
481
ProcessFrameTrigger(const AppExecFwk::InnerEvent::Pointer & event)482 void DCameraSinkController::ProcessFrameTrigger(const AppExecFwk::InnerEvent::Pointer &event)
483 {
484 DHLOGD("Receive frame trigger event then start process data in sink controller.");
485 std::shared_ptr<std::string> param = event->GetSharedObject<std::string>();
486 CHECK_AND_RETURN_LOG(param == nullptr, "ProcessFrameTrigger get param is null");
487 accessControl_->TriggerFrame(*param);
488 }
489
ProcessPostAuthorization(const AppExecFwk::InnerEvent::Pointer & event)490 void DCameraSinkController::ProcessPostAuthorization(const AppExecFwk::InnerEvent::Pointer &event)
491 {
492 DHLOGD("Receive post authorization event then start process data in sink controller.");
493 std::shared_ptr<std::vector<std::shared_ptr<DCameraCaptureInfo>>> captureInfos =
494 event->GetSharedObject<std::vector<std::shared_ptr<DCameraCaptureInfo>>>();
495 CHECK_AND_RETURN_LOG(captureInfos == nullptr, "ProcessPostAuthorization get captureInfos is null");
496 PostAuthorization(*captureInfos);
497 }
498
OnStateChanged(std::shared_ptr<DCameraEvent> & event)499 void DCameraSinkController::OnStateChanged(std::shared_ptr<DCameraEvent>& event)
500 {
501 DHLOGI("DCameraSinkController::OnStateChanged dhId: %{public}s, result: %{public}d",
502 GetAnonyString(dhId_).c_str(), event->eventResult_);
503 if (event->eventResult_ == DCAMERA_EVENT_DEVICE_PREEMPT) {
504 DCameraNotifyInner(DCAMERA_MESSAGE, DCAMERA_EVENT_DEVICE_PREEMPT, std::string("camera device preempted"));
505 } else {
506 DCameraNotifyInner(DCAMERA_MESSAGE, DCAMERA_EVENT_DEVICE_ERROR, std::string("camera error"));
507 }
508 }
509
OnMetadataResult(std::vector<std::shared_ptr<DCameraSettings>> & settings)510 void DCameraSinkController::OnMetadataResult(std::vector<std::shared_ptr<DCameraSettings>>& settings)
511 {
512 DHLOGI("DCameraSinkController::OnMetadataResult dhId: %{public}s", GetAnonyString(dhId_).c_str());
513 if (settings.empty()) {
514 DHLOGE("camera settings is empty");
515 return;
516 }
517 DCameraMetadataSettingCmd cmd;
518 cmd.type_ = DCAMERA_PROTOCOL_TYPE_MESSAGE;
519 cmd.dhId_ = dhId_;
520 cmd.command_ = DCAMERA_PROTOCOL_CMD_METADATA_RESULT;
521 cmd.value_.assign(settings.begin(), settings.end());
522 std::string jsonStr;
523 int32_t ret = cmd.Marshal(jsonStr);
524 if (ret != DCAMERA_OK) {
525 DHLOGE("Marshal metadata settings failed, dhId: %{public}s ret: %{public}d",
526 GetAnonyString(dhId_).c_str(), ret);
527 return;
528 }
529 std::shared_ptr<DataBuffer> buffer = std::make_shared<DataBuffer>(jsonStr.length() + 1);
530 ret = memcpy_s(buffer->Data(), buffer->Capacity(), reinterpret_cast<uint8_t *>(const_cast<char *>(jsonStr.c_str())),
531 jsonStr.length());
532 if (ret != EOK) {
533 DHLOGE("memcpy_s failed, dhId: %{public}s ret: %{public}d", GetAnonyString(dhId_).c_str(), ret);
534 return;
535 }
536 ret = channel_->SendData(buffer);
537 if (ret != DCAMERA_OK) {
538 DHLOGE("channel send data failed, dhId: %{public}s ret: %{public}d", GetAnonyString(dhId_).c_str(), ret);
539 return;
540 }
541 DHLOGI("DCameraSinkController::OnMetadataResult dhId: %{public}s success", GetAnonyString(dhId_).c_str());
542 }
543
OnSessionState(int32_t state,std::string networkId)544 void DCameraSinkController::OnSessionState(int32_t state, std::string networkId)
545 {
546 DHLOGI("DCameraSinkController::OnSessionState dhId: %{public}s, state: %{public}d",
547 GetAnonyString(dhId_).c_str(), state);
548 sessionState_ = state;
549 switch (state) {
550 case DCAMERA_CHANNEL_STATE_CONNECTING:
551 DHLOGI("channel is connecting");
552 break;
553 case DCAMERA_CHANNEL_STATE_CONNECTED: {
554 DHLOGI("channel is connected");
555 if (!ManageSelectChannel::GetInstance().GetSinkConnect()) {
556 break;
557 }
558 srcDevId_ = networkId;
559 int32_t ret = CheckSensitive();
560 if (ret != DCAMERA_OK) {
561 DHLOGE("Check sensitive error. ret %{public}d.", ret);
562 return;
563 }
564 ret = PullUpPage();
565 CHECK_AND_RETURN_LOG(ret != DCAMERA_OK, "PullUpPage failed");
566 break;
567 }
568 case DCAMERA_CHANNEL_STATE_DISCONNECTED: {
569 DHLOGI("channel is disconnected");
570 ffrt::submit([this]() {
571 DHLOGI("DCameraSinkController::OnSessionState %{public}s new thread session state: %{public}d",
572 GetAnonyString(dhId_).c_str(), sessionState_);
573 prctl(PR_SET_NAME, CHANNEL_DISCONNECTED.c_str());
574 std::lock_guard<std::mutex> autoLock(autoLock_);
575 int32_t ret = CloseChannel();
576 if (ret != DCAMERA_OK) {
577 DHLOGE("session state: %{public}d, %{public}s close channel failed, ret: %{public}d",
578 sessionState_, GetAnonyString(dhId_).c_str(), ret);
579 }
580 ret = StopCapture();
581 if (ret != DCAMERA_OK) {
582 DHLOGE("session state: %{public}d, %{public}s stop capture failed, ret: %{public}d",
583 sessionState_, GetAnonyString(dhId_).c_str(), ret);
584 }
585 });
586 break;
587 }
588 default:
589 DHLOGE("unknown session state");
590 break;
591 }
592 }
593
OnSessionError(int32_t eventType,int32_t eventReason,std::string detail)594 void DCameraSinkController::OnSessionError(int32_t eventType, int32_t eventReason, std::string detail)
595 {
596 DHLOGI("DCameraSinkController::OnSessionError dhId: %{public}s, eventType: %{public}d, eventReason: %{public}d,"
597 " detail: %{public}s", GetAnonyString(dhId_).c_str(), eventType, eventReason, detail.c_str());
598 }
599
OnDataReceived(std::vector<std::shared_ptr<DataBuffer>> & buffers)600 void DCameraSinkController::OnDataReceived(std::vector<std::shared_ptr<DataBuffer>>& buffers)
601 {
602 DHLOGI("OnReceivedData %{public}s control channel receive data", GetAnonyString(dhId_).c_str());
603 for (auto& buffer : buffers) {
604 if (buffer->Size() <= 0 || buffer->Size() > DATABUFF_MAX_SIZE) {
605 DHLOGI("buffer is invalid");
606 return;
607 }
608 HandleReceivedData(buffer);
609 }
610 }
611
PostAuthorization(std::vector<std::shared_ptr<DCameraCaptureInfo>> & captureInfos)612 void DCameraSinkController::PostAuthorization(std::vector<std::shared_ptr<DCameraCaptureInfo>>& captureInfos)
613 {
614 DHLOGI("DCameraSinkController::PostAuthorization dhId: %{public}s", GetAnonyString(dhId_).c_str());
615 int32_t ret = StartCaptureInner(captureInfos);
616 if (ret == DCAMERA_OK) {
617 accessControl_->NotifySensitiveSrc(SRC_TYPE);
618 }
619 }
620
StartCaptureInner(std::vector<std::shared_ptr<DCameraCaptureInfo>> & captureInfos)621 int32_t DCameraSinkController::StartCaptureInner(std::vector<std::shared_ptr<DCameraCaptureInfo>>& captureInfos)
622 {
623 DHLOGI("StartCaptureInner dhId: %{public}s", GetAnonyString(dhId_).c_str());
624 std::lock_guard<std::mutex> autoLock(captureLock_);
625 int32_t ret = output_->StartCapture(captureInfos);
626 if (ret != DCAMERA_OK) {
627 DHLOGE("output start capture failed, dhId: %{public}s, ret: %{public}d", GetAnonyString(dhId_).c_str(), ret);
628 DCameraNotifyInner(DCAMERA_MESSAGE, DCAMERA_EVENT_DEVICE_ERROR, std::string("output start capture failed"));
629 return ret;
630 }
631 PropertyCarrier carrier;
632 ret = output_->GetProperty(SURFACE, carrier);
633 if (ret != DCAMERA_OK) {
634 DHLOGD("StartCaptureInner: get property fail.");
635 return DCAMERA_BAD_VALUE;
636 }
637 ret = operator_->StartCapture(captureInfos, carrier.surface_, sceneMode_);
638 if (ret != DCAMERA_OK) {
639 DHLOGE("camera client start capture failed, dhId: %{public}s, ret: %{public}d",
640 GetAnonyString(dhId_).c_str(), ret);
641 if (ret == DCAMERA_ALLOC_ERROR) {
642 DCameraNotifyInner(DCAMERA_MESSAGE, DCAMERA_EVENT_NO_PERMISSION,
643 std::string("operator start capture permission denial."));
644 } else if (ret == DCAMERA_DEVICE_BUSY) {
645 DCameraNotifyInner(DCAMERA_MESSAGE, DCAMERA_EVENT_DEVICE_IN_USE,
646 std::string("operator start capture in used."));
647 }
648 return ret;
649 }
650
651 DCameraNotifyInner(DCAMERA_MESSAGE, DCAMERA_EVENT_CAMERA_SUCCESS, START_CAPTURE_SUCC);
652 DHLOGI("DCameraSinkController::StartCaptureInner %{public}s success", GetAnonyString(dhId_).c_str());
653 return DCAMERA_OK;
654 }
655
DCameraNotifyInner(int32_t type,int32_t result,std::string reason)656 int32_t DCameraSinkController::DCameraNotifyInner(int32_t type, int32_t result, std::string reason)
657 {
658 std::shared_ptr<DCameraEvent> event = std::make_shared<DCameraEvent>();
659 event->eventType_ = type;
660 event->eventResult_ = result;
661 event->eventContent_ = reason;
662 return DCameraNotify(event);
663 }
664
HandleReceivedData(std::shared_ptr<DataBuffer> & dataBuffer)665 int32_t DCameraSinkController::HandleReceivedData(std::shared_ptr<DataBuffer>& dataBuffer)
666 {
667 DHLOGI("DCameraSinkController::HandleReceivedData dhId: %{public}s", GetAnonyString(dhId_).c_str());
668 uint8_t *data = dataBuffer->Data();
669 std::string jsonStr(reinterpret_cast<const char *>(data), dataBuffer->Capacity());
670 cJSON *rootValue = cJSON_Parse(jsonStr.c_str());
671 if (rootValue == nullptr) {
672 return DCAMERA_BAD_VALUE;
673 }
674 cJSON *comvalue = cJSON_GetObjectItemCaseSensitive(rootValue, "Command");
675 if (comvalue == nullptr || !cJSON_IsString(comvalue) || (comvalue->valuestring == nullptr)) {
676 cJSON_Delete(rootValue);
677 DHLOGE("parse command failed");
678 return DCAMERA_BAD_VALUE;
679 }
680 std::string command = std::string(comvalue->valuestring);
681 cJSON_Delete(rootValue);
682 if ((!command.empty()) && (command.compare(DCAMERA_PROTOCOL_CMD_CAPTURE) == 0)) {
683 DCameraCaptureInfoCmd captureInfoCmd;
684 int32_t ret = captureInfoCmd.Unmarshal(jsonStr);
685 if (ret != DCAMERA_OK) {
686 DHLOGE("Capture Info Unmarshal failed, dhId: %{public}s ret: %{public}d",
687 GetAnonyString(dhId_).c_str(), ret);
688 return ret;
689 }
690 sceneMode_ = captureInfoCmd.sceneMode_;
691 return StartCapture(captureInfoCmd.value_, sceneMode_);
692 } else if ((!command.empty()) && (command.compare(DCAMERA_PROTOCOL_CMD_UPDATE_METADATA) == 0)) {
693 DCameraMetadataSettingCmd metadataSettingCmd;
694 int32_t ret = metadataSettingCmd.Unmarshal(jsonStr);
695 if (ret != DCAMERA_OK) {
696 DHLOGE("Metadata Setting Unmarshal failed, dhId: %{public}s ret: %{public}d",
697 GetAnonyString(dhId_).c_str(), ret);
698 return ret;
699 }
700 return UpdateSettings(metadataSettingCmd.value_);
701 } else if ((!command.empty()) && (command.compare(DCAMERA_PROTOCOL_CMD_STOP_CAPTURE) == 0)) {
702 return StopCapture();
703 }
704 return DCAMERA_BAD_VALUE;
705 }
706
PauseDistributedHardware(const std::string & networkId)707 int32_t DCameraSinkController::PauseDistributedHardware(const std::string &networkId)
708 {
709 DHLOGI("Pause distributed hardware dhId: %{public}s", GetAnonyString(dhId_).c_str());
710 if (networkId.empty()) {
711 DHLOGE("networkId is empty");
712 return DCAMERA_BAD_VALUE;
713 }
714 if (operator_ == nullptr) {
715 DHLOGE("operator_ is nullptr.");
716 return DCAMERA_BAD_VALUE;
717 }
718 int32_t ret = operator_->PauseCapture();
719 if (ret != DCAMERA_OK) {
720 DHLOGE("Pause distributed hardware failed, dhId: %{public}s, ret: %{public}d",
721 GetAnonyString(dhId_).c_str(), ret);
722 }
723 return ret;
724 }
725
ResumeDistributedHardware(const std::string & networkId)726 int32_t DCameraSinkController::ResumeDistributedHardware(const std::string &networkId)
727 {
728 DHLOGI("Resume distributed hardware dhId: %{public}s", GetAnonyString(dhId_).c_str());
729 if (networkId.empty()) {
730 DHLOGE("networkId is empty");
731 return DCAMERA_BAD_VALUE;
732 }
733 if (operator_ == nullptr) {
734 DHLOGE("operator_ is nullptr.");
735 return DCAMERA_BAD_VALUE;
736 }
737 int32_t ret = operator_->ResumeCapture();
738 if (ret != DCAMERA_OK) {
739 DHLOGE("Resume distributed hardware failed, dhId: %{public}s, ret: %{public}d",
740 GetAnonyString(dhId_).c_str(), ret);
741 }
742 return ret;
743 }
744
StopDistributedHardware(const std::string & networkId)745 int32_t DCameraSinkController::StopDistributedHardware(const std::string &networkId)
746 {
747 DHLOGI("Stop distributed hardware dhId: %{public}s", GetAnonyString(dhId_).c_str());
748 if (networkId.empty()) {
749 DHLOGE("networkId is empty");
750 return DCAMERA_BAD_VALUE;
751 }
752
753 isPageStatus_.store(false);
754 return DCameraNotifyInner(DCAMERA_SINK_STOP, DCAMERA_EVENT_SINK_STOP, std::string("sink stop dcamera business"));
755 }
756
CheckDeviceSecurityLevel(const std::string & srcDeviceId,const std::string & dstDeviceId)757 bool DCameraSinkController::CheckDeviceSecurityLevel(const std::string &srcDeviceId, const std::string &dstDeviceId)
758 {
759 DHLOGD("CheckDeviceSecurityLevel srcDeviceId %{public}s, dstDeviceId %{public}s.",
760 GetAnonyString(srcDeviceId).c_str(), GetAnonyString(dstDeviceId).c_str());
761 std::string srcUdid = GetUdidByNetworkId(srcDeviceId);
762 if (srcUdid.empty()) {
763 DHLOGE("src udid is empty");
764 return false;
765 }
766 std::string dstUdid = GetUdidByNetworkId(dstDeviceId);
767 if (dstUdid.empty()) {
768 DHLOGE("dst udid is empty");
769 return false;
770 }
771 DHLOGD("CheckDeviceSecurityLevel srcUdid %{public}s, dstUdid %{public}s.",
772 GetAnonyString(srcUdid).c_str(), GetAnonyString(dstUdid).c_str());
773 int32_t srcDeviceSecurityLevel = GetDeviceSecurityLevel(srcUdid);
774 int32_t dstDeviceSecurityLevel = GetDeviceSecurityLevel(dstUdid);
775 DHLOGI("srcDeviceSecurityLevel is %{public}d, dstDeviceSecurityLevel is %{public}d.",
776 srcDeviceSecurityLevel, dstDeviceSecurityLevel);
777 if (srcDeviceSecurityLevel == DEFAULT_DEVICE_SECURITY_LEVEL ||
778 srcDeviceSecurityLevel < dstDeviceSecurityLevel) {
779 DHLOGE("The device security of source device is lower.");
780 return false;
781 }
782 return true;
783 }
784
GetDeviceSecurityLevel(const std::string & udid)785 int32_t DCameraSinkController::GetDeviceSecurityLevel(const std::string &udid)
786 {
787 #ifdef DEVICE_SECURITY_LEVEL_ENABLE
788 DeviceIdentify devIdentify;
789 devIdentify.length = DEVICE_ID_MAX_LEN;
790 int32_t ret = memcpy_s(devIdentify.identity, DEVICE_ID_MAX_LEN, udid.c_str(), DEVICE_ID_MAX_LEN);
791 if (ret != 0) {
792 DHLOGE("str copy failed %{public}d", ret);
793 return DEFAULT_DEVICE_SECURITY_LEVEL;
794 }
795 DeviceSecurityInfo *info = nullptr;
796 ret = RequestDeviceSecurityInfo(&devIdentify, nullptr, &info);
797 if (ret != SUCCESS) {
798 DHLOGE("Request device security info failed %{public}d", ret);
799 FreeDeviceSecurityInfo(info);
800 info = nullptr;
801 return DEFAULT_DEVICE_SECURITY_LEVEL;
802 }
803 #endif
804 int32_t level = 0;
805 #ifdef DEVICE_SECURITY_LEVEL_ENABLE
806 ret = GetDeviceSecurityLevelValue(info, &level);
807 DHLOGD("Get device security level, level is %{public}d", level);
808 FreeDeviceSecurityInfo(info);
809 info = nullptr;
810 if (ret != SUCCESS) {
811 DHLOGE("Get device security level failed %{public}d", ret);
812 return DEFAULT_DEVICE_SECURITY_LEVEL;
813 }
814 #endif
815 return level;
816 }
817
GetUdidByNetworkId(const std::string & networkId)818 std::string DCameraSinkController::GetUdidByNetworkId(const std::string &networkId)
819 {
820 if (networkId.empty()) {
821 DHLOGE("networkId is empty!");
822 return "";
823 }
824 int32_t ret = DeviceManager::GetInstance().InitDeviceManager(DCAMERA_PKG_NAME, initCallback_);
825 if (ret != DCAMERA_OK) {
826 DHLOGE("InitDeviceManager failed ret = %{public}d", ret);
827 return "";
828 }
829 std::string udid = "";
830 ret = DeviceManager::GetInstance().GetUdidByNetworkId(DCAMERA_PKG_NAME, networkId, udid);
831 if (ret != DCAMERA_OK) {
832 DHLOGE("GetUdidByNetworkId failed ret = %{public}d", ret);
833 return "";
834 }
835 return udid;
836 }
837
CheckPermission()838 bool DCameraSinkController::CheckPermission()
839 {
840 DHLOGI("DCameraSinkController CheckPermission Start");
841 auto uid = IPCSkeleton::GetCallingUid();
842 return uid == DCAMERA_UID;
843 }
844
OnRemoteDied()845 void DeviceInitCallback::OnRemoteDied()
846 {
847 DHLOGI("DeviceInitCallback OnRemoteDied");
848 }
849 } // namespace DistributedHardware
850 } // namespace OHOS
851