114cf0368Sopenharmony_ci/*
214cf0368Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
314cf0368Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
414cf0368Sopenharmony_ci * you may not use this file except in compliance with the License.
514cf0368Sopenharmony_ci * You may obtain a copy of the License at
614cf0368Sopenharmony_ci *
714cf0368Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
814cf0368Sopenharmony_ci *
914cf0368Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1014cf0368Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1114cf0368Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1214cf0368Sopenharmony_ci * See the License for the specific language governing permissions and
1314cf0368Sopenharmony_ci * limitations under the License.
1414cf0368Sopenharmony_ci */
1514cf0368Sopenharmony_ci#define LOG_TAG "UtdClient"
1614cf0368Sopenharmony_ci#include <regex>
1714cf0368Sopenharmony_ci#include <thread>
1814cf0368Sopenharmony_ci#include "utd_client.h"
1914cf0368Sopenharmony_ci#include "logger.h"
2014cf0368Sopenharmony_ci#include "utd_graph.h"
2114cf0368Sopenharmony_ci#include "custom_utd_store.h"
2214cf0368Sopenharmony_ci#include "accesstoken_kit.h"
2314cf0368Sopenharmony_ci#include "ipc_skeleton.h"
2414cf0368Sopenharmony_ci#include "os_account_manager.h"
2514cf0368Sopenharmony_cinamespace OHOS {
2614cf0368Sopenharmony_cinamespace UDMF {
2714cf0368Sopenharmony_ciconstexpr const int MAX_UTD_LENGTH = 256;
2814cf0368Sopenharmony_ci
2914cf0368Sopenharmony_ciUtdClient::UtdClient()
3014cf0368Sopenharmony_ci{
3114cf0368Sopenharmony_ci    if (!Init()) {
3214cf0368Sopenharmony_ci        LOG_WARN(UDMF_CLIENT, "construct UtdClient failed, try again.");
3314cf0368Sopenharmony_ci        auto updateTask = []() {
3414cf0368Sopenharmony_ci            std::this_thread::sleep_for(std::chrono::seconds(3));
3514cf0368Sopenharmony_ci            UtdClient::GetInstance().Init();
3614cf0368Sopenharmony_ci        };
3714cf0368Sopenharmony_ci        std::thread(updateTask).detach();
3814cf0368Sopenharmony_ci    }
3914cf0368Sopenharmony_ci    LOG_INFO(UDMF_CLIENT, "construct UtdClient sucess.");
4014cf0368Sopenharmony_ci}
4114cf0368Sopenharmony_ci
4214cf0368Sopenharmony_ciUtdClient::~UtdClient()
4314cf0368Sopenharmony_ci{
4414cf0368Sopenharmony_ci}
4514cf0368Sopenharmony_ci
4614cf0368Sopenharmony_ciUtdClient &UtdClient::GetInstance()
4714cf0368Sopenharmony_ci{
4814cf0368Sopenharmony_ci    static auto instance = new UtdClient();
4914cf0368Sopenharmony_ci    return *instance;
5014cf0368Sopenharmony_ci}
5114cf0368Sopenharmony_ci
5214cf0368Sopenharmony_cibool UtdClient::Init()
5314cf0368Sopenharmony_ci{
5414cf0368Sopenharmony_ci    bool result = true;
5514cf0368Sopenharmony_ci    std::unique_lock<std::shared_mutex> lock(utdMutex_);
5614cf0368Sopenharmony_ci    descriptorCfgs_ = PresetTypeDescriptors::GetInstance().GetPresetTypes();
5714cf0368Sopenharmony_ci    std::vector<TypeDescriptorCfg> customTypes;
5814cf0368Sopenharmony_ci    if (IsHapTokenType()) {
5914cf0368Sopenharmony_ci        customTypes = CustomUtdStore::GetInstance().GetHapTypeCfgs();
6014cf0368Sopenharmony_ci    } else {
6114cf0368Sopenharmony_ci        int32_t userId = DEFAULT_USER_ID;
6214cf0368Sopenharmony_ci        if (GetCurrentActiveUserId(userId) != Status::E_OK) {
6314cf0368Sopenharmony_ci            result = false;
6414cf0368Sopenharmony_ci        }
6514cf0368Sopenharmony_ci        customTypes = CustomUtdStore::GetInstance().GetTypeCfgs(userId);
6614cf0368Sopenharmony_ci    }
6714cf0368Sopenharmony_ci    LOG_INFO(UDMF_CLIENT, "get customUtd, size:%{public}zu", customTypes.size());
6814cf0368Sopenharmony_ci    if (!customTypes.empty()) {
6914cf0368Sopenharmony_ci        descriptorCfgs_.insert(descriptorCfgs_.end(), customTypes.begin(), customTypes.end());
7014cf0368Sopenharmony_ci    }
7114cf0368Sopenharmony_ci    UtdGraph::GetInstance().InitUtdGraph(descriptorCfgs_);
7214cf0368Sopenharmony_ci    return result;
7314cf0368Sopenharmony_ci}
7414cf0368Sopenharmony_ci
7514cf0368Sopenharmony_ciStatus UtdClient::GetTypeDescriptor(const std::string &typeId, std::shared_ptr<TypeDescriptor> &descriptor)
7614cf0368Sopenharmony_ci{
7714cf0368Sopenharmony_ci    {
7814cf0368Sopenharmony_ci        std::shared_lock<std::shared_mutex> guard(utdMutex_);
7914cf0368Sopenharmony_ci        for (const auto &utdTypeCfg : descriptorCfgs_) {
8014cf0368Sopenharmony_ci            if (utdTypeCfg.typeId == typeId) {
8114cf0368Sopenharmony_ci                descriptor = std::make_shared<TypeDescriptor>(utdTypeCfg);
8214cf0368Sopenharmony_ci                LOG_DEBUG(UDMF_CLIENT, "get descriptor success. %{public}s ", typeId.c_str());
8314cf0368Sopenharmony_ci                return Status::E_OK;
8414cf0368Sopenharmony_ci            }
8514cf0368Sopenharmony_ci        }
8614cf0368Sopenharmony_ci    }
8714cf0368Sopenharmony_ci    if (typeId.find(FLEXIBLE_TYPE_FLAG) != typeId.npos) {
8814cf0368Sopenharmony_ci        LOG_DEBUG(UDMF_CLIENT, "get flexible descriptor. %{public}s ", typeId.c_str());
8914cf0368Sopenharmony_ci        return GetFlexibleTypeDescriptor(typeId, descriptor);
9014cf0368Sopenharmony_ci    }
9114cf0368Sopenharmony_ci    return Status::E_OK;
9214cf0368Sopenharmony_ci}
9314cf0368Sopenharmony_ci
9414cf0368Sopenharmony_cibool UtdClient::IsValidFileExtension(const std::string &fileExtension)
9514cf0368Sopenharmony_ci{
9614cf0368Sopenharmony_ci    if (fileExtension.empty()) {
9714cf0368Sopenharmony_ci        return false;
9814cf0368Sopenharmony_ci    }
9914cf0368Sopenharmony_ci    if (fileExtension[0] != '.' || fileExtension.find("?") != fileExtension.npos ||
10014cf0368Sopenharmony_ci        fileExtension.find(":") != fileExtension.npos || fileExtension.find("=") != fileExtension.npos ||
10114cf0368Sopenharmony_ci        fileExtension.find("\\") != fileExtension.npos) {
10214cf0368Sopenharmony_ci            return false;
10314cf0368Sopenharmony_ci    }
10414cf0368Sopenharmony_ci
10514cf0368Sopenharmony_ci    return true;
10614cf0368Sopenharmony_ci}
10714cf0368Sopenharmony_ci
10814cf0368Sopenharmony_cibool UtdClient::IsValidMimeType(const std::string &mimeType)
10914cf0368Sopenharmony_ci{
11014cf0368Sopenharmony_ci    if (mimeType.empty()) {
11114cf0368Sopenharmony_ci        return false;
11214cf0368Sopenharmony_ci    }
11314cf0368Sopenharmony_ci    if (mimeType.find("?") != mimeType.npos || mimeType.find(":") != mimeType.npos ||
11414cf0368Sopenharmony_ci        mimeType.find("=") != mimeType.npos ||mimeType.find("\\") != mimeType.npos) {
11514cf0368Sopenharmony_ci            return false;
11614cf0368Sopenharmony_ci    }
11714cf0368Sopenharmony_ci    return true;
11814cf0368Sopenharmony_ci}
11914cf0368Sopenharmony_ci
12014cf0368Sopenharmony_ciStatus UtdClient::GetFlexibleTypeDescriptor(const std::string &typeId, std::shared_ptr<TypeDescriptor> &descriptor)
12114cf0368Sopenharmony_ci{
12214cf0368Sopenharmony_ci    TypeDescriptorCfg flexibleTypeDescriptorCfg;
12314cf0368Sopenharmony_ci    if (!FlexibleType::ParseFlexibleUtd(typeId, flexibleTypeDescriptorCfg)) {
12414cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CLIENT, "ParseFlexibleUtd failed, invalid typeId: %{public}s", typeId.c_str());
12514cf0368Sopenharmony_ci        return Status::E_ERROR;
12614cf0368Sopenharmony_ci    }
12714cf0368Sopenharmony_ci    descriptor = std::make_shared<TypeDescriptor>(flexibleTypeDescriptorCfg);
12814cf0368Sopenharmony_ci    return Status::E_OK;
12914cf0368Sopenharmony_ci}
13014cf0368Sopenharmony_ci
13114cf0368Sopenharmony_ciStatus UtdClient::GetUniformDataTypeByFilenameExtension(const std::string &fileExtension, std::string &typeId,
13214cf0368Sopenharmony_ci                                                        std::string belongsTo)
13314cf0368Sopenharmony_ci{
13414cf0368Sopenharmony_ci    std::string lowerFileExtension = fileExtension;
13514cf0368Sopenharmony_ci    std::transform(lowerFileExtension.begin(), lowerFileExtension.end(), lowerFileExtension.begin(), ::tolower);
13614cf0368Sopenharmony_ci    if (belongsTo != DEFAULT_TYPE_ID && !UtdGraph::GetInstance().IsValidType(belongsTo)) {
13714cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CLIENT, "invalid belongsTo. fileExtension:%{public}s, belongsTo:%{public}s ",
13814cf0368Sopenharmony_ci                  fileExtension.c_str(), belongsTo.c_str());
13914cf0368Sopenharmony_ci        return Status::E_INVALID_PARAMETERS;
14014cf0368Sopenharmony_ci    }
14114cf0368Sopenharmony_ci    {
14214cf0368Sopenharmony_ci        std::shared_lock<std::shared_mutex> guard(utdMutex_);
14314cf0368Sopenharmony_ci        bool found = false;
14414cf0368Sopenharmony_ci        for (const auto &utdTypeCfg : descriptorCfgs_) {
14514cf0368Sopenharmony_ci            for (auto fileEx : utdTypeCfg.filenameExtensions) {
14614cf0368Sopenharmony_ci                std::transform(fileEx.begin(), fileEx.end(), fileEx.begin(), ::tolower);
14714cf0368Sopenharmony_ci                if (fileEx == lowerFileExtension) {
14814cf0368Sopenharmony_ci                    typeId = utdTypeCfg.typeId;
14914cf0368Sopenharmony_ci                    found = true;
15014cf0368Sopenharmony_ci                    break;
15114cf0368Sopenharmony_ci                }
15214cf0368Sopenharmony_ci            }
15314cf0368Sopenharmony_ci            if (found) {
15414cf0368Sopenharmony_ci                break;
15514cf0368Sopenharmony_ci            }
15614cf0368Sopenharmony_ci        }
15714cf0368Sopenharmony_ci    }
15814cf0368Sopenharmony_ci    // the find typeId is not belongsTo to the belongsTo.
15914cf0368Sopenharmony_ci    if (!typeId.empty() && belongsTo != DEFAULT_TYPE_ID && belongsTo != typeId &&
16014cf0368Sopenharmony_ci        !UtdGraph::GetInstance().IsLowerLevelType(belongsTo, typeId)) {
16114cf0368Sopenharmony_ci        typeId = "";
16214cf0368Sopenharmony_ci    }
16314cf0368Sopenharmony_ci
16414cf0368Sopenharmony_ci    if (typeId.empty()) {
16514cf0368Sopenharmony_ci        if (!IsValidFileExtension(lowerFileExtension)) {
16614cf0368Sopenharmony_ci            LOG_ERROR(UDMF_CLIENT, "invalid fileExtension. fileExtension:%{public}s, belongsTo:%{public}s ",
16714cf0368Sopenharmony_ci                      fileExtension.c_str(), belongsTo.c_str());
16814cf0368Sopenharmony_ci            return Status::E_INVALID_PARAMETERS;
16914cf0368Sopenharmony_ci        }
17014cf0368Sopenharmony_ci        typeId = FlexibleType::GenFlexibleUtd("", lowerFileExtension, belongsTo);
17114cf0368Sopenharmony_ci    }
17214cf0368Sopenharmony_ci    return Status::E_OK;
17314cf0368Sopenharmony_ci}
17414cf0368Sopenharmony_ci
17514cf0368Sopenharmony_ciStatus UtdClient::GetUniformDataTypesByFilenameExtension(const std::string &fileExtension,
17614cf0368Sopenharmony_ci    std::vector<std::string> &typeIds, const std::string &belongsTo)
17714cf0368Sopenharmony_ci{
17814cf0368Sopenharmony_ci    if (belongsTo != DEFAULT_TYPE_ID && !UtdGraph::GetInstance().IsValidType(belongsTo)) {
17914cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CLIENT, "invalid belongsTo. fileExtension:%{public}s, belongsTo:%{public}s ",
18014cf0368Sopenharmony_ci            fileExtension.c_str(), belongsTo.c_str());
18114cf0368Sopenharmony_ci        return Status::E_INVALID_PARAMETERS;
18214cf0368Sopenharmony_ci    }
18314cf0368Sopenharmony_ci    if (!IsValidFileExtension(fileExtension)) {
18414cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CLIENT, "invalid fileExtension. fileExtension:%{public}s, belongsTo:%{public}s ",
18514cf0368Sopenharmony_ci            fileExtension.c_str(), belongsTo.c_str());
18614cf0368Sopenharmony_ci        return Status::E_INVALID_PARAMETERS;
18714cf0368Sopenharmony_ci    }
18814cf0368Sopenharmony_ci
18914cf0368Sopenharmony_ci    std::string lowerFileExtension = fileExtension;
19014cf0368Sopenharmony_ci    std::transform(lowerFileExtension.begin(), lowerFileExtension.end(), lowerFileExtension.begin(), ::tolower);
19114cf0368Sopenharmony_ci    std::vector<std::string> typeIdsInCfg;
19214cf0368Sopenharmony_ci    {
19314cf0368Sopenharmony_ci        std::shared_lock<std::shared_mutex> guard(utdMutex_);
19414cf0368Sopenharmony_ci        for (const auto &utdTypeCfg : descriptorCfgs_) {
19514cf0368Sopenharmony_ci            for (auto fileEx : utdTypeCfg.filenameExtensions) {
19614cf0368Sopenharmony_ci                std::transform(fileEx.begin(), fileEx.end(), fileEx.begin(), ::tolower);
19714cf0368Sopenharmony_ci                if (fileEx == lowerFileExtension) {
19814cf0368Sopenharmony_ci                    typeIdsInCfg.push_back(utdTypeCfg.typeId);
19914cf0368Sopenharmony_ci                    break;
20014cf0368Sopenharmony_ci                }
20114cf0368Sopenharmony_ci            }
20214cf0368Sopenharmony_ci        }
20314cf0368Sopenharmony_ci    }
20414cf0368Sopenharmony_ci    typeIds.clear();
20514cf0368Sopenharmony_ci    for (const auto &typeId : typeIdsInCfg) {
20614cf0368Sopenharmony_ci        // the find typeId is not belongsTo to the belongsTo.
20714cf0368Sopenharmony_ci        if (belongsTo != DEFAULT_TYPE_ID && belongsTo != typeId &&
20814cf0368Sopenharmony_ci            !UtdGraph::GetInstance().IsLowerLevelType(belongsTo, typeId)) {
20914cf0368Sopenharmony_ci            continue;
21014cf0368Sopenharmony_ci        }
21114cf0368Sopenharmony_ci        typeIds.emplace_back(typeId);
21214cf0368Sopenharmony_ci    }
21314cf0368Sopenharmony_ci    if (typeIds.empty()) {
21414cf0368Sopenharmony_ci        typeIds.emplace_back(FlexibleType::GenFlexibleUtd("", lowerFileExtension, belongsTo));
21514cf0368Sopenharmony_ci    }
21614cf0368Sopenharmony_ci    return Status::E_OK;
21714cf0368Sopenharmony_ci}
21814cf0368Sopenharmony_ci
21914cf0368Sopenharmony_ciStatus UtdClient::GetUniformDataTypeByMIMEType(const std::string &mimeType, std::string &typeId,
22014cf0368Sopenharmony_ci                                               std::string belongsTo)
22114cf0368Sopenharmony_ci{
22214cf0368Sopenharmony_ci    std::string lowerMimeType = mimeType;
22314cf0368Sopenharmony_ci    std::transform(lowerMimeType.begin(), lowerMimeType.end(), lowerMimeType.begin(), ::tolower);
22414cf0368Sopenharmony_ci    if (belongsTo != DEFAULT_TYPE_ID && !UtdGraph::GetInstance().IsValidType(belongsTo)) {
22514cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CLIENT, "invalid belongsTo. mimeType:%{public}s, belongsTo:%{public}s ",
22614cf0368Sopenharmony_ci                  mimeType.c_str(), belongsTo.c_str());
22714cf0368Sopenharmony_ci        return Status::E_INVALID_PARAMETERS;
22814cf0368Sopenharmony_ci    }
22914cf0368Sopenharmony_ci    typeId = GetTypeIdFromCfg(lowerMimeType);
23014cf0368Sopenharmony_ci    // the find typeId is not belongsTo to the belongsTo.
23114cf0368Sopenharmony_ci    if (!typeId.empty() && belongsTo != DEFAULT_TYPE_ID && belongsTo != typeId &&
23214cf0368Sopenharmony_ci        !UtdGraph::GetInstance().IsLowerLevelType(belongsTo, typeId)) {
23314cf0368Sopenharmony_ci        typeId = "";
23414cf0368Sopenharmony_ci    }
23514cf0368Sopenharmony_ci    if (typeId.empty()) {
23614cf0368Sopenharmony_ci        if (!IsValidMimeType(mimeType)) {
23714cf0368Sopenharmony_ci            LOG_ERROR(UDMF_CLIENT, "invalid mimeType. mimeType:%{public}s, belongsTo:%{public}s ",
23814cf0368Sopenharmony_ci                      mimeType.c_str(), belongsTo.c_str());
23914cf0368Sopenharmony_ci            return Status::E_INVALID_PARAMETERS;
24014cf0368Sopenharmony_ci        }
24114cf0368Sopenharmony_ci        typeId = FlexibleType::GenFlexibleUtd(lowerMimeType, "", belongsTo);
24214cf0368Sopenharmony_ci    }
24314cf0368Sopenharmony_ci    return Status::E_OK;
24414cf0368Sopenharmony_ci}
24514cf0368Sopenharmony_ci
24614cf0368Sopenharmony_cistd::string UtdClient::GetTypeIdFromCfg(const std::string &mimeType)
24714cf0368Sopenharmony_ci{
24814cf0368Sopenharmony_ci    std::shared_lock<std::shared_mutex> guard(utdMutex_);
24914cf0368Sopenharmony_ci    for (const auto &utdTypeCfg : descriptorCfgs_) {
25014cf0368Sopenharmony_ci        for (auto mime : utdTypeCfg.mimeTypes) {
25114cf0368Sopenharmony_ci            std::transform(mime.begin(), mime.end(), mime.begin(), ::tolower);
25214cf0368Sopenharmony_ci            if (mime == mimeType) {
25314cf0368Sopenharmony_ci                return utdTypeCfg.typeId;
25414cf0368Sopenharmony_ci            }
25514cf0368Sopenharmony_ci        }
25614cf0368Sopenharmony_ci    }
25714cf0368Sopenharmony_ci    if (mimeType.empty() || mimeType.back() != '*') {
25814cf0368Sopenharmony_ci        return "";
25914cf0368Sopenharmony_ci    }
26014cf0368Sopenharmony_ci    std::string prefixType = mimeType.substr(0, mimeType.length() - 1);
26114cf0368Sopenharmony_ci    for (const auto &utdTypeCfg : descriptorCfgs_) {
26214cf0368Sopenharmony_ci        for (auto mime : utdTypeCfg.mimeTypes) {
26314cf0368Sopenharmony_ci            std::transform(mime.begin(), mime.end(), mime.begin(), ::tolower);
26414cf0368Sopenharmony_ci            if (mime.rfind(prefixType, 0) == 0 && utdTypeCfg.belongingToTypes.size() > 0) {
26514cf0368Sopenharmony_ci                return utdTypeCfg.belongingToTypes[0];
26614cf0368Sopenharmony_ci            }
26714cf0368Sopenharmony_ci        }
26814cf0368Sopenharmony_ci    }
26914cf0368Sopenharmony_ci    return "";
27014cf0368Sopenharmony_ci}
27114cf0368Sopenharmony_ci
27214cf0368Sopenharmony_ciStatus UtdClient::GetUniformDataTypesByMIMEType(const std::string &mimeType, std::vector<std::string> &typeIds,
27314cf0368Sopenharmony_ci    const std::string &belongsTo)
27414cf0368Sopenharmony_ci{
27514cf0368Sopenharmony_ci    if (belongsTo != DEFAULT_TYPE_ID && !UtdGraph::GetInstance().IsValidType(belongsTo)) {
27614cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CLIENT, "invalid belongsTo. mimeType:%{public}s, belongsTo:%{public}s ",
27714cf0368Sopenharmony_ci            mimeType.c_str(), belongsTo.c_str());
27814cf0368Sopenharmony_ci        return Status::E_INVALID_PARAMETERS;
27914cf0368Sopenharmony_ci    }
28014cf0368Sopenharmony_ci    if (!IsValidMimeType(mimeType)) {
28114cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CLIENT, "invalid mimeType. mimeType:%{public}s, belongsTo:%{public}s ",
28214cf0368Sopenharmony_ci            mimeType.c_str(), belongsTo.c_str());
28314cf0368Sopenharmony_ci        return Status::E_INVALID_PARAMETERS;
28414cf0368Sopenharmony_ci    }
28514cf0368Sopenharmony_ci
28614cf0368Sopenharmony_ci    std::string lowerMimeType = mimeType;
28714cf0368Sopenharmony_ci    std::transform(lowerMimeType.begin(), lowerMimeType.end(), lowerMimeType.begin(), ::tolower);
28814cf0368Sopenharmony_ci    std::vector<std::string> typeIdsInCfg = GetTypeIdsFromCfg(lowerMimeType);
28914cf0368Sopenharmony_ci    typeIds.clear();
29014cf0368Sopenharmony_ci    for (const auto &typeId : typeIdsInCfg) {
29114cf0368Sopenharmony_ci        // the find typeId is not belongsTo to the belongsTo.
29214cf0368Sopenharmony_ci        if (belongsTo != DEFAULT_TYPE_ID && belongsTo != typeId &&
29314cf0368Sopenharmony_ci            !UtdGraph::GetInstance().IsLowerLevelType(belongsTo, typeId)) {
29414cf0368Sopenharmony_ci            continue;
29514cf0368Sopenharmony_ci        }
29614cf0368Sopenharmony_ci        typeIds.emplace_back(typeId);
29714cf0368Sopenharmony_ci    }
29814cf0368Sopenharmony_ci    if (typeIds.empty()) {
29914cf0368Sopenharmony_ci        typeIds.emplace_back(FlexibleType::GenFlexibleUtd(lowerMimeType, "", belongsTo));
30014cf0368Sopenharmony_ci    }
30114cf0368Sopenharmony_ci    return Status::E_OK;
30214cf0368Sopenharmony_ci}
30314cf0368Sopenharmony_ci
30414cf0368Sopenharmony_cistd::vector<std::string> UtdClient::GetTypeIdsFromCfg(const std::string &mimeType)
30514cf0368Sopenharmony_ci{
30614cf0368Sopenharmony_ci    bool prefixMatch = false;
30714cf0368Sopenharmony_ci    std::string prefixType;
30814cf0368Sopenharmony_ci    if (!mimeType.empty() && mimeType.back() == '*') {
30914cf0368Sopenharmony_ci        prefixType = mimeType.substr(0, mimeType.length() - 1);
31014cf0368Sopenharmony_ci        prefixMatch = true;
31114cf0368Sopenharmony_ci    }
31214cf0368Sopenharmony_ci    std::vector<std::string> typeIdsInCfg;
31314cf0368Sopenharmony_ci
31414cf0368Sopenharmony_ci    std::shared_lock<std::shared_mutex> guard(utdMutex_);
31514cf0368Sopenharmony_ci    for (const auto &utdTypeCfg : descriptorCfgs_) {
31614cf0368Sopenharmony_ci        for (auto mime : utdTypeCfg.mimeTypes) {
31714cf0368Sopenharmony_ci            std::transform(mime.begin(), mime.end(), mime.begin(), ::tolower);
31814cf0368Sopenharmony_ci            if ((mime == mimeType) || (prefixMatch && mime.rfind(prefixType, 0) == 0)) {
31914cf0368Sopenharmony_ci                typeIdsInCfg.push_back(utdTypeCfg.typeId);
32014cf0368Sopenharmony_ci                break;
32114cf0368Sopenharmony_ci            }
32214cf0368Sopenharmony_ci        }
32314cf0368Sopenharmony_ci    }
32414cf0368Sopenharmony_ci    return typeIdsInCfg;
32514cf0368Sopenharmony_ci}
32614cf0368Sopenharmony_ci
32714cf0368Sopenharmony_ciStatus UtdClient::IsUtd(std::string typeId, bool &result)
32814cf0368Sopenharmony_ci{
32914cf0368Sopenharmony_ci    try {
33014cf0368Sopenharmony_ci        if (typeId.empty() || typeId.size() > MAX_UTD_LENGTH) {
33114cf0368Sopenharmony_ci            result = false;
33214cf0368Sopenharmony_ci            return Status::E_INVALID_PARAMETERS;
33314cf0368Sopenharmony_ci        }
33414cf0368Sopenharmony_ci        if (typeId[0] == '.' || find(typeId.begin(), typeId.end(), '/') != typeId.end()) {
33514cf0368Sopenharmony_ci            result = false;
33614cf0368Sopenharmony_ci            return Status::E_OK;
33714cf0368Sopenharmony_ci        }
33814cf0368Sopenharmony_ci        constexpr const char *preSetTypeIdRegexRule =
33914cf0368Sopenharmony_ci            R"(^(general\.|openharmony\.|org\.|com\.|macos\.|debian\.|redhat\.|io\.|de\.|net\.)[a-z0-9-\.]+(\-[a-z0-9-]+)*$)";
34014cf0368Sopenharmony_ci        if (std::regex_match(typeId, std::regex(preSetTypeIdRegexRule))) {
34114cf0368Sopenharmony_ci            result = true;
34214cf0368Sopenharmony_ci            return Status::E_OK;
34314cf0368Sopenharmony_ci        }
34414cf0368Sopenharmony_ci        constexpr const char *customUtdRegexRule = R"(^([A-Za-z]\w*)(\.\w+)+(\.[A-Za-z\d-]+)+)";
34514cf0368Sopenharmony_ci        if (std::regex_match(typeId, std::regex(customUtdRegexRule))) {
34614cf0368Sopenharmony_ci            result = true;
34714cf0368Sopenharmony_ci            return Status::E_OK;
34814cf0368Sopenharmony_ci        }
34914cf0368Sopenharmony_ci        result = false;
35014cf0368Sopenharmony_ci    } catch (...) {
35114cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CLIENT, "exception, typeId:%{public}s", typeId.c_str());
35214cf0368Sopenharmony_ci        result = false;
35314cf0368Sopenharmony_ci        return Status::E_ERROR;
35414cf0368Sopenharmony_ci    }
35514cf0368Sopenharmony_ci    LOG_ERROR(UDMF_CLIENT, "is not utd, typeId:%{public}s", typeId.c_str());
35614cf0368Sopenharmony_ci    return Status::E_OK;
35714cf0368Sopenharmony_ci}
35814cf0368Sopenharmony_ci
35914cf0368Sopenharmony_cibool UtdClient::IsHapTokenType()
36014cf0368Sopenharmony_ci{
36114cf0368Sopenharmony_ci    uint32_t tokenId = IPCSkeleton::GetSelfTokenID();
36214cf0368Sopenharmony_ci    auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
36314cf0368Sopenharmony_ci    LOG_DEBUG(UDMF_CLIENT, "GetTokenTypeFlag, tokenType = %{public}d.", tokenType);
36414cf0368Sopenharmony_ci    if (tokenType == Security::AccessToken::TypeATokenTypeEnum::TOKEN_HAP) {
36514cf0368Sopenharmony_ci        return true;
36614cf0368Sopenharmony_ci    }
36714cf0368Sopenharmony_ci    return false;
36814cf0368Sopenharmony_ci}
36914cf0368Sopenharmony_ci
37014cf0368Sopenharmony_ciStatus UtdClient::GetCurrentActiveUserId(int32_t& userId)
37114cf0368Sopenharmony_ci{
37214cf0368Sopenharmony_ci    std::vector<int32_t> localIds;
37314cf0368Sopenharmony_ci    int32_t status = OHOS::AccountSA::OsAccountManager::QueryActiveOsAccountIds(localIds);
37414cf0368Sopenharmony_ci    if (status != Status::E_OK || localIds.empty()) {
37514cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CLIENT, "Get OsAccountId fail, status:%{public}d", status);
37614cf0368Sopenharmony_ci        return Status::E_ERROR;
37714cf0368Sopenharmony_ci    }
37814cf0368Sopenharmony_ci    userId = localIds[0];
37914cf0368Sopenharmony_ci    return Status::E_OK;
38014cf0368Sopenharmony_ci}
38114cf0368Sopenharmony_ci
38214cf0368Sopenharmony_civoid UtdClient::InstallCustomUtds(const std::string &bundleName, const std::string &jsonStr, int32_t user)
38314cf0368Sopenharmony_ci{
38414cf0368Sopenharmony_ci    if (IsHapTokenType()) {
38514cf0368Sopenharmony_ci        return;
38614cf0368Sopenharmony_ci    }
38714cf0368Sopenharmony_ci    LOG_INFO(UDMF_CLIENT, "start, bundleName:%{public}s, user:%{public}d", bundleName.c_str(), user);
38814cf0368Sopenharmony_ci    std::vector<TypeDescriptorCfg> customTyepCfgs = CustomUtdStore::GetInstance().GetTypeCfgs(user);
38914cf0368Sopenharmony_ci    if (!CustomUtdStore::GetInstance().UninstallCustomUtds(bundleName, user, customTyepCfgs)) {
39014cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CLIENT, "custom utd installed failed. bundleName:%{public}s, user:%{public}d",
39114cf0368Sopenharmony_ci            bundleName.c_str(), user);
39214cf0368Sopenharmony_ci        return;
39314cf0368Sopenharmony_ci    }
39414cf0368Sopenharmony_ci    UpdateGraph(customTyepCfgs);
39514cf0368Sopenharmony_ci    if (!jsonStr.empty()) {
39614cf0368Sopenharmony_ci        if (!CustomUtdStore::GetInstance().InstallCustomUtds(bundleName, jsonStr, user, customTyepCfgs)) {
39714cf0368Sopenharmony_ci            LOG_ERROR(UDMF_CLIENT, "no custom utd installed. bundleName:%{public}s, user:%{public}d",
39814cf0368Sopenharmony_ci                bundleName.c_str(), user);
39914cf0368Sopenharmony_ci            return;
40014cf0368Sopenharmony_ci        }
40114cf0368Sopenharmony_ci        UpdateGraph(customTyepCfgs);
40214cf0368Sopenharmony_ci    }
40314cf0368Sopenharmony_ci}
40414cf0368Sopenharmony_ci
40514cf0368Sopenharmony_civoid UtdClient::UninstallCustomUtds(const std::string &bundleName, int32_t user)
40614cf0368Sopenharmony_ci{
40714cf0368Sopenharmony_ci    if (IsHapTokenType()) {
40814cf0368Sopenharmony_ci        return;
40914cf0368Sopenharmony_ci    }
41014cf0368Sopenharmony_ci    LOG_INFO(UDMF_CLIENT, "start, bundleName:%{public}s, user:%{public}d", bundleName.c_str(), user);
41114cf0368Sopenharmony_ci    std::vector<TypeDescriptorCfg> customTyepCfgs = CustomUtdStore::GetInstance().GetTypeCfgs(user);
41214cf0368Sopenharmony_ci    if (!CustomUtdStore::GetInstance().UninstallCustomUtds(bundleName, user, customTyepCfgs)) {
41314cf0368Sopenharmony_ci        LOG_ERROR(UDMF_CLIENT, "custom utd installed failed. bundleName:%{public}s, user:%{public}d",
41414cf0368Sopenharmony_ci            bundleName.c_str(), user);
41514cf0368Sopenharmony_ci        return;
41614cf0368Sopenharmony_ci    }
41714cf0368Sopenharmony_ci    UpdateGraph(customTyepCfgs);
41814cf0368Sopenharmony_ci}
41914cf0368Sopenharmony_ci
42014cf0368Sopenharmony_civoid UtdClient::UpdateGraph(const std::vector<TypeDescriptorCfg> &customTyepCfgs)
42114cf0368Sopenharmony_ci{
42214cf0368Sopenharmony_ci    std::vector<TypeDescriptorCfg> allTypeCfgs = PresetTypeDescriptors::GetInstance().GetPresetTypes();
42314cf0368Sopenharmony_ci    allTypeCfgs.insert(allTypeCfgs.end(), customTyepCfgs.begin(), customTyepCfgs.end());
42414cf0368Sopenharmony_ci    LOG_INFO(UDMF_CLIENT, "customTyepSize:%{public}zu, allTypeSize:%{public}zu",
42514cf0368Sopenharmony_ci        customTyepCfgs.size(), allTypeCfgs.size());
42614cf0368Sopenharmony_ci    auto graph = UtdGraph::GetInstance().ConstructNewGraph(allTypeCfgs);
42714cf0368Sopenharmony_ci    std::unique_lock<std::shared_mutex> lock(utdMutex_);
42814cf0368Sopenharmony_ci    UtdGraph::GetInstance().Update(std::move(graph));
42914cf0368Sopenharmony_ci    descriptorCfgs_ = allTypeCfgs;
43014cf0368Sopenharmony_ci}
43114cf0368Sopenharmony_ci} // namespace UDMF
43214cf0368Sopenharmony_ci} // namespace OHOS
433