1 /*
2 * Copyright (c) 2021-2025 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 <ctime>
17 #include <iostream>
18 #include <string>
19
20 #include "display_manager_proxy.h"
21 #include "screen_manager.h"
22 #include "snapshot_utils.h"
23 #include "surface_reader.h"
24 #include "surface_reader_handler_impl.h"
25
26 using namespace OHOS;
27 using namespace OHOS::Rosen;
28 using namespace OHOS::Media;
29
30 namespace {
31 constexpr int SLEEP_US = 10 * 1000; // 10ms
32 constexpr int MAX_SNAPSHOT_COUNT = 10;
33 constexpr int MAX_WAIT_COUNT = 200;
34 constexpr float DEFAULT_DENSITY = 2.0;
35 const std::string FILE_NAME = "/data/local/tmp/snapshot_virtual_screen";
36 }
37
38 static ScreenId mainId;
39 static ScreenId virtualScreenId;
40
InitOption(ScreenId mainId,const SurfaceReader & surfaceReader)41 static std::unique_ptr<VirtualScreenOption> InitOption(ScreenId mainId, const SurfaceReader& surfaceReader)
42 {
43 auto defaultScreen = ScreenManager::GetInstance().GetScreenById(mainId);
44 std::unique_ptr<VirtualScreenOption> option = std::make_unique<VirtualScreenOption>();
45 if (option == nullptr) {
46 return option;
47 }
48
49 option->name_ = "virtualScreen";
50 option->width_ = defaultScreen->GetWidth();
51 option->height_ = defaultScreen->GetHeight();
52 option->density_ = DEFAULT_DENSITY;
53 option->surface_ = surfaceReader.GetSurface();
54 option->flags_ = 0;
55 option->isForShot_ = true;
56 return option;
57 }
58
InitMirror(const SurfaceReader & surfaceReader)59 static bool InitMirror(const SurfaceReader& surfaceReader)
60 {
61 mainId = static_cast<ScreenId>(DisplayManager::GetInstance().GetDefaultDisplayId());
62 if (mainId == SCREEN_ID_INVALID) {
63 std::cout<< "get default display id failed!" << std::endl;
64 return false;
65 }
66
67 std::unique_ptr<VirtualScreenOption> option = InitOption(mainId, surfaceReader);
68 if (option == nullptr) {
69 return false;
70 }
71
72 virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(*option);
73 std::vector<ScreenId> mirrorIds;
74 mirrorIds.push_back(virtualScreenId);
75 ScreenId screenGroupId = static_cast<ScreenId>(1);
76 ScreenManager::GetInstance().MakeMirror(mainId, mirrorIds, screenGroupId);
77 return true;
78 }
79
main(int argc,char * argv[])80 int main(int argc, char *argv[])
81 {
82 SurfaceReader surfaceReader;
83 sptr<SurfaceReaderHandlerImpl> surfaceReaderHandler = new SurfaceReaderHandlerImpl();
84 if (!surfaceReader.Init()) {
85 std::cout << "surfaceReader init failed!" << std::endl;
86 return 0;
87 }
88 surfaceReader.SetHandler(surfaceReaderHandler);
89 if (!InitMirror(surfaceReader)) {
90 return 0;
91 }
92 int fileIndex = 1;
93 auto startTime = time(nullptr);
94 if (startTime < 0) {
95 std::cout << "startTime error!" << std::endl;
96 return 0;
97 }
98 while (time(nullptr) - startTime < MAX_SNAPSHOT_COUNT) {
99 int waitCount = 0;
100 while (!surfaceReaderHandler->IsImageOk()) {
101 waitCount++;
102 if (waitCount >= MAX_WAIT_COUNT) {
103 std::cout << "wait image overtime" << std::endl;
104 break;
105 }
106 usleep(SLEEP_US);
107 }
108 if (waitCount >= MAX_WAIT_COUNT) {
109 continue;
110 }
111 auto pixelMap = surfaceReaderHandler->GetPixelMap();
112 bool ret = SnapShotUtils::WriteToJpegWithPixelMap(FILE_NAME + std::to_string(fileIndex) + ".jpeg", *pixelMap);
113 if (ret) {
114 std::cout << "snapshot "<< mainId << " write to " <<
115 (FILE_NAME + std::to_string(fileIndex)).c_str() << " as jpeg" << std::endl;
116 } else {
117 std::cout << "snapshot "<< mainId << " write to " <<
118 (FILE_NAME + std::to_string(fileIndex)).c_str() << " failed!" << std::endl;
119 }
120 surfaceReaderHandler->ResetFlag();
121 fileIndex++;
122 }
123 ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId);
124 std::cout << "DestroyVirtualScreen " << virtualScreenId << std::endl;
125 return 0;
126 }
127