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