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
22 namespace OHOS {
23 namespace CameraStandard {
24 std::unordered_map<int32_t, int32_t> g_cameraToPixelFormat = {
25 {OHOS_CAMERA_FORMAT_RGBA_8888, PIXEL_FMT_RGBA_8888},
26 {OHOS_CAMERA_FORMAT_YCBCR_420_888, PIXEL_FMT_YCBCR_420_SP},
27 {OHOS_CAMERA_FORMAT_YCRCB_420_SP, PIXEL_FMT_YCRCB_420_SP},
28 {OHOS_CAMERA_FORMAT_JPEG, PIXEL_FMT_YCRCB_420_SP},
29 };
30
31 std::map<int, std::string> g_cameraPos = {
32 {0, "Front"},
33 {1, "Back"},
34 {2, "Other"},
35 };
36
37 std::map<int, std::string> g_cameraType = {
38 {0, "Wide-Angle"},
39 {1, "Ultra-Wide"},
40 {2, "TelePhoto"},
41 {3, "TrueDepth"},
42 {4, "Logical"},
43 {5, "Unspecified"},
44 };
45
46 std::map<int, std::string> g_cameraConType = {
47 {0, "Builtin"},
48 {1, "USB-Plugin"},
49 {2, "Remote"},
50 };
51
52 std::map<int, std::string> g_cameraFormat = {
53 {1, "RGBA_8888"},
54 {2, "YCBCR_420_888"},
55 {3, "YCRCB_420_SP"},
56 {4, "JPEG"},
57 };
58
59 std::map<int, std::string> g_cameraFocusMode = {
60 {0, "Manual"},
61 {1, "Continuous-Auto"},
62 {2, "Auto"},
63 {3, "Locked"},
64 };
65
66 std::map<int, std::string> g_cameraExposureMode = {
67 {0, "Manual"},
68 {1, "Continuous-Auto"},
69 {2, "Locked"},
70 {3, "Auto"},
71 };
72
73 std::map<int, std::string> g_cameraFlashMode = {
74 {0, "Close"},
75 {1, "Open"},
76 {2, "Auto"},
77 {3, "Always-Open"},
78 };
79
80 std::map<int, std::string> g_cameraVideoStabilizationMode = {
81 {0, "Off"},
82 {1, "Low"},
83 {2, "Middle"},
84 {3, "High"},
85 {4, "Auto"},
86 };
87
88 std::map<int, std::string> g_cameraPrelaunchAvailable = {
89 {0, "False"},
90 {1, "True"},
91 };
92
93 std::map<int, std::string> g_cameraQuickThumbnailAvailable = {
94 {0, "False"},
95 {1, "True"},
96 };
97
98 static std::mutex g_captureIdsMutex;
99 static std::map<int32_t, bool> g_captureIds;
100
HdiToServiceError(CamRetCode ret)101 int32_t HdiToServiceError(CamRetCode ret)
102 {
103 enum CamServiceError err = CAMERA_UNKNOWN_ERROR;
104
105 switch (ret) {
106 case HDI::Camera::V1_0::NO_ERROR:
107 err = CAMERA_OK;
108 break;
109 case HDI::Camera::V1_0::CAMERA_BUSY:
110 err = CAMERA_DEVICE_BUSY;
111 break;
112 case HDI::Camera::V1_0::INVALID_ARGUMENT:
113 err = CAMERA_INVALID_ARG;
114 break;
115 case HDI::Camera::V1_0::CAMERA_CLOSED:
116 err = CAMERA_DEVICE_CLOSED;
117 break;
118 default:
119 MEDIA_ERR_LOG("HdiToServiceError() error code from hdi: %{public}d", ret);
120 break;
121 }
122 return err;
123 }
124
CreateMsg(const char * format,...)125 std::string CreateMsg(const char* format, ...)
126 {
127 va_list args;
128 va_start(args, format);
129 char msg[MAX_STRING_SIZE] = {0};
130 if (vsnprintf_s(msg, sizeof(msg), sizeof(msg) - 1, format, args) < 0) {
131 MEDIA_ERR_LOG("failed to call vsnprintf_s");
132 va_end(args);
133 return "";
134 }
135 va_end(args);
136 return msg;
137 }
138
AllocateCaptureId(int32_t & captureId)139 int32_t AllocateCaptureId(int32_t &captureId)
140 {
141 std::lock_guard<std::mutex> lock(g_captureIdsMutex);
142 static int32_t currentCaptureId = 0;
143 for (int32_t i = 0; i < INT_MAX; i++) {
144 if (currentCaptureId == INT_MAX) {
145 currentCaptureId = 0;
146 MEDIA_INFO_LOG("Restarting CaptureId");
147 }
148 currentCaptureId++;
149 if (g_captureIds.find(currentCaptureId) == g_captureIds.end()) {
150 g_captureIds[currentCaptureId] = true;
151 captureId = currentCaptureId;
152 return CAMERA_OK;
153 }
154 }
155 return CAMERA_CAPTURE_LIMIT_EXCEED;
156 }
157
ReleaseCaptureId(int32_t captureId)158 void ReleaseCaptureId(int32_t captureId)
159 {
160 std::lock_guard<std::mutex> lock(g_captureIdsMutex);
161 g_captureIds.erase(captureId);
162 return;
163 }
164
IsValidTokenId(uint32_t tokenId)165 bool IsValidTokenId(uint32_t tokenId)
166 {
167 return Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId) ==
168 Security::AccessToken::ATokenTypeEnum::TOKEN_HAP;
169 }
170
IsValidSize(std::shared_ptr<OHOS::Camera::CameraMetadata> cameraAbility,int32_t format,int32_t width,int32_t height)171 bool IsValidSize(
172 std::shared_ptr<OHOS::Camera::CameraMetadata> cameraAbility, int32_t format, int32_t width, int32_t height)
173 {
174 bool isExtendConfig = false;
175 camera_metadata_item_t item;
176 int ret = Camera::FindCameraMetadataItem(cameraAbility->get(),
177 OHOS_ABILITY_STREAM_AVAILABLE_EXTEND_CONFIGURATIONS, &item);
178 if (ret == CAM_META_SUCCESS && item.count != 0) {
179 isExtendConfig = true;
180 } else {
181 ret = Camera::FindCameraMetadataItem(cameraAbility->get(),
182 OHOS_ABILITY_STREAM_AVAILABLE_BASIC_CONFIGURATIONS, &item);
183 if (ret != CAM_META_SUCCESS || item.count == 0) {
184 MEDIA_ERR_LOG("Failed to find stream basic configuration in camera ability with return code %{public}d",
185 ret);
186 return false;
187 }
188 }
189 MEDIA_INFO_LOG("Success to find stream configuration isExtendConfig = %{public}d", isExtendConfig);
190 for (uint32_t index = 0; index < item.count; index++) {
191 if (item.data.i32[index] == format) {
192 if (((index + 1) < item.count) && ((index + 2) < item.count) &&
193 item.data.i32[index + 1] == width && item.data.i32[index + 2] == height) {
194 MEDIA_INFO_LOG("Format:%{public}d, width:%{public}d, height:%{public}d found in supported streams",
195 format, width, height);
196 return true;
197 } else {
198 continue;
199 }
200 } else {
201 continue;
202 }
203 }
204 MEDIA_ERR_LOG("Format:%{public}d, width:%{public}d, height:%{public}d not found in supported streams",
205 format, width, height);
206 return false;
207 }
208
JudgmentPriority(const pid_t & pid,const pid_t & pidCompared)209 int32_t JudgmentPriority(const pid_t& pid, const pid_t& pidCompared)
210 {
211 return PRIORITY_LEVEL_SAME;
212 }
213
IsSameClient(const pid_t & pid,const pid_t & pidCompared)214 bool IsSameClient(const pid_t& pid, const pid_t& pidCompared)
215 {
216 return (pid == pidCompared);
217 }
218
IsInForeGround(const uint32_t callerToken)219 bool IsInForeGround(const uint32_t callerToken)
220 {
221 bool isAllowed = true;
222 if (IsValidTokenId(callerToken)) {
223 isAllowed = Security::AccessToken::PrivacyKit::IsAllowedUsingPermission(callerToken, OHOS_PERMISSION_CAMERA);
224 }
225 return isAllowed;
226 }
227
IsCameraNeedClose(const uint32_t callerToken,const pid_t & pid,const pid_t & pidCompared)228 bool IsCameraNeedClose(const uint32_t callerToken, const pid_t& pid, const pid_t& pidCompared)
229 {
230 bool needClose = !(IsInForeGround(callerToken) && (JudgmentPriority(pid, pidCompared) != PRIORITY_LEVEL_HIGHER));
231 if (Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken) ==
232 Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE) {
233 needClose = true;
234 }
235 MEDIA_INFO_LOG("IsCameraNeedClose pid = %{public}d, IsInForeGround = %{public}d, TokenType = %{public}d, "
236 "needClose = %{public}d",
237 pid, IsInForeGround(callerToken),
238 Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken), needClose);
239 return needClose;
240 }
241
CheckPermission(std::string permissionName,uint32_t callerToken)242 int32_t CheckPermission(std::string permissionName, uint32_t callerToken)
243 {
244 int permissionResult
245 = OHOS::Security::AccessToken::TypePermissionState::PERMISSION_DENIED;
246 Security::AccessToken::ATokenTypeEnum tokenType
247 = OHOS::Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
248 if ((tokenType == OHOS::Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE)
249 || (tokenType == OHOS::Security::AccessToken::ATokenTypeEnum::TOKEN_HAP)) {
250 permissionResult = OHOS::Security::AccessToken::AccessTokenKit::VerifyAccessToken(
251 callerToken, permissionName);
252 } else {
253 MEDIA_ERR_LOG("HCameraService::CheckPermission: Unsupported Access Token Type");
254 return CAMERA_INVALID_ARG;
255 }
256
257 if (permissionResult != OHOS::Security::AccessToken::TypePermissionState::PERMISSION_GRANTED) {
258 MEDIA_ERR_LOG("HCameraService::CheckPermission: Permission to Access Camera Denied!!!!");
259 return CAMERA_OPERATION_NOT_ALLOWED;
260 } else {
261 MEDIA_DEBUG_LOG("HCameraService::CheckPermission: Permission to Access Camera Granted!!!!");
262 }
263 return CAMERA_OK;
264 }
265
GetVersionId(uint32_t major,uint32_t minor)266 int32_t GetVersionId(uint32_t major, uint32_t minor)
267 {
268 const uint32_t offset = 8;
269 return static_cast<int32_t>((major << offset) | minor);
270 }
271 } // namespace CameraStandard
272 } // namespace OHOS
273