1 /*
2 * Copyright (c) 2022-2023 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 "distributed_bms_host.h"
17
18 #include "app_log_wrapper.h"
19 #include "appexecfwk_errors.h"
20 #include "bundle_constants.h"
21 #include "bundle_memory_guard.h"
22 #include "dbms_scope_guard.h"
23 #include "distributed_bundle_ipc_interface_code.h"
24 #include "remote_ability_info.h"
25
26 namespace OHOS {
27 namespace AppExecFwk {
28 namespace {
29 constexpr int32_t GET_REMOTE_ABILITY_INFO_MAX_SIZE = 10;
30 }
31
DistributedBmsHost()32 DistributedBmsHost::DistributedBmsHost()
33 {
34 APP_LOGI("DistributedBmsHost instance is created");
35 }
36
~DistributedBmsHost()37 DistributedBmsHost::~DistributedBmsHost()
38 {
39 APP_LOGI("DistributedBmsHost instance is destroyed");
40 }
41
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)42 int DistributedBmsHost::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
43 {
44 BundleMemoryGuard memoryGuard;
45 APP_LOGI("DistributedBmsHost receives message from client, code = %{public}u, flags = %{public}d", code,
46 option.GetFlags());
47 std::u16string descripter = DistributedBmsHost::GetDescriptor();
48 std::u16string remoteDescripter = data.ReadInterfaceToken();
49 if (descripter != remoteDescripter) {
50 APP_LOGE("verify interface token failed");
51 return ERR_INVALID_STATE;
52 }
53 switch (code) {
54 case static_cast<uint32_t>(DistributedInterfaceCode::GET_REMOTE_ABILITY_INFO):
55 case static_cast<uint32_t>(DistributedInterfaceCode::GET_REMOTE_ABILITY_INFO_WITH_LOCALE):
56 return HandleGetRemoteAbilityInfo(data, reply);
57 case static_cast<uint32_t>(DistributedInterfaceCode::GET_REMOTE_ABILITY_INFOS):
58 case static_cast<uint32_t>(DistributedInterfaceCode::GET_REMOTE_ABILITY_INFOS_WITH_LOCALE):
59 return HandleGetRemoteAbilityInfos(data, reply);
60 case static_cast<uint32_t>(DistributedInterfaceCode::GET_ABILITY_INFO):
61 case static_cast<uint32_t>(DistributedInterfaceCode::GET_ABILITY_INFO_WITH_LOCALE):
62 return HandleGetAbilityInfo(data, reply);
63 case static_cast<uint32_t>(DistributedInterfaceCode::GET_ABILITY_INFOS):
64 case static_cast<uint32_t>(DistributedInterfaceCode::GET_ABILITY_INFOS_WITH_LOCALE):
65 return HandleGetAbilityInfos(data, reply);
66 case static_cast<uint32_t>(DistributedInterfaceCode::GET_DISTRIBUTED_BUNDLE_INFO):
67 return HandleGetDistributedBundleInfo(data, reply);
68 case static_cast<uint32_t>(DistributedInterfaceCode::GET_DISTRIBUTED_BUNDLE_NAME):
69 return HandleGetDistributedBundleName(data, reply);
70 default:
71 APP_LOGW("DistributedBmsHost receives unknown code, code = %{public}d", code);
72 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
73 }
74 return NO_ERROR;
75 }
76
HandleGetRemoteAbilityInfo(Parcel & data,Parcel & reply)77 int DistributedBmsHost::HandleGetRemoteAbilityInfo(Parcel &data, Parcel &reply)
78 {
79 APP_LOGI("DistributedBmsHost handle get remote ability info");
80 std::unique_ptr<ElementName> elementName(data.ReadParcelable<ElementName>());
81 if (!elementName) {
82 APP_LOGE("ReadParcelable<elementName> failed");
83 return ERR_APPEXECFWK_PARCEL_ERROR;
84 }
85 std::string localeInfo = data.ReadString();
86 RemoteAbilityInfo remoteAbilityInfo;
87 int ret = GetRemoteAbilityInfo(*elementName, localeInfo, remoteAbilityInfo);
88 if (ret != NO_ERROR) {
89 APP_LOGE("GetRemoteAbilityInfo result:%{public}d", ret);
90 return ret;
91 }
92 if (!reply.WriteBool(true)) {
93 APP_LOGE("GetRemoteAbilityInfo write failed");
94 return ERR_APPEXECFWK_PARCEL_ERROR;
95 }
96 if (!reply.WriteParcelable(&remoteAbilityInfo)) {
97 APP_LOGE("GetRemoteAbilityInfo write failed");
98 return ERR_APPEXECFWK_PARCEL_ERROR;
99 }
100 return NO_ERROR;
101 }
102
HandleGetRemoteAbilityInfos(Parcel & data,Parcel & reply)103 int DistributedBmsHost::HandleGetRemoteAbilityInfos(Parcel &data, Parcel &reply)
104 {
105 APP_LOGI("DistributedBmsHost handle get remote ability infos");
106 std::vector<ElementName> elementNames;
107 if (!GetParcelableInfos<ElementName>(data, elementNames)) {
108 APP_LOGE("GetRemoteAbilityInfos get parcelable infos failed");
109 return ERR_APPEXECFWK_PARCEL_ERROR;
110 }
111 std::string localeInfo = data.ReadString();
112 std::vector<RemoteAbilityInfo> remoteAbilityInfos;
113 int ret = GetRemoteAbilityInfos(elementNames, localeInfo, remoteAbilityInfos);
114 if (ret != NO_ERROR) {
115 APP_LOGE("GetRemoteAbilityInfos result:%{public}d", ret);
116 return ret;
117 }
118 if (!reply.WriteBool(true)) {
119 APP_LOGE("GetRemoteAbilityInfos write failed");
120 return ERR_APPEXECFWK_PARCEL_ERROR;
121 }
122 if (!WriteParcelableVector<RemoteAbilityInfo>(remoteAbilityInfos, reply)) {
123 APP_LOGE("GetRemoteAbilityInfos write failed");
124 return ERR_APPEXECFWK_PARCEL_ERROR;
125 }
126 return NO_ERROR;
127 }
128
129
HandleGetAbilityInfo(Parcel & data,Parcel & reply)130 int DistributedBmsHost::HandleGetAbilityInfo(Parcel &data, Parcel &reply)
131 {
132 APP_LOGI("DistributedBmsHost handle get ability info");
133 std::unique_ptr<ElementName> elementName(data.ReadParcelable<ElementName>());
134 if (!elementName) {
135 APP_LOGE("ReadParcelable<elementName> failed");
136 return ERR_APPEXECFWK_PARCEL_ERROR;
137 }
138 std::string localeInfo = data.ReadString();
139 bool hasInfo = data.ReadBool();
140 DistributedBmsAclInfo *info = nullptr;
141 DbmsScopeGuard deletePtrGuard([&info] {
142 if (info != nullptr) {
143 delete info;
144 info = nullptr;
145 }
146 });
147 if (hasInfo) {
148 info = data.ReadParcelable<DistributedBmsAclInfo>();
149 if (info == nullptr) {
150 APP_LOGE("HandleGetAbilityInfos get parcelable info failed");
151 return ERR_APPEXECFWK_PARCEL_ERROR;
152 }
153 }
154 RemoteAbilityInfo remoteAbilityInfo;
155 int ret = GetAbilityInfo(*elementName, localeInfo, remoteAbilityInfo, info);
156 if (ret != NO_ERROR) {
157 APP_LOGE("GetAbilityInfo result:%{public}d", ret);
158 return ret;
159 }
160 if (!reply.WriteBool(true)) {
161 APP_LOGE("GetRemoteAbilityInfo write failed");
162 return ERR_APPEXECFWK_PARCEL_ERROR;
163 }
164 if (!reply.WriteParcelable(&remoteAbilityInfo)) {
165 APP_LOGE("GetRemoteAbilityInfo write failed");
166 return ERR_APPEXECFWK_PARCEL_ERROR;
167 }
168 return NO_ERROR;
169 }
170
HandleGetAbilityInfos(Parcel & data,Parcel & reply)171 int DistributedBmsHost::HandleGetAbilityInfos(Parcel &data, Parcel &reply)
172 {
173 APP_LOGI("DistributedBmsHost handle get ability infos");
174 std::vector<ElementName> elementNames;
175 if (!GetParcelableInfos<ElementName>(data, elementNames)) {
176 APP_LOGE("GetRemoteAbilityInfos get parcelable infos failed");
177 return ERR_APPEXECFWK_PARCEL_ERROR;
178 }
179 std::string localeInfo = data.ReadString();
180 bool hasInfo = data.ReadBool();
181 DistributedBmsAclInfo *info = nullptr;
182 DbmsScopeGuard deletePtrGuard([&info] {
183 if (info != nullptr) {
184 delete info;
185 info = nullptr;
186 }
187 });
188 if (hasInfo) {
189 info = data.ReadParcelable<DistributedBmsAclInfo>();
190 if (info == nullptr) {
191 APP_LOGE("HandleGetAbilityInfos get parcelable info failed");
192 return ERR_APPEXECFWK_PARCEL_ERROR;
193 }
194 }
195 std::vector<RemoteAbilityInfo> remoteAbilityInfos;
196 int ret = GetAbilityInfos(elementNames, localeInfo, remoteAbilityInfos, info);
197 if (ret != NO_ERROR) {
198 APP_LOGE("GetAbilityInfos result:%{public}d", ret);
199 return ret;
200 }
201 if (!reply.WriteBool(true)) {
202 APP_LOGE("GetAbilityInfos write failed");
203 return ERR_APPEXECFWK_PARCEL_ERROR;
204 }
205 if (!WriteParcelableVector<RemoteAbilityInfo>(remoteAbilityInfos, reply)) {
206 APP_LOGE("GetAbilityInfos write failed");
207 return ERR_APPEXECFWK_PARCEL_ERROR;
208 }
209 return NO_ERROR;
210 }
211
HandleGetDistributedBundleInfo(Parcel & data,Parcel & reply)212 int DistributedBmsHost::HandleGetDistributedBundleInfo(Parcel &data, Parcel &reply)
213 {
214 APP_LOGI("DistributedBmsHost handle get distributedBundleInfo");
215 std::string networkId = data.ReadString();
216 std::string bundleName = data.ReadString();
217 DistributedBundleInfo distributedBundleInfo;
218 bool ret = GetDistributedBundleInfo(networkId, bundleName, distributedBundleInfo);
219 if (!ret) {
220 APP_LOGE("GetDistributedBundleInfo failed");
221 return INVALID_OPERATION;
222 }
223 if (!reply.WriteBool(true)) {
224 APP_LOGE("GetDistributedBundleInfo write failed");
225 return ERR_APPEXECFWK_PARCEL_ERROR;
226 }
227 if (!reply.WriteParcelable(&distributedBundleInfo)) {
228 APP_LOGE("GetDistributedBundleInfo write failed");
229 return ERR_APPEXECFWK_PARCEL_ERROR;
230 }
231 return NO_ERROR;
232 }
233
HandleGetDistributedBundleName(Parcel & data,Parcel & reply)234 int32_t DistributedBmsHost::HandleGetDistributedBundleName(Parcel &data, Parcel &reply)
235 {
236 APP_LOGD("DistributedBmsHost handle get distributedBundleName");
237 std::string networkId = data.ReadString();
238 uint32_t accessTokenId = data.ReadUint32();
239 std::string bundleName;
240 int32_t ret = GetDistributedBundleName(networkId, accessTokenId, bundleName);
241 if (ret == NO_ERROR && !reply.WriteString(bundleName)) {
242 APP_LOGE("write failed");
243 return ERR_APPEXECFWK_PARCEL_ERROR;
244 }
245 return ret;
246 }
247
248 template<typename T>
WriteParcelableVector(std::vector<T> & parcelableVector,Parcel & reply)249 bool DistributedBmsHost::WriteParcelableVector(std::vector<T> &parcelableVector, Parcel &reply)
250 {
251 if (!reply.WriteInt32(parcelableVector.size())) {
252 APP_LOGE("write ParcelableVector failed");
253 return false;
254 }
255
256 for (auto &parcelable : parcelableVector) {
257 if (!reply.WriteParcelable(&parcelable)) {
258 APP_LOGE("write ParcelableVector failed");
259 return false;
260 }
261 }
262 return true;
263 }
264
265 template<typename T>
GetParcelableInfos(Parcel & data,std::vector<T> & parcelableInfos)266 bool DistributedBmsHost::GetParcelableInfos(Parcel &data, std::vector<T> &parcelableInfos)
267 {
268 int32_t infoSize = data.ReadInt32();
269 if (infoSize > GET_REMOTE_ABILITY_INFO_MAX_SIZE) {
270 APP_LOGE("GetParcelableInfos elements num exceeds the limit %{public}d", GET_REMOTE_ABILITY_INFO_MAX_SIZE);
271 return false;
272 }
273 for (int32_t i = 0; i < infoSize; i++) {
274 std::unique_ptr<T> info(data.ReadParcelable<T>());
275 if (!info) {
276 APP_LOGE("Read Parcelable infos failed");
277 return false;
278 }
279 parcelableInfos.emplace_back(*info);
280 }
281 APP_LOGD("get parcelable infos success");
282 return true;
283 }
284 } // namespace AppExecFwk
285 } // namespace OHOS