1 /*
2 * Copyright (c) 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
16 #include "dcamera_client_demo.h"
17
18 #include "access_token.h"
19 #include "accesstoken_kit.h"
20 #include "hap_token_info.h"
21 #include "ipc_skeleton.h"
22 #include "token_setproc.h"
23
24 using namespace OHOS;
25 using namespace OHOS::Camera;
26 using namespace OHOS::CameraStandard;
27 using namespace OHOS::DistributedHardware;
28
29 constexpr double LATITUDE = 22.306;
30 constexpr double LONGITUDE = 52.12;
31 constexpr double ALTITUDE = 2.365;
32 constexpr int32_t PHOTO_WIDTH = 640;
33 constexpr int32_t PHOTO_HEIGTH = 480;
34 constexpr int32_t PREVIEW_WIDTH = 640;
35 constexpr int32_t PREVIEW_HEIGTH = 480;
36 constexpr int32_t VIDEO_WIDTH = 640;
37 constexpr int32_t VIDEO_HEIGTH = 480;
38 constexpr int32_t SLEEP_FIVE_SECOND = 5;
39 constexpr int32_t SLEEP_TWENTY_SECOND = 20;
40
41 static sptr<CameraDevice> g_cameraInfo = nullptr;
42 static sptr<CameraManager> g_cameraManager = nullptr;
43 static sptr<CaptureInput> g_cameraInput = nullptr;
44 static sptr<CaptureOutput> g_photoOutput = nullptr;
45 static sptr<CaptureOutput> g_previewOutput = nullptr;
46 static sptr<CaptureOutput> g_videoOutput = nullptr;
47 static sptr<CaptureSession> g_captureSession = nullptr;
48 static std::shared_ptr<DCameraCaptureInfo> g_photoInfo = nullptr;
49 static std::shared_ptr<DCameraCaptureInfo> g_previewInfo = nullptr;
50 static std::shared_ptr<DCameraCaptureInfo> g_videoInfo = nullptr;
51
52 #ifdef DCAMERA_YUV
53 constexpr int32_t PHOTO_FORMAT = camera_format_t::OHOS_CAMERA_FORMAT_JPEG;
54 constexpr int32_t PREVIEW_FORMAT = camera_format_t::OHOS_CAMERA_FORMAT_YCRCB_420_SP;
55 constexpr int32_t VIDEO_FORMAT = camera_format_t::OHOS_CAMERA_FORMAT_YCRCB_420_SP;
56 #else
57 constexpr int32_t PHOTO_FORMAT = camera_format_t::OHOS_CAMERA_FORMAT_RGBA_8888;
58 constexpr int32_t PREVIEW_FORMAT = camera_format_t::OHOS_CAMERA_FORMAT_RGBA_8888;
59 constexpr int32_t VIDEO_FORMAT = camera_format_t::OHOS_CAMERA_FORMAT_RGBA_8888;
60 #endif
61
InitCameraStandard()62 static int32_t InitCameraStandard()
63 {
64 g_cameraManager = CameraManager::GetInstance();
65 g_cameraManager->SetCallback(std::make_shared<DemoDCameraManagerCallback>());
66
67 int rv = g_cameraManager->CreateCaptureSession(&g_captureSession);
68 if (rv != DCAMERA_OK) {
69 DHLOGE("InitCameraStandard create captureSession failed, rv: %d", rv);
70 return rv;
71 }
72 g_captureSession->SetCallback(std::make_shared<DemoDCameraSessionCallback>());
73
74 std::vector<sptr<CameraDevice>> cameraObjList = g_cameraManager->GetSupportedCameras();
75 for (auto info : cameraObjList) {
76 DHLOGI("Camera: %s, position: %d, camera type: %d, connection type: %d", GetAnonyString(info->GetID()).c_str(),
77 info->GetPosition(), info->GetCameraType(), info->GetConnectionType());
78 // OHOS_CAMERA_POSITION_FRONT or OHOS_CAMERA_POSITION_BACK
79 if ((info->GetPosition() == CameraPosition::CAMERA_POSITION_FRONT) &&
80 (info->GetConnectionType() == ConnectionType::CAMERA_CONNECTION_REMOTE)) {
81 g_cameraInfo = info;
82 break;
83 }
84 }
85
86 if (g_cameraInfo == nullptr) {
87 DHLOGE("Distributed Camera Demo: have no remote camera");
88 return DCAMERA_BAD_VALUE;
89 }
90
91 rv = g_cameraManager->CreateCameraInput(g_cameraInfo, &((sptr<CameraInput> &)g_cameraInput));
92 if (rv != DCAMERA_OK) {
93 DHLOGE("InitCameraStandard create cameraInput failed, rv: %d", rv);
94 return rv;
95 }
96 int32_t ret = ((sptr<CameraInput> &)g_cameraInput)->Open();
97 if (ret != DCAMERA_OK) {
98 DHLOGE("InitCameraStandard g_cameraInput Open failed, ret: %d", ret);
99 return ret;
100 }
101 std::shared_ptr<DemoDCameraInputCallback> inputCallback = std::make_shared<DemoDCameraInputCallback>();
102 ((sptr<CameraInput> &)g_cameraInput)->SetErrorCallback(inputCallback);
103 g_captureSession->SetFocusCallback(std::make_shared<DemoDCameraSessionCallback>());
104 return DCAMERA_OK;
105 }
106
InitCaptureInfo()107 static void InitCaptureInfo()
108 {
109 g_photoInfo = std::make_shared<DCameraCaptureInfo>();
110 g_photoInfo->width_ = PHOTO_WIDTH;
111 g_photoInfo->height_ = PHOTO_HEIGTH;
112 g_photoInfo->format_ = PHOTO_FORMAT;
113
114 g_previewInfo = std::make_shared<DCameraCaptureInfo>();
115 g_previewInfo->width_ = PREVIEW_WIDTH;
116 g_previewInfo->height_ = PREVIEW_HEIGTH;
117 g_previewInfo->format_ = PREVIEW_FORMAT;
118
119 g_videoInfo = std::make_shared<DCameraCaptureInfo>();
120 g_videoInfo->width_ = VIDEO_WIDTH;
121 g_videoInfo->height_ = VIDEO_HEIGTH;
122 g_videoInfo->format_ = VIDEO_FORMAT;
123 }
124
ConvertToCameraFormat(int32_t format)125 static CameraFormat ConvertToCameraFormat(int32_t format)
126 {
127 CameraFormat ret = CameraFormat::CAMERA_FORMAT_INVALID;
128 DCameraFormat df = static_cast<DCameraFormat>(format);
129 switch (df) {
130 case DCameraFormat::OHOS_CAMERA_FORMAT_RGBA_8888:
131 ret = CameraFormat::CAMERA_FORMAT_RGBA_8888;
132 break;
133 case DCameraFormat::OHOS_CAMERA_FORMAT_YCBCR_420_888:
134 ret = CameraFormat::CAMERA_FORMAT_YCBCR_420_888;
135 break;
136 case DCameraFormat::OHOS_CAMERA_FORMAT_YCRCB_420_SP:
137 ret = CameraFormat::CAMERA_FORMAT_YUV_420_SP;
138 break;
139 case DCameraFormat::OHOS_CAMERA_FORMAT_JPEG:
140 ret = CameraFormat::CAMERA_FORMAT_JPEG;
141 break;
142 default:
143 break;
144 }
145 return ret;
146 }
147
InitPhotoOutput()148 static void InitPhotoOutput()
149 {
150 DHLOGI("Distributed Camera Demo: Create PhotoOutput, width = %d, height = %d, format = %d",
151 g_photoInfo->width_, g_photoInfo->height_, g_photoInfo->format_);
152 sptr<Surface> photoSurface = Surface::CreateSurfaceAsConsumer();
153 sptr<IBufferConsumerListener> photoListener = new DemoDCameraPhotoSurfaceListener(photoSurface);
154 photoSurface->SetDefaultWidthAndHeight(g_photoInfo->width_, g_photoInfo->height_);
155 photoSurface->SetUserData(CAMERA_SURFACE_FORMAT, std::to_string(g_photoInfo->format_));
156 photoSurface->RegisterConsumerListener(photoListener);
157 CameraFormat photoFormat = ConvertToCameraFormat(g_photoInfo->format_);
158 Size photoSize = {g_photoInfo->width_, g_photoInfo->height_};
159 Profile photoProfile(photoFormat, photoSize);
160 int rv = g_cameraManager->CreatePhotoOutput(photoProfile, photoSurface, &((sptr<PhotoOutput> &)g_photoOutput));
161 if (rv != DCAMERA_OK) {
162 DHLOGE("InitPhotoOutput create photoOutput failed, rv: %d", rv);
163 return;
164 }
165 ((sptr<PhotoOutput> &)g_photoOutput)->SetCallback(std::make_shared<DemoDCameraPhotoCallback>());
166 }
167
InitPreviewOutput()168 static void InitPreviewOutput()
169 {
170 DHLOGI("Distributed Camera Demo: Create PreviewOutput, width = %d, height = %d, format = %d",
171 g_previewInfo->width_, g_previewInfo->height_, g_previewInfo->format_);
172 sptr<Surface> previewSurface = Surface::CreateSurfaceAsConsumer();
173 sptr<IBufferConsumerListener> previewListener = new DemoDCameraPreviewSurfaceListener(previewSurface);
174 previewSurface->SetDefaultWidthAndHeight(g_previewInfo->width_, g_previewInfo->height_);
175 previewSurface->SetUserData(CAMERA_SURFACE_FORMAT, std::to_string(g_previewInfo->format_));
176 previewSurface->RegisterConsumerListener(previewListener);
177 CameraFormat previewFormat = ConvertToCameraFormat(g_previewInfo->format_);
178 Size previewSize = {g_previewInfo->width_, g_previewInfo->height_};
179 Profile previewProfile(previewFormat, previewSize);
180 int rv = g_cameraManager->CreatePreviewOutput(
181 previewProfile, previewSurface, &((sptr<PreviewOutput> &)g_previewOutput));
182 if (rv != DCAMERA_OK) {
183 DHLOGE("InitPhotoOutput create previewOutput failed, rv: %d", rv);
184 return;
185 }
186 ((sptr<PreviewOutput> &)g_previewOutput)->SetCallback(std::make_shared<DemoDCameraPreviewCallback>());
187 }
188
InitVideoOutput()189 static void InitVideoOutput()
190 {
191 DHLOGI("Distributed Camera Demo: Create VideoOutput, width = %d, height = %d, format = %d",
192 g_videoInfo->width_, g_videoInfo->height_, g_videoInfo->format_);
193 sptr<Surface> videoSurface = Surface::CreateSurfaceAsConsumer();
194 sptr<IBufferConsumerListener> videoListener = new DemoDCameraVideoSurfaceListener(videoSurface);
195 videoSurface->SetDefaultWidthAndHeight(g_videoInfo->width_, g_videoInfo->height_);
196 videoSurface->SetUserData(CAMERA_SURFACE_FORMAT, std::to_string(g_videoInfo->format_));
197 videoSurface->RegisterConsumerListener(videoListener);
198 CameraFormat videoFormat = ConvertToCameraFormat(g_videoInfo->format_);
199 Size videoSize = {g_videoInfo->width_, g_videoInfo->height_};
200 std::vector<int32_t> framerates = {};
201 VideoProfile videoSettings(videoFormat, videoSize, framerates);
202 int rv = g_cameraManager->CreateVideoOutput(videoSettings, videoSurface, &((sptr<VideoOutput> &)g_videoOutput));
203 if (rv != DCAMERA_OK) {
204 DHLOGE("InitPhotoOutput create videoOutput failed, rv: %d", rv);
205 return;
206 }
207 ((sptr<VideoOutput> &)g_videoOutput)->SetCallback(std::make_shared<DemoDCameraVideoCallback>());
208 }
209
ConfigCaptureSession()210 static void ConfigCaptureSession()
211 {
212 g_captureSession->BeginConfig();
213 g_captureSession->AddInput(g_cameraInput);
214 g_captureSession->AddOutput(g_previewOutput);
215 g_captureSession->AddOutput(g_videoOutput);
216 g_captureSession->AddOutput(g_photoOutput);
217 g_captureSession->CommitConfig();
218
219 std::vector<VideoStabilizationMode> stabilizationModes;
220 int32_t rv = g_captureSession->GetSupportedStabilizationMode(stabilizationModes);
221 if (rv != DCAMERA_OK) {
222 DHLOGE("ConfigCaptureSession get supported stabilization mode failed, rv: %d", rv);
223 return;
224 }
225 for (auto mode : stabilizationModes) {
226 DHLOGI("Distributed Camera Demo: video stabilization mode %d", mode);
227 }
228 g_captureSession->SetVideoStabilizationMode(stabilizationModes.back());
229 }
230
ConfigFocusAndExposure()231 static void ConfigFocusAndExposure()
232 {
233 g_captureSession->LockForControl();
234 FocusMode focusMode = FOCUS_MODE_CONTINUOUS_AUTO;
235 ExposureMode exposureMode = EXPOSURE_MODE_AUTO;
236 int32_t exposureValue = 0;
237 std::vector<int32_t> biasRange;
238 int32_t rv = g_captureSession->GetExposureBiasRange(biasRange);
239 if (rv != DCAMERA_OK) {
240 DHLOGE("ConfigFocusAndExposure get exposure bias range failed, rv: %d", rv);
241 return;
242 }
243 if (!biasRange.empty()) {
244 DHLOGI("Distributed Camera Demo: get %d exposure compensation range", biasRange.size());
245 exposureValue = biasRange[0];
246 }
247 g_captureSession->SetFocusMode(focusMode);
248 g_captureSession->SetExposureMode(exposureMode);
249 g_captureSession->SetExposureBias(exposureValue);
250 g_captureSession->UnlockForControl();
251 }
252
ConfigPhotoCaptureSetting()253 static std::shared_ptr<PhotoCaptureSetting> ConfigPhotoCaptureSetting()
254 {
255 std::shared_ptr<PhotoCaptureSetting> photoCaptureSettings = std::make_shared<PhotoCaptureSetting>();
256 // Rotation
257 PhotoCaptureSetting::RotationConfig rotation = PhotoCaptureSetting::RotationConfig::Rotation_0;
258 photoCaptureSettings->SetRotation(rotation);
259 // QualityLevel
260 PhotoCaptureSetting::QualityLevel quality = PhotoCaptureSetting::QualityLevel::QUALITY_LEVEL_HIGH;
261 photoCaptureSettings->SetQuality(quality);
262 // Location
263 std::unique_ptr<Location> location = std::make_unique<Location>();
264 location->latitude = LATITUDE;
265 location->longitude = LONGITUDE;
266 location->altitude = ALTITUDE;
267 photoCaptureSettings->SetLocation(location);
268 return photoCaptureSettings;
269 }
270
271 static std::string permissionName = "ohos.permission.CAMERA";
272 static OHOS::Security::AccessToken::HapInfoParams g_infoManagerTestInfoParms = {
273 .userID = 1,
274 .bundleName = permissionName,
275 .instIndex = 0,
276 .appIDDesc = "testtesttesttest"
277 };
278
279 static OHOS::Security::AccessToken::PermissionDef g_infoManagerTestPermDef1 = {
280 .permissionName = "ohos.permission.CAMERA",
281 .bundleName = "ohos.permission.CAMERA",
282 .grantMode = 1,
283 .availableLevel = OHOS::Security::AccessToken::ATokenAplEnum::APL_NORMAL,
284 .label = "label",
285 .labelId = 1,
286 .description = "dcamera client test",
287 .descriptionId = 1
288 };
289
290 static OHOS::Security::AccessToken::PermissionStateFull g_infoManagerTestState1 = {
291 .permissionName = "ohos.permission.CAMERA",
292 .isGeneral = true,
293 .resDeviceID = {"local"},
294 .grantStatus = {OHOS::Security::AccessToken::PermissionState::PERMISSION_GRANTED},
295 .grantFlags = {1}
296 };
297
298 static OHOS::Security::AccessToken::HapPolicyParams g_infoManagerTestPolicyPrams = {
299 .apl = OHOS::Security::AccessToken::ATokenAplEnum::APL_NORMAL,
300 .domain = "test.domain",
301 .permList = {g_infoManagerTestPermDef1},
302 .permStateList = {g_infoManagerTestState1}
303 };
304
main()305 int main()
306 {
307 /* Grant the permission so that create camera test can be success */
308 int32_t rc = -1;
309 OHOS::Security::AccessToken::AccessTokenIDEx tokenIdEx = {0};
310 tokenIdEx = OHOS::Security::AccessToken::AccessTokenKit::AllocHapToken(
311 g_infoManagerTestInfoParms,
312 g_infoManagerTestPolicyPrams);
313 if (tokenIdEx.tokenIdExStruct.tokenID == 0) {
314 unsigned int tokenIdOld = 0;
315 DHLOGI("Alloc TokenID failure, cleaning the old token ID \n");
316 tokenIdOld = OHOS::Security::AccessToken::AccessTokenKit::GetHapTokenID(
317 1, permissionName, 0);
318 if (tokenIdOld == 0) {
319 DHLOGI("Unable to get the Old Token ID, need to reflash the board");
320 return 0;
321 }
322 rc = OHOS::Security::AccessToken::AccessTokenKit::DeleteToken(tokenIdOld);
323 if (rc != 0) {
324 DHLOGI("Unable to delete the Old Token ID, need to reflash the board");
325 return 0;
326 }
327
328 /* Retry the token allocation again */
329 tokenIdEx = OHOS::Security::AccessToken::AccessTokenKit::AllocHapToken(
330 g_infoManagerTestInfoParms,
331 g_infoManagerTestPolicyPrams);
332 if (tokenIdEx.tokenIdExStruct.tokenID == 0) {
333 DHLOGI("Alloc TokenID failure, need to reflash the board \n");
334 return 0;
335 }
336 }
337
338 (void)SetSelfTokenID(tokenIdEx.tokenIdExStruct.tokenID);
339
340 rc = Security::AccessToken::AccessTokenKit::GrantPermission(
341 tokenIdEx.tokenIdExStruct.tokenID,
342 permissionName, OHOS::Security::AccessToken::PERMISSION_USER_FIXED);
343 if (rc != 0) {
344 DHLOGI("GrantPermission() failed");
345 (void)OHOS::Security::AccessToken::AccessTokenKit::DeleteToken(
346 tokenIdEx.tokenIdExStruct.tokenID);
347 return 0;
348 } else {
349 DHLOGI("GrantPermission() success");
350 }
351
352 DHLOGI("========== Distributed Camera Demo Start ==========");
353 int32_t ret = InitCameraStandard();
354 if (ret != DCAMERA_OK) {
355 std::cout << "have no remote camera" << std::endl;
356 return 0;
357 }
358
359 InitCaptureInfo();
360 InitPhotoOutput();
361 InitPreviewOutput();
362 InitVideoOutput();
363 ConfigCaptureSession();
364
365 g_captureSession->Start();
366 sleep(SLEEP_FIVE_SECOND);
367
368 if (((sptr<VideoOutput> &)g_videoOutput)->Start() != DCAMERA_OK) {
369 DHLOGE("main g_videoOutput Start failed");
370 }
371 sleep(SLEEP_FIVE_SECOND);
372
373 ConfigFocusAndExposure();
374 sleep(SLEEP_FIVE_SECOND);
375
376 ((sptr<PhotoOutput> &)g_photoOutput)->Capture(ConfigPhotoCaptureSetting());
377 sleep(SLEEP_TWENTY_SECOND);
378
379 if (((sptr<VideoOutput> &)g_videoOutput)->Stop() != DCAMERA_OK) {
380 DHLOGE("main g_videoOutput Stop failed");
381 }
382 sleep(SLEEP_FIVE_SECOND);
383
384 g_captureSession->Stop();
385 if (g_cameraInput->Close() != DCAMERA_OK) {
386 DHLOGE("main g_cameraInput Close failed");
387 }
388 g_captureSession->Release();
389 if (g_cameraInput->Release() != DCAMERA_OK) {
390 DHLOGE("main g_cameraInput Close failed");
391 }
392 DHLOGI("========== Distributed Camera Demo End ==========");
393 return 0;
394 }