1 /*
2 * Copyright (c) 2024 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 "font_manager.h"
17
18 #include <string_ex.h>
19 #include "font_hilog.h"
20 #include "font_event_publish.h"
21 #include "font_config.h"
22 #include "file_utils.h"
23 #include "hisysevent_adapter.h"
24 #include "text/font_mgr.h"
25
26 namespace OHOS {
27 namespace Global {
28 namespace FontManager {
29 using namespace Rosen::Drawing;
30 static const std::string INSTALL_PATH = "/data/service/el1/public/for-all-app/fonts/";
31 static const std::string FONT_CONFIG_FILE = INSTALL_PATH + "install_fontconfig.json";
32 static const std::string FONTS_TEMP_PATH = "/data/service/el1/public/for-all-app/fonts/temp/";
33 static constexpr int32_t MAX_INSTALL_NUM = 200;
34 static constexpr int32_t NUM_TWO = 2;
FontManager()35 FontManager::FontManager()
36 {
37 }
38
~FontManager()39 FontManager::~FontManager()
40 {
41 }
42
CheckInstallPath()43 bool FontManager::CheckInstallPath()
44 {
45 if (!FileUtils::CheckPathExist(INSTALL_PATH)) {
46 return false;
47 }
48 if (!FileUtils::CheckPathExist(FONTS_TEMP_PATH)) {
49 return FileUtils::CreatDirWithPermission(FONTS_TEMP_PATH);
50 }
51 return true;
52 }
53
CheckFontConfigPath()54 bool FontManager::CheckFontConfigPath()
55 {
56 if (FileUtils::CheckPathExist(FONT_CONFIG_FILE)) {
57 return true;
58 }
59 std::string font_list = R"({
60 "fontlist": []
61 })";
62 return FileUtils::CreateFileWithPermission(FONT_CONFIG_FILE, font_list);
63 }
64
InstallFont(const int32_t & fd)65 int32_t FontManager::InstallFont(const int32_t &fd)
66 {
67 if (!(CheckInstallPath() && CheckFontConfigPath())) {
68 return ERR_FILE_NOT_EXISTS;
69 }
70
71 std::vector<std::string> fullNameVector = GetFontFullName(fd);
72 if (fullNameVector.size() == 0) {
73 FONT_LOGE("get fontFullName failed, font file verified failed");
74 return ERR_FILE_VERIFY_FAIL;
75 }
76
77 // 判断字体文件是否已安装
78 FontConfig fontConfig(FONT_CONFIG_FILE);
79 for (const auto &fullName : fullNameVector) {
80 std::string path = fontConfig.GetFontFileByName(fullName);
81 if (!path.empty() && !FileUtils::CheckPathExist(path)) {
82 if (!fontConfig.DeleteFontRecord(path)) {
83 FONT_LOGE("update install_fontconfig fail");
84 return ERR_INSTALL_FAIL;
85 }
86 break;
87 }
88 if (!path.empty()) {
89 FONT_LOGI("Font already installed");
90 return ERR_INSTALLED_ALRADY;
91 }
92 }
93 // 判断是否超过最大安装数量
94 if (fontConfig.GetInstalledFontsNum() >= MAX_INSTALL_NUM) {
95 FONT_LOGI("installed files reach 200, not allowed to install more");
96 return ERR_MAX_FILE_COUNT;
97 }
98 // 将字体文件拷贝到目标目录
99 std::string sourcePath = FileUtils::GetFilePathByFd(fd);
100 std::string destPath = CopyFile(sourcePath, fd);
101 if (destPath.empty()) {
102 FONT_LOGE("copy file %{public}s error", sourcePath.c_str());
103 return ERR_COPY_FAIL;
104 }
105 HisyseventAdapter::GetInstance()->CollectUserDataSize();
106 if (fontConfig.InsertFontRecord(destPath, fullNameVector)) {
107 FontEventPublish::PublishFontUpdate(FontEventType::INSTALL, GetFormatFullName(fullNameVector));
108 return SUCCESS;
109 }
110 return ERR_INSTALL_FAIL;
111 }
112
GetFormatFullName(const std::vector<std::string> & fullNameVector)113 std::string FontManager::GetFormatFullName(const std::vector<std::string> &fullNameVector)
114 {
115 std::string FormatFullName;
116 std::string split = ",";
117 for (const auto &name : fullNameVector) {
118 FormatFullName += name + split;
119 }
120 return FormatFullName.substr(0, FormatFullName.size() - split.size());
121 }
122
GetFontFullName(const int32_t & fd)123 std::vector<std::string> FontManager::GetFontFullName(const int32_t &fd)
124 {
125 // 调用字体引擎接口校验字体格式
126 std::vector<std::string> fullNameVector;
127 std::vector<FontByteArray> fullNameVec;
128 std::shared_ptr<FontMgr> fontMgr = FontMgr::CreateDefaultFontMgr();
129 if (fontMgr == nullptr) {
130 FONT_LOGE("fontMgr is null");
131 return fullNameVector;
132 }
133
134 int ret = fontMgr->GetFontFullName(fd, fullNameVec);
135 if (ret != SUCCESS) {
136 FONT_LOGE("GetFontFullName failed, err:%{public}d", ret);
137 return fullNameVector;
138 }
139
140 for (const auto &name : fullNameVec) {
141 if (name.strData && name.strLen > 0) {
142 std::string fullnameStr = Utf16BEToUtf8(name.strData.get(), name.strLen);
143 FONT_LOGI("GetFontFullname, fullnameStr:%{public}s", fullnameStr.c_str());
144 fullNameVector.emplace_back(std::move(fullnameStr));
145 }
146 }
147 return fullNameVector;
148 }
149
Utf16BEToUtf8(const uint8_t * data,size_t byteLen)150 std::string FontManager::Utf16BEToUtf8(const uint8_t* data, size_t byteLen)
151 {
152 std::u16string utf16Str;
153 for(size_t i = 0; i + 1 < byteLen; i += NUM_TWO) {
154 uint16_t ch = (data[i] << 8) | data[i + 1];
155 utf16Str.push_back(static_cast<char16_t>(ch));
156 }
157 // Convert to UTF-8
158 return Str16ToStr8(utf16Str);
159 }
160
CopyFile(const std::string & sourcePath,const int32_t & fd)161 std::string FontManager::CopyFile(const std::string &sourcePath, const int32_t &fd)
162 {
163 std::string fileName = FileUtils::GetFileName(sourcePath);
164 std::string tempPath = FONTS_TEMP_PATH + fileName;
165
166 if (!FileUtils::CopyFile(fd, tempPath)) {
167 FONT_LOGE("copy file %{public}s error", tempPath.c_str());
168 return "";
169 }
170
171 std::string destPath = INSTALL_PATH + fileName;
172 if (FileUtils::CheckPathExist(destPath)) {
173 std::string split = "_";
174 destPath = INSTALL_PATH + FileUtils::GetFileTime() + split + fileName;
175 FONT_LOGI("target file name is exist, store the file with a new name (%{public}s)", destPath.c_str());
176 }
177 if (!FileUtils::RenameFile(tempPath, destPath)) {
178 FONT_LOGE("rename file %{public}s error", sourcePath.c_str());
179 FileUtils::RemoveFile(tempPath);
180 return "";
181 }
182 return destPath;
183 }
184
UninstallFont(const std::string & fontFullName)185 int32_t FontManager::UninstallFont(const std::string &fontFullName)
186 {
187 FONT_LOGI("FontManager UninstallFont: %{public}s", fontFullName.c_str());
188 if (fontFullName.empty()) {
189 FONT_LOGE("FontManager::UninstallFont, fontName is empty");
190 return ERR_UNINSTALL_FILE_NOT_EXISTS;
191 }
192 FontConfig fontConfig(FONT_CONFIG_FILE);
193 std::string path = fontConfig.GetFontFileByName(fontFullName);
194 if (path.empty()) {
195 FONT_LOGE("Can't find fontFullName = %{public}s", fontFullName.c_str());
196 return ERR_UNINSTALL_FILE_NOT_EXISTS;
197 }
198 HisyseventAdapter::GetInstance()->CollectUserDataSize();
199 if (!FileUtils::RemoveFile(path)) {
200 return ERR_UNINSTALL_REMOVE_FAIL;
201 }
202 if (!fontConfig.DeleteFontRecord(path)) {
203 FONT_LOGE("update install_fontconfig fail");
204 return ERR_UNINSTALL_FAIL;
205 }
206 FontEventPublish::PublishFontUpdate(FontEventType::UNINSTALL, fontFullName);
207 return SUCCESS;
208 }
209 } // namespace FontManager
210 } // namespace Global
211 } // namespace OHOS
212