1686862fbSopenharmony_ci/*
2686862fbSopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
3686862fbSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4686862fbSopenharmony_ci * you may not use this file except in compliance with the License.
5686862fbSopenharmony_ci * You may obtain a copy of the License at
6686862fbSopenharmony_ci *
7686862fbSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8686862fbSopenharmony_ci *
9686862fbSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10686862fbSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11686862fbSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12686862fbSopenharmony_ci * See the License for the specific language governing permissions and
13686862fbSopenharmony_ci * limitations under the License.
14686862fbSopenharmony_ci */
15686862fbSopenharmony_ci
16686862fbSopenharmony_ci#include "dms_version_manager.h"
17686862fbSopenharmony_ci
18686862fbSopenharmony_ci#include "distributed_device_profile_client.h"
19686862fbSopenharmony_ci#include "dms_constant.h"
20686862fbSopenharmony_ci#include "dtbschedmgr_device_info_storage.h"
21686862fbSopenharmony_ci#include "dtbschedmgr_log.h"
22686862fbSopenharmony_ci#include "nlohmann/json.hpp"
23686862fbSopenharmony_ci#include "string_ex.h"
24686862fbSopenharmony_ci
25686862fbSopenharmony_cinamespace OHOS {
26686862fbSopenharmony_cinamespace DistributedSchedule {
27686862fbSopenharmony_ci
28686862fbSopenharmony_ciusing namespace Constants;
29686862fbSopenharmony_ci
30686862fbSopenharmony_cinamespace {
31686862fbSopenharmony_ciconst std::string TAG = "DmsVersionManager";
32686862fbSopenharmony_ciconst int32_t DMS_VERSION_LENGTH = 3;
33686862fbSopenharmony_ciconst int32_t DMS_MAJOR_VERSION_INDEX = 0;
34686862fbSopenharmony_ciconst int32_t DMS_MINOR_VERSION_INDEX = 1;
35686862fbSopenharmony_ciconst int32_t DMS_FEATURE_VERSION_INDEX = 2;
36686862fbSopenharmony_ci}
37686862fbSopenharmony_ci
38686862fbSopenharmony_cibool DmsVersionManager::IsRemoteDmsVersionLower(const std::string& remoteDeviceId,
39686862fbSopenharmony_ci    const DmsVersion& thresholdDmsVersion)
40686862fbSopenharmony_ci{
41686862fbSopenharmony_ci    DmsVersion dmsVersion;
42686862fbSopenharmony_ci    int32_t result = GetRemoteDmsVersion(remoteDeviceId, dmsVersion);
43686862fbSopenharmony_ci    if (result != ERR_OK) {
44686862fbSopenharmony_ci        return false;
45686862fbSopenharmony_ci    }
46686862fbSopenharmony_ci    return CompareDmsVersion(dmsVersion, thresholdDmsVersion);
47686862fbSopenharmony_ci}
48686862fbSopenharmony_ci
49686862fbSopenharmony_ciint32_t DmsVersionManager::GetRemoteDmsVersion(const std::string& deviceId, DmsVersion& dmsVersion)
50686862fbSopenharmony_ci{
51686862fbSopenharmony_ci    std::string appInfoJsonData;
52686862fbSopenharmony_ci    int32_t result = GetAppInfoFromDP(deviceId, appInfoJsonData);
53686862fbSopenharmony_ci    if (result != ERR_OK) {
54686862fbSopenharmony_ci        HILOGI("get app info failed, result: %{public}d!", result);
55686862fbSopenharmony_ci        return result;
56686862fbSopenharmony_ci    }
57686862fbSopenharmony_ci    std::string packageNamesData;
58686862fbSopenharmony_ci    std::string versionsData;
59686862fbSopenharmony_ci    result = ParseAppInfo(appInfoJsonData, packageNamesData, versionsData);
60686862fbSopenharmony_ci    if (result != ERR_OK) {
61686862fbSopenharmony_ci        HILOGI("parse app info failed");
62686862fbSopenharmony_ci        return result;
63686862fbSopenharmony_ci    }
64686862fbSopenharmony_ci
65686862fbSopenharmony_ci    std::string dmsVersionData;
66686862fbSopenharmony_ci    result = GetDmsVersionDataFromAppInfo(packageNamesData, versionsData, dmsVersionData);
67686862fbSopenharmony_ci    if (result != ERR_OK) {
68686862fbSopenharmony_ci        HILOGW("get dms version data failed, result: %{public}d!", result);
69686862fbSopenharmony_ci        return result;
70686862fbSopenharmony_ci    }
71686862fbSopenharmony_ci    if (!ParseDmsVersion(dmsVersionData, dmsVersion)) {
72686862fbSopenharmony_ci        HILOGE("parse dms version failed");
73686862fbSopenharmony_ci        return DMS_VERSION_PARSE_EXCEPTION;
74686862fbSopenharmony_ci    }
75686862fbSopenharmony_ci    return ERR_OK;
76686862fbSopenharmony_ci}
77686862fbSopenharmony_ci
78686862fbSopenharmony_ciint32_t DmsVersionManager::GetAppInfoFromDP(const std::string& deviceId, std::string& appInfoJsonData)
79686862fbSopenharmony_ci{
80686862fbSopenharmony_ci    DistributedDeviceProfile::CharacteristicProfile profile;
81686862fbSopenharmony_ci    std::string udid = "";
82686862fbSopenharmony_ci    udid = DtbschedmgrDeviceInfoStorage::GetInstance().GetUdidByNetworkId(deviceId);
83686862fbSopenharmony_ci    int32_t result = DistributedDeviceProfile::DistributedDeviceProfileClient::GetInstance().GetCharacteristicProfile(
84686862fbSopenharmony_ci        udid, DMS_SERVICE_ID, DMS_CHAR_ID, profile);
85686862fbSopenharmony_ci    if (result != ERR_OK) {
86686862fbSopenharmony_ci        return result;
87686862fbSopenharmony_ci    }
88686862fbSopenharmony_ci    appInfoJsonData = profile.GetCharacteristicValue();
89686862fbSopenharmony_ci    return ERR_OK;
90686862fbSopenharmony_ci}
91686862fbSopenharmony_ci
92686862fbSopenharmony_ciint32_t DmsVersionManager::ParseAppInfo(const std::string& appInfoJsonData, std::string& packageNamesData,
93686862fbSopenharmony_ci    std::string& versionsData)
94686862fbSopenharmony_ci{
95686862fbSopenharmony_ci    if (appInfoJsonData.empty()) {
96686862fbSopenharmony_ci        return DMS_VERSION_EMPTY;
97686862fbSopenharmony_ci    }
98686862fbSopenharmony_ci    nlohmann::json appInfoJson = nlohmann::json::parse(appInfoJsonData.c_str(), nullptr, false);
99686862fbSopenharmony_ci    if (appInfoJson.is_discarded()) {
100686862fbSopenharmony_ci        return DMS_VERSION_EMPTY;
101686862fbSopenharmony_ci    }
102686862fbSopenharmony_ci    if (appInfoJson.find(PACKAGE_NAMES) == appInfoJson.end() || !appInfoJson.at(PACKAGE_NAMES).is_string()) {
103686862fbSopenharmony_ci        return DMS_VERSION_EMPTY;
104686862fbSopenharmony_ci    }
105686862fbSopenharmony_ci    appInfoJson.at(PACKAGE_NAMES).get_to(packageNamesData);
106686862fbSopenharmony_ci
107686862fbSopenharmony_ci    if (appInfoJson.find(VERSIONS) == appInfoJson.end() || !appInfoJson.at(VERSIONS).is_string()) {
108686862fbSopenharmony_ci        return DMS_VERSION_EMPTY;
109686862fbSopenharmony_ci    }
110686862fbSopenharmony_ci    appInfoJson.at(VERSIONS).get_to(versionsData);
111686862fbSopenharmony_ci
112686862fbSopenharmony_ci    return ERR_OK;
113686862fbSopenharmony_ci}
114686862fbSopenharmony_ci
115686862fbSopenharmony_ciint32_t DmsVersionManager::GetDmsVersionDataFromAppInfo(const std::string& packageNamesData,
116686862fbSopenharmony_ci    const std::string& versionsData, std::string& dmsVersionData)
117686862fbSopenharmony_ci{
118686862fbSopenharmony_ci    if (packageNamesData.empty() || versionsData.empty()) {
119686862fbSopenharmony_ci        return DMS_VERSION_EMPTY;
120686862fbSopenharmony_ci    }
121686862fbSopenharmony_ci    std::vector<std::string> packageNameList;
122686862fbSopenharmony_ci    std::vector<std::string> versionsList;
123686862fbSopenharmony_ci    SplitStr(packageNamesData, ",", packageNameList);
124686862fbSopenharmony_ci    SplitStr(versionsData, ",", versionsList);
125686862fbSopenharmony_ci    if (packageNameList.size() != versionsList.size()) {
126686862fbSopenharmony_ci        return DMS_VERSION_PARSE_EXCEPTION;
127686862fbSopenharmony_ci    }
128686862fbSopenharmony_ci    for (std::size_t i = 0; i < packageNameList.size(); i++) {
129686862fbSopenharmony_ci        if (packageNameList[i] == DMS_NAME) {
130686862fbSopenharmony_ci            dmsVersionData = versionsList[i];
131686862fbSopenharmony_ci            return ERR_OK;
132686862fbSopenharmony_ci        }
133686862fbSopenharmony_ci    }
134686862fbSopenharmony_ci    return DMS_VERSION_EMPTY;
135686862fbSopenharmony_ci}
136686862fbSopenharmony_ci
137686862fbSopenharmony_cibool DmsVersionManager::ParseDmsVersion(const std::string& dmsVersionData, DmsVersion& dmsVersion)
138686862fbSopenharmony_ci{
139686862fbSopenharmony_ci    std::vector<std::string> versionNumList;
140686862fbSopenharmony_ci    SplitStr(dmsVersionData, ".", versionNumList);
141686862fbSopenharmony_ci    if (versionNumList.size() != DMS_VERSION_LENGTH) {
142686862fbSopenharmony_ci        return false;
143686862fbSopenharmony_ci    }
144686862fbSopenharmony_ci    int32_t majorVersionNum = -1;
145686862fbSopenharmony_ci    if (!OHOS::StrToInt(versionNumList[DMS_MAJOR_VERSION_INDEX], majorVersionNum) || majorVersionNum < 0) {
146686862fbSopenharmony_ci        return false;
147686862fbSopenharmony_ci    }
148686862fbSopenharmony_ci    dmsVersion.majorVersionNum = static_cast<uint32_t>(majorVersionNum);
149686862fbSopenharmony_ci
150686862fbSopenharmony_ci    int32_t minorVersionNum = -1;
151686862fbSopenharmony_ci    if (!OHOS::StrToInt(versionNumList[DMS_MINOR_VERSION_INDEX], minorVersionNum) || minorVersionNum < 0) {
152686862fbSopenharmony_ci        return false;
153686862fbSopenharmony_ci    }
154686862fbSopenharmony_ci    dmsVersion.minorVersionNum = static_cast<uint32_t>(minorVersionNum);
155686862fbSopenharmony_ci
156686862fbSopenharmony_ci    int32_t featureVersionNum = -1;
157686862fbSopenharmony_ci    if (!OHOS::StrToInt(versionNumList[DMS_FEATURE_VERSION_INDEX], featureVersionNum) || featureVersionNum < 0) {
158686862fbSopenharmony_ci        return false;
159686862fbSopenharmony_ci    }
160686862fbSopenharmony_ci    dmsVersion.featureVersionNum = static_cast<uint32_t>(featureVersionNum);
161686862fbSopenharmony_ci    return true;
162686862fbSopenharmony_ci}
163686862fbSopenharmony_ci
164686862fbSopenharmony_cibool DmsVersionManager::CompareDmsVersion(const DmsVersion& dmsVersion, const DmsVersion& thresholdDmsVersion)
165686862fbSopenharmony_ci{
166686862fbSopenharmony_ci    if (dmsVersion.majorVersionNum < thresholdDmsVersion.majorVersionNum) {
167686862fbSopenharmony_ci        return true;
168686862fbSopenharmony_ci    }
169686862fbSopenharmony_ci    if (dmsVersion.majorVersionNum == thresholdDmsVersion.majorVersionNum &&
170686862fbSopenharmony_ci        dmsVersion.minorVersionNum < thresholdDmsVersion.minorVersionNum) {
171686862fbSopenharmony_ci        return true;
172686862fbSopenharmony_ci    }
173686862fbSopenharmony_ci    if (dmsVersion.majorVersionNum == thresholdDmsVersion.majorVersionNum &&
174686862fbSopenharmony_ci        dmsVersion.minorVersionNum == thresholdDmsVersion.minorVersionNum &&
175686862fbSopenharmony_ci        dmsVersion.featureVersionNum < thresholdDmsVersion.featureVersionNum) {
176686862fbSopenharmony_ci        return true;
177686862fbSopenharmony_ci    }
178686862fbSopenharmony_ci    return false;
179686862fbSopenharmony_ci}
180686862fbSopenharmony_ci} // namespace DistributedSchedule
181686862fbSopenharmony_ci} // namespace OHOS
182