mirror of
https://gitee.com/openharmony/distributeddatamgr_udmf
synced 2024-10-07 05:43:56 +00:00
b433e19d5f
Signed-off-by: zph <zhaopenghui5@huawei.com>
231 lines
8.3 KiB
C++
231 lines
8.3 KiB
C++
/*
|
|
* Copyright (c) 2023 Huawei Device Co., Ltd.
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
#define LOG_TAG "CustomUtdStore"
|
|
#include "custom_utd_store.h"
|
|
#include <fstream>
|
|
#include <sys/stat.h>
|
|
#include "logger.h"
|
|
#include "preset_type_descriptors.h"
|
|
#include "unistd.h"
|
|
#include "utd_cfgs_checker.h"
|
|
#include "utd_graph.h"
|
|
#ifdef WITH_SELINUX
|
|
#include <policycoreutils.h>
|
|
#endif
|
|
namespace OHOS {
|
|
namespace UDMF {
|
|
constexpr const char* UTD_CFG_FILE = "utd-adt.json";
|
|
constexpr const char* CUSTOM_UTD_HAP_DIR = "/data/utd/utd-adt.json";
|
|
constexpr const char* CUSTOM_UTD_SA_DIR = "/data/service/el1/";
|
|
constexpr const char* OLD_CUSTOM_UTD_SA_SUB_DIR = "/distributeddata/utd/";
|
|
constexpr const char* CUSTOM_UTD_SA_SUB_DIR = "/utdtypes/utd/";
|
|
|
|
CustomUtdStore::CustomUtdStore()
|
|
{
|
|
}
|
|
|
|
CustomUtdStore::~CustomUtdStore()
|
|
{
|
|
}
|
|
|
|
CustomUtdStore &CustomUtdStore::GetInstance()
|
|
{
|
|
static CustomUtdStore utdCustomPersistence;
|
|
return utdCustomPersistence;
|
|
}
|
|
|
|
std::vector<TypeDescriptorCfg> CustomUtdStore::GetHapTypeCfgs()
|
|
{
|
|
LOG_DEBUG(UDMF_CLIENT, "get utdcustom from cfg, Path:%{public}s.", CUSTOM_UTD_HAP_DIR);
|
|
std::string jsonStr;
|
|
std::ifstream fin(CUSTOM_UTD_HAP_DIR);
|
|
while (fin.good()) {
|
|
std::string line;
|
|
std::getline(fin, line);
|
|
jsonStr += line;
|
|
}
|
|
std::vector<TypeDescriptorCfg> customUtdTypes;
|
|
utdJsonParser_.ParseStoredCustomUtdJson(jsonStr, customUtdTypes);
|
|
LOG_DEBUG(UDMF_CLIENT, "GetTypeCfgs, customUtdTypes total:%{public}zu.", customUtdTypes.size());
|
|
return customUtdTypes;
|
|
}
|
|
|
|
std::vector<TypeDescriptorCfg> CustomUtdStore::GetTypeCfgs(int32_t userId)
|
|
{
|
|
std::string path = CUSTOM_UTD_SA_DIR + std::to_string(userId) + CUSTOM_UTD_SA_SUB_DIR;
|
|
std::string old_path = CUSTOM_UTD_SA_DIR + std::to_string(userId) + OLD_CUSTOM_UTD_SA_SUB_DIR;
|
|
std::string cfgFilePath = path;
|
|
if (access(path.c_str(), F_OK) != 0 && access(old_path.c_str(), F_OK) == 0) {
|
|
cfgFilePath = old_path;
|
|
}
|
|
cfgFilePath.append(UTD_CFG_FILE);
|
|
LOG_DEBUG(UDMF_CLIENT, "get utdcustom from cfg, Path:%{public}s.", cfgFilePath.c_str());
|
|
std::string jsonStr;
|
|
std::ifstream fin(cfgFilePath);
|
|
while (fin.good()) {
|
|
std::string line;
|
|
std::getline(fin, line);
|
|
jsonStr += line;
|
|
}
|
|
std::vector<TypeDescriptorCfg> customUtdTypes;
|
|
utdJsonParser_.ParseStoredCustomUtdJson(jsonStr, customUtdTypes);
|
|
LOG_DEBUG(UDMF_CLIENT, "GetTypeCfgs, customUtdTypes total:%{public}zu.", customUtdTypes.size());
|
|
return customUtdTypes;
|
|
}
|
|
|
|
int32_t CustomUtdStore::SaveTypeCfgs(const std::vector<TypeDescriptorCfg> &customUtdTypes, int32_t user)
|
|
{
|
|
LOG_DEBUG(UDMF_CLIENT, "customUtdTypes total:%{public}zu.", customUtdTypes.size());
|
|
std::string jsonData;
|
|
std::string cfgFileDir = CUSTOM_UTD_SA_DIR + std::to_string(user) + CUSTOM_UTD_SA_SUB_DIR;
|
|
if (utdJsonParser_.ConvertUtdCfgsToJson(customUtdTypes, jsonData) && CreateDirectory(cfgFileDir)) {
|
|
SavaCfgFile(jsonData, cfgFileDir.append(UTD_CFG_FILE));
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int32_t CustomUtdStore::SavaCfgFile(const std::string &jsonData, const std::string &cfgFilePath)
|
|
{
|
|
std::ofstream ofs;
|
|
LOG_DEBUG(UDMF_CLIENT, "set cfg start, path:%{public}s ", cfgFilePath.c_str());
|
|
ofs.open(cfgFilePath, 0x02);
|
|
if (!ofs.is_open()) {
|
|
LOG_ERROR(UDMF_CLIENT, "open cfg failed, path:%{public}s", cfgFilePath.c_str());
|
|
}
|
|
ofs << jsonData << std::endl;
|
|
ofs.close();
|
|
LOG_DEBUG(UDMF_CLIENT, "set cfg end.");
|
|
return 0;
|
|
}
|
|
|
|
bool CustomUtdStore::CreateDirectory(const std::string &path) const
|
|
{
|
|
LOG_DEBUG(UDMF_CLIENT, "CreateDirectory start, path:%{public}s ", path.c_str());
|
|
if (access(path.c_str(), F_OK) == 0) {
|
|
return true;
|
|
}
|
|
|
|
std::string::size_type index = 0;
|
|
do {
|
|
std::string subPath;
|
|
index = path.find('/', index + 1);
|
|
if (index == std::string::npos) {
|
|
subPath = path;
|
|
} else {
|
|
subPath = path.substr(0, index);
|
|
}
|
|
|
|
if (access(subPath.c_str(), F_OK) != 0) {
|
|
if (mkdir(subPath.c_str(), (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)) != 0) {
|
|
LOG_WARN(UDMF_CLIENT, "CreateDirectory, fail. path:%{public}s, subPath:%{public}s.",
|
|
path.c_str(), subPath.c_str());
|
|
return false;
|
|
}
|
|
}
|
|
} while (index != std::string::npos);
|
|
|
|
if (access(path.c_str(), F_OK) == 0) {
|
|
#ifdef WITH_SELINUX
|
|
Restorecon(path.c_str());
|
|
#endif
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CustomUtdStore::InstallCustomUtds(const std::string &bundleName, const std::string &jsonStr,
|
|
int32_t user, std::vector<TypeDescriptorCfg> &customTyepCfgs)
|
|
{
|
|
CustomUtdCfgs typeCfgs;
|
|
if (!utdJsonParser_.ParseUserCustomUtdJson(jsonStr, typeCfgs.first, typeCfgs.second)) {
|
|
LOG_ERROR(UDMF_CLIENT, "Parse json failed. bundleName:%{public}s", bundleName.c_str());
|
|
return false;
|
|
}
|
|
std::vector<TypeDescriptorCfg> presetTypes = PresetTypeDescriptors::GetInstance().GetPresetTypes();
|
|
|
|
if (!UtdCfgsChecker::GetInstance().CheckTypeDescriptors(
|
|
typeCfgs, presetTypes, customTyepCfgs, bundleName)) {
|
|
LOG_ERROR(UDMF_CLIENT, "check type descriptors failed, bundleName:%{public}s", bundleName.c_str());
|
|
return false;
|
|
}
|
|
|
|
ProcessUtdForSave(typeCfgs, customTyepCfgs, bundleName);
|
|
if (CustomUtdStore::GetInstance().SaveTypeCfgs(customTyepCfgs, user) != E_OK) {
|
|
LOG_ERROR(UDMF_CLIENT, "Save failed, bundleName: %{public}s", bundleName.c_str());
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool CustomUtdStore::UninstallCustomUtds(const std::string &bundleName, int32_t user,
|
|
std::vector<TypeDescriptorCfg> &customTyepCfgs)
|
|
{
|
|
for (auto iter = customTyepCfgs.begin(); iter != customTyepCfgs.end();) {
|
|
auto it = find(iter->installerBundles.begin(), iter->installerBundles.end(), bundleName);
|
|
if (it != iter->installerBundles.end()) {
|
|
iter->installerBundles.erase(it);
|
|
}
|
|
if (iter->installerBundles.empty()) {
|
|
iter = customTyepCfgs.erase(iter);
|
|
} else {
|
|
iter++;
|
|
}
|
|
}
|
|
std::vector<TypeDescriptorCfg> presetTypes = PresetTypeDescriptors::GetInstance().GetPresetTypes();
|
|
if (!UtdCfgsChecker::GetInstance().CheckBelongingToTypes(customTyepCfgs, presetTypes)) {
|
|
LOG_ERROR(UDMF_CLIENT, "belongingToTypes check failed. bundleName:%{public}s", bundleName.c_str());
|
|
return false;
|
|
}
|
|
if (CustomUtdStore::GetInstance().SaveTypeCfgs(customTyepCfgs, user) != E_OK) {
|
|
LOG_ERROR(UDMF_CLIENT, "Save type cfgs failed, bundleName: %{public}s", bundleName.c_str());
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void CustomUtdStore::ProcessUtdForSave(const CustomUtdCfgs &utdTypes, std::vector<TypeDescriptorCfg> &customTyepCfgs,
|
|
const std::string &bundleName)
|
|
{
|
|
for (TypeDescriptorCfg declarationType : utdTypes.first) {
|
|
for (auto iter = customTyepCfgs.begin(); iter != customTyepCfgs.end();) {
|
|
if (iter->typeId == declarationType.typeId) {
|
|
declarationType.installerBundles = iter->installerBundles;
|
|
iter = customTyepCfgs.erase(iter);
|
|
} else {
|
|
iter++;
|
|
}
|
|
}
|
|
declarationType.installerBundles.emplace(bundleName);
|
|
declarationType.ownerBundle = bundleName;
|
|
customTyepCfgs.push_back(declarationType);
|
|
}
|
|
for (TypeDescriptorCfg referenceType : utdTypes.second) {
|
|
bool found = false;
|
|
for (auto &typeCfg : customTyepCfgs) {
|
|
if (typeCfg.typeId == referenceType.typeId) {
|
|
typeCfg.installerBundles.emplace(bundleName);
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
referenceType.installerBundles.emplace(bundleName);
|
|
customTyepCfgs.push_back(referenceType);
|
|
}
|
|
}
|
|
}
|
|
} // namespace UDMF
|
|
} // namespace OHOS
|