1 /*
2 * Copyright (c) 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_client.h"
17
18 #include "ability_manager_errors.h"
19 #include "distributed_parcel_helper.h"
20 #include "iservice_registry.h"
21 #include "system_ability_definition.h"
22
23 namespace OHOS {
24 namespace Rosen {
25 namespace {
26 const std::u16string DMS_PROXY_INTERFACE_TOKEN = u"ohos.distributedschedule.accessToken";
27 }
WM_IMPLEMENT_SINGLE_INSTANCE(DistributedClient)28 WM_IMPLEMENT_SINGLE_INSTANCE(DistributedClient)
29
30 void DistributedClient::DmsDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
31 {
32 TLOGI(WmsLogTag::DEFAULT, "dms died");
33 DistributedClient::GetInstance().ClearDmsProxy();
34 }
35
GetDmsProxy()36 sptr<IRemoteObject> DistributedClient::GetDmsProxy()
37 {
38 std::lock_guard<std::mutex> lock(mutex_);
39 if (dmsProxy_ == nullptr) {
40 ConnectDistributedSchedLocked();
41 }
42 return dmsProxy_;
43 }
44
ConnectDistributedSchedLocked()45 void DistributedClient::ConnectDistributedSchedLocked()
46 {
47 auto samgrProxy = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
48 if (samgrProxy == nullptr) {
49 TLOGE(WmsLogTag::DEFAULT, "fail to get samgr");
50 return;
51 }
52 auto proxy = samgrProxy->CheckSystemAbility(DISTRIBUTED_SCHED_SA_ID);
53 if (!proxy) {
54 TLOGW(WmsLogTag::DEFAULT, "get dms proxy failed");
55 return;
56 }
57 dmsDeath_ = sptr<DmsDeathRecipient>::MakeSptr();
58 if (proxy->IsProxyObject() && !proxy->AddDeathRecipient(dmsDeath_)) {
59 TLOGE(WmsLogTag::DEFAULT, "failed to add death recipient");
60 return;
61 }
62 dmsProxy_ = proxy;
63 TLOGI(WmsLogTag::DEFAULT, "success");
64 }
65
ClearDmsProxy()66 void DistributedClient::ClearDmsProxy()
67 {
68 TLOGI(WmsLogTag::DEFAULT, "in");
69 std::lock_guard<std::mutex> lock(mutex_);
70 dmsProxy_ = nullptr;
71 dmsDeath_ = nullptr;
72 }
73
GetMissionInfos(const std::string & deviceId,int32_t numMissions,std::vector<AAFwk::MissionInfo> & missionInfos)74 int32_t DistributedClient::GetMissionInfos(const std::string& deviceId, int32_t numMissions,
75 std::vector<AAFwk::MissionInfo>& missionInfos)
76 {
77 TLOGI(WmsLogTag::DEFAULT, "called");
78 sptr<IRemoteObject> remote = GetDmsProxy();
79 if (remote == nullptr) {
80 TLOGE(WmsLogTag::DEFAULT, "remote system abiity is null");
81 return AAFwk::INVALID_PARAMETERS_ERR;
82 }
83
84 MessageParcel data;
85 MessageParcel reply;
86 MessageOption option;
87 if (!data.WriteInterfaceToken(DMS_PROXY_INTERFACE_TOKEN)) {
88 return ERR_FLATTEN_OBJECT;
89 }
90 PARCEL_WRITE_HELPER(data, String16, Str8ToStr16(deviceId));
91 PARCEL_WRITE_HELPER(data, Int32, numMissions);
92 int32_t ret = remote->SendRequest(GET_MISSION_INFOS, data, reply, option);
93 if (ret != ERR_NONE) {
94 TLOGW(WmsLogTag::DEFAULT, "sendRequest fail, error: %{public}d", ret);
95 return ret;
96 }
97 return ReadMissionInfosFromParcel(reply, missionInfos) ? ERR_NONE : ERR_FLATTEN_OBJECT;
98 }
99
GetRemoteMissionSnapshotInfo(const std::string & deviceId,int32_t missionId,AAFwk::MissionSnapshot & missionSnapshot)100 int32_t DistributedClient::GetRemoteMissionSnapshotInfo(const std::string& deviceId, int32_t missionId,
101 AAFwk::MissionSnapshot& missionSnapshot)
102 {
103 if (deviceId.empty()) {
104 TLOGE(WmsLogTag::DEFAULT, "deviceId is null");
105 return ERR_NULL_OBJECT;
106 }
107 sptr<IRemoteObject> remote = GetDmsProxy();
108 if (remote == nullptr) {
109 TLOGE(WmsLogTag::DEFAULT, "remote is null");
110 return AAFwk::INVALID_PARAMETERS_ERR;
111 }
112 MessageParcel data;
113 if (!data.WriteInterfaceToken(DMS_PROXY_INTERFACE_TOKEN)) {
114 return ERR_FLATTEN_OBJECT;
115 }
116 PARCEL_WRITE_HELPER(data, String, deviceId);
117 PARCEL_WRITE_HELPER(data, Int32, missionId);
118 MessageParcel reply;
119 MessageOption option;
120 int32_t error = remote->SendRequest(GET_REMOTE_MISSION_SNAPSHOT_INFO, data, reply, option);
121 if (error != ERR_NONE) {
122 TLOGE(WmsLogTag::DEFAULT, "transact failed, error: %{public}d", error);
123 return error;
124 }
125 std::unique_ptr<AAFwk::MissionSnapshot> missionSnapshotPtr(reply.ReadParcelable<AAFwk::MissionSnapshot>());
126 if (missionSnapshotPtr == nullptr) {
127 TLOGE(WmsLogTag::DEFAULT, "missionSnapshotPtr is null");
128 return ERR_UNKNOWN_OBJECT;
129 }
130 missionSnapshot = *missionSnapshotPtr;
131 return ERR_NONE;
132 }
133
ReadMissionInfosFromParcel(Parcel & parcel,std::vector<AAFwk::MissionInfo> & missionInfos)134 bool DistributedClient::ReadMissionInfosFromParcel(Parcel& parcel,
135 std::vector<AAFwk::MissionInfo>& missionInfos)
136 {
137 int32_t hasMissions = parcel.ReadInt32();
138 if (hasMissions == 1) {
139 int32_t len = parcel.ReadInt32();
140 TLOGD(WmsLogTag::DEFAULT, "readLength is:%{public}d", len);
141 if (len < 0) {
142 return false;
143 }
144 size_t size = static_cast<size_t>(len);
145 if ((size > parcel.GetReadableBytes()) || (missionInfos.max_size() < size)) {
146 TLOGE(WmsLogTag::DEFAULT, "Failed to read MissionInfo vector, size = %{public}zu", size);
147 return false;
148 }
149 missionInfos.clear();
150 for (size_t i = 0; i < size; i++) {
151 AAFwk::MissionInfo *ptr = parcel.ReadParcelable<AAFwk::MissionInfo>();
152 if (ptr == nullptr) {
153 TLOGW(WmsLogTag::DEFAULT, "read MissionInfo failed");
154 return false;
155 }
156 missionInfos.emplace_back(*ptr);
157 delete ptr;
158 }
159 }
160 TLOGI(WmsLogTag::DEFAULT, "info size is:%{public}zu", missionInfos.size());
161 return true;
162 }
163
SetMissionContinueState(int32_t missionId,const AAFwk::ContinueState & state)164 int32_t DistributedClient::SetMissionContinueState(int32_t missionId, const AAFwk::ContinueState& state)
165 {
166 TLOGI(WmsLogTag::DEFAULT, "Mission id: %{public}d, state: %{public}d", missionId, state);
167 sptr<IRemoteObject> remote = GetDmsProxy();
168 if (remote == nullptr) {
169 TLOGI(WmsLogTag::DEFAULT, "remote system ablity is null");
170 return AAFwk::INVALID_PARAMETERS_ERR;
171 }
172 MessageParcel data;
173 MessageParcel reply;
174 MessageOption option(MessageOption::TF_ASYNC);
175 if (!data.WriteInterfaceToken(DMS_PROXY_INTERFACE_TOKEN)) {
176 return ERR_FLATTEN_OBJECT;
177 }
178 PARCEL_WRITE_HELPER(data, Int32, missionId);
179 PARCEL_WRITE_HELPER(data, Int32, static_cast<int32_t>(state));
180 int32_t error = remote->SendRequest(SET_MISSION_CONTINUE_STATE, data, reply, option);
181 if (error != ERR_NONE) {
182 TLOGE(WmsLogTag::DEFAULT, "transact failed, error: %{public}d", error);
183 return error;
184 }
185 return ERR_NONE;
186 }
187 } // namespace Rosen
188 } // namespace OHOS
189