1 /*
2 * Copyright (c) 2020 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_service_manager.h"
17
18 #include <log.h>
19
20 #include "ability_kit_command.h"
21 #include "ability_service_interface.h"
22 #include "abilityms_client.h"
23 #include "ohos_errno.h"
24 #include "securec.h"
25 #include "utils.h"
26 #include "want.h"
27
28 namespace OHOS {
~AbilityServiceManager()29 AbilityServiceManager::~AbilityServiceManager()
30 {
31 for (const auto &storeArgs : storeList_) {
32 if (storeArgs == nullptr) {
33 continue;
34 }
35 if (storeArgs->sid != nullptr) {
36 UnregisterIpcCallback(*(storeArgs->sid));
37 delete storeArgs->sid;
38 }
39 delete storeArgs;
40 }
41 storeList_.clear();
42 }
43
ConnectAbility(const Want & want,const IAbilityConnection & conn,uint64_t token,void * storeArg)44 int AbilityServiceManager::ConnectAbility(const Want &want, const IAbilityConnection &conn, uint64_t token, void *storeArg)
45 {
46 if (conn.OnAbilityDisconnectDone == nullptr || conn.OnAbilityConnectDone == nullptr) {
47 HILOG_INFO(HILOG_MODULE_APP, "IAbilityConnection callback func is null");
48 return LITEIPC_EINVAL;
49 }
50
51 StoreArgs *storeArgs = AddStoreArgs(conn, storeArg);
52 if (storeArgs == nullptr) {
53 return LITEIPC_EINVAL;
54 }
55 AbilityMsClient::GetInstance().Initialize();
56 int32_t result = RegisterIpcCallback(ConnectAbilityCallBack, 0, IPC_WAIT_FOREVER, storeArgs->sid, storeArgs);
57 if (result != LITEIPC_OK) {
58 RemoveStoreArgs(nullptr, storeArgs);
59 delete storeArgs->sid;
60 delete storeArgs;
61 return result;
62 }
63 result = AbilityMsClient::GetInstance().ScheduleAms(&want, token, storeArgs->sid, CONNECT_ABILITY);
64 if (result != EC_SUCCESS) {
65 UnregisterIpcCallback(*(storeArgs->sid));
66 RemoveStoreArgs(nullptr, storeArgs);
67 delete storeArgs->sid;
68 delete storeArgs;
69 }
70 return result;
71 }
72
DisconnectAbility(const IAbilityConnection & conn,uint64_t token)73 int AbilityServiceManager::DisconnectAbility(const IAbilityConnection &conn, uint64_t token)
74 {
75 StoreArgs *storeArgs = RemoveStoreArgs(&conn, nullptr);
76 if (storeArgs == nullptr) {
77 HILOG_INFO(HILOG_MODULE_APP, "no need to disconnect");
78 return LITEIPC_EINVAL;
79 }
80 int result = AbilityMsClient::GetInstance().ScheduleAms(nullptr, token, storeArgs->sid, DISCONNECT_ABILITY);
81
82 ClearStore(storeArgs);
83 return result;
84 }
85
AddStoreArgs(const IAbilityConnection & conn,void * storeArg)86 StoreArgs *AbilityServiceManager::AddStoreArgs(const IAbilityConnection &conn, void *storeArg)
87 {
88 std::lock_guard<std::mutex> lock(mutex_);
89 if (GetStoreArgs(conn) != nullptr) {
90 HILOG_ERROR(HILOG_MODULE_APP, "func has already used");
91 return nullptr;
92 }
93 StoreArgs *storeArgs = new StoreArgs();
94 storeArgs->conn = &conn;
95 storeArgs->storeArg = storeArg;
96 storeArgs->sid = new SvcIdentity();
97 storeList_.emplace_back(storeArgs);
98
99 return storeArgs;
100 }
101
GetStoreArgs(const IAbilityConnection & conn) const102 StoreArgs *AbilityServiceManager::GetStoreArgs(const IAbilityConnection &conn) const
103 {
104 for (const auto storeArgs : storeList_) {
105 if (storeArgs->conn == &conn) {
106 return storeArgs;
107 }
108 }
109 return nullptr;
110 }
111
RemoveStoreArgs(const IAbilityConnection * conn,StoreArgs * storeArgs)112 StoreArgs *AbilityServiceManager::RemoveStoreArgs(const IAbilityConnection *conn, StoreArgs *storeArgs)
113 {
114 std::lock_guard<std::mutex> lock(mutex_);
115 if (storeArgs == nullptr) {
116 storeArgs = GetStoreArgs(*conn);
117 }
118 storeList_.remove(storeArgs);
119
120 return storeArgs;
121 }
122
ConnectAbilityCallBack(const IpcContext * context,void * ipcMsg,IpcIo * data,void * arg)123 int32_t AbilityServiceManager::ConnectAbilityCallBack(const IpcContext* context, void *ipcMsg, IpcIo *data, void *arg)
124 {
125 // param check
126 StoreArgs *storeArgs = static_cast<StoreArgs *>(arg);
127 if (storeArgs == nullptr || ipcMsg == nullptr || storeArgs->conn == nullptr ||
128 storeArgs->conn->OnAbilityConnectDone == nullptr || storeArgs->conn->OnAbilityDisconnectDone == nullptr) {
129 HILOG_ERROR(HILOG_MODULE_APP, "storeArgs or callback func or ipcMsg is null");
130 AbilityServiceManager::GetInstance().RemoveStoreArgs(nullptr, storeArgs);
131 ClearStore(storeArgs);
132 FreeBuffer(nullptr, ipcMsg);
133 return LITEIPC_EINVAL;
134 }
135
136 // parse funcId
137 uint32_t funcId = 0;
138 GetCode(ipcMsg, &funcId);
139 int resultCode = (funcId != SCHEDULER_ABILITY_CONNECT_FAIL) ? 0 : -1;
140 // parse service sid
141 SvcIdentity *serviceSid = (funcId == SCHEDULER_ABILITY_CONNECT) ? IpcIoPopSvc(data) : nullptr;
142 if ((funcId == SCHEDULER_ABILITY_CONNECT) && (serviceSid == nullptr)) {
143 resultCode = -1;
144 }
145 // parse element
146 ElementName elementName = { nullptr };
147 if (!DeserializeElement(&elementName, data)) {
148 resultCode = -1;
149 }
150 if (funcId == SCHEDULER_ABILITY_DISCONNECT) {
151 storeArgs->conn->OnAbilityDisconnectDone(&elementName, resultCode, storeArgs->storeArg);
152 } else {
153 storeArgs->conn->OnAbilityConnectDone(&elementName, serviceSid, resultCode, storeArgs->storeArg);
154 }
155 if (funcId != SCHEDULER_ABILITY_CONNECT || resultCode == -1) {
156 AbilityServiceManager::GetInstance().RemoveStoreArgs(nullptr, storeArgs);
157 ClearStore(storeArgs);
158 }
159 #ifdef __LINUX__
160 AdapterFree(serviceSid);
161 serviceSid = nullptr;
162 #endif
163 ClearElement(&elementName);
164 FreeBuffer(nullptr, ipcMsg);
165 return LITEIPC_OK;
166 }
167
ClearStore(StoreArgs * storeArgs)168 void AbilityServiceManager::ClearStore(StoreArgs *storeArgs)
169 {
170 if ((storeArgs == nullptr) || (storeArgs->sid == nullptr)) {
171 HILOG_INFO(HILOG_MODULE_APP, "no need to clear storeArgs");
172 return;
173 }
174 UnregisterIpcCallback(*(storeArgs->sid));
175 delete storeArgs->sid;
176 delete storeArgs;
177 }
178 } // namespace OHOS
179