1 /*
2 * Copyright (C) 2021 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 <iostream>
16 #include <sstream>
17 #include <thread>
18 #include <unistd.h>
19 #include <fcntl.h>
20 #include <sys/stat.h>
21 #include "include/sp_utils.h"
22 #include "include/Capture.h"
23 #include "include/sp_log.h"
24 #include "display_manager.h"
25 #include "wm_common.h"
26 #include "png.h"
27 #include <filesystem>
28 #include "include/common.h"
29 namespace OHOS {
30 namespace SmartPerf {
31 using namespace OHOS::Media;
32 using namespace OHOS::Rosen;
ItemData()33 std::map<std::string, std::string> Capture::ItemData()
34 {
35 std::map<std::string, std::string> result;
36 const int two = 2;
37 const int modResult = callNum % two;
38 callNum++;
39 curTime = GetCurTimes();
40 std::string screenCapPath = "data/local/tmp/capture/screenCap_" + std::to_string(curTime);
41 std::string path = "NA";
42 if (isSocketMessage) {
43 if (modResult == 0) {
44 path = screenCapPath + ".jpeg";
45 result["capture"] = path;
46 TriggerGetCatchSocket(curTime);
47 isSocketMessage = false;
48 }
49 } else {
50 if (modResult == 1) {
51 path = screenCapPath + ".png";
52 result["capture"] = path;
53 TriggerGetCatch();
54 }
55 }
56 result["capture"] = path;
57
58 LOGD("capture = %s", result["capture"].c_str());
59 return result;
60 }
61
SocketMessage()62 void Capture::SocketMessage()
63 {
64 isSocketMessage = true;
65 }
66
GetCurTimes()67 long long Capture::GetCurTimes()
68 {
69 return SPUtils::GetCurTime();
70 }
ThreadGetCatch()71 void Capture::ThreadGetCatch()
72 {
73 const std::string captureDir = "/data/local/tmp/capture";
74 const std::string savePath = captureDir + "/screenCap_" + std::to_string(curTime) + ".png";
75 std::string cmdResult;
76 if (!SPUtils::FileAccess(captureDir)) {
77 std::string capturePath = CMD_COMMAND_MAP.at(CmdCommand::CREAT_DIR) + captureDir;
78 if (!SPUtils::LoadCmd(capturePath, cmdResult)) {
79 LOGE("%s capture not be created!", captureDir.c_str());
80 return;
81 } else {
82 LOGD("%s created successfully!", captureDir.c_str());
83 }
84 };
85 std::ostringstream errorRecv;
86 auto fd = open(savePath.c_str(), O_RDWR | O_CREAT, 0666);
87 if (fd == -1) {
88 LOGE("Failed to open file: %s", savePath.c_str());
89 return;
90 }
91 if (!TakeScreenCap(savePath)) {
92 LOGE("Screen Capture Failed!");
93 }
94 close(fd);
95 }
96
97
ThreadGetCatchSocket(const std::string & captureTime) const98 void Capture::ThreadGetCatchSocket(const std::string &captureTime) const
99 {
100 std::string captureDir = "/data/local/tmp/capture";
101 std::string savePath = captureDir + "/screenCap_" + captureTime + ".jpeg";
102 std::string cmdResult;
103 if (!SPUtils::FileAccess(captureDir)) {
104 std::string capturePath = CMD_COMMAND_MAP.at(CmdCommand::CREAT_DIR) + captureDir;
105 if (!SPUtils::LoadCmd(capturePath, cmdResult)) {
106 LOGE("%s capture not be created!", captureDir.c_str());
107 return;
108 } else {
109 LOGD("%s created successfully!", captureDir.c_str());
110 }
111 };
112
113 char realPath[PATH_MAX] = {0x00};
114 if (realpath(savePath.c_str(), realPath) == nullptr) {
115 std::cout << "" << std::endl;
116 }
117
118 auto fd = open(savePath.c_str(), O_RDWR | O_CREAT, 0644);
119 if (fd == -1) {
120 LOGE("Failed to open file: %s", savePath.c_str());
121 return;
122 }
123 std::string snapshot = CMD_COMMAND_MAP.at(CmdCommand::SNAPSHOT);
124 if (!SPUtils::LoadCmd(snapshot + savePath, cmdResult)) {
125 LOGE("snapshot_display command failed!");
126 close(fd);
127 return;
128 }
129 close(fd);
130 }
131
TriggerGetCatch()132 void Capture::TriggerGetCatch()
133 {
134 auto tStart = std::thread([this]() {
135 this->ThreadGetCatch();
136 });
137 tStart.detach();
138 }
139
TriggerGetCatchSocket(long long captureTime) const140 void Capture::TriggerGetCatchSocket(long long captureTime) const
141 {
142 std::string curTimeStr = std::to_string(captureTime);
143 auto tStart = std::thread([this, curTimeStr]() {
144 this->ThreadGetCatchSocket(curTimeStr);
145 });
146 tStart.detach();
147 }
148
TakeScreenCap(const std::string & savePath) const149 bool Capture::TakeScreenCap(const std::string &savePath) const
150 {
151 Rosen::DisplayManager &displayMgr = Rosen::DisplayManager::GetInstance();
152 std::shared_ptr<Media::PixelMap> pixelMap = displayMgr.GetScreenshot(displayMgr.GetDefaultDisplayId());
153 static constexpr int bitmapDepth = 8;
154 if (pixelMap == nullptr) {
155 LOGE("Failed to get display pixelMap");
156 return false;
157 }
158 auto width = static_cast<uint32_t>(pixelMap->GetWidth());
159 auto height = static_cast<uint32_t>(pixelMap->GetHeight());
160 auto data = pixelMap->GetPixels();
161 auto stride = static_cast<uint32_t>(pixelMap->GetRowBytes());
162 png_structp pngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
163 if (pngStruct == nullptr) {
164 LOGE("png_create_write_struct nullptr!");
165 return false;
166 }
167 png_infop pngInfo = png_create_info_struct(pngStruct);
168 if (pngInfo == nullptr) {
169 LOGE("png_create_info_struct error nullptr!");
170 png_destroy_write_struct(&pngStruct, nullptr);
171 return false;
172 }
173 char realPath[PATH_MAX] = {0x00};
174 if (realpath(savePath.c_str(), realPath) == nullptr) {
175 std::cout << "" << std::endl;
176 }
177 FILE *fp = fopen(realPath, "wb");
178 if (fp == nullptr) {
179 LOGE("open file error!");
180 png_destroy_write_struct(&pngStruct, &pngInfo);
181 return false;
182 }
183 png_init_io(pngStruct, fp);
184 png_set_IHDR(pngStruct, pngInfo, width, height, bitmapDepth, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE,
185 PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
186 png_set_packing(pngStruct); // set packing info
187 png_write_info(pngStruct, pngInfo); // write to header
188 for (uint32_t i = 0; i < height; i++) {
189 png_write_row(pngStruct, data + (i * stride));
190 }
191 png_write_end(pngStruct, pngInfo);
192 // free
193 png_destroy_write_struct(&pngStruct, &pngInfo);
194 (void)fclose(fp);
195 return true;
196 }
SetCollectionNum()197 void Capture::SetCollectionNum()
198 {
199 callNum = 0;
200 }
201 }
202 }
203