• 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 
16 #include "file_manager.h"
17 #include <algorithm>
18 #include "compression_parser.h"
19 #include <iostream>
20 #include "resource_compiler_factory.h"
21 #include "file_entry.h"
22 #include "key_parser.h"
23 #include "reference_parser.h"
24 #include "resource_directory.h"
25 #include "resource_util.h"
26 #include "restool_errors.h"
27 #include "resource_module.h"
28 
29 namespace OHOS {
30 namespace Global {
31 namespace Restool {
32 using namespace std;
ScanModules(const vector<string> & inputs,const string & output,const bool isHar)33 uint32_t FileManager::ScanModules(const vector<string> &inputs, const string &output, const bool isHar)
34 {
35     vector<pair<ResType, string>> noBaseResource;
36     for (auto input : inputs) {
37         if (ScanModule(input, output) != RESTOOL_SUCCESS) {
38             return RESTOOL_ERROR;
39         }
40         CheckAllItems(noBaseResource);
41     }
42     if (!noBaseResource.empty()) {
43         ResourceUtil::PrintWarningMsg(noBaseResource);
44     }
45     return isHar ? RESTOOL_SUCCESS : ParseReference(output);
46 }
47 
MergeResourceItem(const map<int64_t,vector<ResourceItem>> & resourceInfos)48 uint32_t FileManager::MergeResourceItem(const map<int64_t, vector<ResourceItem>> &resourceInfos)
49 {
50     return ResourceModule::MergeResourceItem(items_, resourceInfos);
51 }
52 
53 // below private founction
ScanModule(const string & input,const string & output)54 uint32_t FileManager::ScanModule(const string &input, const string &output)
55 {
56     ResourceModule resourceModule(input, output, moduleName_);
57     if (resourceModule.ScanResource(scanHap_) != RESTOOL_SUCCESS) {
58         return RESTOOL_ERROR;
59     }
60     MergeResourceItem(resourceModule.GetOwner());
61     return RESTOOL_SUCCESS;
62 }
63 
ParseReference(const string & output)64 uint32_t FileManager::ParseReference(const string &output)
65 {
66     ReferenceParser referenceParser;
67     if (referenceParser.ParseRefInResources(items_, output) != RESTOOL_SUCCESS) {
68         return RESTOOL_ERROR;
69     }
70     return RESTOOL_SUCCESS;
71 }
72 
CheckAllItems(vector<pair<ResType,string>> & noBaseResource)73 void FileManager::CheckAllItems(vector<pair<ResType, string>> &noBaseResource)
74 {
75     for (const auto &item : items_) {
76         bool found = any_of(item.second.begin(), item.second.end(), [](const auto &iter) {
77             return iter.GetLimitKey() == "base";
78         });
79         if (!found) {
80             auto firstItem = item.second.front();
81             bool ret = any_of(noBaseResource.begin(), noBaseResource.end(), [firstItem](const auto &iterItem) {
82                 return (firstItem.GetResType() == iterItem.first)  &&
83                     (firstItem.GetName() == iterItem.second);
84             });
85             if (!ret) {
86                 noBaseResource.push_back(make_pair(firstItem.GetResType(), firstItem.GetName()));
87             }
88         }
89     }
90 }
91 
ScaleIcons(const string & output,const std::map<std::string,std::set<uint32_t>> & iconMap)92 bool FileManager::ScaleIcons(const string &output, const std::map<std::string, std::set<uint32_t>> &iconMap)
93 {
94     if (!CompressionParser::GetCompressionParser()->ScaleIconEnable()) {
95         cout << "Info: scale icon is not enable." << endl;
96         return true;
97     }
98     std::set<int64_t> allIconIds;
99     for (auto &it : iconMap) {
100         if (it.first != "icon") {
101             continue;
102         }
103         allIconIds.insert(it.second.begin(), it.second.end());
104     }
105     if (allIconIds.size() == 0) {
106         cout << "Info: no icons need to scale, icon ids size is 0." << endl;
107         return true;
108     }
109     for (auto &id : allIconIds) {
110         std::map<int64_t, std::vector<ResourceItem>>::iterator iter = items_.find(id);
111         if (iter == items_.end()) {
112             continue;
113         }
114         for (auto &item : iter->second) {
115             if (!ScaleIcon(output, item)) {
116                 return false;
117             }
118         }
119     }
120     return true;
121 }
122 
SetScanHap(bool state)123 void FileManager::SetScanHap(bool state)
124 {
125     scanHap_ = state;
126 }
127 
ScaleIcon(const string & output,ResourceItem & item)128 bool FileManager::ScaleIcon(const string &output, ResourceItem &item)
129 {
130     std::string media = "media";
131     // item's data is short path for icon file, such as "entry/resources/base/media/app_icon.png"
132     const string currentData(reinterpret_cast<const char *>(item.GetData()), item.GetDataLength());
133     auto outIndex = currentData.find_last_of(SEPARATOR);
134     if (outIndex == string::npos) {
135         PrintError(GetError(ERR_CODE_INVALID_OUTPUT).FormatCause(currentData.c_str()));
136         return false;
137     }
138     // get current output file name and full path
139     string fileName = currentData.substr(outIndex + 1);
140     FileEntry::FilePath fullFilePath = FileEntry::FilePath(output).Append(RESOURCES_DIR).Append(item.GetLimitKey())
141         .Append(media).Append(fileName);
142     if (fullFilePath.GetExtension() == JSON_EXTENSION) {
143         cout << "Info: can't scale media json file." << endl;
144         return true;
145     }
146     const string fullOutPath = fullFilePath.GetPath();
147     // delete current output file
148     if (!ResourceUtil::RmoveFile(fullOutPath)) {
149         return false;
150     }
151     // get origin icon output full path with the origin icon file name in src
152     std::string dst = FileEntry::FilePath(output).Append(RESOURCES_DIR).Append(item.GetLimitKey()).Append(media)
153         .Append(item.GetName()).GetPath();
154     // the origin full file in src
155     std::string scaleDst = item.GetFilePath();
156     // scale icon
157     if (!CompressionParser::GetCompressionParser()->CheckAndScaleIcon(item.GetFilePath(), dst, scaleDst)) {
158         return false;
159     }
160     // compress scaled icon
161     if (!CompressionParser::GetCompressionParser()->CopyAndTranscode(scaleDst, dst)) {
162         return false;
163     }
164     string newFileName = FileEntry::FilePath(dst).GetFilename();
165     std::string newData = moduleName_ + SEPARATOR + RESOURCES_DIR + SEPARATOR + item.GetLimitKey() + SEPARATOR + media
166         + SEPARATOR + newFileName;
167     if (!item.SetData(reinterpret_cast<const int8_t *>(newData.c_str()), newData.length())) {
168         std::string msg = "item data is null, resource name: " + item.GetName();
169         PrintError(GetError(ERR_CODE_UNDEFINED_ERROR).FormatCause(msg.c_str()).SetPosition(item.GetFilePath()));
170         return false;
171     }
172     return true;
173 }
174 }
175 }
176 }
177