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 #include "camera_util.h"
16 #include <cstdint>
17 #include <securec.h>
18 #include <parameter.h>
19 #include <parameters.h>
20 #include "camera_log.h"
21 #include "access_token.h"
22 #include "accesstoken_kit.h"
23 #include "privacy_kit.h"
24 #include "display_manager.h"
25 #include "display/composer/v1_1/display_composer_type.h"
26 #include "iservice_registry.h"
27 #include "bundle_mgr_interface.h"
28 #include "system_ability_definition.h"
29 #include "ipc_skeleton.h"
30 #include "tokenid_kit.h"
31 
32 namespace OHOS {
33 namespace CameraStandard {
34 using namespace OHOS::HDI::Display::Composer::V1_1;
35 static bool g_tablet = true;
36 std::unordered_map<int32_t, int32_t> g_cameraToPixelFormat = {
37     {OHOS_CAMERA_FORMAT_RGBA_8888, GRAPHIC_PIXEL_FMT_RGBA_8888},
38     {OHOS_CAMERA_FORMAT_YCBCR_420_888, GRAPHIC_PIXEL_FMT_YCBCR_420_SP},
39     {OHOS_CAMERA_FORMAT_YCRCB_420_SP, GRAPHIC_PIXEL_FMT_YCRCB_420_SP}, // NV21
40     {OHOS_CAMERA_FORMAT_JPEG, GRAPHIC_PIXEL_FMT_BLOB},
41     {OHOS_CAMERA_FORMAT_YCBCR_P010, GRAPHIC_PIXEL_FMT_YCBCR_P010},
42     {OHOS_CAMERA_FORMAT_YCRCB_P010, GRAPHIC_PIXEL_FMT_YCRCB_P010},
43     {OHOS_CAMERA_FORMAT_YCBCR_420_SP, GRAPHIC_PIXEL_FMT_YCBCR_420_SP},
44     {OHOS_CAMERA_FORMAT_422_YUYV, GRAPHIC_PIXEL_FMT_YUYV_422_PKG},
45     {OHOS_CAMERA_FORMAT_DEPTH_16, GRAPHIC_PIXEL_FMT_RGBA16_FLOAT},
46     {OHOS_CAMERA_FORMAT_DNG, GRAPHIC_PIXEL_FMT_BLOB},
47 };
48 
49 std::map<int, std::string> g_cameraPos = {
50     {0, "Front"},
51     {1, "Back"},
52     {2, "Other"},
53 };
54 
55 std::map<int, std::string> g_cameraType = {
56     {0, "Wide-Angle"},
57     {1, "Ultra-Wide"},
58     {2, "TelePhoto"},
59     {3, "TrueDepth"},
60     {4, "Logical"},
61     {5, "Unspecified"},
62 };
63 
64 std::map<int, std::string> g_cameraConType = {
65     {0, "Builtin"},
66     {1, "USB-Plugin"},
67     {2, "Remote"},
68 };
69 
70 std::map<int, std::string> g_cameraFormat = {
71     {1, "RGBA_8888"},
72     {2, "YCBCR_420_888"},
73     {3, "YCRCB_420_SP"},
74     {4, "YCBCR_420_SP"},
75     {5, "JPEG"},
76     {6, "YCBCR_P010"},
77     {7, "YCRCB_P010"},
78     {8, "DNG"},
79     {9, "422_YUYV"},
80 };
81 
82 std::map<int, std::string> g_cameraFocusMode = {
83     {0, "Manual"},
84     {1, "Continuous-Auto"},
85     {2, "Auto"},
86     {3, "Locked"},
87 };
88 
89 std::map<int, std::string> g_cameraExposureMode = {
90     {0, "Manual"},
91     {1, "Continuous-Auto"},
92     {2, "Locked"},
93     {3, "Auto"},
94 };
95 
96 std::map<int, std::string> g_cameraFlashMode = {
97     {0, "Close"},
98     {1, "Open"},
99     {2, "Auto"},
100     {3, "Always-Open"},
101 };
102 
103 std::map<int, std::string> g_cameraVideoStabilizationMode = {
104     {0, "Off"},
105     {1, "Low"},
106     {2, "Middle"},
107     {3, "High"},
108     {4, "Auto"},
109 };
110 
111 std::map<int, std::string> g_cameraPrelaunchAvailable = {
112     {0, "False"},
113     {1, "True"},
114 };
115 
116 std::map<int, std::string> g_cameraQuickThumbnailAvailable = {
117     {0, "False"},
118     {1, "True"},
119 };
120 
121 std::map<int, std::string> g_cameraQualityPrioritization = {
122     {0, "HighQuality"},
123     {1, "PowerBalance"},
124 };
125 
126 bool g_cameraDebugOn = false;
127 
HdiToCameraErrorType(OHOS::HDI::Camera::V1_3::ErrorType type)128 int32_t HdiToCameraErrorType(OHOS::HDI::Camera::V1_3::ErrorType type)
129 {
130     enum CamServiceError err = CAMERA_UNKNOWN_ERROR;
131 
132     switch (type) {
133         case HDI::Camera::V1_3::FATAL_ERROR:
134             err = CAMERA_DEVICE_FATAL_ERROR;
135             break;
136         case HDI::Camera::V1_3::REQUEST_TIMEOUT:
137             err = CAMERA_DEVICE_REQUEST_TIMEOUT;
138             break;
139         case HDI::Camera::V1_3::DRIVER_ERROR:
140             err = CAMERA_DEVICE_DRIVER_ERROR;
141             break;
142         case HDI::Camera::V1_3::DEVICE_PREEMPT:
143             err = CAMERA_DEVICE_PREEMPTED;
144             break;
145         case HDI::Camera::V1_3::DEVICE_DISCONNECT:
146             err = CAMERA_DEVICE_DISCONNECT;
147             break;
148         case HDI::Camera::V1_3::SENSOR_DATA_ERROR:
149             err = CAMERA_DEVICE_SENSOR_DATA_ERROR;
150             break;
151         case HDI::Camera::V1_3::DCAMERA_ERROR_BEGIN:
152             err = CAMERA_DCAMERA_ERROR_BEGIN;
153             break;
154         case HDI::Camera::V1_3::DCAMERA_ERROR_DEVICE_IN_USE:
155             err = CAMERA_DCAMERA_ERROR_DEVICE_IN_USE;
156             break;
157         case HDI::Camera::V1_3::DCAMERA_ERROR_NO_PERMISSION:
158             err = CAMERA_DCAMERA_ERROR_NO_PERMISSION;
159             break;
160         default:
161             MEDIA_ERR_LOG("HdiToCameraType() error type from hdi: %{public}d", type);
162             break;
163     }
164     return err;
165 }
166 
HdiToServiceError(OHOS::HDI::Camera::V1_0::CamRetCode ret)167 int32_t HdiToServiceError(OHOS::HDI::Camera::V1_0::CamRetCode ret)
168 {
169     enum CamServiceError err = CAMERA_UNKNOWN_ERROR;
170 
171     switch (ret) {
172         case HDI::Camera::V1_0::NO_ERROR:
173             err = CAMERA_OK;
174             break;
175         case HDI::Camera::V1_0::CAMERA_BUSY:
176             err = CAMERA_DEVICE_BUSY;
177             break;
178         case HDI::Camera::V1_0::INVALID_ARGUMENT:
179             err = CAMERA_INVALID_ARG;
180             break;
181         case HDI::Camera::V1_0::CAMERA_CLOSED:
182             err = CAMERA_DEVICE_CLOSED;
183             break;
184         default:
185             MEDIA_ERR_LOG("HdiToServiceError() error code from hdi: %{public}d", ret);
186             break;
187     }
188     return err;
189 }
190 
HdiToServiceErrorV1_2(HDI::Camera::V1_2::CamRetCode ret)191 int32_t HdiToServiceErrorV1_2(HDI::Camera::V1_2::CamRetCode ret)
192 {
193     enum CamServiceError err = CAMERA_UNKNOWN_ERROR;
194 
195     switch (ret) {
196         case HDI::Camera::V1_2::NO_ERROR:
197             err = CAMERA_OK;
198             break;
199         case HDI::Camera::V1_2::CAMERA_BUSY:
200             err = CAMERA_DEVICE_BUSY;
201             break;
202         case HDI::Camera::V1_2::INVALID_ARGUMENT:
203             err = CAMERA_INVALID_ARG;
204             break;
205         case HDI::Camera::V1_2::CAMERA_CLOSED:
206             err = CAMERA_DEVICE_CLOSED;
207             break;
208         case HDI::Camera::V1_2::DEVICE_ERROR:
209             err = CAMERA_DEVICE_ERROR;
210             break;
211         case HDI::Camera::V1_2::NO_PERMISSION:
212             err = CAMERA_NO_PERMISSION;
213             break;
214         case HDI::Camera::V1_2::DEVICE_CONFLICT:
215             err = CAMERA_DEVICE_CONFLICT;
216             break;
217         default:
218             MEDIA_ERR_LOG("HdiToServiceErrorV1_2() error code from hdi: %{public}d", ret);
219             break;
220     }
221     return err;
222 }
223 
CreateMsg(const char * format,...)224 std::string CreateMsg(const char* format, ...)
225 {
226     va_list args;
227     va_start(args, format);
228     char msg[MAX_STRING_SIZE] = {0};
229     if (vsnprintf_s(msg, sizeof(msg), sizeof(msg) - 1, format, args) < 0) {
230         MEDIA_ERR_LOG("failed to call vsnprintf_s");
231         va_end(args);
232         return "";
233     }
234     va_end(args);
235     return msg;
236 }
237 
IsHapTokenId(uint32_t tokenId)238 bool IsHapTokenId(uint32_t tokenId)
239 {
240     return Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId) ==
241         Security::AccessToken::ATokenTypeEnum::TOKEN_HAP;
242 }
243 
IsValidMode(int32_t opMode,std::shared_ptr<OHOS::Camera::CameraMetadata> cameraAbility)244 bool IsValidMode(int32_t opMode, std::shared_ptr<OHOS::Camera::CameraMetadata> cameraAbility)
245 {
246     if (opMode == 0 || opMode == 1 || opMode == 2) { // 0 is normal mode, 1 is capture mode, 2 is video mode
247         MEDIA_INFO_LOG("operationMode:%{public}d", opMode);
248         return true;
249     }
250     camera_metadata_item_t item;
251     int ret = Camera::FindCameraMetadataItem(cameraAbility->get(), OHOS_ABILITY_CAMERA_MODES, &item);
252     if (ret != CAM_META_SUCCESS || item.count == 0) {
253         MEDIA_ERR_LOG("Failed to find stream extend configuration in camera ability with return code %{public}d", ret);
254         ret = Camera::FindCameraMetadataItem(cameraAbility->get(),
255                                              OHOS_ABILITY_STREAM_AVAILABLE_BASIC_CONFIGURATIONS, &item);
256         if (ret == CAM_META_SUCCESS && item.count != 0) {
257             MEDIA_INFO_LOG("basic config no need valid mode");
258             return true;
259         }
260         return false;
261     }
262 
263     for (uint32_t i = 0; i < item.count; i++) {
264         if (opMode == item.data.u8[i]) {
265             MEDIA_INFO_LOG("operationMode:%{public}d found in supported streams", opMode);
266             return true;
267         }
268     }
269     MEDIA_ERR_LOG("operationMode:%{public}d not found in supported streams", opMode);
270     return false;
271 }
272 
DumpMetadata(std::shared_ptr<OHOS::Camera::CameraMetadata> cameraSettings)273 void DumpMetadata(std::shared_ptr<OHOS::Camera::CameraMetadata> cameraSettings)
274 {
275     if (cameraSettings == nullptr) {
276         return;
277     }
278     auto srcHeader = cameraSettings->get();
279     CHECK_ERROR_RETURN(srcHeader == nullptr);
280     auto srcItemCount = srcHeader->item_count;
281     camera_metadata_item_t item;
282     for (uint32_t index = 0; index < srcItemCount; index++) {
283         int ret = OHOS::Camera::GetCameraMetadataItem(srcHeader, index, &item);
284         CHECK_ERROR_RETURN_LOG(ret != CAM_META_SUCCESS, "Failed to get metadata item at index: %{public}d", index);
285         const char *name = OHOS::Camera::GetCameraMetadataItemName(item.item);
286         CHECK_ERROR_RETURN_LOG(name == nullptr, "U8ItemToString: get u8 item name fail!");
287         if (item.data_type == META_TYPE_BYTE) {
288             for (size_t k = 0; k < item.count; k++) {
289                 MEDIA_DEBUG_LOG("tag index:%d, name:%s, value:%d", item.index, name, (uint8_t)(item.data.u8[k]));
290             }
291         } else if (item.data_type == META_TYPE_INT32) {
292             for (size_t k = 0; k < item.count; k++) {
293                 MEDIA_DEBUG_LOG("tag index:%d, name:%s, value:%d", item.index, name, (int32_t)(item.data.i32[k]));
294             }
295         } else if (item.data_type == META_TYPE_UINT32) {
296             for (size_t k = 0; k < item.count; k++) {
297                 MEDIA_DEBUG_LOG("tag index:%d, name:%s, value:%d", item.index, name, (uint32_t)(item.data.ui32[k]));
298             }
299         } else if (item.data_type == META_TYPE_FLOAT) {
300             for (size_t k = 0; k < item.count; k++) {
301                 MEDIA_DEBUG_LOG("tag index:%d, name:%s, value:%f", item.index, name, (float)(item.data.f[k]));
302             }
303         } else if (item.data_type == META_TYPE_INT64) {
304             for (size_t k = 0; k < item.count; k++) {
305                 MEDIA_DEBUG_LOG("tag index:%d, name:%s, value:%lld", item.index, name, (long long)(item.data.i64[k]));
306             }
307         } else if (item.data_type == META_TYPE_DOUBLE) {
308             for (size_t k = 0; k < item.count; k++) {
309                 MEDIA_DEBUG_LOG("tag index:%d, name:%s, value:%lf", item.index, name, (double)(item.data.d[k]));
310             }
311         } else {
312             MEDIA_DEBUG_LOG("tag index:%d, name:%s", item.index, name);
313         }
314     }
315 }
316 
GetClientBundle(int uid)317 std::string GetClientBundle(int uid)
318 {
319     std::string bundleName = "";
320     auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
321     CHECK_ERROR_RETURN_RET_LOG(samgr == nullptr, bundleName, "GetClientBundle Get ability manager failed");
322 
323     sptr<IRemoteObject> object = samgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
324     CHECK_ERROR_RETURN_RET_LOG(object == nullptr, bundleName, "GetClientBundle object is NULL.");
325 
326     sptr<OHOS::AppExecFwk::IBundleMgr> bms = iface_cast<OHOS::AppExecFwk::IBundleMgr>(object);
327     CHECK_ERROR_RETURN_RET_LOG(bms == nullptr, bundleName, "GetClientBundle bundle manager service is NULL.");
328 
329     auto result = bms->GetNameForUid(uid, bundleName);
330     CHECK_ERROR_RETURN_RET_LOG(result != ERR_OK, "", "GetClientBundle GetBundleNameForUid fail");
331     MEDIA_INFO_LOG("bundle name is %{public}s ", bundleName.c_str());
332 
333     return bundleName;
334 }
335 
JudgmentPriority(const pid_t & pid,const pid_t & pidCompared)336 int32_t JudgmentPriority(const pid_t& pid, const pid_t& pidCompared)
337 {
338     return PRIORITY_LEVEL_SAME;
339 }
340 
IsSameClient(const pid_t & pid,const pid_t & pidCompared)341 bool IsSameClient(const pid_t& pid, const pid_t& pidCompared)
342 {
343     return (pid == pidCompared);
344 }
345 
IsInForeGround(const uint32_t callerToken)346 bool IsInForeGround(const uint32_t callerToken)
347 {
348     bool isAllowed = true;
349     if (IPCSkeleton::GetCallingUid() == 0) {
350         MEDIA_DEBUG_LOG("HCameraService::IsInForeGround isAllowed!");
351         return isAllowed;
352     }
353     if (IsHapTokenId(callerToken)) {
354         isAllowed = Security::AccessToken::PrivacyKit::IsAllowedUsingPermission(callerToken, OHOS_PERMISSION_CAMERA);
355     }
356     return isAllowed;
357 }
358 
IsCameraNeedClose(const uint32_t callerToken,const pid_t & pid,const pid_t & pidCompared)359 bool IsCameraNeedClose(const uint32_t callerToken, const pid_t& pid, const pid_t& pidCompared)
360 {
361     bool needClose = !(IsInForeGround(callerToken) && (JudgmentPriority(pid, pidCompared) != PRIORITY_LEVEL_HIGHER));
362     if (Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken) ==
363         Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) {
364         needClose = true;
365     }
366     MEDIA_INFO_LOG("IsCameraNeedClose pid = %{public}d, IsInForeGround = %{public}d, TokenType = %{public}d, "
367                    "needClose = %{public}d",
368                    pid, IsInForeGround(callerToken),
369                    Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken), needClose);
370     return needClose;
371 }
372 
CheckPermission(const std::string permissionName,uint32_t callerToken)373 int32_t CheckPermission(const std::string permissionName, uint32_t callerToken)
374 {
375     int permissionResult
376         = OHOS::Security::AccessToken::TypePermissionState::PERMISSION_DENIED;
377     Security::AccessToken::ATokenTypeEnum tokenType
378         = OHOS::Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
379     if ((tokenType == OHOS::Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE)
380         || (tokenType == OHOS::Security::AccessToken::ATokenTypeEnum::TOKEN_HAP)) {
381         permissionResult = OHOS::Security::AccessToken::AccessTokenKit::VerifyAccessToken(
382             callerToken, permissionName);
383     } else {
384         MEDIA_ERR_LOG("HCameraService::CheckPermission: Unsupported Access Token Type");
385         return CAMERA_INVALID_ARG;
386     }
387 
388     if (permissionResult != OHOS::Security::AccessToken::TypePermissionState::PERMISSION_GRANTED) {
389         MEDIA_ERR_LOG("HCameraService::CheckPermission: Permission to Access Camera Denied!!!!");
390         return CAMERA_NO_PERMISSION;
391     } else {
392         MEDIA_DEBUG_LOG("HCameraService::CheckPermission: Permission to Access Camera Granted!!!!");
393     }
394     return CAMERA_OK;
395 }
396 
GetVersionId(uint32_t major,uint32_t minor)397 int32_t GetVersionId(uint32_t major, uint32_t minor)
398 {
399     const uint32_t offset = 8;
400     return static_cast<int32_t>((major << offset) | minor);
401 }
402 
AddCameraPermissionUsedRecord(const uint32_t callingTokenId,const std::string permissionName)403 void AddCameraPermissionUsedRecord(const uint32_t callingTokenId, const std::string permissionName)
404 {
405     int32_t successCout = 1;
406     int32_t failCount = 0;
407     int32_t ret = Security::AccessToken::PrivacyKit::AddPermissionUsedRecord(callingTokenId, permissionName,
408         successCout, failCount);
409     MEDIA_INFO_LOG("AddPermissionUsedRecord");
410     if (ret != CAMERA_OK) {
411         MEDIA_ERR_LOG("AddPermissionUsedRecord failed.");
412     }
413 }
IsVerticalDevice()414 bool IsVerticalDevice()
415 {
416     bool isVerticalDevice = true;
417     auto display = OHOS::Rosen::DisplayManager::GetInstance().GetDefaultDisplay();
418     CHECK_ERROR_RETURN_RET_LOG(display == nullptr, isVerticalDevice, "IsVerticalDevice GetDefaultDisplay failed");
419     MEDIA_INFO_LOG("GetDefaultDisplay:W(%{public}d),H(%{public}d),Rotation(%{public}d)",
420                    display->GetWidth(), display->GetHeight(), display->GetRotation());
421     bool isScreenVertical = display->GetRotation() == OHOS::Rosen::Rotation::ROTATION_0 ||
422                             display->GetRotation() == OHOS::Rosen::Rotation::ROTATION_180;
423     bool isScreenHorizontal = display->GetRotation() == OHOS::Rosen::Rotation::ROTATION_90 ||
424                               display->GetRotation() == OHOS::Rosen::Rotation::ROTATION_270;
425     isVerticalDevice = (isScreenVertical && (display->GetWidth() < display->GetHeight())) ||
426                             (isScreenHorizontal && (display->GetWidth() > display->GetHeight()));
427     return isVerticalDevice;
428 }
429 
GetStreamRotation(int32_t & sensorOrientation,camera_position_enum_t & cameraPosition,int & disPlayRotation,std::string & deviceClass)430 int32_t GetStreamRotation(int32_t& sensorOrientation, camera_position_enum_t& cameraPosition, int& disPlayRotation,
431     std::string& deviceClass)
432 {
433     int32_t streamRotation = sensorOrientation;
434     int degrees = 0;
435 
436     switch (disPlayRotation) {
437         case DISPALY_ROTATE_0: degrees = STREAM_ROTATE_0; break;
438         case DISPALY_ROTATE_1: degrees = STREAM_ROTATE_90; break;
439         case DISPALY_ROTATE_2: degrees = STREAM_ROTATE_180; break;
440         case DISPALY_ROTATE_3: degrees = STREAM_ROTATE_270; break; // 逆时针转90
441     }
442 
443     g_tablet = (deviceClass == "tablet");
444     if (cameraPosition == OHOS_CAMERA_POSITION_FRONT) {
445         sensorOrientation = g_tablet ? sensorOrientation + STREAM_ROTATE_90 : sensorOrientation;
446         streamRotation = (STREAM_ROTATE_360 + sensorOrientation - degrees) % STREAM_ROTATE_360;
447     } else {
448         sensorOrientation = g_tablet ? sensorOrientation - STREAM_ROTATE_90 : sensorOrientation;
449         streamRotation = (sensorOrientation + degrees) % STREAM_ROTATE_360;
450         streamRotation = (STREAM_ROTATE_360 - streamRotation) % STREAM_ROTATE_360;
451     }
452     MEDIA_DEBUG_LOG("HStreamRepeat::SetStreamTransform filp streamRotation %{public}d, rotate %{public}d",
453         streamRotation, disPlayRotation);
454     return streamRotation;
455 }
456 
CheckSystemApp()457 bool CheckSystemApp()
458 {
459     Security::AccessToken::AccessTokenID callerToken = IPCSkeleton::GetCallingTokenID();
460     Security::AccessToken::ATokenTypeEnum tokenType =
461         Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
462     if (tokenType !=  Security::AccessToken::TOKEN_HAP) {
463         MEDIA_DEBUG_LOG("Caller is not a application.");
464         return true;
465     }
466     uint64_t accessTokenId = IPCSkeleton::GetCallingFullTokenID();
467     bool isSystemApplication = Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(accessTokenId);
468     MEDIA_DEBUG_LOG("isSystemApplication:%{public}d", isSystemApplication);
469     return isSystemApplication;
470 }
471 } // namespace CameraStandard
472 } // namespace OHOS
473