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