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