• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "dcamera_host.h"
17 
18 #include "anonymous_string.h"
19 #include "distributed_hardware_log.h"
20 #include "metadata_utils.h"
21 #include "dcamera.h"
22 
23 namespace OHOS {
24 namespace DistributedHardware {
25 OHOS::sptr<DCameraHost> DCameraHost::instance_ = nullptr;
26 DCameraHost::AutoRelease DCameraHost::autoRelease_;
27 
CameraHostImplGetInstance(void)28 extern "C" ICameraHost *CameraHostImplGetInstance(void)
29 {
30     return static_cast<ICameraHost *>(DCameraHost::GetInstance().GetRefPtr());
31 }
32 
GetInstance()33 OHOS::sptr<DCameraHost> DCameraHost::GetInstance()
34 {
35     if (instance_ == nullptr) {
36         instance_ = new DCameraHost();
37         if (instance_ == nullptr) {
38             DHLOGE("Get distributed camera host instance failed.");
39             return nullptr;
40         }
41     }
42     return instance_;
43 }
44 
SetCallback(const sptr<ICameraHostCallback> & callbackObj)45 int32_t DCameraHost::SetCallback(const sptr<ICameraHostCallback> &callbackObj)
46 {
47     if (callbackObj == nullptr) {
48         DHLOGE("DCameraHost::SetCallback, input camera host callback is null.");
49         return CamRetCode::INVALID_ARGUMENT;
50     }
51     dCameraHostCallback_ = callbackObj;
52     return CamRetCode::NO_ERROR;
53 }
54 
GetCameraIds(std::vector<std::string> & cameraIds)55 int32_t DCameraHost::GetCameraIds(std::vector<std::string> &cameraIds)
56 {
57     auto iter = dhBaseHashDCamIdMap_.begin();
58     while (iter != dhBaseHashDCamIdMap_.end()) {
59         if (!(iter->second).empty()) {
60             cameraIds.push_back(iter->second);
61         }
62         iter++;
63     }
64     return CamRetCode::NO_ERROR;
65 }
66 
GetCameraAbility(const std::string & cameraId,std::vector<uint8_t> & cameraAbility)67 int32_t DCameraHost::GetCameraAbility(const std::string &cameraId, std::vector<uint8_t> &cameraAbility)
68 {
69     if (IsCameraIdInvalid(cameraId)) {
70         DHLOGE("DCameraHost::GetCameraAbility, input cameraId is invalid.");
71         return CamRetCode::INVALID_ARGUMENT;
72     }
73 
74     DHLOGE("DCameraHost::GetCameraAbility for cameraId: %s", GetAnonyString(cameraId).c_str());
75 
76     auto iter = dCameraDeviceMap_.find(cameraId);
77     std::shared_ptr<CameraAbility> ability = nullptr;
78     int32_t ret = (iter->second)->GetDCameraAbility(ability);
79     if (ret != CamRetCode::NO_ERROR) {
80         DHLOGE("DCameraHost::GetCameraAbility, GetDCameraAbility failed, ret: %d.", ret);
81         return ret;
82     }
83     bool retBool = OHOS::Camera::MetadataUtils::ConvertMetadataToVec(ability, cameraAbility);
84     if (!retBool) {
85         DHLOGE("DCameraHost::GetCameraAbility, ConvertMetadataToVec failed.");
86         return CamRetCode::INVALID_ARGUMENT;
87     }
88 
89     do {
90         camera_metadata_item_t item;
91         constexpr uint32_t WIDTH_OFFSET = 1;
92         constexpr uint32_t HEIGHT_OFFSET = 2;
93         constexpr uint32_t UNIT_LENGTH = 3;
94         ret = OHOS::Camera::FindCameraMetadataItem(ability->get(),
95             OHOS_ABILITY_STREAM_AVAILABLE_BASIC_CONFIGURATIONS, &item);
96         DHLOGI("FindCameraMetadataItem item=%u, count=%u, dataType=%u", item.item, item.count, item.data_type);
97         if (ret != CAM_META_SUCCESS) {
98             DHLOGE("Failed to find stream configuration in camera ability with return code %d", ret);
99             break;
100         }
101         if (item.count % UNIT_LENGTH != 0) {
102             DHLOGE("Invalid stream configuration count: %u", item.count);
103             break;
104         }
105         for (uint32_t index = 0; index < item.count; index += UNIT_LENGTH) {
106             int32_t format = item.data.i32[index];
107             int32_t width = item.data.i32[index + WIDTH_OFFSET];
108             int32_t height = item.data.i32[index + HEIGHT_OFFSET];
109             DHLOGD("format: %d, width: %d, height: %d", format, width, height);
110         }
111     } while (0);
112     return CamRetCode::NO_ERROR;
113 }
114 
OpenCamera(const std::string & cameraId,const sptr<ICameraDeviceCallback> & callbackObj,sptr<ICameraDevice> & device)115 int32_t DCameraHost::OpenCamera(const std::string &cameraId, const sptr<ICameraDeviceCallback> &callbackObj,
116     sptr<ICameraDevice> &device)
117 {
118     if (IsCameraIdInvalid(cameraId) || callbackObj == nullptr) {
119         DHLOGE("DCameraHost::OpenCamera, open camera id is invalid or camera device callback is null.");
120         return CamRetCode::INVALID_ARGUMENT;
121     }
122 
123     DHLOGI("DCameraHost::OpenCamera for cameraId: %s", GetAnonyString(cameraId).c_str());
124 
125     auto iter = dCameraDeviceMap_.find(cameraId);
126     if (iter == dCameraDeviceMap_.end()) {
127         DHLOGE("DCameraHost::OpenCamera, dcamera device not found.");
128         return CamRetCode::INSUFFICIENT_RESOURCES;
129     }
130 
131     OHOS::sptr<DCameraDevice> dcameraDevice = iter->second;
132     if (dcameraDevice == nullptr) {
133         DHLOGE("DCameraHost::OpenCamera, dcamera device is null.");
134         return INSUFFICIENT_RESOURCES;
135     }
136 
137     if (dcameraDevice->IsOpened()) {
138         DHLOGE("DCameraHost::OpenCamera, dcamera device %s already opened.", GetAnonyString(cameraId).c_str());
139         return CamRetCode::CAMERA_BUSY;
140     }
141 
142     CamRetCode ret = dcameraDevice->OpenDCamera(callbackObj);
143     if (ret != CamRetCode::NO_ERROR) {
144         DHLOGE("DCameraHost::OpenCamera, open camera failed.");
145         return ret;
146     }
147     device = dcameraDevice;
148 
149     DHLOGI("DCameraHost::OpenCamera, open camera %s success.", GetAnonyString(cameraId).c_str());
150     return CamRetCode::NO_ERROR;
151 }
152 
SetFlashlight(const std::string & cameraId,bool isEnable)153 int32_t DCameraHost::SetFlashlight(const std::string &cameraId, bool isEnable)
154 {
155     (void)cameraId;
156     (void)isEnable;
157     DHLOGI("DCameraHost::SetFlashlight, distributed camera not support.");
158 
159     return CamRetCode::METHOD_NOT_SUPPORTED;
160 }
161 
AddDCameraDevice(const DHBase & dhBase,const std::string & abilityInfo,const sptr<IDCameraProviderCallback> & callback)162 DCamRetCode DCameraHost::AddDCameraDevice(const DHBase &dhBase, const std::string &abilityInfo,
163     const sptr<IDCameraProviderCallback> &callback)
164 {
165     if (IsDhBaseInfoInvalid(dhBase)) {
166         DHLOGE("DCameraHost::AddDCameraDevice, devId or dhId is invalid.");
167         return DCamRetCode::INVALID_ARGUMENT;
168     }
169     DHLOGI("DCameraHost::AddDCameraDevice for {devId: %s, dhId: %s}",
170         GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
171 
172     if (abilityInfo.empty() || abilityInfo.length() > ABILITYINFO_MAX_LENGTH) {
173         DHLOGE("DCameraHost::AddDCameraDevice, input abilityInfo is invalid.");
174         return DCamRetCode::INVALID_ARGUMENT;
175     }
176 
177     OHOS::sptr<DCameraDevice> dcameraDevice(new (std::nothrow) DCameraDevice(dhBase, abilityInfo));
178     if (dcameraDevice == nullptr) {
179         DHLOGE("DCameraHost::AddDCameraDevice, create dcamera device failed.");
180         return DCamRetCode::INVALID_ARGUMENT;
181     }
182 
183     std::string dCameraId = dcameraDevice->GetDCameraId();
184     dCameraDeviceMap_[dCameraId] = dcameraDevice;
185     DCameraBase dcameraBase(dhBase.deviceId_, dhBase.dhId_);
186     dhBaseHashDCamIdMap_.emplace(dcameraBase, dCameraId);
187     dcameraDevice->SetProviderCallback(callback);
188 
189     if (dCameraHostCallback_ != nullptr) {
190         dCameraHostCallback_->OnCameraEvent(dCameraId, CameraEvent::CAMERA_EVENT_DEVICE_ADD);
191     }
192 
193     DHLOGI("DCameraHost::AddDCameraDevice, create dcamera device success, dCameraId: %s",
194         GetAnonyString(dCameraId).c_str());
195     return DCamRetCode::SUCCESS;
196 }
197 
RemoveDCameraDevice(const DHBase & dhBase)198 DCamRetCode DCameraHost::RemoveDCameraDevice(const DHBase &dhBase)
199 {
200     DHLOGI("DCameraHost::RemoveDCameraDevice for {devId: %s, dhId: %s}",
201         GetAnonyString(dhBase.deviceId_).c_str(), GetAnonyString(dhBase.dhId_).c_str());
202 
203     std::string dCameraId = GetCameraIdByDHBase(dhBase);
204     if (dCameraId.empty()) {
205         DHLOGE("DCameraHost::RemoveDCameraDevice, dhBase not exist.");
206         return DCamRetCode::INVALID_ARGUMENT;
207     }
208 
209     OHOS::sptr<DCameraDevice> dcameraDevice = GetDCameraDeviceByDHBase(dhBase);
210     if (dcameraDevice != nullptr) {
211         if (dcameraDevice->IsOpened()) {
212             dcameraDevice->Close();
213         }
214         dcameraDevice->SetProviderCallback(nullptr);
215     }
216 
217     DCameraBase dcameraBase(dhBase.deviceId_, dhBase.dhId_);
218     dhBaseHashDCamIdMap_.erase(dcameraBase);
219     dCameraDeviceMap_.erase(dCameraId);
220 
221     if (dCameraHostCallback_ != nullptr) {
222         dCameraHostCallback_->OnCameraEvent(dCameraId, CameraEvent::CAMERA_EVENT_DEVICE_RMV);
223     }
224 
225     DHLOGI("DCameraHost::RemoveDCameraDevice, remove dcamera device success, dCameraId: %s",
226         GetAnonyString(dCameraId).c_str());
227     return DCamRetCode::SUCCESS;
228 }
229 
IsCameraIdInvalid(const std::string & cameraId)230 bool DCameraHost::IsCameraIdInvalid(const std::string &cameraId)
231 {
232     if (cameraId.empty() || cameraId.length() > ID_MAX_SIZE) {
233         return true;
234     }
235 
236     auto iter = dhBaseHashDCamIdMap_.begin();
237     while (iter != dhBaseHashDCamIdMap_.end()) {
238         if (cameraId == iter->second) {
239             return false;
240         }
241         iter++;
242     }
243     return true;
244 }
245 
GetCameraIdByDHBase(const DHBase & dhBase)246 std::string DCameraHost::GetCameraIdByDHBase(const DHBase &dhBase)
247 {
248     DCameraBase dcameraBase(dhBase.deviceId_, dhBase.dhId_);
249     auto iter = dhBaseHashDCamIdMap_.find(dcameraBase);
250     if (iter == dhBaseHashDCamIdMap_.end()) {
251         return "";
252     }
253     return iter->second;
254 }
255 
GetDCameraDeviceByDHBase(const DHBase & dhBase)256 OHOS::sptr<DCameraDevice> DCameraHost::GetDCameraDeviceByDHBase(const DHBase &dhBase)
257 {
258     std::string dCameraId = GetCameraIdByDHBase(dhBase);
259     if (dCameraId.empty()) {
260         DHLOGE("DCameraHost::GetDCameraDeviceByDHBase, dhBase not exist.");
261         return nullptr;
262     }
263 
264     auto iter = dCameraDeviceMap_.find(dCameraId);
265     if (iter == dCameraDeviceMap_.end()) {
266         DHLOGE("DCameraHost::GetDCameraDeviceByDHBase, dcamera device not found.");
267         return nullptr;
268     }
269     return iter->second;
270 }
271 
NotifyDCameraStatus(const DHBase & dhBase,int32_t result)272 void DCameraHost::NotifyDCameraStatus(const DHBase &dhBase, int32_t result)
273 {
274     std::string dCameraId = GetCameraIdByDHBase(dhBase);
275     if (dCameraId.empty()) {
276         DHLOGE("DCameraHost::NotifyDCameraStatus, dhBase not exist.");
277         return;
278     }
279     if (dCameraHostCallback_ != nullptr) {
280         dCameraHostCallback_->OnCameraStatus(dCameraId, CameraStatus::UN_AVAILABLE);
281     }
282 }
283 } // namespace DistributedHardware
284 } // namespace OHOS
285