• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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