1 /*
2  * Copyright (c) 2022-2023 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 "form_caller_mgr.h"
17 
18 #include "fms_log_wrapper.h"
19 #include "form_js_info.h"
20 
21 namespace OHOS {
22 namespace AppExecFwk {
23 namespace {
24 constexpr int32_t FORM_TASK_DELAY_TIME = 20; // ms
25 const std::string NAME_FORM_CALLER_MGR = "FormCallerMgr";
26 }
FormCallerMgr()27 FormCallerMgr::FormCallerMgr()
28 {
29     HILOG_DEBUG("call");
30 }
31 
~FormCallerMgr()32 FormCallerMgr::~FormCallerMgr()
33 {
34     HILOG_DEBUG("call");
35 }
36 
AddFormHostCaller(const FormJsInfo & formJsInfo,const sptr<IRemoteObject> & callerToken)37 void FormCallerMgr::AddFormHostCaller(const FormJsInfo &formJsInfo, const sptr<IRemoteObject> &callerToken)
38 {
39     HILOG_DEBUG("call");
40     std::lock_guard<std::mutex> lock(formHostCallerMutex_);
41     std::shared_ptr<FormHostCaller> caller = std::make_shared<FormHostCaller>(formJsInfo, callerToken);
42     formHostCallers_[formJsInfo.formId] = caller;
43 
44     sptr<IRemoteObject::DeathRecipient> deathRecipient =
45         new (std::nothrow) FormHostCallerRecipient([](const wptr<IRemoteObject> &remote) {
46             FormCallerMgr::GetInstance().OnHostCallBackDied(remote);
47         });
48     if (deathRecipient == nullptr) {
49         HILOG_ERROR("create FormHostCallerRecipient error");
50     } else {
51         caller->AddDeathRecipient(deathRecipient);
52     }
53 }
54 
GetFormHostCaller(int64_t formId)55 std::shared_ptr<FormHostCaller> FormCallerMgr::GetFormHostCaller(int64_t formId)
56 {
57     HILOG_DEBUG("call");
58     std::lock_guard<std::mutex> lock(formHostCallerMutex_);
59     auto iter = formHostCallers_.find(formId);
60     if (iter == formHostCallers_.end()) {
61         return nullptr;
62     }
63     return iter->second;
64 }
65 
RemoveFormHostCaller(int64_t formId)66 void FormCallerMgr::RemoveFormHostCaller(int64_t formId)
67 {
68     HILOG_DEBUG("call");
69     std::lock_guard<std::mutex> lock(formHostCallerMutex_);
70     formHostCallers_.erase(formId);
71 }
72 
73 
RemoveFormHostCaller(const sptr<IRemoteObject> & callerToken)74 void FormCallerMgr::RemoveFormHostCaller(const sptr<IRemoteObject> &callerToken)
75 {
76     HILOG_DEBUG("call");
77     std::lock_guard<std::mutex> lock(formHostCallerMutex_);
78     for (auto iter = formHostCallers_.begin(); iter != formHostCallers_.end();) {
79         if (iter->second != nullptr && iter->second->IsSameToken(callerToken)) {
80             iter = formHostCallers_.erase(iter);
81         } else {
82             ++iter;
83         }
84     }
85 }
86 
OnHostCallBackDied(const wptr<IRemoteObject> & remote)87 void FormCallerMgr::OnHostCallBackDied(const wptr<IRemoteObject> &remote)
88 {
89     HILOG_DEBUG("call");
90     auto object = remote.promote();
91     if (object == nullptr) {
92         HILOG_ERROR("null object");
93         return;
94     }
95     auto hostCallBackDiedFunc = [object]() {
96         FormCallerMgr::GetInstance().HandleHostCallBackDiedTask(object);
97     };
98 
99     auto handler = GetEventHandler();
100     handler->PostTask(hostCallBackDiedFunc, FORM_TASK_DELAY_TIME);
101 }
102 
HandleHostCallBackDiedTask(const sptr<IRemoteObject> & remote)103 void FormCallerMgr::HandleHostCallBackDiedTask(const sptr<IRemoteObject> &remote)
104 {
105     RemoveFormHostCaller(remote);
106 }
107 
AddFormProviderCaller(const FormJsInfo & formJsInfo,const sptr<IRemoteObject> & callerToken)108 void FormCallerMgr::AddFormProviderCaller(const FormJsInfo &formJsInfo, const sptr<IRemoteObject> &callerToken)
109 {
110     HILOG_DEBUG("call");
111     std::lock_guard<std::mutex> lock(formProviderCallerMutex_);
112     for (const auto &formProviderCaller : formProviderCallers_) {
113         if (formProviderCaller->IsSameToken(callerToken)) {
114             formProviderCaller->AddForm(formJsInfo);
115             return;
116         }
117     }
118 
119     std::shared_ptr<FormProviderCaller> caller = std::make_shared<FormProviderCaller>(callerToken);
120     caller->AddForm(formJsInfo);
121     formProviderCallers_.emplace_back(caller);
122 
123     sptr<IRemoteObject::DeathRecipient> deathRecipient =
124         new (std::nothrow) FormProviderCallerRecipient([](const wptr<IRemoteObject> &remote) {
125             FormCallerMgr::GetInstance().OnProviderCallBackDied(remote);
126         });
127     if (deathRecipient == nullptr) {
128         HILOG_ERROR("create FormProviderCallerRecipient error");
129     } else {
130         caller->AddDeathRecipient(deathRecipient);
131     }
132 }
133 
GetFormProviderCaller(int64_t formId,std::vector<std::shared_ptr<FormProviderCaller>> & formProviderCallers)134 void FormCallerMgr::GetFormProviderCaller(int64_t formId,
135     std::vector<std::shared_ptr<FormProviderCaller>> &formProviderCallers)
136 {
137     HILOG_DEBUG("call");
138     std::lock_guard<std::mutex> lock(formProviderCallerMutex_);
139     for (const auto &formProviderCaller : formProviderCallers_) {
140         if (formProviderCaller->HasForm(formId)) {
141             formProviderCallers.emplace_back(formProviderCaller);
142         }
143     }
144 }
145 
RemoveFormProviderCaller(int64_t formId,const sptr<IRemoteObject> & callerToken)146 void FormCallerMgr::RemoveFormProviderCaller(int64_t formId, const sptr<IRemoteObject> &callerToken)
147 {
148     HILOG_DEBUG("call");
149     std::lock_guard<std::mutex> lock(formProviderCallerMutex_);
150     for (auto iter = formProviderCallers_.begin(); iter != formProviderCallers_.end(); ++iter) {
151         if ((*iter)->IsSameToken(callerToken)) {
152             continue;
153         }
154         (*iter)->DeleteForm(formId);
155         if ((*iter)->IsFormEmpty()) {
156             iter = formProviderCallers_.erase(iter);
157         }
158         break;
159     }
160 }
161 
RemoveFormProviderCaller(const sptr<IRemoteObject> & callerToken)162 void FormCallerMgr::RemoveFormProviderCaller(const sptr<IRemoteObject> &callerToken)
163 {
164     HILOG_DEBUG("call");
165     std::lock_guard<std::mutex> lock(formProviderCallerMutex_);
166     for (auto iter = formProviderCallers_.begin(); iter != formProviderCallers_.end();) {
167         if ((*iter)->IsSameToken(callerToken)) {
168             ++iter;
169         } else {
170             iter = formProviderCallers_.erase(iter);
171         }
172     }
173 }
174 
OnProviderCallBackDied(const wptr<IRemoteObject> & remote)175 void FormCallerMgr::OnProviderCallBackDied(const wptr<IRemoteObject> &remote)
176 {
177     HILOG_DEBUG("call");
178     auto object = remote.promote();
179     if (object == nullptr) {
180         HILOG_ERROR("null object");
181         return;
182     }
183     auto providerCallBackDiedFunc = [object]() {
184         FormCallerMgr::GetInstance().HandleProviderCallBackDiedTask(object);
185     };
186 
187     auto handler = GetEventHandler();
188     handler->PostTask(providerCallBackDiedFunc, FORM_TASK_DELAY_TIME);
189 }
190 
HandleProviderCallBackDiedTask(const sptr<IRemoteObject> & remote)191 void FormCallerMgr::HandleProviderCallBackDiedTask(const sptr<IRemoteObject> &remote)
192 {
193     RemoveFormProviderCaller(remote);
194 }
195 
GetEventHandler()196 std::shared_ptr<EventHandler> FormCallerMgr::GetEventHandler()
197 {
198     HILOG_DEBUG("call");
199     if (eventHandler_ == nullptr) {
200         auto runner = EventRunner::Create(NAME_FORM_CALLER_MGR);
201         if (runner == nullptr) {
202             HILOG_ERROR("create runner error");
203             return nullptr;
204         }
205 
206         eventHandler_ = std::make_shared<EventHandler>(runner);
207         if (eventHandler_ == nullptr) {
208             HILOG_ERROR("create event handler error");
209             return nullptr;
210         }
211     }
212 
213     return eventHandler_;
214 }
215 } // namespace AppExecFwk
216 } // namespace OHOS
217