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