1 /*
2 * Copyright (c) 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 "ability_manager_adapter.h"
17 #include "ability_manager_errors.h"
18 #include "ability_manager_ipc_interface_code.h"
19 #include "account_error_no.h"
20 #include "account_log_wrapper.h"
21 #include "iservice_registry.h"
22 #include "system_ability_definition.h"
23
24 namespace OHOS {
25 namespace AccountSA {
26 namespace {
27 const std::u16string ABILITY_MGR_DESCRIPTOR = u"ohos.aafwk.AbilityManager";
28 }
29 using namespace AAFwk;
GetInstance()30 AbilityManagerAdapter *AbilityManagerAdapter::GetInstance()
31 {
32 static AbilityManagerAdapter *instance = new (std::nothrow) AbilityManagerAdapter();
33 return instance;
34 }
35
AbilityManagerAdapter()36 AbilityManagerAdapter::AbilityManagerAdapter()
37 {}
38
~AbilityManagerAdapter()39 AbilityManagerAdapter::~AbilityManagerAdapter()
40 {}
41
ConnectAbility(const AAFwk::Want & want,const sptr<AAFwk::IAbilityConnection> & connect,const sptr<IRemoteObject> & callerToken,int32_t userId)42 ErrCode AbilityManagerAdapter::ConnectAbility(const AAFwk::Want &want, const sptr<AAFwk::IAbilityConnection> &connect,
43 const sptr<IRemoteObject> &callerToken, int32_t userId)
44 {
45 auto abms = GetAbilityManager();
46 if (abms == nullptr) {
47 ACCOUNT_LOGE("ability manager proxy is nullptr.");
48 return ERR_ACCOUNT_COMMON_CONNECT_ABILITY_MANAGER_SERVICE_ERROR;
49 }
50
51 return DoConnectAbility(abms, want, connect, callerToken, userId);
52 }
53
DisconnectAbility(const sptr<AAFwk::IAbilityConnection> & connect)54 ErrCode AbilityManagerAdapter::DisconnectAbility(const sptr<AAFwk::IAbilityConnection> &connect)
55 {
56 auto abms = GetAbilityManager();
57 if (abms == nullptr) {
58 ACCOUNT_LOGE("ability manager proxy is nullptr.");
59 return ERR_ACCOUNT_COMMON_CONNECT_ABILITY_MANAGER_SERVICE_ERROR;
60 }
61
62 int error;
63 MessageParcel data;
64 MessageParcel reply;
65 MessageOption option;
66 if (connect == nullptr) {
67 ACCOUNT_LOGE("disconnect ability fail, connect is nullptr");
68 return ERR_INVALID_VALUE;
69 }
70 if (!data.WriteInterfaceToken(ABILITY_MGR_DESCRIPTOR)) {
71 ACCOUNT_LOGE("write interface token failed.");
72 return INNER_ERR;
73 }
74 if (!data.WriteRemoteObject(connect->AsObject())) {
75 ACCOUNT_LOGE("connect write failed.");
76 return ERR_INVALID_VALUE;
77 }
78
79 error = abms->SendRequest(
80 static_cast<uint32_t>(AbilityManagerInterfaceCode::DISCONNECT_ABILITY), data, reply, option);
81 if (error != NO_ERROR) {
82 ACCOUNT_LOGE("Send request error: %{public}d", error);
83 return error;
84 }
85 return reply.ReadInt32();
86 }
87
Connect()88 void AbilityManagerAdapter::Connect()
89 {
90 if (proxy_ != nullptr) {
91 return;
92 }
93 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
94 if (systemManager == nullptr) {
95 ACCOUNT_LOGE("Fail to get system ability registry.");
96 return;
97 }
98 sptr<IRemoteObject> remoteObj = systemManager->CheckSystemAbility(ABILITY_MGR_SERVICE_ID);
99 if (remoteObj == nullptr) {
100 ACCOUNT_LOGE("Fail to connect ability manager service.");
101 return;
102 }
103
104 deathRecipient_ = sptr<IRemoteObject::DeathRecipient>(new (std::nothrow) AbilityMgrDeathRecipient());
105 if (deathRecipient_ == nullptr) {
106 ACCOUNT_LOGE("Failed to create AbilityMgrDeathRecipient!");
107 return;
108 }
109 if ((remoteObj->IsProxyObject()) && (!remoteObj->AddDeathRecipient(deathRecipient_))) {
110 ACCOUNT_LOGE("Add death recipient to AbilityManagerService failed.");
111 return;
112 }
113 proxy_ = remoteObj;
114 }
115
StartUser(int32_t accountId,const sptr<AAFwk::IUserCallback> & callback)116 ErrCode AbilityManagerAdapter::StartUser(int32_t accountId, const sptr<AAFwk::IUserCallback> &callback)
117 {
118 auto abms = GetAbilityManager();
119 if (abms == nullptr) {
120 ACCOUNT_LOGE("ability manager proxy is nullptr.");
121 return ERR_ACCOUNT_COMMON_CONNECT_ABILITY_MANAGER_SERVICE_ERROR;
122 }
123
124 int error;
125 MessageParcel data;
126 MessageParcel reply;
127 MessageOption option(MessageOption::TF_ASYNC);
128
129 if (!data.WriteInterfaceToken(ABILITY_MGR_DESCRIPTOR)) {
130 ACCOUNT_LOGE("write interface token failed.");
131 return INNER_ERR;
132 }
133
134 if (!data.WriteInt32(accountId)) {
135 ACCOUNT_LOGE("StartUser:WriteInt32 fail.");
136 return ERR_INVALID_VALUE;
137 }
138
139 if (callback == nullptr) {
140 data.WriteBool(false);
141 } else {
142 data.WriteBool(true);
143 if (!data.WriteRemoteObject(callback->AsObject())) {
144 ACCOUNT_LOGE("StartUser:write IUserCallback fail.");
145 return ERR_INVALID_VALUE;
146 }
147 }
148 error = abms->SendRequest(static_cast<uint32_t>(AbilityManagerInterfaceCode::START_USER), data, reply, option);
149 if (error != NO_ERROR) {
150 ACCOUNT_LOGE("StartUser:SendRequest error: %{public}d", error);
151 return error;
152 }
153
154 return reply.ReadInt32();
155 }
156
StopUser(int32_t accountId,const sptr<AAFwk::IUserCallback> & callback)157 ErrCode AbilityManagerAdapter::StopUser(int32_t accountId, const sptr<AAFwk::IUserCallback> &callback)
158 {
159 auto abms = GetAbilityManager();
160 if (abms == nullptr) {
161 ACCOUNT_LOGE("ability manager proxy is nullptr.");
162 return ERR_ACCOUNT_COMMON_CONNECT_ABILITY_MANAGER_SERVICE_ERROR;
163 }
164
165 int error;
166 MessageParcel data;
167 MessageParcel reply;
168 MessageOption option(MessageOption::TF_ASYNC);
169
170 if (!data.WriteInterfaceToken(ABILITY_MGR_DESCRIPTOR)) {
171 ACCOUNT_LOGE("write interface token failed.");
172 return INNER_ERR;
173 }
174 if (!data.WriteInt32(accountId)) {
175 ACCOUNT_LOGE("StopUser:WriteInt32 fail.");
176 return ERR_INVALID_VALUE;
177 }
178
179 if (callback == nullptr) {
180 data.WriteBool(false);
181 } else {
182 data.WriteBool(true);
183 if (!data.WriteRemoteObject(callback->AsObject())) {
184 ACCOUNT_LOGE("StopUser:write IUserCallback fail.");
185 return ERR_INVALID_VALUE;
186 }
187 }
188 error = abms->SendRequest(static_cast<uint32_t>(AbilityManagerInterfaceCode::STOP_USER), data, reply, option);
189 if (error != NO_ERROR) {
190 ACCOUNT_LOGE("StopUser:SendRequest error: %{public}d", error);
191 return error;
192 }
193 return reply.ReadInt32();
194 }
195
LogoutUser(int32_t accountId)196 ErrCode AbilityManagerAdapter::LogoutUser(int32_t accountId)
197 {
198 auto abms = GetAbilityManager();
199 if (abms == nullptr) {
200 ACCOUNT_LOGE("ability manager proxy is nullptr.");
201 return ERR_ACCOUNT_COMMON_CONNECT_ABILITY_MANAGER_SERVICE_ERROR;
202 }
203
204 MessageParcel data;
205 MessageParcel reply;
206 MessageOption option;
207
208 if (!data.WriteInterfaceToken(ABILITY_MGR_DESCRIPTOR)) {
209 ACCOUNT_LOGE("write interface token failed.");
210 return INNER_ERR;
211 }
212 if (!data.WriteInt32(accountId)) {
213 ACCOUNT_LOGE("write accountId failed.");
214 return ERR_INVALID_VALUE;
215 }
216
217 int32_t errCode =
218 abms->SendRequest(static_cast<uint32_t>(AbilityManagerInterfaceCode::LOGOUT_USER), data, reply, option);
219 if (errCode != NO_ERROR) {
220 ACCOUNT_LOGE("SendRequest error: %{public}d", errCode);
221 return errCode;
222 }
223 if (!reply.ReadInt32(errCode)) {
224 ACCOUNT_LOGE("read result failed.");
225 return ERR_INVALID_VALUE;
226 }
227 return errCode;
228 }
229
DoConnectAbility(const sptr<IRemoteObject> proxy,const AAFwk::Want & want,const sptr<AAFwk::IAbilityConnection> & connect,const sptr<IRemoteObject> & callerToken,int32_t userId)230 ErrCode AbilityManagerAdapter::DoConnectAbility(const sptr<IRemoteObject> proxy, const AAFwk::Want &want,
231 const sptr<AAFwk::IAbilityConnection> &connect, const sptr<IRemoteObject> &callerToken, int32_t userId)
232 {
233 int error;
234 MessageParcel data;
235 MessageParcel reply;
236 MessageOption option;
237
238 if (proxy == nullptr || connect == nullptr) {
239 ACCOUNT_LOGE("connect ability fail, proxy or connect is nullptr");
240 return ERR_INVALID_VALUE;
241 }
242 if (!data.WriteInterfaceToken(ABILITY_MGR_DESCRIPTOR)) {
243 ACCOUNT_LOGE("write interface token failed.");
244 return INNER_ERR;
245 }
246 if (!data.WriteParcelable(&want)) {
247 ACCOUNT_LOGE("want write failed.");
248 return ERR_INVALID_VALUE;
249 }
250 if (connect->AsObject()) {
251 if (!data.WriteBool(true) || !data.WriteRemoteObject(connect->AsObject())) {
252 ACCOUNT_LOGE("flag and connect write failed.");
253 return ERR_INVALID_VALUE;
254 }
255 } else if (!data.WriteBool(false)) {
256 ACCOUNT_LOGE("flag write failed.");
257 return ERR_INVALID_VALUE;
258 }
259 if (callerToken) {
260 if (!data.WriteBool(true) || !data.WriteRemoteObject(callerToken)) {
261 ACCOUNT_LOGE("flag and callerToken write failed.");
262 return ERR_INVALID_VALUE;
263 }
264 } else if (!data.WriteBool(false)) {
265 ACCOUNT_LOGE("flag write failed.");
266 return ERR_INVALID_VALUE;
267 }
268 if (!data.WriteInt32(userId)) {
269 ACCOUNT_LOGE("userId write failed.");
270 return INNER_ERR;
271 }
272 error = proxy->SendRequest(
273 static_cast<uint32_t>(AbilityManagerInterfaceCode::CONNECT_ABILITY), data, reply, option);
274 if (error != NO_ERROR) {
275 ACCOUNT_LOGE("Send request error: %{public}d", error);
276 return error;
277 }
278 return reply.ReadInt32();
279 }
280
GetAbilityManager()281 sptr<IRemoteObject> AbilityManagerAdapter::GetAbilityManager()
282 {
283 std::lock_guard<std::mutex> lock(proxyMutex_);
284 if (!proxy_) {
285 Connect();
286 }
287 return proxy_;
288 }
289
ResetProxy(const wptr<IRemoteObject> & remote)290 void AbilityManagerAdapter::ResetProxy(const wptr<IRemoteObject>& remote)
291 {
292 std::lock_guard<std::mutex> lock(proxyMutex_);
293 if ((proxy_ != nullptr) && (proxy_ == remote.promote())) {
294 proxy_->RemoveDeathRecipient(deathRecipient_);
295 proxy_ = nullptr;
296 }
297 }
298
OnRemoteDied(const wptr<IRemoteObject> & remote)299 void AbilityManagerAdapter::AbilityMgrDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
300 {
301 ACCOUNT_LOGI("AbilityMgrDeathRecipient handle remote died.");
302 AbilityManagerAdapter::GetInstance()->ResetProxy(remote);
303 }
304 } // namespace AAFwk
305 } // namespace OHOS
306