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 
16 #include <unistd.h>
17 #include "input/camera_input.h"
18 #include "input/camera_manager.h"
19 #include "output/camera_output_capability.h"
20 
21 #include "camera_log.h"
22 #include "surface.h"
23 #include "test_common.h"
24 
25 #include "ipc_skeleton.h"
26 #include "access_token.h"
27 #include "hap_token_info.h"
28 #include "accesstoken_kit.h"
29 #include "nativetoken_kit.h"
30 #include "token_setproc.h"
31 
32 using namespace std;
33 using namespace OHOS;
34 using namespace OHOS::CameraStandard;
35 
ConfigPhotoCaptureSetting()36 static std::shared_ptr<PhotoCaptureSetting> ConfigPhotoCaptureSetting()
37 {
38     std::shared_ptr<PhotoCaptureSetting> photoCaptureSettings = std::make_shared<PhotoCaptureSetting>();
39     // QualityLevel
40     PhotoCaptureSetting::QualityLevel quality = PhotoCaptureSetting::QualityLevel::QUALITY_LEVEL_HIGH;
41     photoCaptureSettings->SetQuality(quality);
42     return photoCaptureSettings;
43 }
44 
main(int argc,char ** argv)45 int main(int argc, char **argv)
46 {
47     const int32_t previewFormatIndex = 1;
48     const int32_t previewWidthIndex = 2;
49     const int32_t previewHeightIndex = 3;
50     const int32_t photoFormatIndex = 4;
51     const int32_t photoWidthIndex = 5;
52     const int32_t photoHeightIndex = 6;
53     const int32_t photoCaptureCountIndex = 7;
54     const int32_t validArgCount = 8;
55     const int32_t gapAfterCapture = 1; // 1 second
56     const int32_t previewCaptureGap = 5; // 5 seconds
57     const char* testName = "camera_capture";
58     int32_t ret = -1;
59     int32_t previewFd = -1;
60     int32_t photoFd = -1;
61     int32_t previewFormat = CAMERA_FORMAT_YUV_420_SP;
62     int32_t previewWidth = 640;
63     int32_t previewHeight = 480;
64     int32_t photoFormat = CAMERA_FORMAT_JPEG;
65     int32_t photoWidth = 1280;
66     int32_t photoHeight = 960;
67     int32_t photoCaptureCount = 1;
68     bool isResolutionConfigured = false;
69     Size previewsize;
70     Size photosize;
71 
72     MEDIA_DEBUG_LOG("Camera new(std::nothrow) sample begin.");
73     // Update sizes if enough number of valid arguments are passed
74     if (argc == validArgCount) {
75         // Validate arguments
76         for (int counter = 1; counter < argc; counter++) {
77             if (!TestUtils::IsNumber(argv[counter])) {
78                 cout << "Invalid argument: " << argv[counter] << endl;
79                 cout << "Retry by giving proper sizes" << endl;
80                 return 0;
81             }
82         }
83         previewFormat = atoi(argv[previewFormatIndex]);
84         previewWidth = atoi(argv[previewWidthIndex]);
85         previewHeight = atoi(argv[previewHeightIndex]);
86         photoFormat = atoi(argv[photoFormatIndex]);
87         photoWidth = atoi(argv[photoWidthIndex]);
88         photoHeight = atoi(argv[photoHeightIndex]);
89         photoCaptureCount = atoi(argv[photoCaptureCountIndex]);
90         isResolutionConfigured = true;
91     } else if (argc != 1) {
92         cout << "Pass " << (validArgCount - 1) << "arguments" << endl;
93         cout << "PreviewFormat, PreviewHeight, PreviewWidth, PhotoFormat, PhotoWidth, PhotoHeight, CaptureCount"
94             << endl;
95         return 0;
96     }
97 
98     uint64_t tokenId;
99     const char *perms[0];
100     perms[0] = "ohos.permission.CAMERA";
101     NativeTokenInfoParams infoInstance = {
102         .dcapsNum = 0,
103         .permsNum = 1,
104         .aclsNum = 0,
105         .dcaps = NULL,
106         .perms = perms,
107         .acls = NULL,
108         .processName = "camera_capture",
109         .aplStr = "system_basic",
110     };
111     tokenId = GetAccessTokenId(&infoInstance);
112     SetSelfTokenID(tokenId);
113     OHOS::Security::AccessToken::AccessTokenKit::ReloadNativeTokenInfo();
114 
115     sptr<CameraManager> camManagerObj = CameraManager::GetInstance();
116     MEDIA_DEBUG_LOG("Setting callback to listen camera status and flash status");
117     camManagerObj->SetCallback(std::make_shared<TestCameraMngerCallback>(testName));
118     std::vector<sptr<CameraDevice>> cameraObjList = camManagerObj->GetSupportedCameras();
119     if (cameraObjList.size() == 0) {
120         return 0;
121     }
122 
123     MEDIA_DEBUG_LOG("Camera ID count: %{public}zu", cameraObjList.size());
124     for (auto& it : cameraObjList) {
125         MEDIA_DEBUG_LOG("Camera ID: %{public}s", it->GetID().c_str());
126     }
127 
128     sptr<CaptureSession> captureSession = camManagerObj->CreateCaptureSession();
129     if (captureSession == nullptr) {
130         return 0;
131     }
132 
133     captureSession->BeginConfig();
134     sptr<CaptureInput> captureInput = camManagerObj->CreateCameraInput(cameraObjList[0]);
135     if (captureInput == nullptr) {
136         return 0;
137     }
138 
139     sptr<CameraInput> cameraInput = (sptr<CameraInput> &)captureInput;
140     cameraInput->Open();
141     if (!isResolutionConfigured) {
142         std::vector<CameraFormat> previewFormats;
143         std::vector<CameraFormat> photoFormats;
144         std::vector<Size> previewSizes;
145         std::vector<Size> photoSizes;
146         sptr<CameraOutputCapability> outputcapability =  camManagerObj->GetSupportedOutputCapability(cameraObjList[0]);
147         std::vector<Profile> previewProfiles = outputcapability->GetPreviewProfiles();
148         for (auto i : previewProfiles) {
149             previewFormats.push_back(i.GetCameraFormat());
150             previewSizes.push_back(i.GetSize());
151         }
152         MEDIA_DEBUG_LOG("Supported preview formats:");
153         for (auto &formatPreview : previewFormats) {
154             MEDIA_DEBUG_LOG("format : %{public}d", formatPreview);
155         }
156         if (std::find(previewFormats.begin(), previewFormats.end(), CAMERA_FORMAT_YUV_420_SP)
157             != previewFormats.end()) {
158             previewFormat = CAMERA_FORMAT_YUV_420_SP;
159             MEDIA_DEBUG_LOG("CAMERA_FORMAT_YUV_420_SP format is present in supported preview formats");
160         } else if (!previewFormats.empty()) {
161             previewFormat = previewFormats[0];
162             MEDIA_DEBUG_LOG("CAMERA_FORMAT_YUV_420_SP format is not present in supported preview formats");
163         }
164         std::vector<Profile> photoProfiles =  outputcapability->GetPhotoProfiles();
165         for (auto i : photoProfiles) {
166             photoFormats.push_back(i.GetCameraFormat());
167             photoSizes.push_back(i.GetSize());
168         }
169         MEDIA_DEBUG_LOG("Supported photo formats:");
170         for (auto &formatPhoto : photoFormats) {
171             MEDIA_DEBUG_LOG("format : %{public}d", formatPhoto);
172         }
173         if (!photoFormats.empty()) {
174             photoFormat = photoFormats[0];
175         }
176         MEDIA_DEBUG_LOG("Supported sizes for preview:");
177         for (auto &size : previewSizes) {
178             MEDIA_DEBUG_LOG("width: %{public}d, height: %{public}d", size.width, size.height);
179         }
180         MEDIA_DEBUG_LOG("Supported sizes for photo:");
181         for (auto &size : photoSizes) {
182             MEDIA_DEBUG_LOG("width: %{public}d, height: %{public}d", size.width, size.height);
183         }
184         if (!previewSizes.empty()) {
185             previewWidth = previewSizes[0].width;
186             previewHeight = previewSizes[0].height;
187         }
188         if (!photoSizes.empty()) {
189             photoWidth = photoSizes[0].width;
190             photoHeight = photoSizes[0].height;
191         }
192     }
193 
194     MEDIA_DEBUG_LOG("previewFormat: %{public}d, previewWidth: %{public}d, previewHeight: %{public}d",
195                     previewFormat, previewWidth, previewHeight);
196     MEDIA_DEBUG_LOG("photoFormat: %{public}d, photoWidth: %{public}d, photoHeight: %{public}d",
197                     photoFormat, photoWidth, photoHeight);
198     MEDIA_DEBUG_LOG("photoCaptureCount: %{public}d", photoCaptureCount);
199 
200     cameraInput->SetErrorCallback(std::make_shared<TestDeviceCallback>(testName));
201     ret = captureSession->AddInput(captureInput);
202     if (ret != 0) {
203         return 0;
204     }
205 
206     sptr<IConsumerSurface> photoSurface = IConsumerSurface::Create();
207     if (photoSurface == nullptr) {
208         return 0;
209     }
210     photosize.width = photoWidth;
211     photosize.height = photoHeight;
212     Profile photoprofile = Profile(static_cast<CameraFormat>(photoFormat), photosize);
213     sptr<SurfaceListener> captureListener = new(std::nothrow) SurfaceListener("Photo", SurfaceType::PHOTO,
214                                                                               photoFd, photoSurface);
215     if (captureListener == nullptr) {
216         return 0;
217     }
218     photoSurface->RegisterConsumerListener((sptr<IBufferConsumerListener> &)captureListener);
219     sptr<IBufferProducer> bp = photoSurface->GetProducer();
220     sptr<CaptureOutput> photoOutput = camManagerObj->CreatePhotoOutput(photoprofile, bp);
221     if (photoOutput == nullptr) {
222         return 0;
223     }
224 
225     MEDIA_DEBUG_LOG("Setting photo callback");
226     ((sptr<PhotoOutput> &)photoOutput)->SetCallback(std::make_shared<TestPhotoOutputCallback>(testName));
227     ret = captureSession->AddOutput(photoOutput);
228     if (ret != 0) {
229         return 0;
230     }
231 
232     sptr<IConsumerSurface> previewSurface = IConsumerSurface::Create();
233     if (previewSurface == nullptr) {
234         return 0;
235     }
236     previewsize.width = previewWidth;
237     previewsize.height = previewHeight;
238     Profile previewprofile = Profile(static_cast<CameraFormat>(previewFormat), previewsize);
239     sptr<SurfaceListener> listener = new(std::nothrow) SurfaceListener("Preview", SurfaceType::PREVIEW,
240                                                                        previewFd, previewSurface);
241     if (listener == nullptr) {
242         return 0;
243     }
244     previewSurface->RegisterConsumerListener((sptr<IBufferConsumerListener> &)listener);
245     sptr<IBufferProducer> previewProducer = previewSurface->GetProducer();
246     sptr<Surface> previewProducerSurface = Surface::CreateSurfaceAsProducer(previewProducer);
247     sptr<CaptureOutput> previewOutput = camManagerObj->CreatePreviewOutput(previewprofile, previewProducerSurface);
248     if (previewOutput == nullptr) {
249         return 0;
250     }
251 
252     MEDIA_DEBUG_LOG("Setting preview callback");
253     ((sptr<PreviewOutput> &)previewOutput)->SetCallback(std::make_shared<TestPreviewOutputCallback>(testName));
254     ret = captureSession->AddOutput(previewOutput);
255     if (ret != 0) {
256         return 0;
257     }
258 
259     ret = captureSession->CommitConfig();
260     if (ret != 0) {
261         return 0;
262     }
263 
264     ret = captureSession->Start();
265     if (ret != 0) {
266         return 0;
267     }
268 
269     MEDIA_DEBUG_LOG("Preview started");
270     sleep(previewCaptureGap);
271     for (int i = 1; i <= photoCaptureCount; i++) {
272         MEDIA_DEBUG_LOG("Photo capture %{public}d started", i);
273         ret = ((sptr<PhotoOutput> &)photoOutput)->Capture(ConfigPhotoCaptureSetting());
274         if (ret != 0) {
275             return 0;
276         }
277         sleep(gapAfterCapture);
278     }
279 
280     MEDIA_DEBUG_LOG("Closing the session");
281     ((sptr<PreviewOutput> &)previewOutput)->Stop();
282     captureSession->Stop();
283     captureSession->Release();
284     cameraInput->Release();
285     camManagerObj->SetCallback(nullptr);
286 
287     MEDIA_DEBUG_LOG("Camera new sample end.");
288     return 0;
289 }
290