1 /*
2 * Copyright (c) 2021-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 "hcapture_session.h"
17
18 #include "camera_util.h"
19 #include "camera_log.h"
20 #include "surface.h"
21 #include "ipc_skeleton.h"
22 #include "metadata_utils.h"
23 #include "bundle_mgr_interface.h"
24 #include "iservice_registry.h"
25 #include "system_ability_definition.h"
26
27 using namespace OHOS::AppExecFwk;
28 using namespace OHOS::AAFwk;
29
30 namespace OHOS {
31 namespace CameraStandard {
32 static std::map<int32_t, sptr<HCaptureSession>> session_;
33 static std::mutex sessionLock_;
34 static std::map<CaptureSessionState, std::string> sessionState_ = {
35 {CaptureSessionState::SESSION_INIT, "Init"},
36 {CaptureSessionState::SESSION_CONFIG_INPROGRESS, "Config_In-progress"},
37 {CaptureSessionState::SESSION_CONFIG_COMMITTED, "Committed"}
38 };
GetClientBundle(int uid)39 static std::string GetClientBundle(int uid)
40 {
41 std::string bundleName = "";
42 auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
43 if (samgr == nullptr) {
44 MEDIA_ERR_LOG("Get ability manager failed");
45 return bundleName;
46 }
47
48 sptr<IRemoteObject> object = samgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
49 if (object == nullptr) {
50 MEDIA_DEBUG_LOG("object is NULL.");
51 return bundleName;
52 }
53
54 sptr<AppExecFwk::IBundleMgr> bms = iface_cast<AppExecFwk::IBundleMgr>(object);
55 if (bms == nullptr) {
56 MEDIA_DEBUG_LOG("bundle manager service is NULL.");
57 return bundleName;
58 }
59
60 auto result = bms->GetBundleNameForUid(uid, bundleName);
61 if (!result) {
62 MEDIA_ERR_LOG("GetBundleNameForUid fail");
63 return "";
64 }
65 MEDIA_INFO_LOG("bundle name is %{public}s ", bundleName.c_str());
66
67 return bundleName;
68 }
69
HCaptureSession(sptr<HCameraHostManager> cameraHostManager,sptr<StreamOperatorCallback> streamOperatorCb,const uint32_t callingTokenId)70 HCaptureSession::HCaptureSession(sptr<HCameraHostManager> cameraHostManager,
71 sptr<StreamOperatorCallback> streamOperatorCb, const uint32_t callingTokenId)
72 : cameraHostManager_(cameraHostManager), streamOperatorCallback_(streamOperatorCb),
73 sessionCallback_(nullptr)
74 {
75 pid_ = IPCSkeleton::GetCallingPid();
76 uid_ = IPCSkeleton::GetCallingUid();
77 MEDIA_DEBUG_LOG("HCaptureSession: camera stub services(%{public}zu) pid(%{public}d).", session_.size(), pid_);
78 std::map<int32_t, sptr<HCaptureSession>> oldSessions;
79 for (auto it = session_.begin(); it != session_.end(); it++) {
80 sptr<HCaptureSession> session = it->second;
81 oldSessions[it->first] = session;
82 }
83 for (auto it = oldSessions.begin(); it != oldSessions.end(); it++) {
84 if (it->second != nullptr) {
85 sptr<HCaptureSession> session = it->second;
86 sptr<HCameraDevice> disconnectDevice;
87 int32_t rc = session->GetCameraDevice(disconnectDevice);
88 if (rc == CAMERA_OK) {
89 disconnectDevice->OnError(DEVICE_PREEMPT, 0);
90 }
91 session->Release(it->first);
92 MEDIA_ERR_LOG("currently multi-session not supported, release session for pid(%{public}d)", it->first);
93 }
94 }
95 std::lock_guard<std::mutex> lock(sessionLock_);
96 session_[pid_] = this;
97 callerToken_ = callingTokenId;
98 if (IsValidTokenId(callerToken_)) {
99 StartUsingPermissionCallback(callerToken_, ACCESS_CAMERA);
100 RegisterPermissionCallback(callerToken_, ACCESS_CAMERA);
101 }
102 MEDIA_DEBUG_LOG("HCaptureSession: camera stub services(%{public}zu).", session_.size());
103 }
104
~HCaptureSession()105 HCaptureSession::~HCaptureSession()
106 {}
107
BeginConfig()108 int32_t HCaptureSession::BeginConfig()
109 {
110 CAMERA_SYNC_TRACE;
111 if (curState_ == CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
112 MEDIA_ERR_LOG("HCaptureSession::BeginConfig Already in config inprogress state!");
113 return CAMERA_INVALID_STATE;
114 }
115 std::lock_guard<std::mutex> lock(sessionLock_);
116 prevState_ = curState_;
117 curState_ = CaptureSessionState::SESSION_CONFIG_INPROGRESS;
118 tempCameraDevices_.clear();
119 tempStreams_.clear();
120 deletedStreamIds_.clear();
121 return CAMERA_OK;
122 }
123
AddInput(sptr<ICameraDeviceService> cameraDevice)124 int32_t HCaptureSession::AddInput(sptr<ICameraDeviceService> cameraDevice)
125 {
126 CAMERA_SYNC_TRACE;
127 sptr<HCameraDevice> localCameraDevice = nullptr;
128
129 if (cameraDevice == nullptr) {
130 MEDIA_ERR_LOG("HCaptureSession::AddInput cameraDevice is null");
131 return CAMERA_INVALID_ARG;
132 }
133 std::lock_guard<std::mutex> lock(sessionLock_);
134 if (curState_ != CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
135 MEDIA_ERR_LOG("HCaptureSession::AddInput Need to call BeginConfig before adding input");
136 return CAMERA_INVALID_STATE;
137 }
138 if (!tempCameraDevices_.empty() || (cameraDevice_ != nullptr && !cameraDevice_->IsReleaseCameraDevice())) {
139 MEDIA_ERR_LOG("HCaptureSession::AddInput Only one input is supported");
140 return CAMERA_INVALID_SESSION_CFG;
141 }
142 localCameraDevice = static_cast<HCameraDevice*>(cameraDevice.GetRefPtr());
143 if (cameraDevice_ == localCameraDevice && cameraDevice_ != nullptr) {
144 cameraDevice_->SetReleaseCameraDevice(false);
145 } else {
146 tempCameraDevices_.emplace_back(localCameraDevice);
147 CAMERA_SYSEVENT_STATISTIC(CreateMsg("CaptureSession::AddInput"));
148 }
149
150 sptr<IStreamOperator> streamOperator;
151 int32_t rc = localCameraDevice->GetStreamOperator(streamOperatorCallback_, streamOperator);
152 if (rc != CAMERA_OK) {
153 MEDIA_ERR_LOG("HCaptureSession::GetCameraDevice GetStreamOperator returned %{public}d", rc);
154 localCameraDevice->Close();
155 return rc;
156 }
157 return CAMERA_OK;
158 }
159
AddOutputStream(sptr<HStreamCommon> stream)160 int32_t HCaptureSession::AddOutputStream(sptr<HStreamCommon> stream)
161 {
162 std::lock_guard<std::mutex> lock(sessionLock_);
163 if (stream == nullptr) {
164 MEDIA_ERR_LOG("HCaptureSession::AddOutputStream stream is null");
165 return CAMERA_INVALID_ARG;
166 }
167 if (curState_ != CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
168 MEDIA_ERR_LOG("HCaptureSession::AddOutputStream Need to call BeginConfig before adding output");
169 return CAMERA_INVALID_STATE;
170 }
171 if (std::find(tempStreams_.begin(), tempStreams_.end(), stream) != tempStreams_.end()) {
172 MEDIA_ERR_LOG("HCaptureSession::AddOutputStream Adding same output multiple times in tempStreams_");
173 return CAMERA_INVALID_SESSION_CFG;
174 }
175 auto it = std::find(streams_.begin(), streams_.end(), stream);
176 if (it != streams_.end()) {
177 if (stream && stream->IsReleaseStream()) {
178 stream->SetReleaseStream(false);
179 auto it2 = std::find(deletedStreamIds_.begin(), deletedStreamIds_.end(), stream->GetStreamId());
180 if (it2 != deletedStreamIds_.end()) {
181 deletedStreamIds_.erase(it2);
182 }
183 return CAMERA_OK;
184 } else {
185 MEDIA_ERR_LOG("HCaptureSession::AddOutputStream Adding same output multiple times in streams_");
186 return CAMERA_INVALID_SESSION_CFG;
187 }
188 }
189 if (stream) {
190 stream->SetReleaseStream(false);
191 }
192 tempStreams_.emplace_back(stream);
193 return CAMERA_OK;
194 }
195
AddOutput(StreamType streamType,sptr<IStreamCommon> stream)196 int32_t HCaptureSession::AddOutput(StreamType streamType, sptr<IStreamCommon> stream)
197 {
198 int32_t rc = CAMERA_INVALID_ARG;
199 if (stream == nullptr) {
200 MEDIA_ERR_LOG("HCaptureSession::AddOutput stream is null");
201 return rc;
202 }
203 // Temp hack to fix the library linking issue
204 sptr<Surface> captureSurface = Surface::CreateSurfaceAsConsumer();
205
206 if (streamType == StreamType::CAPTURE) {
207 rc = AddOutputStream(static_cast<HStreamCapture *>(stream.GetRefPtr()));
208 } else if (streamType == StreamType::REPEAT) {
209 rc = AddOutputStream(static_cast<HStreamRepeat *>(stream.GetRefPtr()));
210 } else if (streamType == StreamType::METADATA) {
211 rc = AddOutputStream(static_cast<HStreamMetadata *>(stream.GetRefPtr()));
212 }
213 CAMERA_SYSEVENT_STATISTIC(CreateMsg("CaptureSession::AddOutput with %d", streamType));
214 MEDIA_INFO_LOG("CaptureSession::AddOutput with with %{public}d, rc = %{public}d", streamType, rc);
215 return rc;
216 }
217
RemoveInput(sptr<ICameraDeviceService> cameraDevice)218 int32_t HCaptureSession::RemoveInput(sptr<ICameraDeviceService> cameraDevice)
219 {
220 if (cameraDevice == nullptr) {
221 MEDIA_ERR_LOG("HCaptureSession::RemoveInput cameraDevice is null");
222 return CAMERA_INVALID_ARG;
223 }
224 if (curState_ != CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
225 MEDIA_ERR_LOG("HCaptureSession::RemoveInput Need to call BeginConfig before removing input");
226 return CAMERA_INVALID_STATE;
227 }
228 std::lock_guard<std::mutex> lock(sessionLock_);
229 sptr<HCameraDevice> localCameraDevice;
230 localCameraDevice = static_cast<HCameraDevice*>(cameraDevice.GetRefPtr());
231 auto it = std::find(tempCameraDevices_.begin(), tempCameraDevices_.end(), localCameraDevice);
232 if (it != tempCameraDevices_.end()) {
233 tempCameraDevices_.erase(it);
234 } else if (cameraDevice_ != nullptr && cameraDevice_ == localCameraDevice) {
235 cameraDevice_->SetReleaseCameraDevice(true);
236 } else {
237 MEDIA_ERR_LOG("HCaptureSession::RemoveInput Invalid camera device");
238 return CAMERA_INVALID_SESSION_CFG;
239 }
240 CAMERA_SYSEVENT_STATISTIC(CreateMsg("CaptureSession::RemoveInput"));
241 return CAMERA_OK;
242 }
243
RemoveOutputStream(sptr<HStreamCommon> stream)244 int32_t HCaptureSession::RemoveOutputStream(sptr<HStreamCommon> stream)
245 {
246 if (stream == nullptr) {
247 MEDIA_ERR_LOG("HCaptureSession::RemoveOutputStream stream is null");
248 return CAMERA_INVALID_ARG;
249 }
250 if (curState_ != CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
251 MEDIA_ERR_LOG("HCaptureSession::RemoveOutputStream Need to call BeginConfig before removing output");
252 return CAMERA_INVALID_STATE;
253 }
254 auto it = std::find(tempStreams_.begin(), tempStreams_.end(), stream);
255 if (it != tempStreams_.end()) {
256 tempStreams_.erase(it);
257 } else {
258 it = std::find(streams_.begin(), streams_.end(), stream);
259 if (it != streams_.end()) {
260 if (stream && !stream->IsReleaseStream()) {
261 deletedStreamIds_.emplace_back(stream->GetStreamId());
262 stream->SetReleaseStream(true);
263 }
264 } else {
265 MEDIA_ERR_LOG("HCaptureSession::RemoveOutputStream Invalid output");
266 return CAMERA_INVALID_SESSION_CFG;
267 }
268 }
269 return CAMERA_OK;
270 }
271
RemoveOutput(StreamType streamType,sptr<IStreamCommon> stream)272 int32_t HCaptureSession::RemoveOutput(StreamType streamType, sptr<IStreamCommon> stream)
273 {
274 int32_t rc = CAMERA_INVALID_ARG;
275 if (stream == nullptr) {
276 MEDIA_ERR_LOG("HCaptureSession::RemoveOutput stream is null");
277 return rc;
278 }
279 std::lock_guard<std::mutex> lock(sessionLock_);
280 if (streamType == StreamType::CAPTURE) {
281 rc = RemoveOutputStream(static_cast<HStreamCapture *>(stream.GetRefPtr()));
282 } else if (streamType == StreamType::REPEAT) {
283 rc = RemoveOutputStream(static_cast<HStreamRepeat *>(stream.GetRefPtr()));
284 } else if (streamType == StreamType::METADATA) {
285 rc = RemoveOutputStream(static_cast<HStreamMetadata *>(stream.GetRefPtr()));
286 }
287 CAMERA_SYSEVENT_STATISTIC(CreateMsg("CaptureSession::RemoveOutput with %d", streamType));
288 return rc;
289 }
290
ValidateSessionInputs()291 int32_t HCaptureSession::ValidateSessionInputs()
292 {
293 if (tempCameraDevices_.empty() && (cameraDevice_ == nullptr || cameraDevice_->IsReleaseCameraDevice())) {
294 MEDIA_ERR_LOG("HCaptureSession::ValidateSessionInputs No inputs present");
295 return CAMERA_INVALID_SESSION_CFG;
296 }
297 return CAMERA_OK;
298 }
299
ValidateSessionOutputs()300 int32_t HCaptureSession::ValidateSessionOutputs()
301 {
302 if (tempStreams_.size() + streams_.size() - deletedStreamIds_.size() == 0) {
303 MEDIA_ERR_LOG("HCaptureSession::ValidateSessionOutputs No outputs present");
304 return CAMERA_INVALID_SESSION_CFG;
305 }
306 return CAMERA_OK;
307 }
308
GetCameraDevice(sptr<HCameraDevice> & device)309 int32_t HCaptureSession::GetCameraDevice(sptr<HCameraDevice> &device)
310 {
311 if (cameraDevice_ != nullptr && !cameraDevice_->IsReleaseCameraDevice()) {
312 MEDIA_DEBUG_LOG("HCaptureSession::GetCameraDevice Camera device has not changed");
313 device = cameraDevice_;
314 return CAMERA_OK;
315 } else if (!tempCameraDevices_.empty()) {
316 device = tempCameraDevices_[0];
317 return CAMERA_OK;
318 }
319
320 MEDIA_ERR_LOG("HCaptureSession::GetCameraDevice Failed because don't have camera device");
321 return CAMERA_INVALID_STATE;
322 }
323
GetCurrentStreamInfos(sptr<HCameraDevice> & device,std::shared_ptr<OHOS::Camera::CameraMetadata> & deviceSettings,std::vector<StreamInfo> & streamInfos)324 int32_t HCaptureSession::GetCurrentStreamInfos(sptr<HCameraDevice> &device,
325 std::shared_ptr<OHOS::Camera::CameraMetadata> &deviceSettings,
326 std::vector<StreamInfo> &streamInfos)
327 {
328 int32_t rc;
329 int32_t streamId = streamId_;
330 bool isNeedLink;
331 StreamInfo curStreamInfo;
332 sptr<IStreamOperator> streamOperator;
333 sptr<HStreamCommon> curStream;
334 if (device != nullptr) {
335 streamOperator = device->GetStreamOperator();
336 }
337 isNeedLink = (device != cameraDevice_);
338 for (auto item = streams_.begin(); item != streams_.end(); ++item) {
339 curStream = *item;
340 if (curStream && curStream->IsReleaseStream()) {
341 continue;
342 }
343 if (curStream && isNeedLink) {
344 rc = curStream->LinkInput(streamOperator, deviceSettings, streamId);
345 if (rc != CAMERA_OK) {
346 MEDIA_ERR_LOG("HCaptureSession::GetCurrentStreamInfos() Failed to link Output, %{public}d", rc);
347 return rc;
348 }
349 streamId++;
350 }
351 if (curStream) {
352 curStream->SetStreamInfo(curStreamInfo);
353 }
354 streamInfos.push_back(curStreamInfo);
355 }
356
357 if (streamId != streamId_) {
358 streamId_ = streamId;
359 }
360 return CAMERA_OK;
361 }
362
CreateAndCommitStreams(sptr<HCameraDevice> & device,std::shared_ptr<OHOS::Camera::CameraMetadata> & deviceSettings,std::vector<StreamInfo> & streamInfos)363 int32_t HCaptureSession::CreateAndCommitStreams(sptr<HCameraDevice> &device,
364 std::shared_ptr<OHOS::Camera::CameraMetadata> &deviceSettings,
365 std::vector<StreamInfo> &streamInfos)
366 {
367 CamRetCode hdiRc = HDI::Camera::V1_0::NO_ERROR;
368 StreamInfo curStreamInfo;
369 sptr<IStreamOperator> streamOperator;
370 if (device != nullptr) {
371 streamOperator = device->GetStreamOperator();
372 }
373 if (streamOperator != nullptr && !streamInfos.empty()) {
374 hdiRc = (CamRetCode)(streamOperator->CreateStreams(streamInfos));
375 } else {
376 MEDIA_INFO_LOG("HCaptureSession::CreateAndCommitStreams(), No new streams to create");
377 }
378 if (streamOperator != nullptr && hdiRc == HDI::Camera::V1_0::NO_ERROR) {
379 std::vector<uint8_t> setting;
380 OHOS::Camera::MetadataUtils::ConvertMetadataToVec(deviceSettings, setting);
381 hdiRc = (CamRetCode)(streamOperator->CommitStreams(NORMAL, setting));
382 if (hdiRc != HDI::Camera::V1_0::NO_ERROR) {
383 MEDIA_ERR_LOG("HCaptureSession::CreateAndCommitStreams(), Failed to commit %{public}d", hdiRc);
384 std::vector<int32_t> streamIds;
385 for (auto item = streamInfos.begin(); item != streamInfos.end(); ++item) {
386 curStreamInfo = *item;
387 streamIds.emplace_back(curStreamInfo.streamId_);
388 }
389 if (!streamIds.empty() && streamOperator->ReleaseStreams(streamIds) != HDI::Camera::V1_0::NO_ERROR) {
390 MEDIA_ERR_LOG("HCaptureSession::CreateAndCommitStreams(), Failed to release streams");
391 }
392 }
393 }
394 return HdiToServiceError(hdiRc);
395 }
396
CheckAndCommitStreams(sptr<HCameraDevice> & device,std::shared_ptr<OHOS::Camera::CameraMetadata> & deviceSettings,std::vector<StreamInfo> & allStreamInfos,std::vector<StreamInfo> & newStreamInfos)397 int32_t HCaptureSession::CheckAndCommitStreams(sptr<HCameraDevice> &device,
398 std::shared_ptr<OHOS::Camera::CameraMetadata> &deviceSettings,
399 std::vector<StreamInfo> &allStreamInfos,
400 std::vector<StreamInfo> &newStreamInfos)
401 {
402 return CreateAndCommitStreams(device, deviceSettings, newStreamInfos);
403 }
404
DeleteReleasedStream()405 void HCaptureSession::DeleteReleasedStream()
406 {
407 auto matchFunction = [](const auto& curStream) { return curStream->IsReleaseStream();};
408 captureStreams_.erase(std::remove_if(captureStreams_.begin(), captureStreams_.end(), matchFunction),
409 captureStreams_.end());
410 repeatStreams_.erase(std::remove_if(repeatStreams_.begin(), repeatStreams_.end(), matchFunction),
411 repeatStreams_.end());
412 metadataStreams_.erase(std::remove_if(metadataStreams_.begin(), metadataStreams_.end(), matchFunction),
413 metadataStreams_.end());
414 sptr<HStreamCommon> curStream;
415 for (auto item = streams_.begin(); item != streams_.end(); ++item) {
416 curStream = *item;
417 if (curStream && curStream->IsReleaseStream()) {
418 curStream->Release();
419 streams_.erase(item--);
420 }
421 }
422 }
423
RestorePreviousState(sptr<HCameraDevice> & device,bool isCreateReleaseStreams)424 void HCaptureSession::RestorePreviousState(sptr<HCameraDevice> &device, bool isCreateReleaseStreams)
425 {
426 std::vector<StreamInfo> streamInfos;
427 StreamInfo streamInfo;
428 std::shared_ptr<OHOS::Camera::CameraMetadata> settings;
429 sptr<HStreamCommon> curStream;
430
431 MEDIA_DEBUG_LOG("HCaptureSession::RestorePreviousState, Restore to previous state");
432
433 for (auto item = streams_.begin(); item != streams_.end(); ++item) {
434 curStream = *item;
435 if (curStream && isCreateReleaseStreams && curStream->IsReleaseStream()) {
436 curStream->SetStreamInfo(streamInfo);
437 streamInfos.push_back(streamInfo);
438 }
439 if (curStream) {
440 curStream->SetReleaseStream(false);
441 }
442 }
443
444 for (auto item = tempStreams_.begin(); item != tempStreams_.end(); ++item) {
445 curStream = *item;
446 if (curStream) {
447 curStream->Release();
448 }
449 }
450 tempStreams_.clear();
451 deletedStreamIds_.clear();
452 tempCameraDevices_.clear();
453 if (device != nullptr) {
454 device->SetReleaseCameraDevice(false);
455 if (isCreateReleaseStreams) {
456 settings = device->GetSettings();
457 if (settings != nullptr) {
458 CreateAndCommitStreams(device, settings, streamInfos);
459 }
460 }
461 }
462 curState_ = prevState_;
463 }
464
UpdateSessionConfig(sptr<HCameraDevice> & device)465 void HCaptureSession::UpdateSessionConfig(sptr<HCameraDevice> &device)
466 {
467 DeleteReleasedStream();
468 deletedStreamIds_.clear();
469
470 sptr<HStreamCommon> curStream;
471 for (auto item = tempStreams_.begin(); item != tempStreams_.end(); ++item) {
472 curStream = *item;
473 if (curStream && curStream->GetStreamType() == StreamType::REPEAT) {
474 repeatStreams_.emplace_back(curStream);
475 } else if (curStream && curStream->GetStreamType() == StreamType::CAPTURE) {
476 captureStreams_.emplace_back(curStream);
477 } else if (curStream && curStream->GetStreamType() == StreamType::METADATA) {
478 metadataStreams_.emplace_back(curStream);
479 }
480 streams_.emplace_back(curStream);
481 }
482 tempStreams_.clear();
483 if (streamOperatorCallback_ == nullptr) {
484 MEDIA_ERR_LOG("HCaptureSession::UpdateSessionConfig streamOperatorCallback_ is nullptr");
485 return;
486 }
487 streamOperatorCallback_->SetCaptureSession(this);
488 cameraDevice_ = device;
489 curState_ = CaptureSessionState::SESSION_CONFIG_COMMITTED;
490 }
491
HandleCaptureOuputsConfig(sptr<HCameraDevice> & device)492 int32_t HCaptureSession::HandleCaptureOuputsConfig(sptr<HCameraDevice> &device)
493 {
494 int32_t rc;
495 int32_t streamId;
496 std::vector<StreamInfo> newStreamInfos;
497 std::vector<StreamInfo> allStreamInfos;
498 StreamInfo curStreamInfo;
499 std::shared_ptr<OHOS::Camera::CameraMetadata> settings;
500 sptr<IStreamOperator> streamOperator;
501 sptr<HStreamCommon> curStream;
502 if (device != nullptr) {
503 settings = device->GetSettings();
504 }
505 if (device == nullptr || settings == nullptr) {
506 return CAMERA_UNKNOWN_ERROR;
507 }
508
509 rc = GetCurrentStreamInfos(device, settings, allStreamInfos);
510 if (rc != CAMERA_OK) {
511 MEDIA_ERR_LOG("HCaptureSession::HandleCaptureOuputsConfig() Failed to get streams info, %{public}d", rc);
512 return rc;
513 }
514
515 if (cameraDevice_ != device) {
516 newStreamInfos = allStreamInfos;
517 }
518
519 streamOperator = device->GetStreamOperator();
520 streamId = streamId_;
521 for (auto item = tempStreams_.begin(); item != tempStreams_.end(); ++item) {
522 curStream = *item;
523 if (curStream == nullptr) {
524 MEDIA_ERR_LOG("HCaptureSession::HandleCaptureOuputsConfig() curStream is null");
525 return CAMERA_UNKNOWN_ERROR;
526 }
527 if (curStream) {
528 rc = curStream->LinkInput(streamOperator, settings, streamId);
529 if (rc != CAMERA_OK) {
530 MEDIA_ERR_LOG("HCaptureSession::HandleCaptureOuputsConfig() Failed to link Output, %{public}d", rc);
531 return rc;
532 }
533 }
534 if (curStream) {
535 curStream->SetStreamInfo(curStreamInfo);
536 }
537 newStreamInfos.push_back(curStreamInfo);
538 allStreamInfos.push_back(curStreamInfo);
539 streamId++;
540 }
541
542 rc = CheckAndCommitStreams(device, settings, allStreamInfos, newStreamInfos);
543 if (rc == CAMERA_OK) {
544 streamId_ = streamId;
545 }
546 return rc;
547 }
548
CommitConfig()549 int32_t HCaptureSession::CommitConfig()
550 {
551 sptr<HCameraDevice> device = nullptr;
552
553 if (curState_ != CaptureSessionState::SESSION_CONFIG_INPROGRESS) {
554 MEDIA_ERR_LOG("HCaptureSession::CommitConfig() Need to call BeginConfig before committing configuration");
555 return CAMERA_INVALID_STATE;
556 }
557
558 int32_t rc = ValidateSessionInputs();
559 if (rc != CAMERA_OK) {
560 return rc;
561 }
562 rc = ValidateSessionOutputs();
563 if (rc != CAMERA_OK) {
564 return rc;
565 }
566
567 std::lock_guard<std::mutex> lock(sessionLock_);
568 rc = GetCameraDevice(device);
569 if ((rc == CAMERA_OK) && (device == cameraDevice_) && !deletedStreamIds_.empty()) {
570 rc = HdiToServiceError((CamRetCode)(device->GetStreamOperator()->ReleaseStreams(deletedStreamIds_)));
571 }
572
573 if (rc != CAMERA_OK) {
574 MEDIA_ERR_LOG("HCaptureSession::CommitConfig() Failed to commit config. camera device rc: %{public}d", rc);
575 if (device != nullptr && device != cameraDevice_) {
576 device->Close();
577 }
578 RestorePreviousState(cameraDevice_, false);
579 return rc;
580 }
581
582 rc = HandleCaptureOuputsConfig(device);
583 if (rc != CAMERA_OK) {
584 MEDIA_ERR_LOG("HCaptureSession::CommitConfig() Failed to commit config. rc: %{public}d", rc);
585 if (device != nullptr && device != cameraDevice_) {
586 device->Close();
587 }
588 RestorePreviousState(cameraDevice_, !deletedStreamIds_.empty());
589 return rc;
590 }
591 if (device != nullptr) {
592 int32_t pid = IPCSkeleton::GetCallingPid();
593 int32_t uid = IPCSkeleton::GetCallingUid();
594 POWERMGR_SYSEVENT_CAMERA_CONNECT(pid, uid, device->GetCameraId().c_str(),
595 GetClientBundle(uid));
596 }
597
598 if (cameraDevice_ != nullptr && device != cameraDevice_) {
599 cameraDevice_->Close();
600 cameraDevice_ = nullptr;
601 }
602 UpdateSessionConfig(device);
603 return rc;
604 }
605
GetSessionState(CaptureSessionState & sessionState)606 int32_t HCaptureSession::GetSessionState(CaptureSessionState &sessionState)
607 {
608 int32_t rc = CAMERA_OK;
609 sessionState = curState_;
610 return rc;
611 }
612
Start()613 int32_t HCaptureSession::Start()
614 {
615 int32_t rc = CAMERA_OK;
616 sptr<HStreamRepeat> curStreamRepeat;
617 if (curState_ != CaptureSessionState::SESSION_CONFIG_COMMITTED) {
618 MEDIA_ERR_LOG("HCaptureSession::Start(), Invalid session state: %{public}d", rc);
619 return CAMERA_INVALID_STATE;
620 }
621 std::lock_guard<std::mutex> lock(sessionLock_);
622 for (auto item = repeatStreams_.begin(); item != repeatStreams_.end(); ++item) {
623 curStreamRepeat = static_cast<HStreamRepeat *>((*item).GetRefPtr());
624 if (!curStreamRepeat->IsVideo()) {
625 rc = curStreamRepeat->Start();
626 if (rc != CAMERA_OK) {
627 MEDIA_ERR_LOG("HCaptureSession::Start(), Failed to start preview, rc: %{public}d", rc);
628 break;
629 }
630 }
631 }
632 return rc;
633 }
634
Stop()635 int32_t HCaptureSession::Stop()
636 {
637 int32_t rc = CAMERA_OK;
638 sptr<HStreamRepeat> curStreamRepeat;
639 if (curState_ != CaptureSessionState::SESSION_CONFIG_COMMITTED) {
640 return CAMERA_INVALID_STATE;
641 }
642 std::lock_guard<std::mutex> lock(sessionLock_);
643 for (auto item = repeatStreams_.begin(); item != repeatStreams_.end(); ++item) {
644 curStreamRepeat = static_cast<HStreamRepeat *>((*item).GetRefPtr());
645 if (!curStreamRepeat->IsVideo()) {
646 rc = curStreamRepeat->Stop();
647 if (rc != CAMERA_OK) {
648 MEDIA_ERR_LOG("HCaptureSession::Stop(), Failed to stop preview, rc: %{public}d", rc);
649 break;
650 }
651 }
652 }
653
654 return rc;
655 }
656
ClearCaptureSession(pid_t pid)657 void HCaptureSession::ClearCaptureSession(pid_t pid)
658 {
659 MEDIA_DEBUG_LOG("ClearCaptureSession: camera stub services(%{public}zu) pid(%{public}d).", session_.size(), pid);
660 auto it = session_.find(pid);
661 if (it != session_.end()) {
662 session_.erase(it);
663 }
664 MEDIA_DEBUG_LOG("ClearCaptureSession: camera stub services(%{public}zu).", session_.size());
665 }
666
ReleaseStreams()667 void HCaptureSession::ReleaseStreams()
668 {
669 std::vector<int32_t> streamIds;
670 sptr<HStreamCommon> curStream;
671
672 for (auto item = streams_.begin(); item != streams_.end(); ++item) {
673 curStream = *item;
674 if (curStream) {
675 streamIds.emplace_back(curStream->GetStreamId());
676 curStream->Release();
677 }
678 }
679 repeatStreams_.clear();
680 captureStreams_.clear();
681 metadataStreams_.clear();
682 streams_.clear();
683 if ((cameraDevice_ != nullptr) && (cameraDevice_->GetStreamOperator() != nullptr) && !streamIds.empty()) {
684 cameraDevice_->GetStreamOperator()->ReleaseStreams(streamIds);
685 }
686 }
687
ReleaseInner()688 int32_t HCaptureSession::ReleaseInner()
689 {
690 MEDIA_INFO_LOG("HCaptureSession::ReleaseInner enter");
691 return Release(pid_);
692 }
693
Release(pid_t pid)694 int32_t HCaptureSession::Release(pid_t pid)
695 {
696 std::lock_guard<std::mutex> lock(sessionLock_);
697 MEDIA_INFO_LOG("HCaptureSession::Release pid(%{public}d).", pid);
698 auto it = session_.find(pid);
699 if (it == session_.end()) {
700 MEDIA_DEBUG_LOG("HCaptureSession::Release session for pid(%{public}d) already released.", pid);
701 return CAMERA_OK;
702 }
703 ReleaseStreams();
704 tempCameraDevices_.clear();
705 if (streamOperatorCallback_ != nullptr) {
706 streamOperatorCallback_->SetCaptureSession(nullptr);
707 streamOperatorCallback_ = nullptr;
708 }
709 if (cameraDevice_ != nullptr) {
710 cameraDevice_->Close();
711 POWERMGR_SYSEVENT_CAMERA_DISCONNECT(cameraDevice_->GetCameraId().c_str());
712 cameraDevice_ = nullptr;
713 }
714 if (IsValidTokenId(callerToken_)) {
715 StopUsingPermissionCallback(callerToken_, ACCESS_CAMERA);
716 UnregisterPermissionCallback(callerToken_);
717 }
718 tempStreams_.clear();
719 ClearCaptureSession(pid);
720 sessionCallback_ = nullptr;
721 cameraHostManager_ = nullptr;
722 return CAMERA_OK;
723 }
724
RegisterPermissionCallback(const uint32_t callingTokenId,const std::string permissionName)725 void HCaptureSession::RegisterPermissionCallback(const uint32_t callingTokenId, const std::string permissionName)
726 {
727 Security::AccessToken::PermStateChangeScope scopeInfo;
728 scopeInfo.permList = {permissionName};
729 scopeInfo.tokenIDs = {callingTokenId};
730 callbackPtr_ = std::make_shared<PermissionStatusChangeCb>(scopeInfo);
731 callbackPtr_->SetCaptureSession(this);
732 MEDIA_DEBUG_LOG("after tokenId:%{public}d register", callingTokenId);
733 int32_t res = Security::AccessToken::AccessTokenKit::RegisterPermStateChangeCallback(callbackPtr_);
734 if (res != CAMERA_OK) {
735 MEDIA_ERR_LOG("RegisterPermStateChangeCallback failed.");
736 }
737 }
738
UnregisterPermissionCallback(const uint32_t callingTokenId)739 void HCaptureSession::UnregisterPermissionCallback(const uint32_t callingTokenId)
740 {
741 if (callbackPtr_ == nullptr) {
742 MEDIA_ERR_LOG("callbackPtr_ is null.");
743 return;
744 }
745 int32_t res = Security::AccessToken::AccessTokenKit::UnRegisterPermStateChangeCallback(callbackPtr_);
746 if (res != CAMERA_OK) {
747 MEDIA_ERR_LOG("UnRegisterPermStateChangeCallback failed.");
748 }
749 if (callbackPtr_) {
750 callbackPtr_->SetCaptureSession(nullptr);
751 callbackPtr_ = nullptr;
752 }
753 MEDIA_DEBUG_LOG("after tokenId:%{public}d unregister", callingTokenId);
754 }
755
DestroyStubObjectForPid(pid_t pid)756 void HCaptureSession::DestroyStubObjectForPid(pid_t pid)
757 {
758 MEDIA_DEBUG_LOG("camera stub services(%{public}zu) pid(%{public}d).", session_.size(), pid);
759 sptr<HCaptureSession> session;
760
761 auto it = session_.find(pid);
762 if (it != session_.end()) {
763 if (it->second != nullptr) {
764 session = it->second;
765 session->Release(pid);
766 }
767 }
768 MEDIA_DEBUG_LOG("camera stub services(%{public}zu).", session_.size());
769 }
770
SetCallback(sptr<ICaptureSessionCallback> & callback)771 int32_t HCaptureSession::SetCallback(sptr<ICaptureSessionCallback> &callback)
772 {
773 if (callback == nullptr) {
774 MEDIA_ERR_LOG("HCaptureSession::SetCallback callback is null");
775 return CAMERA_INVALID_ARG;
776 }
777
778 sessionCallback_ = callback;
779 return CAMERA_OK;
780 }
781
GetSessionState()782 std::string HCaptureSession::GetSessionState()
783 {
784 std::map<CaptureSessionState, std::string>::const_iterator iter =
785 sessionState_.find(curState_);
786 if (iter != sessionState_.end()) {
787 return iter->second;
788 }
789 return nullptr;
790 }
791
CameraSessionSummary(std::string & dumpString)792 void HCaptureSession::CameraSessionSummary(std::string& dumpString)
793 {
794 dumpString += "# Number of Camera clients:[" + std::to_string(session_.size()) + "]:\n";
795 }
796
dumpSessions(std::string & dumpString)797 void HCaptureSession::dumpSessions(std::string& dumpString)
798 {
799 for (auto it = session_.begin(); it != session_.end(); it++) {
800 if (it->second != nullptr) {
801 sptr<HCaptureSession> session = it->second;
802 dumpString += "No. of sessions for client:[" + std::to_string(1) + "]:\n";
803 session->dumpSessionInfo(dumpString);
804 }
805 }
806 }
807
dumpSessionInfo(std::string & dumpString)808 void HCaptureSession::dumpSessionInfo(std::string& dumpString)
809 {
810 dumpString += "Client pid:[" + std::to_string(pid_)
811 + "] Client uid:[" + std::to_string(uid_) + "]:\n";
812 dumpString += "session state:[" + GetSessionState() + "]:\n";
813 if (cameraDevice_ != nullptr) {
814 dumpString += "session Camera Id:[" + cameraDevice_->GetCameraId() + "]:\n";
815 dumpString += "session Camera release status:["
816 + std::to_string(cameraDevice_->IsReleaseCameraDevice()) + "]:\n";
817 }
818 for (const auto& stream : captureStreams_) {
819 stream->DumpStreamInfo(dumpString);
820 }
821 for (const auto& stream : repeatStreams_) {
822 stream->DumpStreamInfo(dumpString);
823 }
824 for (const auto& stream : metadataStreams_) {
825 stream->DumpStreamInfo(dumpString);
826 }
827 }
828
StartUsingPermissionCallback(const uint32_t callingTokenId,const std::string permissionName)829 void HCaptureSession::StartUsingPermissionCallback(const uint32_t callingTokenId, const std::string permissionName)
830 {
831 cameraUseCallbackPtr_ = std::make_shared<CameraUseStateChangeCb>();
832 cameraUseCallbackPtr_->SetCaptureSession(this);
833 MEDIA_DEBUG_LOG("after StartUsingPermissionCallback tokenId:%{public}d", callingTokenId);
834 int32_t res = Security::AccessToken::PrivacyKit::StartUsingPermission(
835 callingTokenId, permissionName, cameraUseCallbackPtr_);
836 if (res != CAMERA_OK) {
837 MEDIA_ERR_LOG("StartUsingPermissionCallback failed.");
838 }
839 }
840
StopUsingPermissionCallback(const uint32_t callingTokenId,const std::string permissionName)841 void HCaptureSession::StopUsingPermissionCallback(const uint32_t callingTokenId, const std::string permissionName)
842 {
843 MEDIA_DEBUG_LOG("enter StopUsingPermissionCallback tokenId:%{public}d", callingTokenId);
844 int32_t res = Security::AccessToken::PrivacyKit::StopUsingPermission(callingTokenId, permissionName);
845 if (res != CAMERA_OK) {
846 MEDIA_ERR_LOG("StopUsingPermissionCallback failed.");
847 }
848 if (cameraUseCallbackPtr_) {
849 cameraUseCallbackPtr_->SetCaptureSession(nullptr);
850 cameraUseCallbackPtr_ = nullptr;
851 }
852 }
853
~PermissionStatusChangeCb()854 PermissionStatusChangeCb::~PermissionStatusChangeCb()
855 {
856 captureSession_ = nullptr;
857 }
858
SetCaptureSession(sptr<HCaptureSession> captureSession)859 void PermissionStatusChangeCb::SetCaptureSession(sptr<HCaptureSession> captureSession)
860 {
861 captureSession_ = captureSession;
862 }
863
PermStateChangeCallback(Security::AccessToken::PermStateChangeInfo & result)864 void PermissionStatusChangeCb::PermStateChangeCallback(Security::AccessToken::PermStateChangeInfo& result)
865 {
866 auto item = captureSession_.promote();
867 if ((result.PermStateChangeType == 0) && (item != nullptr)) {
868 item->ReleaseInner();
869 }
870 };
871
~CameraUseStateChangeCb()872 CameraUseStateChangeCb::~CameraUseStateChangeCb()
873 {
874 captureSession_ = nullptr;
875 }
876
SetCaptureSession(sptr<HCaptureSession> captureSession)877 void CameraUseStateChangeCb::SetCaptureSession(sptr<HCaptureSession> captureSession)
878 {
879 captureSession_ = captureSession;
880 }
881
StateChangeNotify(Security::AccessToken::AccessTokenID tokenId,bool isShowing)882 void CameraUseStateChangeCb::StateChangeNotify(Security::AccessToken::AccessTokenID tokenId, bool isShowing)
883 {
884 const int32_t delayProcessTime = 200000;
885 usleep(delayProcessTime);
886 MEDIA_INFO_LOG("enter CameraUseStateChangeNotify tokenId:%{public}d", tokenId);
887 auto item = captureSession_.promote();
888 if ((isShowing == false) && (item != nullptr)) {
889 item->ReleaseInner();
890 }
891 };
892
893
StreamOperatorCallback(sptr<HCaptureSession> session)894 StreamOperatorCallback::StreamOperatorCallback(sptr<HCaptureSession> session)
895 {
896 captureSession_ = session;
897 }
898
~StreamOperatorCallback()899 StreamOperatorCallback::~StreamOperatorCallback()
900 {
901 captureSession_ = nullptr;
902 }
903
GetStreamByStreamID(int32_t streamId)904 sptr<HStreamCommon> StreamOperatorCallback::GetStreamByStreamID(int32_t streamId)
905 {
906 sptr<HStreamCommon> curStream;
907 sptr<HStreamCommon> result = nullptr;
908 std::lock_guard<std::mutex> lock(sessionLock_);
909 if (captureSession_ != nullptr) {
910 for (auto item = captureSession_->streams_.begin(); item != captureSession_->streams_.end(); ++item) {
911 curStream = *item;
912 if (curStream && curStream->GetStreamId() == streamId) {
913 result = curStream;
914 break;
915 }
916 }
917 }
918 return result;
919 }
920
OnCaptureStarted(int32_t captureId,const std::vector<int32_t> & streamIds)921 int32_t StreamOperatorCallback::OnCaptureStarted(int32_t captureId,
922 const std::vector<int32_t> &streamIds)
923 {
924 sptr<HStreamCommon> curStream;
925
926 for (auto item = streamIds.begin(); item != streamIds.end(); ++item) {
927 curStream = GetStreamByStreamID(*item);
928 if (curStream == nullptr) {
929 MEDIA_ERR_LOG("StreamOperatorCallback::OnCaptureStarted StreamId: %{public}d not found", *item);
930 return CAMERA_INVALID_ARG;
931 } else if (curStream->GetStreamType() == StreamType::REPEAT) {
932 static_cast<HStreamRepeat *>(curStream.GetRefPtr())->OnFrameStarted();
933 } else if (curStream->GetStreamType() == StreamType::CAPTURE) {
934 static_cast<HStreamCapture *>(curStream.GetRefPtr())->OnCaptureStarted(captureId);
935 }
936 }
937 return CAMERA_OK;
938 }
939
OnCaptureEnded(int32_t captureId,const std::vector<CaptureEndedInfo> & infos)940 int32_t StreamOperatorCallback::OnCaptureEnded(int32_t captureId, const std::vector<CaptureEndedInfo>& infos)
941 {
942 sptr<HStreamCommon> curStream;
943 CaptureEndedInfo captureInfo;
944
945 for (auto item = infos.begin(); item != infos.end(); ++item) {
946 captureInfo = *item;
947 curStream = GetStreamByStreamID(captureInfo.streamId_);
948 if (curStream == nullptr) {
949 MEDIA_ERR_LOG("StreamOperatorCallback::OnCaptureEnded StreamId: %{public}d not found."
950 " Framecount: %{public}d", captureInfo.streamId_, captureInfo.frameCount_);
951 return CAMERA_INVALID_ARG;
952 } else if (curStream->GetStreamType() == StreamType::REPEAT) {
953 static_cast<HStreamRepeat *>(curStream.GetRefPtr())->OnFrameEnded(captureInfo.frameCount_);
954 } else if (curStream->GetStreamType() == StreamType::CAPTURE) {
955 static_cast<HStreamCapture *>(curStream.GetRefPtr())->OnCaptureEnded(captureId, captureInfo.frameCount_);
956 }
957 }
958 return CAMERA_OK;
959 }
960
OnCaptureError(int32_t captureId,const std::vector<CaptureErrorInfo> & infos)961 int32_t StreamOperatorCallback::OnCaptureError(int32_t captureId, const std::vector<CaptureErrorInfo>& infos)
962 {
963 sptr<HStreamCommon> curStream;
964 CaptureErrorInfo errInfo;
965
966 for (auto item = infos.begin(); item != infos.end(); ++item) {
967 errInfo = *item;
968 curStream = GetStreamByStreamID(errInfo.streamId_);
969 if (curStream == nullptr) {
970 MEDIA_ERR_LOG("StreamOperatorCallback::OnCaptureError StreamId: %{public}d not found."
971 " Error: %{public}d", errInfo.streamId_, errInfo.error_);
972 return CAMERA_INVALID_ARG;
973 } else if (curStream->GetStreamType() == StreamType::REPEAT) {
974 static_cast<HStreamRepeat *>(curStream.GetRefPtr())->OnFrameError(errInfo.error_);
975 } else if (curStream->GetStreamType() == StreamType::CAPTURE) {
976 static_cast<HStreamCapture *>(curStream.GetRefPtr())->OnCaptureError(captureId, errInfo.error_);
977 }
978 }
979 return CAMERA_OK;
980 }
981
OnFrameShutter(int32_t captureId,const std::vector<int32_t> & streamIds,uint64_t timestamp)982 int32_t StreamOperatorCallback::OnFrameShutter(int32_t captureId,
983 const std::vector<int32_t> &streamIds,
984 uint64_t timestamp)
985 {
986 sptr<HStreamCommon> curStream;
987
988 for (auto item = streamIds.begin(); item != streamIds.end(); ++item) {
989 curStream = GetStreamByStreamID(*item);
990 if ((curStream != nullptr) && (curStream->GetStreamType() == StreamType::CAPTURE)) {
991 static_cast<HStreamCapture *>(curStream.GetRefPtr())->OnFrameShutter(captureId, timestamp);
992 } else {
993 MEDIA_ERR_LOG("StreamOperatorCallback::OnFrameShutter StreamId: %{public}d not found", *item);
994 return CAMERA_INVALID_ARG;
995 }
996 }
997 return CAMERA_OK;
998 }
999
SetCaptureSession(sptr<HCaptureSession> captureSession)1000 void StreamOperatorCallback::SetCaptureSession(sptr<HCaptureSession> captureSession)
1001 {
1002 captureSession_ = captureSession;
1003 }
1004 } // namespace CameraStandard
1005 } // namespace OHOS
1006