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