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_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 HILOG_DEBUG("%{public}s begin.", __func__);
33 mutex_.lock();
34 if (abilityConnectCallbackList_.empty()) {
35 HILOG_ERROR("%{public}s abilityConnectCallbackList is empty.", __func__);
36 mutex_.unlock();
37 return;
38 }
39
40 SetRemoteObject(remoteObject);
41 SetResultCode(resultCode);
42 SetConnectionState(CONNECTION_STATE_CONNECTED);
43
44 std::vector<sptr<AbilityConnectCallback>> callbacks = GetCallbackList();
45 mutex_.unlock();
46
47 auto item = callbacks.begin();
48 while (item != callbacks.end()) {
49 (*item)->OnAbilityConnectDone(element, remoteObject, resultCode);
50 item++;
51 }
52 HILOG_DEBUG("%{public}s end, bundleName:%{public}s, abilityName:%{public}s.",
53 __func__, element.GetBundleName().c_str(), element.GetAbilityName().c_str());
54 }
55
OnAbilityDisconnectDone(const AppExecFwk::ElementName & element,int resultCode)56 void AbilityConnection::OnAbilityDisconnectDone(const AppExecFwk::ElementName& element, int resultCode)
57 {
58 HILOG_DEBUG("%{public}s begin, resultCode:%{public}d.", __func__, resultCode);
59 mutex_.lock();
60 SetConnectionState(CONNECTION_STATE_DISCONNECTED);
61 if (abilityConnectCallbackList_.empty()) {
62 HILOG_ERROR("%{public}s abilityConnectCallback is empty.", __func__);
63 mutex_.unlock();
64 return;
65 }
66 // if resultCode < 0 that means the service is dead
67 if (resultCode == DIED) {
68 sptr<AbilityConnection> connection(this);
69 bool ret = ConnectionManager::GetInstance().RemoveConnection(connection);
70 if (ret) {
71 ConnectionManager::GetInstance().ReportConnectionLeakEvent(getpid(), gettid());
72 HILOG_INFO("The service connection is not disconnected.");
73 }
74 resultCode = DIED + 1;
75 }
76
77 std::vector<sptr<AbilityConnectCallback>> callbacks = GetCallbackList();
78 mutex_.unlock();
79
80 auto item = callbacks.begin();
81 while (item != callbacks.end()) {
82 (*item)->OnAbilityDisconnectDone(element, resultCode);
83 item++;
84 }
85 HILOG_DEBUG("%{public}s end, bundleName:%{public}s, abilityName:%{public}s.",
86 __func__, element.GetBundleName().c_str(), element.GetAbilityName().c_str());
87 }
88
AddConnectCallback(const sptr<AbilityConnectCallback> & abilityConnectCallback)89 void AbilityConnection::AddConnectCallback(const sptr<AbilityConnectCallback>& abilityConnectCallback)
90 {
91 std::lock_guard<std::mutex> lock(mutex_);
92 auto item = abilityConnectCallbackList_.begin();
93 while (item != abilityConnectCallbackList_.end()) {
94 if (*item == abilityConnectCallback) {
95 return;
96 }
97 item++;
98 }
99 abilityConnectCallbackList_.push_back(abilityConnectCallback);
100 }
101
RemoveConnectCallback(const sptr<AbilityConnectCallback> & abilityConnectCallback)102 void AbilityConnection::RemoveConnectCallback(const sptr<AbilityConnectCallback>& abilityConnectCallback)
103 {
104 std::lock_guard<std::mutex> lock(mutex_);
105 auto item = abilityConnectCallbackList_.begin();
106 while (item != abilityConnectCallbackList_.end()) {
107 if (*item == abilityConnectCallback) {
108 abilityConnectCallbackList_.erase(item);
109 break;
110 } else {
111 item++;
112 }
113 }
114 }
115
SetRemoteObject(const sptr<IRemoteObject> & remoteObject)116 void AbilityConnection::SetRemoteObject(const sptr<IRemoteObject>& remoteObject)
117 {
118 remoteObject_ = remoteObject;
119 }
120
SetResultCode(int resultCode)121 void AbilityConnection::SetResultCode(int resultCode)
122 {
123 resultCode_ = resultCode;
124 }
125
SetConnectionState(int connectionState)126 void AbilityConnection::SetConnectionState(int connectionState)
127 {
128 connectionState_ = connectionState;
129 }
130
GetRemoteObject() const131 sptr<IRemoteObject> AbilityConnection::GetRemoteObject() const
132 {
133 return remoteObject_;
134 }
135
GetResultCode() const136 int AbilityConnection::GetResultCode() const
137 {
138 return resultCode_;
139 }
140
GetConnectionState() const141 int AbilityConnection::GetConnectionState() const
142 {
143 return connectionState_;
144 }
145
GetCallbackList()146 std::vector<sptr<AbilityConnectCallback>> AbilityConnection::GetCallbackList()
147 {
148 return abilityConnectCallbackList_;
149 }
150 } // namespace AbilityRuntime
151 } // namespace OHOS
152