• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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