• 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 "bundle_distributed_manager.h"
17 
18 #include "bundle_manager_callback.h"
19 #include "bundle_memory_guard.h"
20 #include "bundle_mgr_service.h"
21 #include "syscap_interface.h"
22 
23 #ifdef BMS_DEVICE_INFO_MANAGER_ENABLE
24 #include "distributed_device_profile_client.h"
25 #endif // BMS_DEVICE_INFO_MANAGER_ENABLE
26 
27 namespace OHOS {
28 namespace AppExecFwk {
29 using namespace ffrt;
30 namespace {
31 constexpr int8_t CHECK_ABILITY_ENABLE_INSTALL = 1;
32 constexpr uint16_t OUT_TIME = 3000;
33 constexpr const char* DISTRIBUTED_MANAGER_QUEUE = "DistributedManagerQueue";
34 const std::u16string DMS_BUNDLE_MANAGER_CALLBACK_TOKEN = u"ohos.DistributedSchedule.IDmsBundleManagerCallback";
35 const std::u16string SERVICE_CENTER_TOKEN = u"abilitydispatcherhm.openapi.hapinstall.IHapInstall";
36 // syscap
37 constexpr const char* CHARACTER_OS_SYSCAP = "ossyscap";
38 constexpr const char* CHARACTER_PRIVATE_SYSCAP = "privatesyscap";
39 }
40 
BundleDistributedManager()41 BundleDistributedManager::BundleDistributedManager()
42 {
43     APP_LOGD("create BundleDistributedManager");
44     serialQueue_ = std::make_shared<SerialQueue>(DISTRIBUTED_MANAGER_QUEUE);
45 }
46 
~BundleDistributedManager()47 BundleDistributedManager::~BundleDistributedManager()
48 {
49     APP_LOGD("destroy BundleDistributedManager");
50 }
51 
ConvertTargetAbilityInfo(const Want & want,TargetAbilityInfo & targetAbilityInfo)52 bool BundleDistributedManager::ConvertTargetAbilityInfo(const Want &want, TargetAbilityInfo &targetAbilityInfo)
53 {
54     auto elementName = want.GetElement();
55     std::string bundleName = elementName.GetBundleName();
56     std::string moduleName = elementName.GetModuleName();
57     std::string abilityName = elementName.GetAbilityName();
58     APP_LOGI("ConvertTargetAbilityInfo %{public}s, %{public}s, %{public}s",
59         bundleName.c_str(), moduleName.c_str(), abilityName.c_str());
60     AppExecFwk::TargetInfo targetInfo;
61     targetInfo.transactId = std::to_string(this->GetTransactId());
62     targetInfo.bundleName = bundleName;
63     targetInfo.moduleName = moduleName;
64     targetInfo.abilityName = abilityName;
65     targetAbilityInfo.targetInfo = targetInfo;
66     return true;
67 }
68 
ComparePcIdString(const Want & want,const RpcIdResult & rpcIdResult)69 int32_t BundleDistributedManager::ComparePcIdString(const Want &want, const RpcIdResult &rpcIdResult)
70 {
71 #ifdef BMS_DEVICE_INFO_MANAGER_ENABLE
72     DistributedDeviceProfile::DeviceProfile profile;
73     int32_t result = DistributedDeviceProfile::DistributedDeviceProfileClient::GetInstance().GetDeviceProfile(
74         want.GetElement().GetDeviceID(), profile);
75     if (result != 0) {
76         APP_LOGE("GetDeviceProfile failed %{public}d", result);
77         return ErrorCode::GET_DEVICE_PROFILE_FAILED;
78     }
79     std::string jsonData = profile.GetOsSysCap();
80     APP_LOGI("CharacteristicProfileJson:%{public}s", jsonData.c_str());
81     nlohmann::json jsonObject = nlohmann::json::parse(jsonData, nullptr, false);
82     if (jsonObject.is_discarded()) {
83         APP_LOGE("jsonObject is_discarded");
84         return ErrorCode::DECODE_SYS_CAP_FAILED;
85     }
86     if ((jsonObject.find(CHARACTER_OS_SYSCAP) == jsonObject.end()) ||
87         (jsonObject.find(CHARACTER_PRIVATE_SYSCAP) == jsonObject.end())) {
88         APP_LOGE("ossyscap no exist ");
89         return ErrorCode::DECODE_SYS_CAP_FAILED;
90     }
91     std::vector<int> values = jsonObject[CHARACTER_OS_SYSCAP].get<std::vector<int>>();
92     std::string pcId;
93     for (int value : values) {
94         pcId = pcId + std::to_string(value) + ",";
95     }
96     std::string capabilities = jsonObject[CHARACTER_PRIVATE_SYSCAP];
97     if (capabilities.empty()) {
98         pcId.resize(pcId.length() - 1);
99     } else {
100         pcId = pcId + capabilities;
101     }
102     APP_LOGD("sysCap pcId:%{public}s", pcId.c_str());
103     for (auto &rpcId : rpcIdResult.abilityInfo.rpcId) {
104         APP_LOGD("sysCap rpcId:%{public}s", rpcId.c_str());
105         CompareError compareError = {{0}, 0, 0};
106         int32_t ret = ComparePcidString(pcId.c_str(), rpcId.c_str(), &compareError);
107         if (ret != 0) {
108             APP_LOGE("ComparePcIdString failed err %{public}d", ret);
109             return ErrorCode::COMPARE_PC_ID_FAILED;
110         }
111     }
112     return ErrorCode::NO_ERROR;
113 #else
114     APP_LOGW("BMS_DEVICE_INFO_MANAGER_ENABLE is false");
115     return ErrorCode::ERR_BMS_DEVICE_INFO_MANAGER_ENABLE_DISABLED;
116 #endif
117 }
118 
CheckAbilityEnableInstall(const Want & want,int32_t missionId,int32_t userId,const sptr<IRemoteObject> & callback)119 bool BundleDistributedManager::CheckAbilityEnableInstall(
120     const Want &want, int32_t missionId, int32_t userId, const sptr<IRemoteObject> &callback)
121 {
122     APP_LOGI("BundleDistributedManager::CheckAbilityEnableInstall");
123     AppExecFwk::TargetAbilityInfo targetAbilityInfo;
124     if (!ConvertTargetAbilityInfo(want, targetAbilityInfo)) {
125         return false;
126     }
127     auto dataMgr = DelayedSingleton<BundleMgrService>::GetInstance()->GetDataMgr();
128     if (dataMgr == nullptr) {
129         APP_LOGE("fail to get data mgr");
130         return false;
131     }
132     ApplicationInfo applicationInfo;
133     if (!dataMgr->GetApplicationInfo(
134         targetAbilityInfo.targetInfo.bundleName, 0, userId, applicationInfo)) {
135         APP_LOGE("fail get bundleName %{public}s", targetAbilityInfo.targetInfo.bundleName.c_str());
136         return false;
137     }
138     sptr<QueryRpcIdParams> queryRpcIdParams = new(std::nothrow) QueryRpcIdParams();
139     if (queryRpcIdParams == nullptr) {
140         APP_LOGE("queryRpcIdParams is nullptr");
141         return false;
142     }
143     queryRpcIdParams->missionId = missionId;
144     queryRpcIdParams->callback = callback;
145     queryRpcIdParams->want = want;
146     queryRpcIdParams->versionCode = applicationInfo.versionCode;
147     {
148         std::unique_lock<ffrt::shared_mutex> lock(mutex_);
149         auto ret = queryAbilityParamsMap_.emplace(targetAbilityInfo.targetInfo.transactId, *queryRpcIdParams);
150         if (!ret.second) {
151             APP_LOGE("BundleDistributedManager::QueryAbilityInfo map emplace error");
152             return false;
153         }
154     }
155     auto queryRpcIdByAbilityFunc = [this, targetAbilityInfo]() {
156         BundleMemoryGuard memoryGuard;
157         auto res = this->QueryRpcIdByAbilityToServiceCenter(targetAbilityInfo);
158         if (!res) {
159             SendCallbackRequest(ErrorCode::WAITING_TIMEOUT, targetAbilityInfo.targetInfo.transactId);
160         }
161     };
162     ffrt::submit(queryRpcIdByAbilityFunc);
163     return true;
164 }
165 
QueryRpcIdByAbilityToServiceCenter(const TargetAbilityInfo & targetAbilityInfo)166 bool BundleDistributedManager::QueryRpcIdByAbilityToServiceCenter(const TargetAbilityInfo &targetAbilityInfo)
167 {
168     APP_LOGI("QueryRpcIdByAbilityToServiceCenter");
169     auto connectAbility = DelayedSingleton<BundleMgrService>::GetInstance()->GetConnectAbility();
170     if (connectAbility == nullptr) {
171         APP_LOGE("fail to connect ServiceCenter");
172         return false;
173     }
174     std::shared_ptr<BundleMgrService> bms = DelayedSingleton<BundleMgrService>::GetInstance();
175     std::shared_ptr<BundleDataMgr> bundleDataMgr_ = bms->GetDataMgr();
176     if (bundleDataMgr_ == nullptr) {
177         APP_LOGE("GetDataMgr failed, bundleDataMgr_ is nullptr");
178         SendCallbackRequest(ErrorCode::WAITING_TIMEOUT, targetAbilityInfo.targetInfo.transactId);
179         return true;
180     }
181     std::string bundleName;
182     std::string abilityName;
183     if (!(bundleDataMgr_->QueryAppGalleryAbilityName(bundleName, abilityName))) {
184         APP_LOGE("Fail to query ServiceCenter ability and bundle name");
185         SendCallbackRequest(ErrorCode::CONNECT_FAILED, targetAbilityInfo.targetInfo.transactId);
186         return true;
187     }
188     Want serviceCenterWant;
189     serviceCenterWant.SetElementName(bundleName, abilityName);
190     bool ret = connectAbility->ConnectAbility(serviceCenterWant, nullptr);
191     if (!ret) {
192         APP_LOGE("fail to connect ServiceCenter");
193         SendCallbackRequest(ErrorCode::CONNECT_FAILED, targetAbilityInfo.targetInfo.transactId);
194         return true;
195     }
196     const std::string targetInfo = GetJsonStrFromInfo(targetAbilityInfo);
197     APP_LOGI("queryRpcId param %{public}s", targetInfo.c_str());
198     MessageParcel data;
199     MessageParcel reply;
200     MessageOption option(MessageOption::TF_ASYNC);
201     if (!data.WriteInterfaceToken(SERVICE_CENTER_TOKEN)) {
202         APP_LOGE("failed to sendCallback due to write MessageParcel fail");
203         return false;
204     }
205     if (!data.WriteString16(Str8ToStr16(targetInfo))) {
206         APP_LOGE("WriteString16 failed");
207         return false;
208     }
209     sptr<BundleManagerCallback> bundleManagerCallback = new(std::nothrow) BundleManagerCallback(weak_from_this());
210     if (bundleManagerCallback == nullptr) {
211         APP_LOGE("bundleManagerCallback is nullptr");
212         return false;
213     }
214     if (!data.WriteRemoteObject(bundleManagerCallback)) {
215         APP_LOGE("failed to write remote object");
216         return false;
217     }
218     ret = connectAbility->SendRequest(ServiceCenterFunction::CONNECT_QUERY_RPCID, data, reply);
219     if (!ret) {
220         APP_LOGE("send request to serviceCenter failed");
221         SendCallbackRequest(ErrorCode::SEND_REQUEST_FAILED, targetAbilityInfo.targetInfo.transactId);
222         return true;
223     }
224     OutTimeMonitor(targetAbilityInfo.targetInfo.transactId);
225     return true;
226 }
227 
OutTimeMonitor(const std::string transactId)228 void BundleDistributedManager::OutTimeMonitor(const std::string transactId)
229 {
230     APP_LOGI("BundleDistributedManager::OutTimeMonitor");
231     auto registerEventListenerFunc = [this, transactId]() {
232         BundleMemoryGuard memoryGuard;
233         APP_LOGI("RegisterEventListenerFunc transactId:%{public}s", transactId.c_str());
234         this->SendCallbackRequest(ErrorCode::WAITING_TIMEOUT, transactId);
235     };
236     if (serialQueue_ == nullptr) {
237         APP_LOGE("serialQueue_ is null");
238         return;
239     }
240     serialQueue_->ScheduleDelayTask(transactId, OUT_TIME, registerEventListenerFunc);
241 }
242 
OnQueryRpcIdFinished(const std::string & queryRpcIdResult)243 void BundleDistributedManager::OnQueryRpcIdFinished(const std::string &queryRpcIdResult)
244 {
245     RpcIdResult rpcIdResult;
246     APP_LOGI("queryRpcIdResult:%{public}s", queryRpcIdResult.c_str());
247     if (!ParseInfoFromJsonStr(queryRpcIdResult.c_str(), rpcIdResult)) {
248         APP_LOGE("Parse info from json fail");
249         return;
250     }
251     Want want;
252     {
253         std::shared_lock<ffrt::shared_mutex> lock(mutex_);
254         auto queryAbilityParams = queryAbilityParamsMap_.find(rpcIdResult.transactId);
255         if (queryAbilityParams == queryAbilityParamsMap_.end()) {
256             APP_LOGE("no node");
257             return;
258         }
259         want = queryAbilityParams->second.want;
260     }
261     serialQueue_->CancelDelayTask(rpcIdResult.transactId);
262     if (rpcIdResult.retCode != 0) {
263         APP_LOGE("query RpcId fail%{public}d", rpcIdResult.retCode);
264         SendCallbackRequest(rpcIdResult.retCode, rpcIdResult.transactId);
265         return;
266     }
267     int32_t ret = ComparePcIdString(want, rpcIdResult);
268     if (ret != 0) {
269         APP_LOGE("Compare pcId fail%{public}d", ret);
270     }
271     SendCallbackRequest(ret, rpcIdResult.transactId);
272 }
273 
SendCallbackRequest(int32_t resultCode,const std::string & transactId)274 void BundleDistributedManager::SendCallbackRequest(int32_t resultCode, const std::string &transactId)
275 {
276     APP_LOGI("sendCallbackRequest resultCode:%{public}d, transactId:%{public}s", resultCode, transactId.c_str());
277     QueryRpcIdParams queryRpcIdParams;
278     {
279         std::shared_lock<ffrt::shared_mutex> lock(mutex_);
280         auto queryAbilityParams = queryAbilityParamsMap_.find(transactId);
281         if (queryAbilityParams == queryAbilityParamsMap_.end()) {
282             APP_LOGE("Can not find transactId:%{public}s in queryAbilityParamsMap", transactId.c_str());
283             return;
284         }
285         queryRpcIdParams = queryAbilityParams->second;
286     }
287     SendCallback(resultCode, queryRpcIdParams);
288 
289     uint32_t mapSize;
290     {
291         std::unique_lock<ffrt::shared_mutex> lock(mutex_);
292         queryAbilityParamsMap_.erase(transactId);
293         mapSize = queryAbilityParamsMap_.size();
294     }
295 
296     if (mapSize == 0) {
297         auto connectAbility = DelayedSingleton<BundleMgrService>::GetInstance()->GetConnectAbility();
298         if (connectAbility == nullptr) {
299             APP_LOGW("fail to connect ServiceCenter");
300             return;
301         }
302         connectAbility->DisconnectAbility();
303     }
304 }
305 
SendCallback(int32_t resultCode,const QueryRpcIdParams & queryRpcIdParams)306 void BundleDistributedManager::SendCallback(int32_t resultCode, const QueryRpcIdParams &queryRpcIdParams)
307 {
308     auto remoteObject = queryRpcIdParams.callback;
309     if (remoteObject == nullptr) {
310         APP_LOGW("sendCallbackRequest remoteObject is invalid");
311         return;
312     }
313     MessageParcel data;
314     if (!data.WriteInterfaceToken(DMS_BUNDLE_MANAGER_CALLBACK_TOKEN)) {
315         APP_LOGE("failed to sendCallback due to write MessageParcel fail");
316         return;
317     }
318     if (!data.WriteInt32(resultCode)) {
319         APP_LOGE("fail to sendCallback due to write resultCode fail");
320         return;
321     }
322     if (!data.WriteUint32(queryRpcIdParams.versionCode)) {
323         APP_LOGE("fail to sendCallback due to write versionCode fail");
324         return;
325     }
326     if (!data.WriteInt32(queryRpcIdParams.missionId)) {
327         APP_LOGE("fail to sendCallback due to write missionId fail");
328         return;
329     }
330     MessageParcel reply;
331     MessageOption option(MessageOption::TF_SYNC);
332     int32_t result = remoteObject->SendRequest(CHECK_ABILITY_ENABLE_INSTALL, data, reply, option);
333     if (result != 0) {
334         APP_LOGE("failed send request code %{public}d", result);
335     }
336 }
337 }  // namespace AppExecFwk
338 }  // namespace OHOS
339