• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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