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