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