• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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();
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:ItemData map size(%u)", result.size());
59     return result;
60 }
61 
GetCurTimes()62 long long Capture::GetCurTimes()
63 {
64     return SPUtils::GetCurTime();
65 }
66 
SocketMessage()67 void Capture::SocketMessage()
68 {
69     isSocketMessage = true;
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         return;
94     }
95     close(fd);
96 }
97 
98 
ThreadGetCatchSocket()99 void Capture::ThreadGetCatchSocket()
100 {
101     std::string captureTime = std::to_string(curTime);
102     std::string captureDir = "/data/local/tmp/capture";
103     std::string savePath = captureDir + "/screenCap_" + captureTime + ".jpeg";
104     std::string cmdResult;
105     if (!SPUtils::FileAccess(captureDir)) {
106         std::string capturePath = CMD_COMMAND_MAP.at(CmdCommand::CREAT_DIR) + captureDir;
107         if (!SPUtils::LoadCmd(capturePath, cmdResult)) {
108             LOGE("%s capture not be created!", captureDir.c_str());
109             return;
110         } else {
111             LOGD("%s created successfully!", captureDir.c_str());
112         }
113     };
114 
115     auto fd = open(savePath.c_str(), O_RDWR | O_CREAT, 0644);
116     if (fd == -1) {
117         LOGE("Capture::ThreadGetCatchSocket Failed to open file");
118         return;
119     }
120     std::string snapshot = CMD_COMMAND_MAP.at(CmdCommand::SNAPSHOT);
121     if (!SPUtils::LoadCmd(snapshot + savePath, cmdResult)) {
122         LOGE("snapshot_display command failed!");
123         close(fd);
124         return;
125     }
126     close(fd);
127 }
128 
TriggerGetCatch()129 void Capture::TriggerGetCatch()
130 {
131     auto tStart = std::thread([this]() {
132         this->ThreadGetCatch();
133     });
134     tStart.detach();
135 }
136 
TriggerGetCatchSocket()137 void Capture::TriggerGetCatchSocket()
138 {
139     auto tStart = std::thread([this]() {
140         this->ThreadGetCatchSocket();
141     });
142     tStart.detach();
143 }
144 
TakeScreenCap(const std::string & savePath) const145 bool Capture::TakeScreenCap(const std::string &savePath) const
146 {
147     Rosen::DisplayManager &displayMgr = Rosen::DisplayManager::GetInstance();
148     std::shared_ptr<Media::PixelMap> pixelMap = displayMgr.GetScreenshot(displayMgr.GetDefaultDisplayId());
149     static constexpr int bitmapDepth = 8;
150     if (pixelMap == nullptr) {
151         LOGE("Failed to get display pixelMap");
152         return false;
153     }
154     auto width = static_cast<uint32_t>(pixelMap->GetWidth());
155     auto height = static_cast<uint32_t>(pixelMap->GetHeight());
156     auto data = pixelMap->GetPixels();
157     auto stride = static_cast<uint32_t>(pixelMap->GetRowBytes());
158     png_structp pngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
159     if (pngStruct == nullptr) {
160         LOGE("png_create_write_struct nullptr!");
161         return false;
162     }
163     png_infop pngInfo = png_create_info_struct(pngStruct);
164     if (pngInfo == nullptr) {
165         LOGE("png_create_info_struct error nullptr!");
166         png_destroy_write_struct(&pngStruct, nullptr);
167         return false;
168     }
169     char realPath[PATH_MAX] = {0x00};
170     if (realpath(savePath.c_str(), realPath) == nullptr) {
171         std::cout << "" << std::endl;
172     }
173     FILE *fp = fopen(realPath, "wb");
174     if (fp == nullptr) {
175         LOGE("open file error!");
176         png_destroy_write_struct(&pngStruct, &pngInfo);
177         return false;
178     }
179     png_init_io(pngStruct, fp);
180     png_set_IHDR(pngStruct, pngInfo, width, height, bitmapDepth, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE,
181         PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
182     png_set_packing(pngStruct);         // set packing info
183     png_write_info(pngStruct, pngInfo); // write to header
184     for (uint32_t i = 0; i < height; i++) {
185         png_write_row(pngStruct, data + (i * stride));
186     }
187     png_write_end(pngStruct, pngInfo);
188     // free
189     png_destroy_write_struct(&pngStruct, &pngInfo);
190     (void)fclose(fp);
191     return true;
192 }
SetCollectionNum()193 void Capture::SetCollectionNum()
194 {
195     callNum = 0;
196 }
197 }
198 }
199