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