• 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 <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