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