1 /*
2 * Copyright (c) 2021-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_sched_adapter.h"
17
18 #include "datetime_ex.h"
19 #include "dfx/dms_hisysevent_report.h"
20 #include "distributed_sched_service.h"
21 #include "dtbschedmgr_device_info_storage.h"
22 #include "dtbschedmgr_log.h"
23 #include "ipc_skeleton.h"
24 #include "ipc_types.h"
25 #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
26 #include "mission/distributed_sched_mission_manager.h"
27 #include "mission/mission_info_converter.h"
28 #endif
29 #include "os_account_manager.h"
30 #include "parcel_helper.h"
31 #include "string_ex.h"
32
33 namespace OHOS {
34 namespace DistributedSchedule {
35 using namespace std;
36 using namespace AAFwk;
37 using namespace AccountSA;
38 using namespace AppExecFwk;
39 using DstbMissionChangeListener = DistributedMissionChangeListener;
40 namespace {
41 // set a non-zero value on need later
42 constexpr int64_t DEVICE_OFFLINE_DELAY_TIME = 0;
43 const std::string TAG = "DistributedSchedAdapter";
44 }
45
46 IMPLEMENT_SINGLE_INSTANCE(DistributedSchedAdapter);
47
Init()48 void DistributedSchedAdapter::Init()
49 {
50 if (dmsAdapterHandler_ == nullptr) {
51 shared_ptr<EventRunner> runner = EventRunner::Create("dmsAdapter");
52 if (runner == nullptr) {
53 HILOGE("create runner failed");
54 return;
55 }
56 dmsAdapterHandler_ = make_shared<EventHandler>(runner);
57 }
58 }
59
UnInit()60 void DistributedSchedAdapter::UnInit()
61 {
62 dmsAdapterHandler_ = nullptr;
63 }
64
ConnectAbility(const OHOS::AAFwk::Want & want,const sptr<IRemoteObject> & connect,const sptr<IRemoteObject> & callerToken)65 int32_t DistributedSchedAdapter::ConnectAbility(const OHOS::AAFwk::Want& want,
66 const sptr<IRemoteObject>& connect, const sptr<IRemoteObject>& callerToken)
67 {
68 HILOGD("ConnectAbility");
69 ErrCode errCode = AAFwk::AbilityManagerClient::GetInstance()->Connect();
70 if (errCode != ERR_OK) {
71 HILOGE("connect ability server failed, errCode=%{public}d", errCode);
72 DmsHiSysEventReport::ReportFaultEvent(FaultEvent::CONNECT_REMOTE_ABILITY,
73 EventErrorType::GET_ABILITY_MGR_FAILED);
74 return errCode;
75 }
76 int32_t activeAccountId = -1;
77 #ifdef OS_ACCOUNT_PART
78 std::vector<int> ids;
79 errCode = AccountSA::OsAccountManager::QueryActiveOsAccountIds(ids);
80 if (errCode != ERR_OK || ids.empty()) {
81 return INVALID_PARAMETERS_ERR;
82 }
83 activeAccountId = ids[0];
84 #endif
85 errCode = AAFwk::AbilityManagerClient::GetInstance()->ConnectAbility(want,
86 iface_cast<AAFwk::IAbilityConnection>(connect), callerToken, activeAccountId);
87 return errCode;
88 }
89
DisconnectAbility(const sptr<IRemoteObject> & connect)90 int32_t DistributedSchedAdapter::DisconnectAbility(const sptr<IRemoteObject>& connect)
91 {
92 HILOGD("DisconnectAbility");
93 ErrCode errCode = AAFwk::AbilityManagerClient::GetInstance()->Connect();
94 if (errCode != ERR_OK) {
95 HILOGE("connect ability server failed, errCode=%{public}d", errCode);
96 DmsHiSysEventReport::ReportFaultEvent(FaultEvent::DISCONNECT_REMOTE_ABILITY,
97 EventErrorType::GET_ABILITY_MGR_FAILED);
98 return errCode;
99 }
100 ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->DisconnectAbility(
101 iface_cast<AAFwk::IAbilityConnection>(connect));
102 return ret;
103 }
104
DeviceOnline(const std::string & networkId)105 void DistributedSchedAdapter::DeviceOnline(const std::string& networkId)
106 {
107 if (dmsAdapterHandler_ == nullptr) {
108 HILOGE("DeviceOnline dmsAdapterHandler is null");
109 return;
110 }
111
112 if (networkId.empty()) {
113 HILOGW("DeviceOnline networkId is empty");
114 return;
115 }
116
117 HILOGD("process DeviceOnline networkId is %{public}s",
118 DnetworkAdapter::AnonymizeNetworkId(networkId).c_str());
119 dmsAdapterHandler_->RemoveTask(networkId);
120 }
121
DeviceOffline(const std::string & networkId)122 void DistributedSchedAdapter::DeviceOffline(const std::string& networkId)
123 {
124 if (dmsAdapterHandler_ == nullptr) {
125 HILOGE("DeviceOffline dmsAdapterHandler is null");
126 return;
127 }
128
129 if (networkId.empty()) {
130 HILOGW("DeviceOffline networkId is empty");
131 return;
132 }
133 HILOGD("process DeviceOffline networkId is %{public}s",
134 DnetworkAdapter::AnonymizeNetworkId(networkId).c_str());
135 auto callback = [networkId, this] () {
136 ProcessDeviceOffline(networkId);
137 };
138 if (!dmsAdapterHandler_->PostTask(callback, networkId, DEVICE_OFFLINE_DELAY_TIME)) {
139 HILOGW("DeviceOffline PostTask failed");
140 }
141 }
142
ProcessDeviceOffline(const std::string & deviceId)143 void DistributedSchedAdapter::ProcessDeviceOffline(const std::string& deviceId)
144 {
145 HILOGD("ProcessDeviceOffline");
146 DistributedSchedService::GetInstance().ProcessDeviceOffline(deviceId);
147 }
148
ProcessConnectDied(const sptr<IRemoteObject> & connect)149 void DistributedSchedAdapter::ProcessConnectDied(const sptr<IRemoteObject>& connect)
150 {
151 if (dmsAdapterHandler_ == nullptr) {
152 HILOGE("ProcessConnectDied dmsAdapterHandler is null");
153 return;
154 }
155
156 if (connect == nullptr) {
157 HILOGE("ProcessConnectDied connect is null");
158 return;
159 }
160 HILOGD("process connect died");
161 auto callback = [connect] () {
162 DistributedSchedService::GetInstance().ProcessConnectDied(connect);
163 };
164 if (!dmsAdapterHandler_->PostTask(callback)) {
165 HILOGW("ProcessConnectDied PostTask failed");
166 }
167 }
168
ProcessCalleeDied(const sptr<IRemoteObject> & connect)169 void DistributedSchedAdapter::ProcessCalleeDied(const sptr<IRemoteObject>& connect)
170 {
171 if (dmsAdapterHandler_ == nullptr) {
172 HILOGE("ProcessCalleeDied dmsAdapterHandler is null");
173 return;
174 }
175 if (connect == nullptr) {
176 HILOGE("ProcessCalleeDied connect is null");
177 return;
178 }
179 HILOGD("process callee died");
180 auto callback = [connect] () {
181 DistributedSchedService::GetInstance().ProcessCalleeDied(connect);
182 };
183 if (!dmsAdapterHandler_->PostTask(callback)) {
184 HILOGE("ProcessCalleeDied PostTask failed");
185 }
186 }
187
ProcessCallResult(const sptr<IRemoteObject> & calleeConnect,const sptr<IRemoteObject> & callerConnect)188 void DistributedSchedAdapter::ProcessCallResult(const sptr<IRemoteObject>& calleeConnect,
189 const sptr<IRemoteObject>& callerConnect)
190 {
191 if (dmsAdapterHandler_ == nullptr) {
192 HILOGE("ProcessCallResult dmsAdapterHandler is null");
193 return;
194 }
195 if (calleeConnect == nullptr || callerConnect == nullptr) {
196 HILOGE("ProcessCallResult connect is null");
197 return;
198 }
199 HILOGD("process call result start");
200 auto callback = [calleeConnect, callerConnect] () {
201 DistributedSchedService::GetInstance().ProcessCallResult(calleeConnect, callerConnect);
202 };
203 if (!dmsAdapterHandler_->PostTask(callback)) {
204 HILOGE("ProcessCalleeDied PostTask failed");
205 }
206 }
207
ProcessCallerDied(const sptr<IRemoteObject> & connect,int32_t deviceType)208 void DistributedSchedAdapter::ProcessCallerDied(const sptr<IRemoteObject>& connect, int32_t deviceType)
209 {
210 if (dmsAdapterHandler_ == nullptr) {
211 HILOGE("ProcessCallerDied dmsAdapterHandler is null");
212 return;
213 }
214 if (connect == nullptr) {
215 HILOGE("ProcessCallerDied connect is null");
216 return;
217 }
218 HILOGD("process caller died");
219 auto callback = [connect, deviceType] () {
220 DistributedSchedService::GetInstance().ProcessCallerDied(connect, deviceType);
221 };
222 if (!dmsAdapterHandler_->PostTask(callback)) {
223 HILOGE("ProcessCallerDied PostTask failed");
224 }
225 }
226
ReleaseAbility(const sptr<IRemoteObject> & connect,const AppExecFwk::ElementName & element)227 int32_t DistributedSchedAdapter::ReleaseAbility(const sptr<IRemoteObject>& connect,
228 const AppExecFwk::ElementName &element)
229 {
230 HILOGD("ReleaseAbility called");
231 ErrCode errCode = AAFwk::AbilityManagerClient::GetInstance()->Connect();
232 if (errCode != ERR_OK) {
233 HILOGE("ReleaseAbility:connect ability server failed, errCode=%{public}d", errCode);
234 DmsHiSysEventReport::ReportFaultEvent(FaultEvent::RELEASE_REMOTE_ABILITY,
235 EventErrorType::GET_ABILITY_MGR_FAILED);
236 return errCode;
237 }
238 AppExecFwk::ElementName elementWithoutDeviceId("", element.GetBundleName(), element.GetAbilityName());
239 ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->ReleaseCall(
240 iface_cast<AAFwk::IAbilityConnection>(connect), elementWithoutDeviceId);
241 return ret;
242 }
243
StartAbilityByCall(const OHOS::AAFwk::Want & want,const sptr<IRemoteObject> & connect,const sptr<IRemoteObject> & callerToken)244 int32_t DistributedSchedAdapter::StartAbilityByCall(const OHOS::AAFwk::Want& want,
245 const sptr<IRemoteObject>& connect, const sptr<IRemoteObject>& callerToken)
246 {
247 HILOGD("ResolveAbility called");
248 ErrCode errCode = AAFwk::AbilityManagerClient::GetInstance()->Connect();
249 if (errCode != ERR_OK) {
250 HILOGE("ResolveAbility:connect ability server failed, errCode=%{public}d", errCode);
251 DmsHiSysEventReport::ReportFaultEvent(FaultEvent::START_REMOTE_ABILITY_BYCALL,
252 EventErrorType::GET_ABILITY_MGR_FAILED);
253 return errCode;
254 }
255 ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->StartAbilityByCall(want,
256 iface_cast<AAFwk::IAbilityConnection>(connect), callerToken);
257 return ret;
258 }
259
InitHichainService()260 bool DistributedSchedAdapter::InitHichainService()
261 {
262 if (hichainGmInstance_ != nullptr) {
263 HILOGD("hichain GmInstance is already exist");
264 return true;
265 }
266 if (InitDeviceAuthService() != ERR_OK) {
267 HILOGE("hichain init DeviceAuthService failed");
268 return false;
269 }
270 hichainGmInstance_ = GetGmInstance();
271 if (hichainGmInstance_ == nullptr) {
272 HILOGE("hichain get GmInstance failed");
273 return false;
274 }
275 return true;
276 }
277
CheckAccessToGroup(const std::string & groupId,const std::string & targetBundleName)278 bool DistributedSchedAdapter::CheckAccessToGroup(const std::string& groupId, const std::string& targetBundleName)
279 {
280 std::lock_guard<std::mutex> autoLock(hichainLock_);
281 int64_t begin = GetTickCount();
282 if (!InitHichainService()) {
283 return false;
284 }
285 int32_t ret = hichainGmInstance_->checkAccessToGroup(ANY_OS_ACCOUNT, targetBundleName.c_str(),
286 groupId.c_str());
287 HILOGI("[PerformanceTest] checkAccessToGroup spend %{public}" PRId64 " ms", GetTickCount() - begin);
288 if (ret != ERR_OK) {
289 HILOGE("hichain checkAccessToGroup failed, ret:%{public}d", ret);
290 return false;
291 }
292 HILOGD("hichain checkAccessToGroup success");
293 return true;
294 }
295
GetRelatedGroups(const std::string & udid,const std::string & bundleName,std::string & returnGroups)296 bool DistributedSchedAdapter::GetRelatedGroups(const std::string& udid, const std::string& bundleName,
297 std::string& returnGroups)
298 {
299 std::lock_guard<std::mutex> autoLock(hichainLock_);
300 int64_t begin = GetTickCount();
301 if (!InitHichainService()) {
302 return false;
303 }
304 uint32_t groupNum = 0;
305 char* groupsJsonStr = nullptr;
306 int32_t ret = hichainGmInstance_->getRelatedGroups(ANY_OS_ACCOUNT, bundleName.c_str(), udid.c_str(),
307 &groupsJsonStr, &groupNum);
308 HILOGI("[PerformanceTest] getRelatedGroups spend %{public}" PRId64 " ms", GetTickCount() - begin);
309 if (ret != ERR_OK) {
310 HILOGE("hichain getRelatedGroups failed, ret:%{public}d", ret);
311 return false;
312 }
313 if (groupsJsonStr == nullptr || groupNum == 0) {
314 HILOGE("groupsJsonStr is nullptr");
315 return false;
316 }
317 returnGroups = groupsJsonStr;
318 return true;
319 }
320
321 #ifdef SUPPORT_DISTRIBUTED_MISSION_MANAGER
GetLocalMissionInfos(int32_t numMissions,std::vector<DstbMissionInfo> & missionInfos)322 int32_t DistributedSchedAdapter::GetLocalMissionInfos(int32_t numMissions,
323 std::vector<DstbMissionInfo>& missionInfos)
324
325 {
326 ErrCode errCode = AAFwk::AbilityManagerClient::GetInstance()->Connect();
327 if (errCode != ERR_OK) {
328 HILOGE("get ability server failed, errCode = %{public}d", errCode);
329 return errCode;
330 }
331 std::vector<MissionInfo> amsMissions;
332 ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->GetMissionInfos("", numMissions, amsMissions);
333 if (ret != ERR_OK) {
334 HILOGE("GetMissionInfos failed, ret = %{public}d", ret);
335 return ret;
336 }
337 if (amsMissions.empty()) {
338 HILOGI("empty missions");
339 return ERR_OK;
340 }
341 HILOGI("GetMissionInfos size:%{public}zu", amsMissions.size());
342 return MissionInfoConverter::ConvertToDstbMissionInfos(amsMissions, missionInfos);
343 }
344
RegisterMissionListener(const sptr<IMissionListener> & listener)345 int32_t DistributedSchedAdapter::RegisterMissionListener(const sptr<IMissionListener>& listener)
346 {
347 HILOGD("called.");
348 if (listener == nullptr) {
349 HILOGE("listener is null");
350 return INVALID_PARAMETERS_ERR;
351 }
352 ErrCode errCode = AAFwk::AbilityManagerClient::GetInstance()->Connect();
353 if (errCode != ERR_OK) {
354 HILOGE("get ability server failed, errCode=%{public}d", errCode);
355 return errCode;
356 }
357 ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->RegisterMissionListener(listener);
358 if (ret != ERR_OK) {
359 HILOGE("RegisterMissionListener failed, ret=%{public}d", ret);
360 return ret;
361 }
362 return ERR_OK;
363 }
364
UnRegisterMissionListener(const sptr<IMissionListener> & listener)365 int32_t DistributedSchedAdapter::UnRegisterMissionListener(const sptr<IMissionListener>& listener)
366 {
367 if (listener == nullptr) {
368 HILOGE("listener is null");
369 return INVALID_PARAMETERS_ERR;
370 }
371 ErrCode errCode = AAFwk::AbilityManagerClient::GetInstance()->Connect();
372 if (errCode != ERR_OK) {
373 HILOGE("get ability server failed, errCode=%{public}d", errCode);
374 return errCode;
375 }
376
377 ErrCode ret = AAFwk::AbilityManagerClient::GetInstance()->UnRegisterMissionListener(listener);
378 if (ret != ERR_OK) {
379 HILOGE("UnRegisterMissionListener failed, ret=%{public}d", ret);
380 return ret;
381 }
382 return ERR_OK;
383 }
384
GetLocalMissionSnapshotInfo(const std::string & networkId,int32_t missionId,MissionSnapshot & missionSnapshot)385 int32_t DistributedSchedAdapter::GetLocalMissionSnapshotInfo(const std::string& networkId, int32_t missionId,
386 MissionSnapshot& missionSnapshot)
387 {
388 int64_t begin = GetTickCount();
389 ErrCode errCode = AAFwk::AbilityManagerClient::GetInstance()->Connect();
390 if (errCode != ERR_OK) {
391 HILOGE("get ability server failed, errCode=%{public}d", errCode);
392 return errCode;
393 }
394 errCode = AAFwk::AbilityManagerClient::GetInstance()->GetMissionSnapshot(networkId,
395 missionId, missionSnapshot);
396 HILOGI("[PerformanceTest] GetMissionSnapshot spend %{public}" PRId64 " ms", GetTickCount() - begin);
397 if (errCode != ERR_OK) {
398 HILOGE("get mission snapshot failed, missionId=%{public}d, errCode=%{public}d", missionId, errCode);
399 return errCode;
400 }
401 if (missionSnapshot.snapshot == nullptr) {
402 HILOGE("pixel map is nullptr!");
403 return ERR_NULL_OBJECT;
404 }
405 HILOGD("pixelMap size:%{public}d", missionSnapshot.snapshot->GetCapacity());
406 return ERR_OK;
407 }
408 #endif
409 } // namespace DistributedSchedule
410 } // namespace OHOS
411