1 /*
2  * Copyright (c) 2021-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_connection.h"
17 
18 #include <unistd.h>
19 
20 #include "connection_manager.h"
21 #include "hilog_tag_wrapper.h"
22 
23 namespace OHOS {
24 namespace AbilityRuntime {
25 namespace {
26 constexpr int32_t DIED = -1;
27 } // namespace
28 
OnAbilityConnectDone(const AppExecFwk::ElementName & element,const sptr<IRemoteObject> & remoteObject,int resultCode)29 void AbilityConnection::OnAbilityConnectDone(
30     const AppExecFwk::ElementName& element, const sptr<IRemoteObject>& remoteObject, int resultCode)
31 {
32     TAG_LOGI(AAFwkTag::CONNECTION,
33         "OnAbilityConnectDone, bundleName:%{public}s, abilityName:%{public}s, resultCode:%{public}d",
34         element.GetBundleName().c_str(), element.GetAbilityName().c_str(), resultCode);
35     mutex_.lock();
36     if (abilityConnectCallbackList_.empty()) {
37         TAG_LOGW(AAFwkTag::CONNECTION, "empty callbackList");
38         mutex_.unlock();
39         return;
40     }
41 
42     SetRemoteObject(remoteObject);
43     SetResultCode(resultCode);
44     SetConnectionState(CONNECTION_STATE_CONNECTED);
45 
46     std::vector<sptr<AbilityConnectCallback>> callbacks = GetCallbackList();
47     mutex_.unlock();
48     sptr<AbilityConnection> connection(this);
49     if (ConnectionManager::GetInstance().DisconnectNonexistentService(element, connection)) {
50         TAG_LOGW(AAFwkTag::CONNECTION, "No need onConnect callback");
51         return;
52     }
53 
54     auto item = callbacks.begin();
55     while (item != callbacks.end()) {
56         (*item)->OnAbilityConnectDone(element, remoteObject, resultCode);
57         item++;
58     }
59 }
60 
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)61 void AbilityConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int resultCode)
62 {
63     TAG_LOGI(AAFwkTag::CONNECTION,
64         "OnAbilityDisconnectDone, bundleName:%{public}s, abilityName:%{public}s, resultCode:%{public}d",
65         element.GetBundleName().c_str(), element.GetAbilityName().c_str(), resultCode);
66     mutex_.lock();
67     SetConnectionState(CONNECTION_STATE_DISCONNECTED);
68     if (abilityConnectCallbackList_.empty()) {
69         TAG_LOGE(AAFwkTag::CONNECTION, "empty abilityConnectCallback");
70         mutex_.unlock();
71         return;
72     }
73 
74     std::vector<sptr<AbilityConnectCallback>> callbacks = GetCallbackList();
75     mutex_.unlock();
76 
77     // if resultCode < 0 that means the service is dead
78     if (resultCode == DIED) {
79         sptr<AbilityConnection> connection(this);
80         bool ret = ConnectionManager::GetInstance().RemoveConnection(connection);
81         if (ret) {
82             ConnectionManager::GetInstance().ReportConnectionLeakEvent(getpid(), gettid());
83             TAG_LOGI(AAFwkTag::CONNECTION, "not disconnected");
84         }
85         resultCode = DIED + 1;
86     }
87 
88     auto item = callbacks.begin();
89     while (item != callbacks.end()) {
90         (*item)->OnAbilityDisconnectDone(element, resultCode);
91         item++;
92     }
93     TAG_LOGD(AAFwkTag::CONNECTION, "bundleName:%{public}s, abilityName:%{public}s",
94         element.GetBundleName().c_str(), element.GetAbilityName().c_str());
95     SetRemoteObject(nullptr);
96 }
97 
AddConnectCallback(const sptr<AbilityConnectCallback> & abilityConnectCallback)98 void AbilityConnection::AddConnectCallback(const sptr<AbilityConnectCallback>& abilityConnectCallback)
99 {
100     std::lock_guard<std::mutex> lock(mutex_);
101     auto item = abilityConnectCallbackList_.begin();
102     while (item != abilityConnectCallbackList_.end()) {
103         if (*item == abilityConnectCallback) {
104             return;
105         }
106         item++;
107     }
108     abilityConnectCallbackList_.push_back(abilityConnectCallback);
109 }
110 
RemoveConnectCallback(const sptr<AbilityConnectCallback> & abilityConnectCallback)111 void AbilityConnection::RemoveConnectCallback(const sptr<AbilityConnectCallback>& abilityConnectCallback)
112 {
113     std::lock_guard<std::mutex> lock(mutex_);
114     auto item = abilityConnectCallbackList_.begin();
115     while (item != abilityConnectCallbackList_.end()) {
116         if (*item == abilityConnectCallback) {
117             abilityConnectCallbackList_.erase(item);
118             break;
119         } else {
120             item++;
121         }
122     }
123 }
124 
SetRemoteObject(const sptr<IRemoteObject> & remoteObject)125 void AbilityConnection::SetRemoteObject(const sptr<IRemoteObject>& remoteObject)
126 {
127     remoteObject_ = remoteObject;
128 }
129 
SetResultCode(int resultCode)130 void AbilityConnection::SetResultCode(int resultCode)
131 {
132     resultCode_ = resultCode;
133 }
134 
SetConnectionState(int connectionState)135 void AbilityConnection::SetConnectionState(int connectionState)
136 {
137     connectionState_ = connectionState;
138 }
139 
GetRemoteObject() const140 sptr<IRemoteObject> AbilityConnection::GetRemoteObject() const
141 {
142     return remoteObject_;
143 }
144 
GetResultCode() const145 int AbilityConnection::GetResultCode() const
146 {
147     return resultCode_;
148 }
149 
GetConnectionState() const150 int AbilityConnection::GetConnectionState() const
151 {
152     return connectionState_;
153 }
154 
GetCallbackList()155 std::vector<sptr<AbilityConnectCallback>> AbilityConnection::GetCallbackList()
156 {
157     return abilityConnectCallbackList_;
158 }
159 } // namespace AbilityRuntime
160 } // namespace OHOS
161