1/*
2 * Copyright (c) 2022 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 "json_utils.h"
17#include "avsession_log.h"
18#include "av_session.h"
19
20namespace OHOS::AVSession {
21int32_t JsonUtils::ConvertSessionType(const std::string& typeString)
22{
23    int32_t type =  AVSession::SESSION_TYPE_INVALID;
24    if (typeString == "audio") {
25        type = AVSession::SESSION_TYPE_AUDIO;
26    } else if (typeString == "video") {
27        type = AVSession::SESSION_TYPE_VIDEO;
28    }
29    return type;
30}
31
32std::string JsonUtils::ConvertSessionType(int32_t type)
33{
34    if (type == AVSession::SESSION_TYPE_AUDIO) {
35        return "audio";
36    } else if (type == AVSession::SESSION_TYPE_VIDEO) {
37        return "video";
38    } else {
39        return "";
40    }
41}
42
43int32_t JsonUtils::JsonToVector(json object, std::vector<int32_t>& out)
44{
45    CHECK_AND_RETURN_RET_LOG(!object.is_null(), AVSESSION_ERROR, "json object is null");
46    CHECK_AND_RETURN_RET_LOG(object.is_array(), AVSESSION_ERROR, "json object is not array");
47    for (json::iterator it = object.begin(); it != object.end(); ++it) {
48        out.push_back(it.value());
49    }
50    return AVSESSION_SUCCESS;
51}
52
53int32_t JsonUtils::GetJsonCapability(const std::vector<std::vector<int32_t>>& capability, std::string& jsonCapability)
54{
55    json jsonObject;
56    for (uint32_t i = 0; i < capability.size(); i++) {
57        if (i == SESSION_DATA_META) {
58            jsonObject["metaData"] = capability[i];
59            continue;
60        }
61        if (i == SESSION_DATA_PLAYBACK_STATE) {
62            jsonObject["playbackState"] = capability[i];
63            continue;
64        }
65        if (i == SESSION_DATA_CONTROL_COMMAND) {
66            jsonObject["controlCommand"] = capability[i];
67            continue;
68        }
69    }
70    jsonCapability = jsonObject.dump();
71    return AVSESSION_SUCCESS;
72}
73
74bool JsonUtils::IsInt32(const json& jsonObj, const std::string& key)
75{
76    bool res = jsonObj.contains(key) && jsonObj[key].is_number_integer()
77        && INT32_MIN <= jsonObj[key] && jsonObj[key] <= INT32_MAX;
78    if (!res) {
79        SLOGE("The key %{public}s of jsonObj is invalid", key.c_str());
80    }
81    return res;
82}
83
84bool JsonUtils::IsString(const json& jsonObj, const std::string& key)
85{
86    bool res = jsonObj.contains(key) && jsonObj[key].is_string();
87    if (!res) {
88        SLOGE("The key %{public}s of jsonObj is invalid", key.c_str());
89    }
90    return res;
91}
92
93bool JsonUtils::IsBool(const json& jsonObj, const std::string& key)
94{
95    bool res = jsonObj.contains(key) && jsonObj[key].is_boolean();
96    if (!res) {
97        SLOGE("The key %{public}s of jsonObj is invalid", key.c_str());
98    }
99    return res;
100}
101
102int32_t JsonUtils::GetVectorCapability(const std::string& jsonCapability,
103                                       std::vector<std::vector<int32_t>>& vectorCapability)
104{
105    CHECK_AND_RETURN_RET_LOG(!jsonCapability.empty(), AVSESSION_ERROR, "jsonCapability is empty");
106    json jsonObj = json::parse(jsonCapability, nullptr, false);
107    CHECK_AND_RETURN_RET_LOG(!jsonObj.is_discarded() && !jsonObj.is_null(), AVSESSION_ERROR, "json object is null");
108    int32_t ret = JsonToVector(jsonObj["metaData"], vectorCapability[SESSION_DATA_META]);
109    CHECK_AND_CONTINUE_LOG(ret == AVSESSION_SUCCESS, "Get metaDataCapability error");
110    ret = JsonToVector(jsonObj["playbackState"], vectorCapability[SESSION_DATA_PLAYBACK_STATE]);
111    CHECK_AND_CONTINUE_LOG(ret == AVSESSION_SUCCESS, "Get playbackStateCapability error");
112    ret = JsonToVector(jsonObj["controlCommand"], vectorCapability[SESSION_DATA_CONTROL_COMMAND]);
113    CHECK_AND_CONTINUE_LOG(ret == AVSESSION_SUCCESS, "Get controlCommandCapability error");
114    return AVSESSION_SUCCESS;
115}
116
117int32_t JsonUtils::GetAllCapability(const std::string& sessionInfo, std::string& jsonCapability)
118{
119    CHECK_AND_RETURN_RET_LOG(!sessionInfo.empty(), AVSESSION_ERROR, "sessionInfo is empty");
120    json jsonSessionInfo = json::parse(sessionInfo, nullptr, false);
121    CHECK_AND_RETURN_RET_LOG(!jsonSessionInfo.is_discarded() && !jsonSessionInfo.is_null(), AVSESSION_ERROR,
122        "json object is null");
123    CHECK_AND_RETURN_RET_LOG(jsonSessionInfo.contains("compatibility"), AVSESSION_ERROR,
124        "The key of jsonObj is invalid");
125    json compatibility = jsonSessionInfo["compatibility"];
126    CHECK_AND_RETURN_RET_LOG(!compatibility.is_null(), AVSESSION_ERROR, "Getcompatibility error");
127    CHECK_AND_RETURN_RET_LOG(compatibility.contains("capabilitySet"), AVSESSION_ERROR,
128        "The key of compatibility is invalid");
129    json capabilitySet = compatibility["capabilitySet"];
130    CHECK_AND_RETURN_RET_LOG(!capabilitySet.is_null(), AVSESSION_ERROR, "GetCapabilitySet error");
131    jsonCapability = capabilitySet.dump();
132    return AVSESSION_SUCCESS;
133}
134
135int32_t JsonUtils::SetSessionBasicInfo(std::string& sessionInfo, const AVSessionBasicInfo& basicInfo)
136{
137    json jsonObj;
138    if (sessionInfo.empty()) {
139        jsonObj = json::parse(R"({})", nullptr, false);
140        CHECK_AND_RETURN_RET_LOG(!jsonObj.is_discarded() && !jsonObj.is_null(), AVSESSION_ERROR, "json object is null");
141    } else {
142        jsonObj = json::parse(sessionInfo, nullptr, false);
143        CHECK_AND_RETURN_RET_LOG(!jsonObj.is_discarded() && !jsonObj.is_null(), AVSESSION_ERROR, "json object is null");
144    }
145    jsonObj["compatibility"]["networkId"] = basicInfo.networkId_;
146    jsonObj["compatibility"]["vendorId"] = basicInfo.vendorId_;
147    jsonObj["compatibility"]["deviceType"] = basicInfo.deviceType_;
148    jsonObj["compatibility"]["systemVersion"] = basicInfo.systemVersion_;
149    jsonObj["compatibility"]["avsessionVersion"] = basicInfo.sessionVersion_;
150    jsonObj["compatibility"]["reserve"] = basicInfo.reserve_;
151    jsonObj["compatibility"]["features"] = basicInfo.feature_;
152    jsonObj["compatibility"]["capabilitySet"]["metaData"] = basicInfo.metaDataCap_;
153    jsonObj["compatibility"]["capabilitySet"]["playbackState"] = basicInfo.playBackStateCap_;
154    jsonObj["compatibility"]["capabilitySet"]["controlCommand"] = basicInfo.controlCommandCap_;
155    jsonObj["compatibility"]["extendCapability"] = basicInfo.extendCapability_;
156    jsonObj["data"]["systemTime"] = basicInfo.systemTime_;
157    jsonObj["data"]["extend"] = basicInfo.extend_;
158    CHECK_AND_RETURN_RET_LOG(!jsonObj.empty(), AVSESSION_ERROR, "SetBasicInfo error");
159    sessionInfo = jsonObj.dump();
160    return AVSESSION_SUCCESS;
161}
162
163int32_t JsonUtils::GetSessionBasicInfo(const std::string& sessionInfo, AVSessionBasicInfo& basicInfo)
164{
165    CHECK_AND_RETURN_RET_LOG(!sessionInfo.empty(), AVSESSION_ERROR, "sessionInfo is empty");
166    json jsonObj = json::parse(sessionInfo, nullptr, false);
167    CHECK_AND_RETURN_RET_LOG(!jsonObj.is_discarded() && !jsonObj.is_null(), AVSESSION_ERROR, "json object is null");
168    CHECK_AND_RETURN_RET_LOG(jsonObj.contains("compatibility") && jsonObj.contains("data"), AVSESSION_ERROR,
169        "The key of jsonObj is invalid");
170    json compatibility = jsonObj["compatibility"];
171    CHECK_AND_RETURN_RET_LOG(!compatibility.empty(), AVSESSION_ERROR, "Getcompatibility error");
172    CHECK_AND_RETURN_RET_LOG(IsString(compatibility, "networkId") && IsString(compatibility, "vendorId")
173        && IsString(compatibility, "deviceType") && IsString(compatibility, "systemVersion")
174        && IsInt32(compatibility, "avsessionVersion") && IsInt32(jsonObj["data"], "systemTime")
175        && compatibility.contains("reserve") && compatibility.contains("features")
176        && compatibility.contains("extendCapability"), AVSESSION_ERROR,
177        "The key of jsonObj is invalid");
178    basicInfo.networkId_ = compatibility["networkId"];
179    basicInfo.vendorId_ = compatibility["vendorId"];
180    basicInfo.deviceType_ = compatibility["deviceType"];
181    basicInfo.systemVersion_ = compatibility["systemVersion"];
182    basicInfo.sessionVersion_ = compatibility["avsessionVersion"];
183    int32_t ret = JsonToVector(compatibility["reserve"], basicInfo.reserve_);
184    CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, AVSESSION_ERROR, "Get reserve error");
185    ret = JsonToVector(compatibility["features"], basicInfo.feature_);
186    CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, AVSESSION_ERROR, "Get feature error");
187    CHECK_AND_RETURN_RET_LOG(compatibility.contains("capabilitySet"), AVSESSION_ERROR,
188        "The key of jsonObj is invalid");
189    json capabilitySet = compatibility["capabilitySet"];
190    CHECK_AND_RETURN_RET_LOG(!capabilitySet.empty(), AVSESSION_ERROR, "GetCapabilitySet error");
191    CHECK_AND_RETURN_RET_LOG(capabilitySet.contains("metaData") && capabilitySet.contains("playbackState")
192        && capabilitySet.contains("controlCommand"), AVSESSION_ERROR, "The key of jsonObj is invalid");
193    ret = JsonToVector(capabilitySet["metaData"], basicInfo.metaDataCap_);
194    CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, AVSESSION_ERROR, "Get metaData error");
195    ret = JsonToVector(capabilitySet["playbackState"], basicInfo.playBackStateCap_);
196    CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, AVSESSION_ERROR, "Get playbackState error");
197    ret = JsonToVector(capabilitySet["controlCommand"], basicInfo.controlCommandCap_);
198    CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, AVSESSION_ERROR, "Get controlCommand error");
199    ret = JsonToVector(compatibility["extendCapability"], basicInfo.extendCapability_);
200    CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, AVSESSION_ERROR, "Get extendCapability error");
201    basicInfo.systemTime_ = jsonObj["data"]["systemTime"];
202    ret = JsonToVector(jsonObj["data"]["extend"], basicInfo.extend_);
203    CHECK_AND_RETURN_RET_LOG(ret == AVSESSION_SUCCESS, AVSESSION_ERROR, "Get data extend error");
204    return AVSESSION_SUCCESS;
205}
206
207int32_t JsonUtils::SetSessionDescriptors(std::string& sessionInfo, const std::vector<AVSessionDescriptor>& descriptors)
208{
209    json jsonObj;
210    if (sessionInfo.empty()) {
211        jsonObj = json::parse(R"({})", nullptr, false);
212        CHECK_AND_RETURN_RET_LOG(!jsonObj.is_discarded() && !jsonObj.is_null(), AVSESSION_ERROR, "json object is null");
213    } else {
214        jsonObj = json::parse(sessionInfo, nullptr, false);
215        CHECK_AND_RETURN_RET_LOG(!jsonObj.is_discarded() && !jsonObj.is_null(), AVSESSION_ERROR, "json object is null");
216    }
217    for (uint32_t i = 0; i < descriptors.size(); i++) {
218        jsonObj["data"]["sessionDescriptors"][i]["sessionId"] = descriptors[i].sessionId_;
219        jsonObj["data"]["sessionDescriptors"][i]["type"] = ConvertSessionType(descriptors[i].sessionType_);
220        jsonObj["data"]["sessionDescriptors"][i]["bundleName"] = descriptors[i].elementName_.GetBundleName();
221        jsonObj["data"]["sessionDescriptors"][i]["abilityName"] = descriptors[i].elementName_.GetAbilityName();
222        jsonObj["data"]["sessionDescriptors"][i]["tag"] = descriptors[i].sessionTag_;
223        jsonObj["data"]["sessionDescriptors"][i]["isThirdPartyApp"] = descriptors[i].isThirdPartyApp_;
224    }
225    sessionInfo = jsonObj.dump();
226    return AVSESSION_SUCCESS;
227}
228
229int32_t JsonUtils::GetSessionDescriptors(const std::string& sessionInfo, std::vector<AVSessionDescriptor>& descriptors)
230{
231    CHECK_AND_RETURN_RET_LOG(!sessionInfo.empty(), AVSESSION_ERROR, "sessionInfo is empty");
232    json jsonObj = json::parse(sessionInfo, nullptr, false);
233    CHECK_AND_RETURN_RET_LOG(!jsonObj.is_discarded() && !jsonObj.is_null(), AVSESSION_ERROR, "json object is null");
234    CHECK_AND_RETURN_RET_LOG(jsonObj.contains("data"), AVSESSION_ERROR, "json object data is null");
235    CHECK_AND_RETURN_RET_LOG(jsonObj["data"].contains("sessionDescriptors"), AVSESSION_ERROR,
236        "The key of jsonObj is invalid");
237    json sessionDescriptors = jsonObj["data"]["sessionDescriptors"];
238    CHECK_AND_RETURN_RET_LOG(!sessionDescriptors.is_null(), AVSESSION_ERROR, "sessionDescriptors is null");
239    CHECK_AND_RETURN_RET_LOG(sessionDescriptors.is_array(), AVSESSION_ERROR, "json sessionDescriptors is not array");
240    for (json::iterator it = sessionDescriptors.begin(); it != sessionDescriptors.end(); ++it) {
241        CHECK_AND_RETURN_RET_LOG(IsString(it.value(), "sessionId") && IsString(it.value(), "type")
242            && IsString(it.value(), "bundleName") && IsString(it.value(), "abilityName")
243            && IsString(it.value(), "tag") && IsBool(it.value(), "isThirdPartyApp"), AVSESSION_ERROR,
244            "The key of jsonObj is invalid");
245        AVSessionDescriptor descriptor;
246        descriptor.sessionId_ = it.value()["sessionId"];
247        std::string type = it.value()["type"];
248        descriptor.sessionType_ = ConvertSessionType(type);
249        descriptor.elementName_.SetBundleName(it.value()["bundleName"]);
250        descriptor.elementName_.SetAbilityName(it.value()["abilityName"]);
251        descriptor.sessionTag_ = it.value()["tag"];
252        descriptor.isThirdPartyApp_ = it.value()["isThirdPartyApp"];
253        descriptors.push_back(descriptor);
254    }
255    return AVSESSION_SUCCESS;
256}
257
258int32_t JsonUtils::SetSessionDescriptor(std::string& sessionInfo, const AVSessionDescriptor& descriptor)
259{
260    json jsonObj;
261    if (sessionInfo.empty()) {
262        jsonObj = json::parse(R"({})", nullptr, false);
263        CHECK_AND_RETURN_RET_LOG(!jsonObj.is_discarded() && !jsonObj.is_null(), AVSESSION_ERROR, "json object is null");
264    } else {
265        jsonObj = json::parse(sessionInfo, nullptr, false);
266        CHECK_AND_RETURN_RET_LOG(!jsonObj.is_discarded() && !jsonObj.is_null(), AVSESSION_ERROR, "json object is null");
267    }
268    jsonObj["data"]["sessionDescriptor"]["sessionId"] = descriptor.sessionId_;
269    jsonObj["data"]["sessionDescriptor"]["type"] = ConvertSessionType(descriptor.sessionType_);
270    jsonObj["data"]["sessionDescriptor"]["bundleName"] = descriptor.elementName_.GetBundleName();
271    jsonObj["data"]["sessionDescriptor"]["abilityName"] = descriptor.elementName_.GetAbilityName();
272    jsonObj["data"]["sessionDescriptor"]["tag"] = descriptor.sessionTag_;
273    jsonObj["data"]["sessionDescriptor"]["isThirdPartyApp"] = descriptor.isThirdPartyApp_;
274    sessionInfo = jsonObj.dump();
275    return AVSESSION_SUCCESS;
276}
277
278int32_t JsonUtils::GetSessionDescriptor(const std::string& sessionInfo, AVSessionDescriptor& descriptor)
279{
280    CHECK_AND_RETURN_RET_LOG(!sessionInfo.empty(), AVSESSION_ERROR, "sessionInfo is empty");
281    json jsonObj = json::parse(sessionInfo, nullptr, false);
282    CHECK_AND_RETURN_RET_LOG(!jsonObj.is_discarded() && !jsonObj.is_null(), AVSESSION_ERROR, "json object is null");
283    CHECK_AND_RETURN_RET_LOG(jsonObj.contains("data"), AVSESSION_ERROR, "json object data is null");
284    CHECK_AND_RETURN_RET_LOG(jsonObj["data"].contains("sessionDescriptor"), AVSESSION_ERROR,
285        "The key of jsonObj is invalid");
286    json sessionDescriptor = jsonObj["data"]["sessionDescriptor"];
287    CHECK_AND_RETURN_RET_LOG(!sessionDescriptor.is_null(), AVSESSION_ERROR, "sessionDescriptor is null");
288    CHECK_AND_RETURN_RET_LOG(IsString(sessionDescriptor, "sessionId") && IsString(sessionDescriptor, "type")
289        && IsString(sessionDescriptor, "bundleName") && IsString(sessionDescriptor, "abilityName")
290        && IsString(sessionDescriptor, "tag") && IsBool(sessionDescriptor, "isThirdPartyApp"), AVSESSION_ERROR,
291        "The key of jsonObj is invalid");
292
293    descriptor.sessionId_ = sessionDescriptor["sessionId"];
294    std::string type = sessionDescriptor["type"];
295    descriptor.sessionType_ = ConvertSessionType(type);
296    descriptor.elementName_.SetBundleName(sessionDescriptor["bundleName"]);
297    descriptor.elementName_.SetAbilityName(sessionDescriptor["abilityName"]);
298    descriptor.sessionTag_ = sessionDescriptor["tag"];
299    descriptor.isThirdPartyApp_ = sessionDescriptor["isThirdPartyApp"];
300    return AVSESSION_SUCCESS;
301}
302} // namespace OHOS::AVSession
303