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