1 /*
2  * Copyright (c) 2022-2024 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 #include "local_call_record.h"
16 
17 #include "hilog_tag_wrapper.h"
18 
19 namespace OHOS {
20 namespace AbilityRuntime {
21 namespace {
22 constexpr int32_t FOREGROUND = 2;
23 constexpr int32_t BACKGROUND = 4;
24 }
25 int64_t LocalCallRecord::callRecordId = 0;
LocalCallRecord(const AppExecFwk::ElementName & elementName)26 LocalCallRecord::LocalCallRecord(const AppExecFwk::ElementName& elementName)
27 {
28     recordId_ = callRecordId++;
29     elementName_ = elementName;
30 }
31 
~LocalCallRecord()32 LocalCallRecord::~LocalCallRecord()
33 {
34     ClearData();
35 }
36 
ClearData()37 void LocalCallRecord::ClearData()
38 {
39     if (remoteObject_ == nullptr) {
40         return;
41     }
42 
43     if (callRecipient_) {
44         remoteObject_->RemoveDeathRecipient(callRecipient_);
45         callRecipient_ = nullptr;
46     }
47 
48     callers_.clear();
49     remoteObject_ = nullptr;
50 }
51 
SetRemoteObject(const sptr<IRemoteObject> & call)52 void LocalCallRecord::SetRemoteObject(const sptr<IRemoteObject>& call)
53 {
54     if (call == nullptr) {
55         TAG_LOGE(AAFwkTag::LOCAL_CALL, "object is nullptr");
56         return;
57     }
58 
59     remoteObject_ = call;
60     if (callRecipient_ == nullptr) {
61         auto self(weak_from_this());
62         auto diedTask = [self](const wptr<IRemoteObject>& remote) {
63             auto record = self.lock();
64             if (record == nullptr) {
65                 TAG_LOGE(AAFwkTag::LOCAL_CALL, "OnCallStubDied failed");
66                 return;
67             }
68             record->OnCallStubDied(remote);
69         };
70         callRecipient_ = new CallRecipient(diedTask);
71     }
72     remoteObject_->AddDeathRecipient(callRecipient_);
73 }
74 
SetRemoteObject(const sptr<IRemoteObject> & call,sptr<IRemoteObject::DeathRecipient> callRecipient)75 void LocalCallRecord::SetRemoteObject(const sptr<IRemoteObject>& call,
76     sptr<IRemoteObject::DeathRecipient> callRecipient)
77 {
78     if (call == nullptr) {
79         TAG_LOGE(AAFwkTag::LOCAL_CALL, "object is nullptr");
80         return;
81     }
82 
83     remoteObject_ = call;
84     callRecipient_ = callRecipient;
85 
86     remoteObject_->AddDeathRecipient(callRecipient_);
87 }
88 
AddCaller(const std::shared_ptr<CallerCallBack> & callback)89 void LocalCallRecord::AddCaller(const std::shared_ptr<CallerCallBack>& callback)
90 {
91     if (callback == nullptr) {
92         TAG_LOGE(AAFwkTag::LOCAL_CALL, "param is nullptr");
93         return;
94     }
95 
96     callback->SetRecord(weak_from_this());
97     callers_.emplace_back(callback);
98 }
99 
RemoveCaller(const std::shared_ptr<CallerCallBack> & callback)100 bool LocalCallRecord::RemoveCaller(const std::shared_ptr<CallerCallBack>& callback)
101 {
102     if (callers_.empty()) {
103         TAG_LOGE(AAFwkTag::LOCAL_CALL, "caller is empty.");
104         return false;
105     }
106 
107     auto iter = std::find(callers_.begin(), callers_.end(), callback);
108     if (iter != callers_.end()) {
109         callback->InvokeOnRelease(ON_RELEASE);
110         callers_.erase(iter);
111         return true;
112     }
113 
114     TAG_LOGE(AAFwkTag::LOCAL_CALL, "callback not find");
115     return false;
116 }
117 
OnCallStubDied(const wptr<IRemoteObject> & remote)118 void LocalCallRecord::OnCallStubDied(const wptr<IRemoteObject>& remote)
119 {
120     TAG_LOGD(AAFwkTag::LOCAL_CALL, "call");
121     for (auto& callBack : callers_) {
122         if (callBack != nullptr) {
123             TAG_LOGE(AAFwkTag::LOCAL_CALL, "callBack is nullptr");
124             callBack->InvokeOnRelease(ON_DIED);
125         }
126     }
127 }
128 
InvokeCallBack() const129 void LocalCallRecord::InvokeCallBack() const
130 {
131     if (remoteObject_ == nullptr) {
132         TAG_LOGE(AAFwkTag::LOCAL_CALL, "object is nullptr");
133         return;
134     }
135 
136     for (auto& callBack : callers_) {
137         if (callBack != nullptr && !callBack->IsCallBack()) {
138             callBack->InvokeCallBack(remoteObject_);
139         }
140     }
141 }
142 
NotifyRemoteStateChanged(int32_t abilityState)143 void LocalCallRecord::NotifyRemoteStateChanged(int32_t abilityState)
144 {
145     if (remoteObject_ == nullptr) {
146         TAG_LOGE(AAFwkTag::LOCAL_CALL, "object is nullptr");
147         return;
148     }
149     std::string state = "";
150     if (abilityState == FOREGROUND) {
151         state = "foreground";
152     } else if (abilityState == BACKGROUND) {
153         state = "background";
154     }
155 
156     for (auto& callBack : callers_) {
157         if (callBack != nullptr && callBack->IsCallBack()) {
158             TAG_LOGI(AAFwkTag::LOCAL_CALL, "callback is not nullptr and is callbcak ");
159             callBack->InvokeOnNotify(state);
160         }
161     }
162 }
163 
GetRemoteObject() const164 sptr<IRemoteObject> LocalCallRecord::GetRemoteObject() const
165 {
166     return remoteObject_;
167 }
168 
GetElementName() const169 AppExecFwk::ElementName LocalCallRecord::GetElementName() const
170 {
171     return elementName_;
172 }
173 
IsExistCallBack() const174 bool LocalCallRecord::IsExistCallBack() const
175 {
176     return !callers_.empty();
177 }
178 
GetRecordId() const179 int LocalCallRecord::GetRecordId() const
180 {
181     return recordId_;
182 }
183 
GetCallers() const184 std::vector<std::shared_ptr<CallerCallBack>> LocalCallRecord::GetCallers() const
185 {
186     return callers_;
187 }
188 
IsSameObject(const sptr<IRemoteObject> & remote) const189 bool LocalCallRecord::IsSameObject(const sptr<IRemoteObject>& remote) const
190 {
191     if (remote == nullptr) {
192         TAG_LOGE(AAFwkTag::LOCAL_CALL, "input remote object is nullptr");
193         return false;
194     }
195 
196     bool retVal = (remoteObject_ == remote);
197     TAG_LOGD(AAFwkTag::LOCAL_CALL, "remoteObject_ matches remote: %{public}s", retVal ? "true" : "false");
198     return retVal;
199 }
200 
SetIsSingleton(bool flag)201 void LocalCallRecord::SetIsSingleton(bool flag)
202 {
203     isSingleton_ = flag;
204 }
205 
IsSingletonRemote()206 bool LocalCallRecord::IsSingletonRemote()
207 {
208     return isSingleton_;
209 }
210 
SetConnection(const sptr<IRemoteObject> & connect)211 void LocalCallRecord::SetConnection(const sptr<IRemoteObject> &connect)
212 {
213     connection_ = connect;
214 }
215 
GetConnection()216 sptr<IRemoteObject> LocalCallRecord::GetConnection()
217 {
218     return connection_.promote();
219 }
220 
SetUserId(int32_t userId)221 void LocalCallRecord::SetUserId(int32_t userId)
222 {
223     userId_ = userId;
224 }
225 
GetUserId() const226 int32_t LocalCallRecord::GetUserId() const
227 {
228     return userId_;
229 }
230 } // namespace AbilityRuntime
231 } // namespace OHOS
232