1 /*
2  * Copyright (c) 2023-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 "dialog_session_info.h"
17 
18 #include "hilog_tag_wrapper.h"
19 #include "parcel_macro.h"
20 
21 namespace OHOS {
22 namespace AAFwk {
23 constexpr int32_t CYCLE_LIMIT = 1000;
24 constexpr size_t MEMBER_NUM = 11;
25 
GetURI() const26 std::string DialogAbilityInfo::GetURI() const
27 {
28     return bundleName + "/" + moduleName + "/" + abilityName + "/" +
29         std::to_string(bundleIconId) + "/" + std::to_string(bundleLabelId) + "/" +
30         std::to_string(abilityIconId) + "/" + std::to_string(abilityLabelId) + "/" +
31         std::to_string(visible) + "/" + std::to_string(appIndex) + "/" +
32         std::to_string(static_cast<int32_t>(multiAppMode.multiAppModeType)) + "/" +
33         std::to_string(multiAppMode.maxCount);
34 }
35 
ParseURI(const std::string & uri)36 bool DialogAbilityInfo::ParseURI(const std::string &uri)
37 {
38     if (std::count(uri.begin(), uri.end(), '/') != MEMBER_NUM - 1) {
39         TAG_LOGE(AAFwkTag::DIALOG, "Invalid uri: %{public}s", uri.c_str());
40         return false;
41     }
42 
43     std::vector<std::string> uriVec;
44     Split(uri, "/", uriVec);
45     uriVec.resize(MEMBER_NUM);
46 
47     int index = 0;
48     bundleName = uriVec[index++];
49     moduleName = uriVec[index++];
50     abilityName = uriVec[index++];
51     bundleIconId = static_cast<int32_t>(std::stoi(uriVec[index++]));
52     bundleLabelId = static_cast<int32_t>(std::stoi(uriVec[index++]));
53     abilityIconId = static_cast<int32_t>(std::stoi(uriVec[index++]));
54     abilityLabelId = static_cast<int32_t>(std::stoi(uriVec[index++]));
55     visible = std::stoi(uriVec[index++]);
56     appIndex = static_cast<int32_t>(std::stoi(uriVec[index++]));
57     multiAppMode.multiAppModeType = static_cast<AppExecFwk::MultiAppModeType>(std::stoi(uriVec[index++]));
58     multiAppMode.maxCount = static_cast<int32_t>(std::stoi(uriVec[index++]));
59     return true;
60 }
61 
Split(const std::string & str,const std::string & delim,std::vector<std::string> & vec)62 void DialogAbilityInfo::Split(const std::string &str, const std::string &delim, std::vector<std::string> &vec)
63 {
64     std::string::size_type posLeft = 0;
65     std::string::size_type posRight = str.find(delim);
66     while (std::string::npos != posRight) {
67         vec.push_back(str.substr(posLeft, posRight - posLeft));
68         posLeft = posRight + delim.size();
69         posRight = str.find(delim, posLeft);
70     }
71     if (posLeft != str.size()) {
72         vec.push_back(str.substr(posLeft));
73     }
74 }
75 
ReadFromParcel(Parcel & parcel)76 bool DialogSessionInfo::ReadFromParcel(Parcel &parcel)
77 {
78     std::string callerAbilityInfoUri = Str16ToStr8(parcel.ReadString16());
79     if (!callerAbilityInfo.ParseURI(callerAbilityInfoUri)) {
80         TAG_LOGE(AAFwkTag::DIALOG, "parse callerAbilityInfo failed");
81         return false;
82     }
83     int32_t targetAbilityInfoSize = 0;
84     READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, targetAbilityInfoSize);
85     CONTAINER_SECURITY_VERIFY(parcel, targetAbilityInfoSize, &targetAbilityInfos);
86     if (targetAbilityInfoSize > CYCLE_LIMIT) {
87         TAG_LOGE(AAFwkTag::DIALOG, "size too large");
88         return false;
89     }
90     for (auto i = 0; i < targetAbilityInfoSize; i++) {
91         std::string targetAbilityInfoUri = Str16ToStr8(parcel.ReadString16());
92         DialogAbilityInfo targetAbilityInfo;
93         if (!targetAbilityInfo.ParseURI(targetAbilityInfoUri)) {
94             TAG_LOGE(AAFwkTag::DIALOG, "parse targetAbilityInfo failed");
95             return false;
96         }
97         targetAbilityInfos.emplace_back(targetAbilityInfo);
98     }
99     std::unique_ptr<AAFwk::WantParams> params(parcel.ReadParcelable<AAFwk::WantParams>());
100     if (!params) {
101         APP_LOGE("ReadParcelable WantParams failed");
102         return false;
103     }
104     parameters = *params;
105     return true;
106 }
107 
Marshalling(Parcel & parcel) const108 bool DialogSessionInfo::Marshalling(Parcel &parcel) const
109 {
110     std::string callerAbilityInfoUri = callerAbilityInfo.GetURI();
111     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(callerAbilityInfoUri));
112 
113     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, targetAbilityInfos.size());
114     for (const auto &targetAbilityInfo : targetAbilityInfos) {
115         std::string targetAbilityInfoUri = targetAbilityInfo.GetURI();
116         WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(targetAbilityInfoUri));
117     }
118     WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Parcelable, parcel, &parameters);
119     return true;
120 }
121 
Unmarshalling(Parcel & parcel)122 DialogSessionInfo *DialogSessionInfo::Unmarshalling(Parcel &parcel)
123 {
124     DialogSessionInfo *info = new (std::nothrow) DialogSessionInfo();
125     if (info && !info->ReadFromParcel(parcel)) {
126         TAG_LOGE(AAFwkTag::DIALOG, "read from parcel failed");
127         delete info;
128         info = nullptr;
129     }
130     return info;
131 }
132 }  // namespace AAFwk
133 }  // namespace OHOS
134