• 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 "resource_manager_impl.h"
17 #include "hitrace_meter.h"
18 #include "resource_manager.h"
19 #include "resource_manager_log.h"
20 #include "securec.h"
21 #include "utils.h"
22 #include "cj_common_ffi.h"
23 
24 using namespace OHOS::Global::Resource;
25 using namespace OHOS::Ace;
26 using namespace OHOS::FFI;
27 
28 namespace OHOS::Resource {
29 std::map<std::string, std::shared_ptr<Global::Resource::ResourceManager>> g_resourceMgr;
30 std::mutex g_resMapLock;
31 
ResourceManagerImpl(OHOS::AbilityRuntime::Context * context)32 ResourceManagerImpl::ResourceManagerImpl(OHOS::AbilityRuntime::Context* context)
33 {
34     LOGI("ResourceManagerImpl::ResourceManagerImpl start");
35     if (context == nullptr) {
36         LOGE("Failed to get native context instance");
37         return;
38     }
39     resMgr_ = context->GetResourceManager();
40     bundleName_ = context->GetBundleName();
41     context_ = std::shared_ptr<OHOS::AbilityRuntime::Context>(context);
42     isSystem_ = false;
43     LOGI("ResourceManagerImpl::ResourceManagerImpl success");
44 }
45 
ResourceManagerImpl()46 ResourceManagerImpl::ResourceManagerImpl()
47 {
48     std::shared_ptr<Global::Resource::ResourceManager> resMgr(Global::Resource::GetSystemResourceManager());
49     resMgr_ = resMgr;
50     context_ = nullptr;
51     bundleName_ = "";
52     isSystem_ = true;
53 }
54 
ResourceManagerImpl(std::string bundleName,std::shared_ptr<Global::Resource::ResourceManager> resMgr,std::shared_ptr<AbilityRuntime::Context> context)55 ResourceManagerImpl::ResourceManagerImpl(std::string bundleName,
56     std::shared_ptr<Global::Resource::ResourceManager> resMgr, std::shared_ptr<AbilityRuntime::Context> context)
57     : resMgr_(resMgr), bundleName_(bundleName), context_(context)
58 {
59     isOverride_ = true;
60 }
61 
IsEmpty()62 bool ResourceManagerImpl::IsEmpty()
63 {
64     return resMgr_ == nullptr;
65 }
66 
CloseRawFd(const std::string & name)67 int32_t ResourceManagerImpl::CloseRawFd(const std::string &name)
68 {
69     if (IsEmpty()) {
70         LOGE("Empty resource manager.");
71         return ERR_INVALID_INSTANCE_CODE;
72     }
73     return resMgr_->CloseRawFileDescriptor(name);
74 }
75 
GetRawFd(const std::string & rawFileName,Global::Resource::ResourceManager::RawFileDescriptor & descriptor)76 int32_t ResourceManagerImpl::GetRawFd(
77     const std::string &rawFileName, Global::Resource::ResourceManager::RawFileDescriptor &descriptor)
78 {
79     if (IsEmpty()) {
80         LOGE("Empty resource manager.");
81         return ERR_INVALID_INSTANCE_CODE;
82     }
83     return resMgr_->GetRawFileDescriptorFromHap(rawFileName, descriptor);
84 }
85 
GetRawFileContent(const std::string & name,size_t & len,std::unique_ptr<uint8_t[]> & outValue)86 int32_t ResourceManagerImpl::GetRawFileContent(
87     const std::string &name, size_t &len, std::unique_ptr<uint8_t[]> &outValue)
88 {
89     if (IsEmpty()) {
90         LOGE("Empty resource manager.");
91         return ERR_INVALID_INSTANCE_CODE;
92     }
93     return resMgr_->GetRawFileFromHap(name, len, outValue);
94 }
95 
GetRawFileList(const std::string & rawDirPath,std::vector<std::string> & rawfileList)96 int32_t ResourceManagerImpl::GetRawFileList(const std::string &rawDirPath, std::vector<std::string> &rawfileList)
97 {
98     if (IsEmpty()) {
99         LOGE("Empty resource manager.");
100         return ERR_INVALID_INSTANCE_CODE;
101     }
102     return resMgr_->GetRawFileList(rawDirPath, rawfileList);
103 }
104 
GetColorByName(const char * name,uint32_t & outValue)105 int32_t ResourceManagerImpl::GetColorByName(const char *name, uint32_t &outValue)
106 {
107     if (IsEmpty()) {
108         LOGE("Empty resource manager.");
109         return ERR_INVALID_INSTANCE_CODE;
110     }
111     return resMgr_->GetColorByName(name, outValue);
112 }
113 
GetColorById(uint32_t id,uint32_t & outValue)114 int32_t ResourceManagerImpl::GetColorById(uint32_t id, uint32_t &outValue)
115 {
116     if (IsEmpty()) {
117         LOGE("Empty resource manager.");
118         return ERR_INVALID_INSTANCE_CODE;
119     }
120     return resMgr_->GetColorById(id, outValue);
121 }
122 
GetPluralStringValue(uint32_t resId,int64_t num,std::string & outValue)123 int32_t ResourceManagerImpl::GetPluralStringValue(uint32_t resId, int64_t num, std::string &outValue)
124 {
125     if (IsEmpty()) {
126         LOGE("Empty resource manager.");
127         return ERR_INVALID_INSTANCE_CODE;
128     }
129     return resMgr_->GetPluralStringByIdFormat(outValue, resId, num, num);
130 }
131 
GetStringArrayValue(uint32_t resId,std::vector<std::string> & outValue)132 int32_t ResourceManagerImpl::GetStringArrayValue(uint32_t resId, std::vector<std::string> &outValue)
133 {
134     if (IsEmpty()) {
135         LOGE("Empty resource manager.");
136         return ERR_INVALID_INSTANCE_CODE;
137     }
138     return resMgr_->GetStringArrayById(resId, outValue);
139 }
140 
GetStringArrayByName(const char * name,std::vector<std::string> & outValue)141 int32_t ResourceManagerImpl::GetStringArrayByName(const char *name, std::vector<std::string> &outValue)
142 {
143     if (IsEmpty()) {
144         LOGE("Empty resource manager.");
145         return ERR_INVALID_INSTANCE_CODE;
146     }
147     return resMgr_->GetStringArrayByName(name, outValue);
148 }
149 
GetString(uint32_t resId,std::string & outValue)150 int32_t ResourceManagerImpl::GetString(uint32_t resId, std::string &outValue)
151 {
152     if (IsEmpty()) {
153         LOGE("Empty resource manager.");
154         return ERR_INVALID_INSTANCE_CODE;
155     }
156     return resMgr_->GetStringById(resId, outValue);
157 }
158 
GetStringByName(const char * name,std::string & outValue)159 int32_t ResourceManagerImpl::GetStringByName(const char *name, std::string &outValue)
160 {
161     if (IsEmpty()) {
162         LOGE("Empty resource manager.");
163         return ERR_INVALID_INSTANCE_CODE;
164     }
165     return resMgr_->GetStringByName(name, outValue);
166 }
167 
GetPluralStringValue(const char * name,int64_t num,std::string & outValue)168 int32_t ResourceManagerImpl::GetPluralStringValue(const char *name, int64_t num, std::string &outValue)
169 {
170     if (IsEmpty()) {
171         LOGE("Empty resource manager.");
172         return ERR_INVALID_INSTANCE_CODE;
173     }
174     return resMgr_->GetPluralStringByNameFormat(outValue, name, num, num);
175 }
176 
AddResource(const char * path)177 int32_t ResourceManagerImpl::AddResource(const char *path)
178 {
179     bool state = resMgr_->AddAppOverlay(path);
180     if (!state) {
181         return RState::ERROR_CODE_OVERLAY_RES_PATH_INVALID;
182     }
183     return RState::SUCCESS;
184 }
185 
RemoveResource(const char * path)186 int32_t ResourceManagerImpl::RemoveResource(const char *path)
187 {
188     bool state = resMgr_->RemoveAppOverlay(path);
189     if (!state) {
190         return RState::ERROR_CODE_OVERLAY_RES_PATH_INVALID;
191     }
192     return RState::SUCCESS;
193 }
194 
GetBooleanById(uint32_t id,bool & outValue)195 int32_t ResourceManagerImpl::GetBooleanById(uint32_t id, bool &outValue)
196 {
197     if (IsEmpty()) {
198         LOGE("Empty resource manager.");
199         return ERR_INVALID_INSTANCE_CODE;
200     }
201     return resMgr_->GetBooleanById(id, outValue);
202 }
203 
GetBooleanByName(const char * name,bool & outValue)204 int32_t ResourceManagerImpl::GetBooleanByName(const char *name, bool &outValue)
205 {
206     if (IsEmpty()) {
207         LOGE("Empty resource manager.");
208         return ERR_INVALID_INSTANCE_CODE;
209     }
210     return resMgr_->GetBooleanByName(name, outValue);
211 }
212 
GetIntegerById(uint32_t id,int & outValue)213 int32_t ResourceManagerImpl::GetIntegerById(uint32_t id, int &outValue)
214 {
215     if (IsEmpty()) {
216         LOGE("Empty resource manager.");
217         return ERR_INVALID_INSTANCE_CODE;
218     }
219     return resMgr_->GetIntegerById(id, outValue);
220 }
221 
GetIntegerByName(const char * name,int & outValue)222 int32_t ResourceManagerImpl::GetIntegerByName(const char *name, int &outValue)
223 {
224     if (IsEmpty()) {
225         LOGE("Empty resource manager.");
226         return ERR_INVALID_INSTANCE_CODE;
227     }
228     return resMgr_->GetIntegerByName(name, outValue);
229 }
230 
GetFloatById(uint32_t id,float & outValue)231 int32_t ResourceManagerImpl::GetFloatById(uint32_t id, float &outValue)
232 {
233     if (IsEmpty()) {
234         LOGE("Empty resource manager.");
235         return ERR_INVALID_INSTANCE_CODE;
236     }
237     return resMgr_->GetFloatById(id, outValue);
238 }
239 
GetFloatByName(const char * name,float & outValue)240 int32_t ResourceManagerImpl::GetFloatByName(const char *name, float &outValue)
241 {
242     if (IsEmpty()) {
243         LOGE("Empty resource manager.");
244         return ERR_INVALID_INSTANCE_CODE;
245     }
246     return resMgr_->GetFloatByName(name, outValue);
247 }
248 
GetLocale(std::unique_ptr<Global::Resource::ResConfig> & cfg)249 std::string GetLocale(std::unique_ptr<Global::Resource::ResConfig> &cfg)
250 {
251     std::string result;
252 #ifdef SUPPORT_GRAPHICS
253     const icu::Locale *localeInfo = cfg->GetLocaleInfo();
254     if (localeInfo == nullptr) {
255         return result;
256     }
257     const char *lang = localeInfo->getLanguage();
258     if (lang == nullptr) {
259         return result;
260     }
261     result = lang;
262 
263     const char *script = localeInfo->getScript();
264     if (script != nullptr) {
265         result += std::string("_") + script;
266     }
267 
268     const char *region = localeInfo->getCountry();
269     if (region != nullptr) {
270         result += std::string("_") + region;
271     }
272 #endif
273     return result;
274 }
275 
GetConfiguration(Configuration & configuration)276 void ResourceManagerImpl::GetConfiguration(Configuration &configuration)
277 {
278     LOGI("ResourceManagerImpl::GetConfiguration start");
279     std::unique_ptr<ResConfig> cfg(CreateResConfig());
280     if (!cfg) {
281         LOGE("Failed to create ResConfig object.");
282         return;
283     }
284     resMgr_->GetResConfig(*cfg);
285     configuration.direction = static_cast<int32_t>(cfg->GetDirection());
286     LOGI("ResourceManagerImpl::GetConfiguration ok %{public}" PRId32, configuration.direction);
287     std::string locale = GetLocale(cfg);
288 
289     auto temp = ::Utils::MallocCString(locale);
290     if (temp == nullptr) {
291         return;
292     }
293     configuration.locale = temp;
294 }
295 
ResConfigToConfigurationEx(std::unique_ptr<ResConfig> & config,ConfigurationEx * configuration)296 void ResConfigToConfigurationEx(std::unique_ptr<ResConfig> &config, ConfigurationEx *configuration)
297 {
298     configuration->direction = static_cast<int32_t>(config->GetDirection());
299     configuration->deviceType = static_cast<int32_t>(config->GetDeviceType());
300     configuration->screenDensity = static_cast<int32_t>(config->GetScreenDensityDpi());
301     configuration->colorMode = static_cast<int32_t>(config->GetColorMode());
302     configuration->mcc = config->GetMcc();
303     configuration->mnc = config->GetMnc();
304 
305     std::string locale = GetLocale(config);
306     auto temp = ::Utils::MallocCString(locale);
307     if (temp == nullptr) {
308         return;
309     }
310     configuration->locale = temp;
311     return;
312 }
313 
GetConfiguration(ConfigurationEx * configuration)314 void ResourceManagerImpl::GetConfiguration(ConfigurationEx *configuration)
315 {
316     std::unique_ptr<ResConfig> cfg(CreateResConfig());
317     if (!cfg) {
318         LOGE("Failed to create ResConfig object.");
319         return;
320     }
321     resMgr_->GetResConfig(*cfg);
322     return ResConfigToConfigurationEx(cfg, configuration);
323 }
324 
GetOverrideConfiguration(ConfigurationEx * configuration)325 void ResourceManagerImpl::GetOverrideConfiguration(ConfigurationEx *configuration)
326 {
327     std::unique_ptr<ResConfig> cfg(CreateResConfig());
328     if (!cfg) {
329         LOGE("Failed to create ResConfig object.");
330         return;
331     }
332     resMgr_->GetOverrideResConfig(*cfg);
333     return ResConfigToConfigurationEx(cfg, configuration);
334 }
335 
GetDeviceCapability(DeviceCapability & deviceCapability)336 void ResourceManagerImpl::GetDeviceCapability(DeviceCapability &deviceCapability)
337 {
338     std::unique_ptr<ResConfig> cfg(CreateResConfig());
339     if (!cfg) {
340         LOGE("Failed to create ResConfig object.");
341         return;
342     }
343     resMgr_->GetResConfig(*cfg);
344     deviceCapability.screenDensity = static_cast<int32_t>(cfg->ConvertDensity(cfg->GetScreenDensity()));
345     deviceCapability.deviceType = static_cast<int32_t>(cfg->GetDeviceType());
346     LOGI("ResourceManagerImpl::GetDeviceCapability ok screenDensity %{public}" PRId32, deviceCapability.screenDensity);
347 }
348 
GetMediaDataByName(const char * name,size_t & len,std::unique_ptr<uint8_t[]> & outValue,uint32_t density)349 int32_t ResourceManagerImpl::GetMediaDataByName(
350     const char *name, size_t &len, std::unique_ptr<uint8_t[]> &outValue, uint32_t density)
351 {
352     if (IsEmpty()) {
353         LOGE("Empty resource manager.");
354         return ERR_INVALID_INSTANCE_CODE;
355     }
356     return resMgr_->GetMediaDataByName(name, len, outValue, density);
357 }
358 
GetMediaDataById(uint32_t id,size_t & len,std::unique_ptr<uint8_t[]> & outValue,uint32_t density)359 int32_t ResourceManagerImpl::GetMediaDataById(
360     uint32_t id, size_t &len, std::unique_ptr<uint8_t[]> &outValue, uint32_t density)
361 {
362     if (IsEmpty()) {
363         LOGE("Empty resource manager.");
364         return ERR_INVALID_INSTANCE_CODE;
365     }
366     return resMgr_->GetMediaDataById(id, len, outValue, density);
367 }
368 
GetMediaContentBase64ById(uint32_t id,std::string & outValue,uint32_t density)369 int32_t ResourceManagerImpl::GetMediaContentBase64ById(uint32_t id, std::string &outValue, uint32_t density)
370 {
371     if (IsEmpty()) {
372         LOGE("Empty resource manager.");
373         return ERR_INVALID_INSTANCE_CODE;
374     }
375     return resMgr_->GetMediaBase64DataById(id, outValue, density);
376 }
377 
GetMediaContentBase64ByName(const char * name,std::string & outValue,uint32_t density)378 int32_t ResourceManagerImpl::GetMediaContentBase64ByName(const char *name, std::string &outValue, uint32_t density)
379 {
380     if (IsEmpty()) {
381         LOGE("Empty resource manager.");
382         return ERR_INVALID_INSTANCE_CODE;
383     }
384     return resMgr_->GetMediaBase64DataByName(name, outValue, density);
385 }
386 
GetDrawableDescriptor(uint32_t id,int64_t & outValue,uint32_t density)387 int32_t ResourceManagerImpl::GetDrawableDescriptor(uint32_t id, int64_t &outValue, uint32_t density)
388 {
389     RState state = SUCCESS;
390     OHOS::Ace::Napi::DrawableDescriptor::DrawableType drawableType;
391     auto drawableDescriptor =
392         OHOS::Ace::Napi::DrawableDescriptorFactory::Create(id, resMgr_, state, drawableType, density);
393     if (state != SUCCESS) {
394         LOGE("Failed to Create drawableDescriptor by %{public}" PRIu32, id);
395         return state;
396     }
397     auto ptr = FFIData::Create<DrawableDescriptorImpl>(drawableDescriptor.release());
398     if (!ptr) {
399         return ERR_INVALID_INSTANCE_CODE;
400     }
401     outValue = ptr->GetID();
402     return state;
403 }
404 
GetDrawableDescriptorByName(const char * name,int64_t & outValue,uint32_t density)405 int32_t ResourceManagerImpl::GetDrawableDescriptorByName(const char *name, int64_t &outValue, uint32_t density)
406 {
407     RState state = SUCCESS;
408     OHOS::Ace::Napi::DrawableDescriptor::DrawableType drawableType;
409     auto drawableDescriptor =
410         OHOS::Ace::Napi::DrawableDescriptorFactory::Create(name, resMgr_, state, drawableType, density);
411     if (state != SUCCESS) {
412         return state;
413     }
414     auto ptr = FFIData::Create<DrawableDescriptorImpl>(drawableDescriptor.release());
415     if (!ptr) {
416         return ERR_INVALID_INSTANCE_CODE;
417     }
418     outValue = ptr->GetID();
419     return state;
420 }
421 
GetHapResourceManager(Global::Resource::ResourceManager::Resource resource,std::shared_ptr<Global::Resource::ResourceManager> & resMgr,uint32_t & resId)422 bool ResourceManagerImpl::GetHapResourceManager(Global::Resource::ResourceManager::Resource resource,
423     std::shared_ptr<Global::Resource::ResourceManager> &resMgr, uint32_t &resId)
424 {
425     resId = resource.id;
426     if (isSystem_) {
427         resMgr = resMgr_;
428         return true;
429     }
430 
431     std::string key(resource.bundleName + "/" + resource.moduleName);
432     std::lock_guard<std::mutex> lock(g_resMapLock);
433     auto iter = g_resourceMgr.find(key);
434     if (iter != g_resourceMgr.end()) {
435         resMgr = g_resourceMgr[key];
436         return true;
437     }
438 
439     auto moduleContext = context_->CreateModuleContext(resource.bundleName, resource.moduleName);
440     if (moduleContext == nullptr) {
441         return false;
442     }
443     resMgr = moduleContext->GetResourceManager();
444     g_resourceMgr[key] = resMgr;
445     return true;
446 }
447 
GetDrawableDescriptorPtr(uint32_t id,std::shared_ptr<Global::Resource::ResourceManager> resMgr,uint32_t density,RState & state)448 OHOS::Ace::Napi::DrawableDescriptor* GetDrawableDescriptorPtr(
449     uint32_t id, std::shared_ptr<Global::Resource::ResourceManager> resMgr, uint32_t density, RState &state)
450 {
451     OHOS::Ace::Napi::DrawableDescriptor::DrawableType drawableType;
452     auto drawableDescriptor =
453         OHOS::Ace::Napi::DrawableDescriptorFactory::Create(id, resMgr, state, drawableType, density);
454     if (state != SUCCESS) {
455         LOGE("Failed to Create drawableDescriptor by %{public}" PRIu32, id);
456         return nullptr;
457     }
458 
459     return drawableDescriptor.release();
460 }
461 
GetLocales(bool includeSystem,std::vector<std::string> & outValue)462 void ResourceManagerImpl::GetLocales(bool includeSystem, std::vector<std::string> &outValue)
463 {
464     if (IsEmpty()) {
465         LOGE("Empty resource manager.");
466         return;
467     }
468     return resMgr_->GetLocales(outValue, includeSystem);
469 }
470 
GetSymbolById(uint32_t id,uint32_t & outValue)471 int32_t ResourceManagerImpl::GetSymbolById(uint32_t id, uint32_t &outValue)
472 {
473     if (IsEmpty()) {
474         LOGE("Empty resource manager.");
475         return ERR_INVALID_INSTANCE_CODE;
476     }
477     return resMgr_->GetSymbolById(id, outValue);
478 }
479 
GetSymbolByName(const char * name,uint32_t & outValue)480 int32_t ResourceManagerImpl::GetSymbolByName(const char *name, uint32_t &outValue)
481 {
482     if (IsEmpty()) {
483         LOGE("Empty resource manager.");
484         return ERR_INVALID_INSTANCE_CODE;
485     }
486     return resMgr_->GetSymbolByName(name, outValue);
487 }
488 
GetOverrideResMgr(ConfigurationEx & cfg,int32_t & errCode)489 std::shared_ptr<ResourceManager> ResourceManagerImpl::GetOverrideResMgr(ConfigurationEx &cfg, int32_t &errCode)
490 {
491     std::shared_ptr<ResConfig> config(CreateDefaultResConfig());
492     if (config == nullptr) {
493         LOGE("GetOverrideResMgr, new config failed");
494         errCode = ERROR_CODE_INVALID_INPUT_PARAMETER;
495         return nullptr;
496     }
497     config->SetDirection(static_cast<Direction>(cfg.direction));
498     config->SetDeviceType(static_cast<DeviceType>(cfg.deviceType));
499     config->SetScreenDensityDpi(static_cast<ScreenDensity>(cfg.screenDensity));
500     config->SetColorMode(static_cast<ColorMode>(cfg.colorMode));
501     config->SetMcc(cfg.mcc);
502     config->SetMnc(cfg.mnc);
503 #ifdef SUPPORT_GRAPHICS
504     config->SetLocaleInfo(cfg.locale);
505 #endif
506     std::shared_ptr<ResourceManager> overrideResMgr = resMgr_->GetOverrideResourceManager(config);
507     if (overrideResMgr == nullptr) {
508         errCode = ERROR_CODE_INVALID_INPUT_PARAMETER;
509         return nullptr;
510     }
511     return overrideResMgr;
512 }
513 
GetBundleName()514 std::string ResourceManagerImpl::GetBundleName()
515 {
516     return bundleName_;
517 }
518 
GetContext()519 std::shared_ptr<AbilityRuntime::Context> ResourceManagerImpl::GetContext()
520 {
521     return context_;
522 }
523 }
524