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