• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "wukong_util.h"
17 
18 #include <climits>
19 #include <dirent.h>
20 #include <fstream>
21 #include <iostream>
22 #include <memory.h>
23 #include <sstream>
24 #include <sys/stat.h>
25 
26 #include "display_manager.h"
27 #include "if_system_ability_manager.h"
28 #include "iservice_registry.h"
29 #include "launcher_service.h"
30 #include "png.h"
31 #include "string_ex.h"
32 #include "system_ability_definition.h"
33 #include "wukong_define.h"
34 #include "bundle_mgr_proxy.h"
35 
36 namespace OHOS {
37 namespace WuKong {
38 namespace {
39 const std::string DEFAULT_DIR = "/data/local/tmp/wukong/report/";
TakeWuKongScreenCap(const std::string & wkScreenPath)40 bool TakeWuKongScreenCap(const std::string &wkScreenPath)
41 {
42     // get PixelMap from DisplayManager API
43     Rosen::DisplayManager &displayMgr = Rosen::DisplayManager::GetInstance();
44     std::shared_ptr<Media::PixelMap> pixelMap = displayMgr.GetScreenshot(displayMgr.GetDefaultDisplayId());
45     static constexpr int bitmapDepth = 8;
46     if (pixelMap == nullptr) {
47         DEBUG_LOG("Failed to get display pixelMap");
48         return false;
49     }
50     auto width = static_cast<uint32_t>(pixelMap->GetWidth());
51     auto height = static_cast<uint32_t>(pixelMap->GetHeight());
52     auto data = pixelMap->GetPixels();
53     auto stride = static_cast<uint32_t>(pixelMap->GetRowBytes());
54     png_structp pngStruct = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
55     if (pngStruct == nullptr) {
56         DEBUG_LOG("error: png_create_write_struct nullptr!");
57         return false;
58     }
59     png_infop pngInfo = png_create_info_struct(pngStruct);
60     if (pngInfo == nullptr) {
61         DEBUG_LOG("error: png_create_info_struct error nullptr!");
62         png_destroy_write_struct(&pngStruct, nullptr);
63         return false;
64     }
65     FILE *fp = fopen(wkScreenPath.c_str(), "wb");
66     if (fp == nullptr) {
67         ERROR_LOG("error: open file error!");
68         png_destroy_write_struct(&pngStruct, &pngInfo);
69         return false;
70     }
71     png_init_io(pngStruct, fp);
72     png_set_IHDR(pngStruct, pngInfo, width, height, bitmapDepth, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE,
73                  PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
74     png_set_packing(pngStruct);          // set packing info
75     png_write_info(pngStruct, pngInfo);  // write to header
76     for (uint32_t i = 0; i < height; i++) {
77         png_write_row(pngStruct, data + (i * stride));
78     }
79     png_write_end(pngStruct, pngInfo);
80     // free
81     png_destroy_write_struct(&pngStruct, &pngInfo);
82     (void)fclose(fp);
83     return true;
84 }
85 }  // namespace
86 using namespace std;
87 using namespace OHOS::AppExecFwk;
88 const int USE_ID = 100;
WuKongUtil()89 WuKongUtil::WuKongUtil()
90 {
91     TRACK_LOG_STD();
92     const int timeBufsize = 32;
93     char fileNameBuf[timeBufsize] = {0};
94     time_t currentTime = time(0);
95     uint32_t res = 0;
96 
97     if (currentTime > 0) {
98         tm *timePtr = localtime(&currentTime);
99         if (timePtr == nullptr) {
100             ERROR_LOG("timePtr is nullptr");
101             return;
102         }
103         res = strftime(fileNameBuf, timeBufsize, "%Y%m%d_%H%M%S", timePtr);
104     }
105     if (res > 0) {
106         startRunTime_ = std::string(fileNameBuf);
107     } else {
108         startRunTime_ = "unvalid_time";
109     }
110     curDir_ = DEFAULT_DIR + startRunTime_ + "/";
111     DEBUG_LOG_STR("common dir{%s}", curDir_.c_str());
112     DIR *rootDir = nullptr;
113     std::string dirStr = "/";
114     std::vector<std::string> strs;
115     OHOS::SplitStr(curDir_, "/", strs);
116     for (auto str : strs) {
117         dirStr.append(str);
118         dirStr.append("/");
119         if ((rootDir = opendir(dirStr.c_str())) == nullptr) {
120             int ret = mkdir(dirStr.c_str(), S_IROTH | S_IRWXU | S_IRWXG);
121             if (ret != 0 && dirStr != "/data/" && dirStr != "/data/local/") {
122                 std::cerr << "failed to create dir: " << dirStr << std::endl;
123                 break;
124             }
125         } else {
126             closedir(rootDir);
127         }
128     }
129     DEBUG_LOG_STR("%s", startRunTime_.c_str());
130     TRACK_LOG_END();
131 }
132 
133 /**
134  * @brief: release util
135  */
~WuKongUtil()136 WuKongUtil::~WuKongUtil()
137 {
138     TRACK_LOG_STD();
139 }
140 
GetAllAppInfo()141 ErrCode WuKongUtil::GetAllAppInfo()
142 {
143     AppExecFwk::LauncherService launcherservice;
144     std::vector<AppExecFwk::LauncherAbilityInfo> launcherAbilityInfos(0);
145 
146     bool result = launcherservice.GetAllLauncherAbilityInfos(USE_ID, launcherAbilityInfos);
147     DEBUG_LOG_STR("GetAllLauncherAbilityInfos: size (%u), result (%d)", launcherAbilityInfos.size(), result);
148     if (launcherAbilityInfos.size() == 0) {
149         ERROR_LOG("GetAllLauncherAbilityInfos size is 0");
150         return OHOS::ERR_INVALID_VALUE;
151     }
152     for (auto item : launcherAbilityInfos) {
153         iconPath_ = item.applicationInfo.iconPath;
154         DEBUG_LOG_STR("iconPath: %s", item.applicationInfo.iconPath.c_str());
155         DEBUG_LOG_STR("codePath: %s", item.applicationInfo.codePath.c_str());
156         DEBUG_LOG_STR("dataDir: %s", item.applicationInfo.dataDir.c_str());
157         DEBUG_LOG_STR("dataBaseDir: %s", item.applicationInfo.dataBaseDir.c_str());
158         DEBUG_LOG_STR("cacheDir: %s", item.applicationInfo.cacheDir.c_str());
159         DEBUG_LOG_STR("entryDir: %s", item.applicationInfo.entryDir.c_str());
160         std::string bundleName = item.elementName.GetBundleName();
161         // store the list of all bundle names
162         bundleList_.push_back(bundleName);
163         abilityList_.push_back(item.elementName.GetAbilityName());
164         uint32_t isInBlockList = FindElement(blockList_, bundleName);
165         if (isInBlockList != INVALIDVALUE) {
166             continue;
167         }
168         // store the list of bundle names except for block list
169         validBundleList_.push_back(bundleName);
170         validAbilityList_.push_back(item.elementName.GetAbilityName());
171     }
172     return OHOS::ERR_OK;
173 }
174 
GetBundleList(std::vector<std::string> & bundlelist,std::vector<std::string> & abilitylist)175 void WuKongUtil::GetBundleList(std::vector<std::string> &bundlelist, std::vector<std::string> &abilitylist)
176 {
177     if (bundleList_.size() == 0) {
178         GetAllAppInfo();
179     }
180     bundlelist = bundleList_;
181     abilitylist = abilityList_;
182 }
183 
FindElement(std::vector<std::string> bundleList,std::string key)184 uint32_t WuKongUtil::FindElement(std::vector<std::string> bundleList, std::string key)
185 {
186     auto it = find(bundleList.begin(), bundleList.end(), key);
187     if (it != bundleList.end()) {
188         return distance(bundleList.begin(), it);
189     }
190     return INVALIDVALUE;
191 }
192 
CheckBundleNameList()193 ErrCode WuKongUtil::CheckBundleNameList()
194 {
195     std::set<std::string> m(allowList_.begin(), allowList_.end());
196 
197     for (auto it = blockList_.begin(); it != blockList_.end(); it++) {
198         if (m.find(*it) != m.end()) {
199             ERROR_LOG("invalid param:please check params of '-p' and '-b'");
200             return OHOS::ERR_INVALID_VALUE;
201         }
202     }
203     return OHOS::ERR_OK;
204 }
205 
CheckArgumentList(std::vector<std::string> & arguments)206 ErrCode WuKongUtil::CheckArgumentList(std::vector<std::string> &arguments)
207 {
208     ErrCode result = OHOS::ERR_OK;
209     GetAllAppInfo();
210     for (uint32_t i = 0; i < arguments.size(); i++) {
211         uint32_t index = FindElement(bundleList_, arguments[i]);
212         if (index == INVALIDVALUE) {
213             ERROR_LOG_STR("bundle name '%s' is not be included in all bundles", arguments[i].c_str());
214             result = OHOS::ERR_INVALID_VALUE;
215         }
216     }
217     return result;
218 }
219 
SetAllowList(const std::string & optarg)220 ErrCode WuKongUtil::SetAllowList(const std::string &optarg)
221 {
222     SplitStr(optarg, ",", allowList_);
223     ErrCode result = CheckArgumentList(allowList_);
224     if (result == OHOS::ERR_OK) {
225         // delete repeat argument
226         DelRepeatArguments(allowList_);
227         if (allowList_.size() > 0) {
228             result = CheckBundleNameList();
229         }
230     }
231     return result;
232 }
233 
SetBlockList(const std::string & optarg)234 ErrCode WuKongUtil::SetBlockList(const std::string &optarg)
235 {
236     SplitStr(optarg, ",", blockList_);
237     ErrCode result = CheckArgumentList(blockList_);
238     if (result == OHOS::ERR_OK) {
239         // delete repeat argument
240         DelRepeatArguments(blockList_);
241         if (blockList_.size() > 0) {
242             result = CheckBundleNameList();
243         }
244     }
245     return result;
246 }
247 
DelRepeatArguments(std::vector<std::string> & argumentlist)248 void WuKongUtil::DelRepeatArguments(std::vector<std::string> &argumentlist)
249 {
250     std::set<std::string> s(argumentlist.begin(), argumentlist.end());
251     argumentlist.assign(s.begin(), s.end());
252 }
253 
GetAllowList(std::vector<std::string> & allowList)254 void WuKongUtil::GetAllowList(std::vector<std::string> &allowList)
255 {
256     allowList = allowList_;
257 }
258 
GetBlockList(std::vector<std::string> & blockList)259 void WuKongUtil::GetBlockList(std::vector<std::string> &blockList)
260 {
261     blockList = blockList_;
262 }
263 
GetValidBundleList(std::vector<std::string> & validbundlelist)264 void WuKongUtil::GetValidBundleList(std::vector<std::string> &validbundlelist)
265 {
266     validbundlelist = validBundleList_;
267 }
268 
SetAllAppInfo(std::vector<std::string> & bundleList,std::vector<std::string> & abilityList)269 void WuKongUtil::SetAllAppInfo(std::vector<std::string> &bundleList, std::vector<std::string> &abilityList)
270 {
271     bundleList_ = bundleList;
272     abilityList_ = abilityList;
273 }
274 
SetTempAllowList(std::vector<std::string> tempAllowList)275 void WuKongUtil::SetTempAllowList(std::vector<std::string> tempAllowList)
276 {
277     tempAllowList_ = tempAllowList;
278 }
279 
GetTempAllowList()280 std::vector<std::string> WuKongUtil::GetTempAllowList()
281 {
282     return tempAllowList_;
283 }
284 
SetOrderFlag(bool orderFlag)285 void WuKongUtil::SetOrderFlag(bool orderFlag)
286 {
287     orderFlag_ = orderFlag;
288 }
289 
GetOrderFlag()290 bool WuKongUtil::GetOrderFlag()
291 {
292     return orderFlag_;
293 }
294 
GetScreenSize(int32_t & width,int32_t & height)295 ErrCode WuKongUtil::GetScreenSize(int32_t &width, int32_t &height)
296 {
297     ErrCode result = OHOS::ERR_OK;
298     if (screenWidth_ == -1 || screenHeight_ == -1) {
299         OHOS::Rosen::DisplayManager &displayMgr = OHOS::Rosen::DisplayManager::GetInstance();
300         sptr<OHOS::Rosen::Display> display = displayMgr.GetDefaultDisplay();
301         if (display == nullptr) {
302             ERROR_LOG("get screen size failed");
303             return OHOS::ERR_NO_INIT;
304         }
305         screenWidth_ = display->GetWidth();
306         screenHeight_ = display->GetHeight();
307     }
308     width = screenWidth_;
309     height = screenHeight_;
310     return result;
311 }
312 
GetIconPath(std::string & iconpath)313 void WuKongUtil::GetIconPath(std::string &iconpath)
314 {
315     iconpath = iconPath_;
316 }
317 
WukongScreenCap(std::string & screenStorePath)318 ErrCode WuKongUtil::WukongScreenCap(std::string &screenStorePath)
319 {
320     using namespace std::chrono;
321     ErrCode result = ERR_OK;
322     auto wukongts = to_string(time_point_cast<milliseconds>(system_clock::now()).time_since_epoch().count());
323     int fileExist_ = access((curDir_ + "screenshot").c_str(), F_OK);
324     if (fileExist_ == 0) {
325         DEBUG_LOG("File exist.");
326     } else {
327         const int wukongScreenShot = mkdir((curDir_ + "screenshot").c_str(), 0777);
328         DEBUG_LOG("File create.");
329         if (wukongScreenShot == -1) {
330             DEBUG_LOG("Error creating directory!");
331             result = ERR_NO_INIT;
332         }
333     }
334     auto wkScreenPath = curDir_ + "screenshot/" + "/" + wukongts + ".png";
335     DEBUG_LOG_STR("WukongScreenCap store path is  {%s}", wkScreenPath.c_str());
336     bool isTakeScreen = TakeWuKongScreenCap(wkScreenPath);
337     if (isTakeScreen == true) {
338         screenStorePath = wkScreenPath;
339         DEBUG_LOG("The snapshot has been created.");
340     } else {
341         DEBUG_LOG("This snapshot can not be created.");
342     }
343     return result;
344 }
345 
GetBundleMgrProxy() const346 sptr<IBundleMgr> WuKongUtil::GetBundleMgrProxy() const
347 {
348     sptr<ISystemAbilityManager> systemAbilityManager =
349         SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
350     if (!systemAbilityManager) {
351         ERROR_LOG("failed to get system ability mgr.");
352         return nullptr;
353     }
354 
355     sptr<IRemoteObject> remoteObject = systemAbilityManager->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
356     if (!remoteObject) {
357         ERROR_LOG("failed to get bundle manager proxy.");
358         return nullptr;
359     }
360 
361     return iface_cast<IBundleMgr>(remoteObject);
362 }
363 
GetAllAbilitiesByBundleName(std::string bundleName,std::vector<std::string> & abilities)364 void WuKongUtil::GetAllAbilitiesByBundleName(std::string bundleName, std::vector<std::string> &abilities)
365 {
366     TRACK_LOG_STD();
367     sptr<IBundleMgr> bundleMgrProxy = GetBundleMgrProxy();
368     std::vector<BundleInfo> bundleInfos;
369     if (!bundleMgrProxy) {
370         ERROR_LOG("bundleMgrProxy is nullptr");
371         return;
372     }
373     bool getInfoResult = bundleMgrProxy->GetBundleInfos(BundleFlag::GET_BUNDLE_DEFAULT, bundleInfos, USE_ID);
374     if (!getInfoResult) {
375         ERROR_LOG("GetBundleInfos ERR");
376         return;
377     }
378     DEBUG_LOG_STR("bundles length{%d}", bundleInfos.size());
379     for (auto &bundleIter : bundleInfos) {
380         DEBUG_LOG_STR("bundleIter.name{%s}", bundleName.c_str());
381         BundleInfo bundleInfo;
382         if (bundleIter.name == bundleName) {
383             DEBUG_LOG_STR("map bundleName{%s}", bundleName.c_str());
384             bool result =
385                 bundleMgrProxy->GetBundleInfo(bundleIter.name, BundleFlag::GET_BUNDLE_WITH_ABILITIES, bundleInfo, 100);
386             if (!result) {
387                 ERROR_LOG_STR("WriteWuKongBundleInfo getBundleInfo result %d", result);
388                 break;
389             }
390             for (auto &abilityIter : bundleInfo.abilityInfos) {
391                 DEBUG_LOG_STR("bundleName{%s} container abilities item{%s}", bundleName.c_str(),
392                               (abilityIter.name).c_str());
393                 abilities.push_back(abilityIter.name);
394             }
395         }
396     }
397     TRACK_LOG_END();
398 }
399 
GetCurrentTestDir()400 std::string WuKongUtil::GetCurrentTestDir()
401 {
402     return curDir_;
403 }
404 
CopyFile(std::string & targetFile,std::string & sourceDir,std::string & destDir)405 bool WuKongUtil::CopyFile(std::string &targetFile, std::string &sourceDir, std::string &destDir)
406 {
407     std::ifstream in;
408     std::ofstream out;
409     DEBUG_LOG_STR("targetFile{%s} sourceDir{%s} destDir{%s}", targetFile.c_str(), sourceDir.c_str(), destDir.c_str());
410     char filepathSource[PATH_MAX] = {'\0'};
411     std::string sourceFile = sourceDir + targetFile;
412     char *realPathSource = realpath(sourceFile.c_str(), filepathSource);
413     if (realPathSource == nullptr) {
414         ERROR_LOG_STR("failed to get source file path (%s), errno: (%d)", sourceFile.c_str(), errno);
415         return false;
416     }
417     in.open(filepathSource, std::ios::binary);
418     if (in.fail()) {
419         std::cout << "Error 1: Fail to open the source file." << std::endl;
420         in.close();
421         out.close();
422         return false;
423     }
424 
425     char filepathDest[PATH_MAX] = {'\0'};
426     char *realPathDest = realpath(destDir.c_str(), filepathDest);
427     if (realPathDest == nullptr) {
428         ERROR_LOG_STR("failed to get dest dir path (%s), errno: (%d)", destDir.c_str(), errno);
429         return false;
430     }
431     DEBUG_LOG_STR("destDir{%s}", filepathDest);
432     std::string destFile = destDir + targetFile;
433     out.open(destFile.c_str(), std::ios::binary);
434     if (out.fail()) {
435         std::cout << "Error 2: Fail to create the new file." << std::endl;
436         out.close();
437         in.close();
438         return false;
439     }
440     out << in.rdbuf();
441     out.close();
442     in.close();
443     return true;
444 }
445 
DeleteFile(std::string targetDir)446 bool WuKongUtil::DeleteFile(std::string targetDir)
447 {
448     DIR *dirdp = nullptr;
449     char filepathSource[PATH_MAX] = {'\0'};
450     char *realPathSource = realpath(targetDir.c_str(), filepathSource);
451     if (realPathSource != nullptr) {
452         struct dirent *dp;
453         dirdp = opendir(targetDir.c_str());
454         while ((dp = readdir(dirdp)) != NULL) {
455             std::string currentFileName(dp->d_name);
456             std::string sourceFile = targetDir + currentFileName;
457             char *realFileSource = realpath(sourceFile.c_str(), filepathSource);
458             if (realFileSource != nullptr) {
459                 remove(sourceFile.c_str());
460             }
461         }
462     } else {
463         return false;
464     }
465     (void)closedir(dirdp);
466     return true;
467 }
468 }  // namespace WuKong
469 }  // namespace OHOS
470