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