• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "bundle_resource_callback.h"
17 
18 #include <fstream>
19 
20 #include "account_helper.h"
21 #include "bundle_constants.h"
22 #include "bundle_parser.h"
23 #include "bundle_resource_constants.h"
24 #include "bundle_resource_manager.h"
25 #ifdef GLOBAL_RESMGR_ENABLE
26 #include "resource_manager.h"
27 #endif
28 namespace OHOS {
29 namespace AppExecFwk {
30 std::mutex BundleResourceCallback::userFileMutex_;
31 
OnUserIdSwitched(const int32_t oldUserId,const int32_t userId,const uint32_t type)32 bool BundleResourceCallback::OnUserIdSwitched(const int32_t oldUserId, const int32_t userId, const uint32_t type)
33 {
34     APP_LOGI("start, oldUserId:%{public}d to newUserId:%{public}d no need to process", oldUserId, userId);
35     return true;
36 }
37 
OnSystemColorModeChanged(const std::string & colorMode,const uint32_t type)38 bool BundleResourceCallback::OnSystemColorModeChanged(const std::string &colorMode, const uint32_t type)
39 {
40     APP_LOGI("start, colorMode: %{public}s", colorMode.c_str());
41     if (colorMode == BundleSystemState::GetInstance().GetSystemColorMode()) {
42         APP_LOGD("colorMode: %{public}s no change", colorMode.c_str());
43         return true;
44     }
45     APP_LOGI("end, colorMode: %{public}s", colorMode.c_str());
46     return true;
47 }
48 
OnSystemLanguageChange(const std::string & language,const uint32_t type)49 bool BundleResourceCallback::OnSystemLanguageChange(const std::string &language, const uint32_t type)
50 {
51     APP_LOGI("start, language %{public}s", language.c_str());
52     if (language == BundleSystemState::GetInstance().GetSystemLanguage()) {
53         APP_LOGD("current language is %{public}s no change", language.c_str());
54         return true;
55     }
56     int32_t currentUserId = AccountHelper::GetCurrentActiveUserId();
57     if (currentUserId <= 0) {
58         currentUserId = Constants::START_USERID;
59     }
60     SetConfigInFile(language, "", -1, -1, type, currentUserId);
61     BundleSystemState::GetInstance().SetSystemLanguage(language);
62     // need delete all and reload all
63     auto manager = DelayedSingleton<BundleResourceManager>::GetInstance();
64     if (manager == nullptr) {
65         APP_LOGE("manager is nullptr");
66         return false;
67     }
68 
69     if (!manager->AddAllResourceInfo(currentUserId, type)) {
70         APP_LOGE("AddAllResourceInfo currentUserId %{public}d failed", currentUserId);
71         return false;
72     }
73     DeleteConfigInFile(currentUserId, type);
74     APP_LOGI("end, language %{public}s", language.c_str());
75     return true;
76 }
77 
OnApplicationThemeChanged(const std::string & theme,const int32_t themeId,const int32_t themeIcon,const uint32_t type)78 bool BundleResourceCallback::OnApplicationThemeChanged(const std::string &theme,
79     const int32_t themeId, const int32_t themeIcon, const uint32_t type)
80 {
81     APP_LOGI("start, theme:%{public}s, themeId:%{public}d", theme.c_str(), themeId);
82     if (theme.empty()) {
83         APP_LOGW("theme is empty, no need to change");
84         return false;
85     }
86 
87     nlohmann::json jsonObject = nlohmann::json::parse(theme, nullptr, false);
88     if (jsonObject.is_discarded()) {
89         APP_LOGE("failed parse theme %{public}s", theme.c_str());
90         return false;
91     }
92     const auto &jsonObjectEnd = jsonObject.end();
93     int32_t parseResult = ERR_OK;
94     int32_t updateIcons = 0;
95     GetValueIfFindKey<int32_t>(jsonObject, jsonObjectEnd, "icons", updateIcons,
96         JsonType::NUMBER, false, parseResult, ArrayType::NOT_ARRAY);
97     if (updateIcons == 0) {
98         APP_LOGI("icons no need to change, return");
99         return false;
100     }
101     int32_t currentUserId = AccountHelper::GetCurrentActiveUserId();
102     if (currentUserId <= 0) {
103         currentUserId = Constants::START_USERID;
104     }
105     SetConfigInFile("", theme, themeId, themeIcon, type, currentUserId);
106 #ifdef GLOBAL_RESMGR_ENABLE
107     if (!SetThemeParamForThemeChanged(themeId, themeIcon)) {
108         APP_LOGE("set theme param failed, themeId %{public}d themeIcon %{public}d", themeId, themeIcon);
109     }
110 #endif
111 
112     auto manager = DelayedSingleton<BundleResourceManager>::GetInstance();
113     if (manager == nullptr) {
114         APP_LOGE("manager is nullptr");
115         return false;
116     }
117 
118     if (!manager->AddAllResourceInfo(currentUserId, type)) {
119         APP_LOGE("AddAllResourceInfo currentUserId %{public}d failed", currentUserId);
120         return false;
121     }
122     DeleteConfigInFile(currentUserId, type);
123     APP_LOGI("end, theme:%{public}s", theme.c_str());
124     return true;
125 }
126 
OnOverlayStatusChanged(const std::string & bundleName,bool isEnabled,int32_t userId)127 bool BundleResourceCallback::OnOverlayStatusChanged(
128     const std::string &bundleName,
129     bool isEnabled,
130     int32_t userId)
131 {
132     APP_LOGI("start, bundleName:%{public}s, isEnabled:%{public}d, userId:%{public}d",
133         bundleName.c_str(), isEnabled, userId);
134     int32_t currentUserId = AccountHelper::GetCurrentActiveUserId();
135     if ((currentUserId > 0) && (userId != currentUserId)) {
136         APP_LOGW("userId:%{public}d current:%{public}d not same", currentUserId, userId);
137         return false;
138     }
139     auto manager = DelayedSingleton<BundleResourceManager>::GetInstance();
140     if (manager == nullptr) {
141         APP_LOGE("manager is nullptr");
142         return false;
143     }
144     std::string targetBundleName = bundleName;
145     manager->GetTargetBundleName(bundleName, targetBundleName);
146     APP_LOGI("bundleName:%{public}s, targetBundleName:%{public}s overlay changed", bundleName.c_str(),
147         targetBundleName.c_str());
148     if (!manager->AddResourceInfoByBundleNameWhenUpdate(targetBundleName, userId)) {
149         APP_LOGE("add resource failed %{public}s", targetBundleName.c_str());
150         return false;
151     }
152     APP_LOGI("end, targetBundleName:%{public}s, isEnabled:%{public}d, userId:%{public}d",
153         targetBundleName.c_str(), isEnabled, userId);
154     return true;
155 }
156 
SetThemeParamForThemeChanged(const int32_t themeId,const int32_t themeIcon)157 bool BundleResourceCallback::SetThemeParamForThemeChanged(const int32_t themeId, const int32_t themeIcon)
158 {
159     if (themeId <= 0) {
160         return false;
161     }
162 #ifdef GLOBAL_RESMGR_ENABLE
163     auto resourcePtr = std::shared_ptr<Global::Resource::ResourceManager>(Global::Resource::CreateResourceManager());
164     if (resourcePtr == nullptr) {
165         APP_LOGE("resource is nullptr, themeId %{public}d themeIcon %{public}d", themeId, themeIcon);
166         return false;
167     }
168     int32_t currentUserId = AccountHelper::GetCurrentActiveUserId();
169     if (currentUserId <= 0) {
170         APP_LOGW("currentUserId get failed");
171         currentUserId = Constants::START_USERID;
172     }
173     resourcePtr->userId = currentUserId;
174     APP_LOGI("start set themeId %{public}d userId %{public}d themeIcon %{public}d",
175         themeId, currentUserId, themeIcon);
176     std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
177     if (resConfig == nullptr) {
178         APP_LOGE("resConfig is nullptr, themeId %{public}d themeIcon %{public}d", themeId, themeIcon);
179         return false;
180     }
181     resConfig->SetThemeId(themeId);
182     resConfig->SetThemeIcon(themeIcon > 0 ? true : false);
183     Global::Resource::RState ret = resourcePtr->UpdateResConfig(*resConfig); // no need to process ret
184     if (ret != Global::Resource::RState::SUCCESS) {
185         APP_LOGW("UpdateResConfig ret %{public}d, themeId %{public}d, themeIcon %{public}d",
186             static_cast<int32_t>(ret), themeId, themeIcon);
187     }
188     APP_LOGI("end set themeId %{public}d themeIcon %{public}d", themeId, themeIcon);
189 #endif
190     return true;
191 }
192 
SetUserId(const int32_t userId)193 void BundleResourceCallback::SetUserId(const int32_t userId)
194 {
195     std::string path = std::string(BundleResourceConstants::BUNDLE_RESOURCE_RDB_PATH) +
196         std::string(BundleResourceConstants::USER_FILE_NAME);
197     nlohmann::json jsonBuf;
198     if (!BundleParser::ReadFileIntoJson(path, jsonBuf)) {
199         APP_LOGW("read user file failed, errno %{public}d", errno);
200     }
201     std::ofstream out(path, std::ios::out);
202     if (!out.is_open()) {
203         APP_LOGE("open user file failed, errno:%{public}d", errno);
204         return;
205     }
206     jsonBuf[BundleResourceConstants::USER] = userId;
207     out << jsonBuf.dump();
208     out.close();
209 }
210 
DeleteConfigInFile(const int32_t userId,const uint32_t type)211 void BundleResourceCallback::DeleteConfigInFile(const int32_t userId, const uint32_t type)
212 {
213     std::string path = std::string(BundleResourceConstants::BUNDLE_RESOURCE_RDB_PATH) +
214         std::string(BundleResourceConstants::USER_FILE_NAME);
215     nlohmann::json jsonBuf;
216     std::lock_guard<std::mutex> lock(userFileMutex_);
217     if (!BundleParser::ReadFileIntoJson(path, jsonBuf)) {
218         APP_LOGW("read user file failed, errno %{public}d", errno);
219         return;
220     }
221     std::string key;
222     if (type == static_cast<uint32_t>(BundleResourceChangeType::SYSTEM_LANGUE_CHANGE)) {
223         key = std::string(BundleResourceConstants::LANGUAGE) +
224             std::string(BundleResourceConstants::UNDER_LINE) + std::to_string(userId);
225     } else if (type == static_cast<uint32_t>(BundleResourceChangeType::SYSTEM_THEME_CHANGE)) {
226         key = std::string(BundleResourceConstants::THEME) +
227             std::string(BundleResourceConstants::UNDER_LINE) + std::to_string(userId);
228     } else {
229         return;
230     }
231     auto it = jsonBuf.find(key);
232     if (it == jsonBuf.end()) {
233         return;
234     }
235     jsonBuf.erase(it);
236     std::ofstream out(path, std::ios::out);
237     if (!out.is_open()) {
238         APP_LOGE("open user file failed, errno:%{public}d", errno);
239         return;
240     }
241     out << jsonBuf.dump();
242     out.close();
243     APP_LOGI("-u %{public}d -t %{public}d delete config success.", userId, type);
244 }
245 
SetConfigInFile(const std::string & language,const std::string & theme,const int32_t id,const int32_t themeIcon,const uint32_t type,const int32_t userId)246 void BundleResourceCallback::SetConfigInFile(const std::string &language, const std::string &theme,
247     const int32_t id, const int32_t themeIcon, const uint32_t type, const int32_t userId)
248 {
249     std::string path = std::string(BundleResourceConstants::BUNDLE_RESOURCE_RDB_PATH) +
250         std::string(BundleResourceConstants::USER_FILE_NAME);
251     nlohmann::json jsonBuf;
252     std::lock_guard<std::mutex> lock(userFileMutex_);
253     if (!BundleParser::ReadFileIntoJson(path, jsonBuf)) {
254         APP_LOGW("read user file failed, errno %{public}d", errno);
255     }
256     if (jsonBuf.is_discarded()) {
257         APP_LOGW("bad profile file %{public}s", path.c_str());
258         return;
259     }
260     FILE *out = fopen(path.c_str(), "w");
261     if (out == nullptr) {
262         APP_LOGE("fopen %{public}s failed", path.c_str());
263         return;
264     }
265     nlohmann::json config;
266     if (type == static_cast<uint32_t>(BundleResourceChangeType::SYSTEM_LANGUE_CHANGE)) {
267         config[BundleResourceConstants::LANGUAGE] = language;
268         config[BundleResourceConstants::USER] = userId;
269         config[BundleResourceConstants::TYPE] = type;
270         std::string key = std::string(BundleResourceConstants::LANGUAGE) +
271             std::string(BundleResourceConstants::UNDER_LINE) + std::to_string(userId);
272         jsonBuf[key] = config;
273     } else if (type == static_cast<uint32_t>(BundleResourceChangeType::SYSTEM_THEME_CHANGE)) {
274         config[BundleResourceConstants::THEME] = theme;
275         config[BundleResourceConstants::THEME_ID] = id;
276         config[BundleResourceConstants::THEME_ICON] = themeIcon;
277         config[BundleResourceConstants::USER] = userId;
278         config[BundleResourceConstants::TYPE] = type;
279         std::string key = std::string(BundleResourceConstants::THEME) +
280             std::string(BundleResourceConstants::UNDER_LINE) + std::to_string(userId);
281         jsonBuf[key] = config;
282     } else {
283         (void)fclose(out);
284         return;
285     }
286 
287     if (fputs(jsonBuf.dump().c_str(), out) == EOF) {
288         APP_LOGE("fputs %{public}s failed", path.c_str());
289         (void)fclose(out);
290         return;
291     }
292     (void)fsync(fileno(out));
293     (void)fclose(out);
294     APP_LOGI("-u %{public}d -t %{public}d save config success.", userId, type);
295 }
296 } // AppExecFwk
297 } // OHOS
298