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