1 /*
2  * Copyright (c) 2021-2024 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_handler.h"
17 
18 #include <functional>
19 
20 #include "anonymous_string.h"
21 #include "avcodec_info.h"
22 #include "avcodec_list.h"
23 #include "dcamera_manager_callback.h"
24 #include "dcamera_utils_tools.h"
25 #include "distributed_camera_constants.h"
26 #include "distributed_camera_errno.h"
27 #include "distributed_hardware_log.h"
28 #include "metadata_utils.h"
29 
30 namespace OHOS {
31 namespace DistributedHardware {
32 IMPLEMENT_SINGLE_INSTANCE(DCameraHandler);
33 
34 const int32_t MAXWIDTHSIZE = 65535;
35 
~DCameraHandler()36 DCameraHandler::~DCameraHandler()
37 {
38     DHLOGI("~DCameraHandler");
39 }
40 
Initialize()41 int32_t DCameraHandler::Initialize()
42 {
43     DHLOGI("start");
44     cameraManager_ = CameraStandard::CameraManager::GetInstance();
45     if (cameraManager_ == nullptr) {
46         DHLOGE("cameraManager getInstance failed");
47         return DCAMERA_INIT_ERR;
48     }
49     std::shared_ptr<DCameraManagerCallback> cameraMgrCallback = std::make_shared<DCameraManagerCallback>();
50     cameraManager_->SetCallback(cameraMgrCallback);
51     DHLOGI("success");
52     return DCAMERA_OK;
53 }
54 
QueryMeta()55 std::vector<DHItem> DCameraHandler::QueryMeta()
56 {
57     std::vector<DHItem> itemList;
58     CHECK_AND_RETURN_RET_LOG(cameraManager_ == nullptr, itemList, "cameraManager is null.");
59     std::vector<sptr<CameraStandard::CameraDevice>> cameraList = cameraManager_->GetSupportedCameras();
60     uint64_t listSize = static_cast<uint64_t>(cameraList.size());
61     DHLOGI("get %{public}" PRIu64" cameras", listSize);
62     if (cameraList.empty()) {
63         DHLOGE("no camera device");
64         return itemList;
65     }
66     for (auto& info : cameraList) {
67         if (info->GetConnectionType() != CameraStandard::ConnectionType::CAMERA_CONNECTION_BUILT_IN) {
68             DHLOGI("connection type: %{public}d", info->GetConnectionType());
69             continue;
70         }
71         DHLOGI("get %{public}s, position: %{public}d, cameraType: %{public}d",
72             GetAnonyString(info->GetID()).c_str(), info->GetPosition(), info->GetCameraType());
73         DHItem item;
74         if (CreateMetaDHItem(info, item) == DCAMERA_OK) {
75             itemList.emplace_back(item);
76         }
77     }
78     listSize = static_cast<uint64_t>(itemList.size());
79     DHLOGI("success, get %{public}" PRIu64" items", listSize);
80     return itemList;
81 }
82 
Query()83 std::vector<DHItem> DCameraHandler::Query()
84 {
85     std::vector<DHItem> itemList;
86     CHECK_AND_RETURN_RET_LOG(cameraManager_ == nullptr, itemList, "cameraManager is null.");
87     std::vector<sptr<CameraStandard::CameraDevice>> cameraList = cameraManager_->GetSupportedCameras();
88     uint64_t listSize = static_cast<uint64_t>(cameraList.size());
89     DHLOGI("get %{public}" PRIu64" cameras", listSize);
90     if (cameraList.empty()) {
91         DHLOGE("no camera device");
92         return itemList;
93     }
94     for (auto& info : cameraList) {
95         if ((info->GetConnectionType() != CameraStandard::ConnectionType::CAMERA_CONNECTION_BUILT_IN)) {
96             DHLOGI("connection type: %{public}d", info->GetConnectionType());
97             continue;
98         }
99         DHLOGI("get %{public}s, position: %{public}d, cameraType: %{public}d",
100             GetAnonyString(info->GetID()).c_str(), info->GetPosition(), info->GetCameraType());
101         DHItem item;
102         if (CreateDHItem(info, item) == DCAMERA_OK) {
103             itemList.emplace_back(item);
104         }
105     }
106     listSize = static_cast<uint64_t>(itemList.size());
107     DHLOGI("success, get %{public}" PRIu64" items", listSize);
108     return itemList;
109 }
110 
QueryExtraInfo()111 std::map<std::string, std::string> DCameraHandler::QueryExtraInfo()
112 {
113     DHLOGI("enter");
114     std::map<std::string, std::string> extraInfo;
115     return extraInfo;
116 }
117 
IsSupportPlugin()118 bool DCameraHandler::IsSupportPlugin()
119 {
120     DHLOGI("enter");
121     return false;
122 }
123 
RegisterPluginListener(std::shared_ptr<PluginListener> listener)124 void DCameraHandler::RegisterPluginListener(std::shared_ptr<PluginListener> listener)
125 {
126     DHLOGI("enter");
127     if (listener == nullptr) {
128         DHLOGE("DCameraHandler unregistering plugin listener");
129     }
130     pluginListener_ = listener;
131 }
132 
UnRegisterPluginListener()133 void DCameraHandler::UnRegisterPluginListener()
134 {
135     DHLOGI("enter");
136     pluginListener_ = nullptr;
137 }
138 
GetCameras()139 std::vector<std::string> DCameraHandler::GetCameras()
140 {
141     std::vector<std::string> cameras;
142     std::vector<sptr<CameraStandard::CameraDevice>> cameraList = cameraManager_->GetSupportedCameras();
143     uint64_t listSize = static_cast<uint64_t>(cameraList.size());
144     DHLOGI("get %{public}" PRIu64" cameras", listSize);
145     if (cameraList.empty()) {
146         DHLOGE("no camera device");
147         return cameras;
148     }
149     for (auto& info : cameraList) {
150         sptr<CameraStandard::CameraOutputCapability> capability = cameraManager_->GetSupportedOutputCapability(info);
151         if (capability == nullptr) {
152             DHLOGI("get supported capability is null");
153             continue;
154         }
155         if (info->GetConnectionType() != CameraStandard::ConnectionType::CAMERA_CONNECTION_BUILT_IN) {
156             DHLOGI("connection type: %{public}d", info->GetConnectionType());
157             continue;
158         }
159         DHLOGI("get %{public}s, position: %{public}d, cameraType: %{public}d",
160             GetAnonyString(info->GetID()).c_str(), info->GetPosition(), info->GetCameraType());
161         std::string dhId = CAMERA_ID_PREFIX + info->GetID();
162         cameras.emplace_back(dhId);
163     }
164     listSize = static_cast<uint64_t>(cameras.size());
165     DHLOGI("success, get %{public}" PRIu64" items", listSize);
166     return cameras;
167 }
168 
CreateAVCodecList(cJSON * root)169 int32_t DCameraHandler::CreateAVCodecList(cJSON *root)
170 {
171     DHLOGI("Create avCodecList start");
172     std::shared_ptr<MediaAVCodec::AVCodecList> avCodecList = MediaAVCodec::AVCodecListFactory::CreateAVCodecList();
173     if (avCodecList == nullptr) {
174         DHLOGI("Create avCodecList failed");
175         return DCAMERA_BAD_VALUE;
176     }
177     const std::vector<std::string> encoderName = {std::string(MediaAVCodec::CodecMimeType::VIDEO_AVC),
178                                                   std::string(MediaAVCodec::CodecMimeType::VIDEO_HEVC)};
179     cJSON *array = cJSON_CreateArray();
180     if (array == nullptr) {
181         DHLOGI("Create arrray failed");
182         return DCAMERA_BAD_VALUE;
183     }
184     cJSON_AddItemToObject(root, CAMERA_CODEC_TYPE_KEY.c_str(), array);
185     for (auto &coder : encoderName) {
186         MediaAVCodec::CapabilityData *capData = avCodecList->GetCapability(coder, true,
187             MediaAVCodec::AVCodecCategory::AVCODEC_HARDWARE);
188         if (capData == nullptr) {
189             DHLOGI("capData is nullptr");
190             return DCAMERA_BAD_VALUE;
191         }
192         std::string mimeType = capData->mimeType;
193         cJSON_AddItemToArray(array, cJSON_CreateString(mimeType.c_str()));
194         DHLOGI("codec name: %{public}s, mimeType: %{public}s", coder.c_str(), mimeType.c_str());
195     }
196     return DCAMERA_OK;
197 }
198 
CreateMetaDHItem(sptr<CameraStandard::CameraDevice> & info,DHItem & item)199 int32_t DCameraHandler::CreateMetaDHItem(sptr<CameraStandard::CameraDevice>& info, DHItem& item)
200 {
201     std::string id = info->GetID();
202     item.dhId = CAMERA_ID_PREFIX + id;
203     item.subtype = "camera";
204     DHLOGI("camera id: %{public}s", GetAnonyString(id).c_str());
205 
206     cJSON *root = cJSON_CreateObject();
207     CHECK_AND_RETURN_RET_LOG(root == nullptr, DCAMERA_BAD_VALUE, "Create cJSON object failed");
208     cJSON_AddStringToObject(root, CAMERA_METADATA_KEY.c_str(), CAMERA_METADATA_KEY.c_str());
209     char *jsonstr = cJSON_Print(root);
210     if (jsonstr == nullptr) {
211         cJSON_Delete(root);
212         return DCAMERA_BAD_VALUE;
213     }
214     item.attrs = jsonstr;
215     cJSON_free(jsonstr);
216     cJSON_Delete(root);
217     return DCAMERA_OK;
218 }
219 
CreateDHItem(sptr<CameraStandard::CameraDevice> & info,DHItem & item)220 int32_t DCameraHandler::CreateDHItem(sptr<CameraStandard::CameraDevice>& info, DHItem& item)
221 {
222     std::string id = info->GetID();
223     item.dhId = CAMERA_ID_PREFIX + id;
224     item.subtype = "camera";
225 
226     cJSON *root = cJSON_CreateObject();
227     CHECK_AND_RETURN_RET_LOG(root == nullptr, DCAMERA_BAD_VALUE, "Create cJSON object failed");
228     cJSON_AddStringToObject(root, CAMERA_PROTOCOL_VERSION_KEY.c_str(), CAMERA_PROTOCOL_VERSION_VALUE.c_str());
229     cJSON_AddStringToObject(root, CAMERA_POSITION_KEY.c_str(), GetCameraPosition(info->GetPosition()).c_str());
230     int32_t ret = CreateAVCodecList(root);
231     CHECK_AND_FREE_RETURN_RET_LOG(ret != DCAMERA_OK, DCAMERA_BAD_VALUE, root, "CreateAVCodecList failed");
232     sptr<CameraStandard::CameraOutputCapability> capability = cameraManager_->GetSupportedOutputCapability(info);
233     CHECK_AND_FREE_RETURN_RET_LOG(capability == nullptr, DCAMERA_BAD_VALUE, root, "get supported capability is null");
234     std::vector<CameraStandard::Profile> photoProfiles = capability->GetPhotoProfiles();
235     ConfigFormatphoto(SNAPSHOT_FRAME, root, photoProfiles);
236 
237     std::vector<CameraStandard::Profile> previewProfiles = capability->GetPreviewProfiles();
238     ConfigFormatvideo(CONTINUOUS_FRAME, root, previewProfiles);
239 
240     std::vector<CameraStandard::SceneMode> supportedModes = cameraManager_->GetSupportedModes(info);
241     if (!supportedModes.empty()) {
242         cJSON *modeArray = cJSON_CreateArray();
243         CHECK_AND_FREE_RETURN_RET_LOG(modeArray == nullptr, DCAMERA_BAD_VALUE, root, "Create modeArray object failed");
244         cJSON_AddItemToObject(root, CAMERA_SUPPORT_MODE.c_str(), modeArray);
245         for (auto &mode : supportedModes) {
246             DHLOGI("The camera id: %{public}s, The supportedModes is : %{public}d", GetAnonyString(id).c_str(), mode);
247             cJSON_AddItemToArray(modeArray, cJSON_CreateNumber(mode));
248             auto capability = cameraManager_->GetSupportedOutputCapability(info, mode);
249             CHECK_AND_FREE_RETURN_RET_LOG(
250                 capability == nullptr, DCAMERA_BAD_VALUE, root, "supported capability is null");
251             cJSON *modeData = cJSON_CreateObject();
252             CHECK_AND_FREE_RETURN_RET_LOG(modeData == nullptr, DCAMERA_BAD_VALUE, root, "Create cJSON object failed");
253             std::vector<CameraStandard::Profile> photoProfiles = capability->GetPhotoProfiles();
254             ConfigFormatphoto(SNAPSHOT_FRAME, modeData, photoProfiles);
255 
256             std::vector<CameraStandard::Profile> previewProfiles = capability->GetPreviewProfiles();
257             ConfigFormatvideo(CONTINUOUS_FRAME, modeData, previewProfiles);
258 
259             cJSON_AddItemToObject(root, std::to_string(mode).c_str(), modeData);
260         }
261     }
262 
263     ret = CreateMeatdataStr(info, root);
264     CHECK_AND_FREE_RETURN_RET_LOG(ret != DCAMERA_OK, DCAMERA_BAD_VALUE, root, "CreateMeatdataStr failed");
265     char *jsonstr = cJSON_Print(root);
266     CHECK_AND_FREE_RETURN_RET_LOG(jsonstr == nullptr, DCAMERA_BAD_VALUE, root, "jsonstr is null");
267 
268     item.attrs = jsonstr;
269     cJSON_free(jsonstr);
270     cJSON_Delete(root);
271     return DCAMERA_OK;
272 }
273 
CreateMeatdataStr(sptr<CameraStandard::CameraDevice> & info,cJSON * root)274 int32_t DCameraHandler::CreateMeatdataStr(sptr<CameraStandard::CameraDevice>& info, cJSON *root)
275 {
276     sptr<CameraStandard::CameraInput> cameraInput = nullptr;
277     int32_t rv = cameraManager_->CreateCameraInput(info, &cameraInput);
278     if (rv != DCAMERA_OK) {
279         DHLOGE("create cameraInput failed");
280         return DCAMERA_BAD_VALUE;
281     }
282 
283     std::hash<std::string> h;
284     std::string abilityStr = cameraInput->GetCameraSettings();
285     DHLOGI("abilityString hash: %{public}zu, length: %{public}zu", h(abilityStr), abilityStr.length());
286 
287     std::string encStr = Base64Encode(reinterpret_cast<const unsigned char*>(abilityStr.c_str()), abilityStr.length());
288     DHLOGI("encodeString hash: %zu, length: %zu", h(encStr), encStr.length());
289     cJSON_AddStringToObject(root, CAMERA_METADATA_KEY.c_str(), encStr.c_str());
290     CHECK_AND_LOG(cameraInput->Release() != DCAMERA_OK, "cameraInput Release failed");
291     return DCAMERA_OK;
292 }
293 
GetCameraPosition(CameraStandard::CameraPosition position)294 std::string DCameraHandler::GetCameraPosition(CameraStandard::CameraPosition position)
295 {
296     DHLOGI("position: %{public}d", position);
297     std::string ret = "";
298     switch (position) {
299         case CameraStandard::CameraPosition::CAMERA_POSITION_BACK: {
300             ret = CAMERA_POSITION_BACK;
301             break;
302         }
303         case CameraStandard::CameraPosition::CAMERA_POSITION_FRONT: {
304             ret = CAMERA_POSITION_FRONT;
305             break;
306         }
307         case CameraStandard::CameraPosition::CAMERA_POSITION_UNSPECIFIED: {
308             ret = CAMERA_POSITION_UNSPECIFIED;
309             break;
310         }
311         default: {
312             DHLOGE("unknown camera position");
313             break;
314         }
315     }
316     DHLOGI("success ret: %{public}s", ret.c_str());
317     return ret;
318 }
319 
ProcessProfile(const DCStreamType type,std::map<std::string,std::list<std::string>> & formatMap,std::vector<CameraStandard::Profile> & profileList,std::set<int32_t> & formatSet)320 void DCameraHandler::ProcessProfile(const DCStreamType type, std::map<std::string, std::list<std::string>>& formatMap,
321     std::vector<CameraStandard::Profile>& profileList, std::set<int32_t>& formatSet)
322 {
323     for (auto& profile : profileList) {
324         CameraStandard::CameraFormat format = profile.GetCameraFormat();
325         CameraStandard::Size picSize = profile.GetSize();
326         int32_t dformat = CovertToDcameraFormat(format);
327         if (dformat == INVALID_FORMAT) {
328             continue;
329         }
330         formatSet.insert(dformat);
331         DHLOGI("width: %{public}d, height: %{public}d, format: %{public}d", picSize.width, picSize.height, dformat);
332         std::string formatName = std::to_string(dformat);
333         if (IsValid(type, picSize)) {
334             std::string resolutionValue = std::to_string(picSize.width) + "*" + std::to_string(picSize.height);
335             formatMap[formatName].push_back(resolutionValue);
336         }
337     }
338 }
339 
ConfigFormatphoto(const DCStreamType type,cJSON * root,std::vector<CameraStandard::Profile> & profileList)340 void DCameraHandler::ConfigFormatphoto(const DCStreamType type, cJSON* root,
341     std::vector<CameraStandard::Profile>& profileList)
342 {
343     DHLOGI("type: %{public}d, size: %{public}zu", type, profileList.size());
344     std::set<int32_t> formatSet;
345     cJSON* formatphotoObj = cJSON_CreateObject();
346     if (formatphotoObj == nullptr) {
347         return;
348     }
349     cJSON_AddItemToObject(root, CAMERA_FORMAT_PHOTO.c_str(), formatphotoObj);
350     std::map<std::string, std::list<std::string>> formatMap;
351     ProcessProfile(type, formatMap, profileList, formatSet);
352     cJSON* resolutionObj = cJSON_CreateObject();
353     if (resolutionObj == nullptr) {
354         return;
355     }
356     for (auto &pair : formatMap) {
357         cJSON* array = cJSON_CreateArray();
358         cJSON_AddItemToObject(resolutionObj, pair.first.c_str(), array);
359         for (auto &value : pair.second) {
360             cJSON_AddItemToArray(array, cJSON_CreateString(value.c_str()));
361         }
362     }
363     cJSON_AddItemToObject(formatphotoObj, CAMERA_RESOLUTION_KEY.c_str(), resolutionObj);
364     cJSON* array = cJSON_CreateArray();
365     if (array == nullptr) {
366         return;
367     }
368     for (auto format : formatSet) {
369         cJSON_AddItemToArray(array, cJSON_CreateNumber(format));
370     }
371     cJSON_AddItemToObject(formatphotoObj, CAMERA_FORMAT_KEY.c_str(), array);
372 }
373 
ConfigFormatvideo(const DCStreamType type,cJSON * root,std::vector<CameraStandard::Profile> & profileList)374 void DCameraHandler::ConfigFormatvideo(const DCStreamType type, cJSON* root,
375     std::vector<CameraStandard::Profile>& profileList)
376 {
377     DHLOGI("type: %d, size: %{public}zu", type, profileList.size());
378     std::set<int32_t> formatSet;
379     cJSON* formatpreviewObj = cJSON_CreateObject();
380     if (formatpreviewObj == nullptr) {
381         return;
382     }
383     cJSON_AddItemToObject(root, CAMERA_FORMAT_PREVIEW.c_str(), formatpreviewObj);
384     std::map<std::string, std::list<std::string>> formatMap;
385     ProcessProfile(type, formatMap, profileList, formatSet);
386     cJSON* resolutionObj = cJSON_CreateObject();
387     if (resolutionObj == nullptr) {
388         return;
389     }
390     for (auto &pair : formatMap) {
391         cJSON* array = cJSON_CreateArray();
392         cJSON_AddItemToObject(resolutionObj, pair.first.c_str(), array);
393         for (auto &value : pair.second) {
394             cJSON_AddItemToArray(array, cJSON_CreateString(value.c_str()));
395         }
396     }
397     cJSON_AddItemToObject(formatpreviewObj, CAMERA_RESOLUTION_KEY.c_str(), resolutionObj);
398     cJSON* array = cJSON_CreateArray();
399     if (array == nullptr) {
400         return;
401     }
402     for (auto format : formatSet) {
403         cJSON_AddItemToArray(array, cJSON_CreateNumber(format));
404     }
405     cJSON_AddItemToObject(formatpreviewObj, CAMERA_FORMAT_KEY.c_str(), array);
406     cJSON* formatvideoObj = cJSON_Duplicate(formatpreviewObj, 1);
407     cJSON_AddItemToObject(root, CAMERA_FORMAT_VIDEO.c_str(), formatvideoObj);
408 }
409 
CovertToDcameraFormat(CameraStandard::CameraFormat format)410 int32_t DCameraHandler::CovertToDcameraFormat(CameraStandard::CameraFormat format)
411 {
412     DHLOGI("format: %{public}d", format);
413     int32_t ret = INVALID_FORMAT;
414     switch (format) {
415         case CameraStandard::CameraFormat::CAMERA_FORMAT_RGBA_8888:
416             ret = camera_format_t::OHOS_CAMERA_FORMAT_RGBA_8888;
417             break;
418         case CameraStandard::CameraFormat::CAMERA_FORMAT_YCBCR_420_888:
419             ret = camera_format_t::OHOS_CAMERA_FORMAT_YCBCR_420_888;
420             break;
421         case CameraStandard::CameraFormat::CAMERA_FORMAT_YUV_420_SP:
422             ret = camera_format_t::OHOS_CAMERA_FORMAT_YCRCB_420_SP;
423             break;
424         case CameraStandard::CameraFormat::CAMERA_FORMAT_JPEG:
425             ret = camera_format_t::OHOS_CAMERA_FORMAT_JPEG;
426             break;
427         case CameraStandard::CameraFormat::CAMERA_FORMAT_YCBCR_P010:
428             ret = camera_format_t::OHOS_CAMERA_FORMAT_YCBCR_P010;
429             break;
430         case CameraStandard::CameraFormat::CAMERA_FORMAT_YCRCB_P010:
431             ret = camera_format_t::OHOS_CAMERA_FORMAT_YCRCB_P010;
432             break;
433         default:
434             DHLOGE("invalid camera format");
435             break;
436     }
437     return ret;
438 }
439 
IsValid(const DCStreamType type,const CameraStandard::Size & size)440 bool DCameraHandler::IsValid(const DCStreamType type, const CameraStandard::Size& size)
441 {
442     bool ret = false;
443     switch (type) {
444         case CONTINUOUS_FRAME: {
445             ret = (size.width >= RESOLUTION_MIN_WIDTH) &&
446                     (size.height >= RESOLUTION_MIN_HEIGHT) &&
447                     (size.width <= RESOLUTION_MAX_WIDTH_CONTINUOUS) &&
448                     (size.height <= RESOLUTION_MAX_HEIGHT_CONTINUOUS);
449             break;
450         }
451         case SNAPSHOT_FRAME: {
452             if (size.width > MAXWIDTHSIZE) {
453                 DHLOGE("size width out of range.");
454                 return ret;
455             }
456             uint64_t dcResolution = static_cast<uint64_t>(size.width * size.width);
457             uint64_t dcMaxResolution = static_cast<uint64_t>(RESOLUTION_MAX_WIDTH_SNAPSHOT *
458                                                              RESOLUTION_MAX_HEIGHT_SNAPSHOT);
459             uint64_t dcMinResolution = static_cast<uint64_t>(RESOLUTION_MIN_WIDTH *
460                                                              RESOLUTION_MIN_HEIGHT);
461             ret = (dcResolution >= dcMinResolution) && (dcResolution <= dcMaxResolution);
462             break;
463         }
464         default: {
465             DHLOGE("unknown stream type");
466             break;
467         }
468     }
469     return ret;
470 }
471 
GetHardwareHandler()472 IHardwareHandler* GetHardwareHandler()
473 {
474     DHLOGI("DCameraHandler::GetHardwareHandler");
475     return &DCameraHandler::GetInstance();
476 }
477 } // namespace DistributedHardware
478 } // namespace OHOS