• 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 
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