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