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     context_ = std::shared_ptr<OHOS::AbilityRuntime::Context>(context);
41     bundleName_ = context->GetBundleName();
42     isSystem_ = false;
43     LOGI("ResourceManagerImpl::ResourceManagerImpl success");
44 }
45 
CloseRawFd(const std::string & name)46 int32_t ResourceManagerImpl::CloseRawFd(const std::string &name)
47 {
48     RState state = resMgr_->CloseRawFileDescriptor(name);
49     if (state != RState::SUCCESS) {
50         LOGE("ResourceManagerImpl::CloseRawFd failed %{public}" PRIu32, state);
51     } else {
52         LOGI("ResourceManagerImpl::CloseRawFd success");
53     }
54     return state;
55 }
56 
GetRawFd(const std::string & rawFileName,Global::Resource::ResourceManager::RawFileDescriptor & descriptor)57 int32_t ResourceManagerImpl::GetRawFd(const std::string &rawFileName,
58     Global::Resource::ResourceManager::RawFileDescriptor &descriptor)
59 {
60     RState state = resMgr_->GetRawFileDescriptorFromHap(rawFileName, descriptor);
61     if (state != RState::SUCCESS) {
62         LOGE("ResourceManagerImpl::GetRawFd failed %{public}" PRIu32, state);
63     } else {
64         LOGI("ResourceManagerImpl::GetRawFd success");
65     }
66     return state;
67 }
68 
GetRawFileContent(const std::string & name,size_t & len,std::unique_ptr<uint8_t[]> & outValue)69 int32_t ResourceManagerImpl::GetRawFileContent(const std::string &name, size_t &len,
70     std::unique_ptr<uint8_t[]> &outValue)
71 {
72     RState state = resMgr_->GetRawFileFromHap(name, len, outValue);
73     if (state != RState::SUCCESS) {
74         LOGE("ResourceManagerImpl::GetRawFileContent failed %{public}" PRIu32, state);
75     } else {
76         LOGI("ResourceManagerImpl::GetRawFileContent success");
77     }
78     return state;
79 }
80 
GetRawFileList(const std::string & rawDirPath,std::vector<std::string> & rawfileList)81 int32_t ResourceManagerImpl::GetRawFileList(const std::string &rawDirPath, std::vector<std::string>& rawfileList)
82 {
83     RState state = resMgr_->GetRawFileList(rawDirPath, rawfileList);
84     if (state != RState::SUCCESS) {
85         LOGE("ResourceManagerImpl::GetRawFileList failed %{public}" PRIu32, state);
86     } else {
87         LOGI("ResourceManagerImpl::GetRawFileList success, list size %{public}" PRIu64,
88             static_cast<uint64_t>(rawfileList.size()));
89     }
90     return state;
91 }
92 
GetColorByName(const char * name,uint32_t & outValue)93 int32_t ResourceManagerImpl::GetColorByName(const char *name, uint32_t &outValue)
94 {
95     RState state = resMgr_->GetColorByName(name, outValue);
96     if (state != RState::SUCCESS) {
97         LOGE("ResourceManagerImpl::GetColorByName failed %{public}" PRIu32, state);
98     } else {
99         LOGI("ResourceManagerImpl::GetColorByName success");
100     }
101     return state;
102 }
103 
GetColorById(uint32_t id,uint32_t & outValue)104 int32_t ResourceManagerImpl::GetColorById(uint32_t id, uint32_t &outValue)
105 {
106     RState state = resMgr_->GetColorById(id, outValue);
107     if (state != RState::SUCCESS) {
108         LOGE("ResourceManagerImpl::GetColorById failed %{public}" PRIu32, state);
109     } else {
110         LOGI("ResourceManagerImpl::GetColorById success");
111     }
112     return state;
113 }
114 
GetPluralStringValue(uint32_t resId,int64_t num,std::string & outValue)115 int32_t ResourceManagerImpl::GetPluralStringValue(uint32_t resId, int64_t num, std::string &outValue)
116 {
117     RState state = resMgr_->GetPluralStringByIdFormat(outValue, resId, num, num);
118     if (state != RState::SUCCESS) {
119         LOGE("ResourceManagerImpl::GetPluralStringByIdFormat failed %{public}" PRIu32, state);
120     } else {
121         LOGI("ResourceManagerImpl::GetPluralStringByIdFormat success");
122     }
123     return state;
124 }
125 
GetStringArrayValue(uint32_t resId,std::vector<std::string> & outValue)126 int32_t ResourceManagerImpl::GetStringArrayValue(uint32_t resId, std::vector<std::string> &outValue)
127 {
128     RState state = resMgr_->GetStringArrayById(resId, outValue);
129     if (state != RState::SUCCESS) {
130         LOGE("ResourceManagerImpl::GetStringArrayById failed %{public}" PRIu32, state);
131     } else {
132         LOGI("ResourceManagerImpl::GetStringArrayById success");
133     }
134     return state;
135 }
136 
GetStringArrayByName(const char * name,std::vector<std::string> & outValue)137 int32_t ResourceManagerImpl::GetStringArrayByName(const char *name, std::vector<std::string> &outValue)
138 {
139     RState state = resMgr_->GetStringArrayByName(name, outValue);
140     if (state != RState::SUCCESS) {
141         LOGE("ResourceManagerImpl::GetStringArrayById failed %{public}" PRIu32, state);
142     } else {
143         LOGI("ResourceManagerImpl::GetStringArrayById success");
144     }
145     return state;
146 }
147 
GetString(uint32_t resId,std::string & outValue)148 int32_t ResourceManagerImpl::GetString(uint32_t resId, std::string &outValue)
149 {
150     RState state = resMgr_->GetStringById(resId, outValue);
151     if (state != RState::SUCCESS) {
152         LOGE("ResourceManagerImpl::GetStringById failed %{public}" PRIu32, state);
153     } else {
154         LOGI("ResourceManagerImpl::GetStringById success");
155     }
156     return state;
157 }
158 
GetStringByName(const char * name,std::string & outValue)159 int32_t ResourceManagerImpl::GetStringByName(const char *name, std::string &outValue)
160 {
161     RState state = resMgr_->GetStringByName(name, outValue);
162     if (state != RState::SUCCESS) {
163         LOGE("ResourceManagerImpl::GetStringById failed %{public}" PRIu32, state);
164     } else {
165         LOGI("ResourceManagerImpl::GetStringById success");
166     }
167     return state;
168 }
169 
GetPluralStringValue(const char * name,int64_t num,std::string & outValue)170 int32_t ResourceManagerImpl::GetPluralStringValue(const char *name, int64_t num, std::string &outValue)
171 {
172     RState state = resMgr_->GetPluralStringByNameFormat(outValue, name, num, num);
173     if (state != RState::SUCCESS) {
174         LOGE("ResourceManagerImpl::GetPluralStringByName failed %{public}" PRIu32, state);
175     } else {
176         LOGI("ResourceManagerImpl::GetPluralStringByName success");
177     }
178     return state;
179 }
180 
AddResource(const char * path)181 int32_t ResourceManagerImpl::AddResource(const char *path)
182 {
183     bool state = resMgr_->AddAppOverlay(path);
184     if (!state) {
185         return RState::ERROR_CODE_OVERLAY_RES_PATH_INVALID;
186     }
187     return RState::SUCCESS;
188 }
189 
RemoveResource(const char * path)190 int32_t ResourceManagerImpl::RemoveResource(const char *path)
191 {
192     bool state = resMgr_->RemoveAppOverlay(path);
193     if (!state) {
194         return RState::ERROR_CODE_OVERLAY_RES_PATH_INVALID;
195     }
196     return RState::SUCCESS;
197 }
198 
GetBooleanById(uint32_t id,bool & outValue)199 int32_t ResourceManagerImpl::GetBooleanById(uint32_t id, bool &outValue)
200 {
201     RState state = resMgr_->GetBooleanById(id, outValue);
202     if (state != RState::SUCCESS) {
203         LOGE("ResourceManagerImpl::GetBooleanById failed %{public}" PRIu32, state);
204     } else {
205         LOGI("ResourceManagerImpl::GetBooleanById success");
206     }
207     return state;
208 }
209 
GetBooleanByName(const char * name,bool & outValue)210 int32_t ResourceManagerImpl::GetBooleanByName(const char *name, bool &outValue)
211 {
212     RState state = resMgr_->GetBooleanByName(name, outValue);
213     if (state != RState::SUCCESS) {
214         LOGE("ResourceManagerImpl::GetBooleanByName failed %{public}" PRIu32, state);
215     } else {
216         LOGI("ResourceManagerImpl::GetBooleanByName success");
217     }
218     return state;
219 }
220 
GetIntegerById(uint32_t id,int & outValue)221 int32_t ResourceManagerImpl::GetIntegerById(uint32_t id, int &outValue)
222 {
223     RState state = resMgr_->GetIntegerById(id, outValue);
224     if (state != RState::SUCCESS) {
225         LOGE("ResourceManagerImpl::GetIntegerById failed %{public}" PRIu32, state);
226     } else {
227         LOGI("ResourceManagerImpl::GetIntegerById success");
228     }
229     return state;
230 }
231 
GetIntegerByName(const char * name,int & outValue)232 int32_t ResourceManagerImpl::GetIntegerByName(const char *name, int &outValue)
233 {
234     RState state = resMgr_->GetIntegerByName(name, outValue);
235     if (state != RState::SUCCESS) {
236         LOGE("ResourceManagerImpl::GetIntegerByName failed %{public}" PRIu32, state);
237     } else {
238         LOGI("ResourceManagerImpl::GetIntegerByName success");
239     }
240     return state;
241 }
242 
GetFloatById(uint32_t id,float & outValue)243 int32_t ResourceManagerImpl::GetFloatById(uint32_t id, float &outValue)
244 {
245     RState state = resMgr_->GetFloatById(id, outValue);
246     if (state != RState::SUCCESS) {
247         LOGE("ResourceManagerImpl::GetFloatById failed %{public}" PRIu32, state);
248     } else {
249         LOGI("ResourceManagerImpl::GetFloatById success");
250     }
251     return state;
252 }
253 
GetFloatByName(const char * name,float & outValue)254 int32_t ResourceManagerImpl::GetFloatByName(const char *name, float &outValue)
255 {
256     RState state = resMgr_->GetFloatByName(name, outValue);
257     if (state != RState::SUCCESS) {
258         LOGE("ResourceManagerImpl::GetFloatByName failed %{public}" PRIu32, state);
259     } else {
260         LOGI("ResourceManagerImpl::GetFloatByName success");
261     }
262     return state;
263 }
264 
GetConfiguration(Configuration & configuration)265 void ResourceManagerImpl::GetConfiguration(Configuration &configuration)
266 {
267     LOGI("ResourceManagerImpl::GetConfiguration start");
268     std::unique_ptr<ResConfig> cfg(CreateResConfig());
269     resMgr_->GetResConfig(*cfg);
270     configuration.direction = static_cast<int32_t>(cfg->GetDirection());
271     LOGI("ResourceManagerImpl::GetConfiguration ok %{public}" PRId32, configuration.direction);
272     std::string locale = GetLocale(cfg);
273 
274     auto temp = ::Utils::MallocCString(locale);
275     if (temp == nullptr) {
276         return;
277     }
278     configuration.locale = temp;
279 }
280 
GetDeviceCapability(DeviceCapability & deviceCapability)281 void ResourceManagerImpl::GetDeviceCapability(DeviceCapability &deviceCapability)
282 {
283     std::unique_ptr<ResConfig> cfg(CreateResConfig());
284     resMgr_->GetResConfig(*cfg);
285     deviceCapability.screenDensity = static_cast<int32_t>(cfg->ConvertDensity(cfg->GetScreenDensity()));
286     deviceCapability.deviceType = static_cast<int32_t>(cfg->GetDeviceType());
287     LOGI("ResourceManagerImpl::GetDeviceCapability ok screenDensity %{public}" PRId32,
288         deviceCapability.screenDensity);
289     LOGI("ResourceManagerImpl::GetDeviceCapability ok deviceType %{public}" PRId32, deviceCapability.deviceType);
290 }
291 
GetMediaDataByName(const char * name,size_t & len,std::unique_ptr<uint8_t[]> & outValue,uint32_t density)292 int32_t ResourceManagerImpl::GetMediaDataByName(const char *name, size_t &len, std::unique_ptr<uint8_t[]> &outValue,
293     uint32_t density)
294 {
295     RState state = resMgr_->GetMediaDataByName(name, len, outValue, density);
296     if (state != RState::SUCCESS) {
297         LOGE("ResourceManagerImpl::GetMediaDataByName failed %{public}" PRIu32, state);
298     } else {
299         LOGI("ResourceManagerImpl::GetMediaDataByName success");
300     }
301     return state;
302 }
303 
GetMediaDataById(uint32_t id,size_t & len,std::unique_ptr<uint8_t[]> & outValue,uint32_t density)304 int32_t ResourceManagerImpl::GetMediaDataById(uint32_t id, size_t &len, std::unique_ptr<uint8_t[]> &outValue,
305     uint32_t density)
306 {
307     RState state = resMgr_->GetMediaDataById(id, len, outValue, density);
308     if (state != RState::SUCCESS) {
309         LOGE("ResourceManagerImpl::GetMediaDataById failed %{public}" PRIu32, state);
310     } else {
311         LOGI("ResourceManagerImpl::GetMediaDataById success");
312     }
313     return state;
314 }
315 
GetMediaContentBase64ById(uint32_t id,std::string & outValue,uint32_t density)316 int32_t ResourceManagerImpl::GetMediaContentBase64ById(uint32_t id, std::string &outValue, uint32_t density)
317 {
318     RState state = resMgr_->GetMediaBase64DataById(id, outValue, density);
319         if (state != RState::SUCCESS) {
320         LOGE("ResourceManagerImpl::GetMediaDataById failed %{public}" PRIu32, state);
321     } else {
322         LOGI("ResourceManagerImpl::GetMediaDataById success");
323     }
324     return state;
325 }
326 
GetMediaContentBase64ByName(const char * name,std::string & outValue,uint32_t density)327 int32_t ResourceManagerImpl::GetMediaContentBase64ByName(const char *name, std::string &outValue, uint32_t density)
328 {
329     RState state = resMgr_->GetMediaBase64DataByName(name, outValue, density);
330         if (state != RState::SUCCESS) {
331         LOGE("ResourceManagerImpl::GetMediaDataById failed %{public}" PRIu32, state);
332     } else {
333         LOGI("ResourceManagerImpl::GetMediaDataById success");
334     }
335     return state;
336 }
337 
GetDrawableDescriptor(uint32_t id,int64_t & outValue,uint32_t density)338 int32_t ResourceManagerImpl::GetDrawableDescriptor(uint32_t id, int64_t &outValue, uint32_t density)
339 {
340     RState state = SUCCESS;
341     OHOS::Ace::Napi::DrawableDescriptor::DrawableType drawableType;
342     auto drawableDescriptor = OHOS::Ace::Napi::DrawableDescriptorFactory::Create(id, resMgr_,
343         state, drawableType, density);
344     if (state != SUCCESS) {
345         LOGE("Failed to Create drawableDescriptor by %{public}" PRIu32, id);
346         return state;
347     }
348     auto ptr = FFIData::Create<DrawableDescriptorImpl>(drawableDescriptor.release());
349     if (!ptr) {
350         return ERR_INVALID_INSTANCE_CODE;
351     }
352     outValue = ptr->GetID();
353     return state;
354 }
355 
GetDrawableDescriptorByName(const char * name,int64_t & outValue,uint32_t density)356 int32_t ResourceManagerImpl::GetDrawableDescriptorByName(const char *name, int64_t &outValue, uint32_t density)
357 {
358     RState state = SUCCESS;
359     OHOS::Ace::Napi::DrawableDescriptor::DrawableType drawableType;
360     auto drawableDescriptor = OHOS::Ace::Napi::DrawableDescriptorFactory::Create(name, resMgr_,
361         state, drawableType, density);
362     if (state != SUCCESS) {
363         return state;
364     }
365     auto ptr = FFIData::Create<DrawableDescriptorImpl>(drawableDescriptor.release());
366     if (!ptr) {
367         return ERR_INVALID_INSTANCE_CODE;
368     }
369     outValue = ptr->GetID();
370     return state;
371 }
372 
GetHapResourceManager(Global::Resource::ResourceManager::Resource resource,std::shared_ptr<Global::Resource::ResourceManager> & resMgr,int32_t & resId)373 bool ResourceManagerImpl::GetHapResourceManager(Global::Resource::ResourceManager::Resource resource,
374     std::shared_ptr<Global::Resource::ResourceManager> &resMgr, int32_t &resId)
375 {
376     resId = resource.id;
377     if (isSystem_) {
378         resMgr = resMgr_;
379         return true;
380     }
381 
382     std::string key(resource.bundleName + "/" + resource.moduleName);
383     std::lock_guard<std::mutex> lock(g_resMapLock);
384     auto iter = g_resourceMgr.find(key);
385     if (iter != g_resourceMgr.end()) {
386         resMgr = g_resourceMgr[key];
387         return true;
388     }
389 
390     auto moduleContext = context_->CreateModuleContext(resource.bundleName, resource.moduleName);
391     if (moduleContext == nullptr) {
392         return false;
393     }
394     resMgr = moduleContext->GetResourceManager();
395     g_resourceMgr[key] = resMgr;
396     return true;
397 }
398 
GetLocale(std::unique_ptr<Global::Resource::ResConfig> & cfg)399 std::string ResourceManagerImpl::GetLocale(std::unique_ptr<Global::Resource::ResConfig> &cfg)
400 {
401     std::string result;
402 #ifdef SUPPORT_GRAPHICS
403         const icu::Locale *localeInfo = cfg->GetLocaleInfo();
404         if (localeInfo == nullptr) {
405             return result;
406         }
407         const char *lang = localeInfo->getLanguage();
408         if (lang == nullptr) {
409             return result;
410         }
411         result = lang;
412 
413         const char *script = localeInfo->getScript();
414         if (script != nullptr) {
415             result += std::string("_") + script;
416         }
417 
418         const char *region = localeInfo->getCountry();
419         if (region != nullptr) {
420             result += std::string("_") + region;
421         }
422 #endif
423     return result;
424 }
425 
GetDrawableDescriptorPtr(uint32_t id,std::shared_ptr<Global::Resource::ResourceManager> resMgr,uint32_t density,RState & state)426 OHOS::Ace::Napi::DrawableDescriptor* GetDrawableDescriptorPtr(uint32_t id,
427     std::shared_ptr<Global::Resource::ResourceManager> resMgr, uint32_t density, RState &state)
428 {
429     OHOS::Ace::Napi::DrawableDescriptor::DrawableType drawableType;
430     auto drawableDescriptor = OHOS::Ace::Napi::DrawableDescriptorFactory::Create(id, resMgr, state, drawableType,
431     density);
432     if (state != SUCCESS) {
433         LOGE("Failed to Create drawableDescriptor by %{public}" PRIu32, id);
434         return nullptr;
435     }
436 
437     return drawableDescriptor.release();
438 }
439 
GetLocales(bool includeSystem,std::vector<std::string> & outValue)440 void ResourceManagerImpl::GetLocales(bool includeSystem, std::vector<std::string> &outValue)
441 {
442     return resMgr_->GetLocales(outValue, includeSystem);
443 }
444 }
445