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