• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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