1 /*
2  * Copyright (c) 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 "session_listener_controller.h"
17 
18 
19 namespace OHOS {
20 namespace Rosen {
21 namespace {
22 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "SessionListenerController"};
23 const std::string THREAD_NAME = "OS_SessionListener";
24 }
25 
SessionListenerController()26 SessionListenerController::SessionListenerController()
27 {
28 }
29 
~SessionListenerController()30 SessionListenerController::~SessionListenerController()
31 {}
32 
Init()33 void SessionListenerController::Init()
34 {
35     if (!taskScheduler_) {
36         taskScheduler_ = std::make_shared<TaskScheduler>(THREAD_NAME);
37     }
38 }
39 
AddSessionListener(const sptr<ISessionListener> & listener)40 WSError SessionListenerController::AddSessionListener(const sptr<ISessionListener>& listener)
41 {
42     if (!listener) {
43         WLOGFE("listener is invalid");
44         return WSError::WS_ERROR_INVALID_PARAM;
45     }
46 
47     std::lock_guard<ffrt::mutex> guard(listenerLock_);
48     auto it = std::find_if(sessionListeners_.begin(), sessionListeners_.end(),
49                            [&listener](const sptr<ISessionListener>& item) {
50                                return (item && item->AsObject() == listener->AsObject());
51                            });
52     if (it != sessionListeners_.end()) {
53         WLOGFW("listener was already added, do not add again");
54         return WSError::WS_OK;
55     }
56 
57     if (!listenerDeathRecipient_) {
58         std::weak_ptr<SessionListenerController> thisWeakPtr(shared_from_this());
59         listenerDeathRecipient_ = new ListenerDeathRecipient([thisWeakPtr](const wptr<IRemoteObject>& remote) {
60             auto controller = thisWeakPtr.lock();
61             if (controller) {
62                 controller->OnListenerDied(remote);
63             }
64         });
65     }
66     auto listenerObject = listener->AsObject();
67     if (listenerObject) {
68         listenerObject->AddDeathRecipient(listenerDeathRecipient_);
69     }
70     WLOGFI("Add SessionListener");
71     sessionListeners_.emplace_back(listener);
72 
73     return WSError::WS_OK;
74 }
75 
DelSessionListener(const sptr<ISessionListener> & listener)76 void SessionListenerController::DelSessionListener(const sptr<ISessionListener>& listener)
77 {
78     if (!listener) {
79         WLOGFE("listener is invalid");
80         return;
81     }
82 
83     std::lock_guard<ffrt::mutex> guard(listenerLock_);
84     auto it = std::find_if(sessionListeners_.begin(), sessionListeners_.end(),
85                            [&listener](const sptr<ISessionListener> item) {
86                                return (item && item->AsObject() == listener->AsObject());
87                            });
88     if (it != sessionListeners_.end()) {
89         WLOGFI("Delete SessionListener");
90         sessionListeners_.erase(it);
91     }
92 }
93 
NotifySessionCreated(int32_t persistentId)94 void SessionListenerController::NotifySessionCreated(int32_t persistentId)
95 {
96     if (persistentId == -1) {
97         return;
98     }
99 
100     if (!taskScheduler_) {
101         WLOGFE("taskScheduler is null");
102         return;
103     }
104     auto task = [weak = weak_from_this(), persistentId]() {
105         auto self = weak.lock();
106         if (self == nullptr) {
107             WLOGFE("self is nullptr, NotifySessionCreated failed");
108             return;
109         }
110         WLOGFI("NotifySessionCreated, persistentId:%{public}d.", persistentId);
111         self->CallListeners(&ISessionListener::OnMissionCreated, persistentId);
112     };
113     taskScheduler_->PostVoidSyncTask(task, "NotifySessionCreated:PID:" + std::to_string(persistentId));
114 }
115 
NotifySessionDestroyed(int32_t persistentId)116 void SessionListenerController::NotifySessionDestroyed(int32_t persistentId)
117 {
118     if (persistentId == -1) {
119         return;
120     }
121 
122     if (!taskScheduler_) {
123         WLOGFE("taskScheduler is null");
124         return;
125     }
126     auto task = [weak = weak_from_this(), persistentId]() {
127         auto self = weak.lock();
128         if (self == nullptr) {
129             WLOGFE("self is nullptr, NotifySessionDestroyed failed");
130             return;
131         }
132         WLOGFI("NotifySessionDestroyed, persistentId:%{public}d.", persistentId);
133         self->CallListeners(&ISessionListener::OnMissionDestroyed, persistentId);
134     };
135     taskScheduler_->PostVoidSyncTask(task, "NotifySessionDestroyed:PID:" + std::to_string(persistentId));
136 }
137 
HandleUnInstallApp(const std::list<int32_t> & sessions)138 void SessionListenerController::HandleUnInstallApp(const std::list<int32_t>& sessions)
139 {
140     if (sessions.empty()) {
141         return;
142     }
143 
144     if (!taskScheduler_) {
145         WLOGFE("taskScheduler is null");
146         return;
147     }
148     auto task = [weak = weak_from_this(), sessions]() {
149         auto self = weak.lock();
150         if (self == nullptr) {
151             WLOGFE("self is nullptr, HandleUnInstallApp failed");
152             return;
153         }
154         for (auto id : sessions) {
155             self->CallListeners(&ISessionListener::OnMissionDestroyed, id);
156         }
157     };
158     taskScheduler_->PostVoidSyncTask(task, "HandleUnInstallApp");
159 }
160 
NotifySessionSnapshotChanged(int32_t persistentId)161 void SessionListenerController::NotifySessionSnapshotChanged(int32_t persistentId)
162 {
163     if (persistentId == -1) {
164         return;
165     }
166 
167     if (!taskScheduler_) {
168         WLOGFE("taskScheduler is null");
169         return;
170     }
171     auto task = [weak = weak_from_this(), persistentId]() {
172         auto self = weak.lock();
173         if (self == nullptr) {
174             WLOGFE("self is nullptr, NotifySessionSnapshotChanged failed");
175             return;
176         }
177         WLOGFI("NotifySessionSnapshotChanged, persistentId:%{public}d.", persistentId);
178         self->CallListeners(&ISessionListener::OnMissionSnapshotChanged, persistentId);
179     };
180     taskScheduler_->PostVoidSyncTask(task, "NotifySessionSnapshotChanged:PID:" + std::to_string(persistentId));
181 }
182 
NotifySessionMovedToFront(int32_t persistentId)183 void SessionListenerController::NotifySessionMovedToFront(int32_t persistentId)
184 {
185     if (persistentId == -1) {
186         return;
187     }
188 
189     if (!taskScheduler_) {
190         WLOGFE("taskScheduler is null");
191         return;
192     }
193     auto task = [weak = weak_from_this(), persistentId]() {
194         auto self = weak.lock();
195         if (self == nullptr) {
196             WLOGFE("self is nullptr, NotifySessionMovedToFront failed");
197             return;
198         }
199         WLOGFI("NotifySessionMovedToFront, persistentId:%{public}d.", persistentId);
200         self->CallListeners(&ISessionListener::OnMissionMovedToFront, persistentId);
201     };
202     taskScheduler_->PostVoidSyncTask(task, "NotifySessionMovedToFront" + std::to_string(persistentId));
203 }
204 
NotifySessionFocused(int32_t persistentId)205 void SessionListenerController::NotifySessionFocused(int32_t persistentId)
206 {
207     if (persistentId == -1) {
208         return;
209     }
210 
211     if (!taskScheduler_) {
212         WLOGFE("taskScheduler is null");
213         return;
214     }
215     auto task = [weak = weak_from_this(), persistentId]() {
216         auto self = weak.lock();
217         if (self == nullptr) {
218             TLOGE(WmsLogTag::WMS_FOCUS, "self is nullptr, NotifySessionFocused failed");
219             return;
220         }
221         TLOGI(WmsLogTag::WMS_FOCUS, "NotifySessionFocused, persistentId:%{public}d.", persistentId);
222         self->CallListeners(&ISessionListener::OnMissionFocused, persistentId);
223     };
224     taskScheduler_->PostVoidSyncTask(task, "NotifySessionFocused" + std::to_string(persistentId));
225 }
226 
NotifySessionUnfocused(int32_t persistentId)227 void SessionListenerController::NotifySessionUnfocused(int32_t persistentId)
228 {
229     if (persistentId == -1) {
230         return;
231     }
232 
233     if (!taskScheduler_) {
234         WLOGFE("taskScheduler is null");
235         return;
236     }
237     auto task = [weak = weak_from_this(), persistentId]() {
238         auto self = weak.lock();
239         if (self == nullptr) {
240             TLOGD(WmsLogTag::WMS_FOCUS, "self is nullptr, NotifySessionUnfocused failed");
241             return;
242         }
243         TLOGI(WmsLogTag::WMS_FOCUS, "NotifySessionUnfocused, persistentId:%{public}d.", persistentId);
244         self->CallListeners(&ISessionListener::OnMissionUnfocused, persistentId);
245     };
246     taskScheduler_->PostVoidSyncTask(task, "NotifySessionUnfocused:PID:" + std::to_string(persistentId));
247 }
248 
NotifySessionIconChanged(int32_t persistentId,const std::shared_ptr<OHOS::Media::PixelMap> & icon)249 void SessionListenerController::NotifySessionIconChanged(int32_t persistentId,
250                                                          const std::shared_ptr<OHOS::Media::PixelMap>& icon)
251 {
252     if (persistentId == -1) {
253         return;
254     }
255 
256     if (!taskScheduler_) {
257         WLOGFE("taskScheduler is null");
258         return;
259     }
260     auto task = [weak = weak_from_this(), persistentId, icon]() {
261         auto self = weak.lock();
262         if (self == nullptr) {
263             WLOGFE("self is nullptr, NotifySessionIconChanged failed");
264             return;
265         }
266         WLOGFI("NotifySessionIconChanged, persistentId:%{public}d.", persistentId);
267         self->CallListeners(&ISessionListener::OnMissionIconUpdated, persistentId, icon);
268     };
269     taskScheduler_->PostVoidSyncTask(task, "NotifySessionIconChanged:PID:" + std::to_string(persistentId));
270 }
271 
NotifySessionClosed(int32_t persistentId)272 void SessionListenerController::NotifySessionClosed(int32_t persistentId)
273 {
274     if (persistentId == -1) {
275         return;
276     }
277 
278     if (!taskScheduler_) {
279         WLOGFE("taskScheduler is null");
280         return;
281     }
282     auto task = [weak = weak_from_this(), persistentId]() {
283         auto self = weak.lock();
284         if (self == nullptr) {
285             WLOGFE("self is nullptr, NotifySessionClosed failed");
286             return;
287         }
288         WLOGFI("NotifySessionClosed, persistentId:%{public}d.", persistentId);
289         self->CallListeners(&ISessionListener::OnMissionClosed, persistentId);
290     };
291     taskScheduler_->PostVoidSyncTask(task, "NotifySessionClosed:PID:" + std::to_string(persistentId));
292 }
293 
NotifySessionLabelUpdated(int32_t persistentId)294 void SessionListenerController::NotifySessionLabelUpdated(int32_t persistentId)
295 {
296     if (persistentId == -1) {
297         return;
298     }
299 
300     if (!taskScheduler_) {
301         WLOGFE("taskScheduler is null");
302         return;
303     }
304     auto task = [weak = weak_from_this(), persistentId]() {
305         auto self = weak.lock();
306         if (self == nullptr) {
307             WLOGFE("self is nullptr, NotifySessionLabelUpdated failed");
308             return;
309         }
310         WLOGFI("NotifySessionLabelUpdated, persistentId:%{public}d.", persistentId);
311         self->CallListeners(&ISessionListener::OnMissionLabelUpdated, persistentId);
312     };
313     taskScheduler_->PostVoidSyncTask(task, "NotifySessionLabelUpdated" + std::to_string(persistentId));
314 }
315 
OnListenerDied(const wptr<IRemoteObject> & remote)316 void SessionListenerController::OnListenerDied(const wptr<IRemoteObject>& remote)
317 {
318     WLOGFD("On session listener died.");
319     auto remoteObj = remote.promote();
320     if (!remoteObj) {
321         WLOGFD("invalid remote object.");
322         return;
323     }
324     remoteObj->RemoveDeathRecipient(listenerDeathRecipient_);
325 
326     std::lock_guard<ffrt::mutex> guard(listenerLock_);
327     auto it = std::find_if(sessionListeners_.begin(), sessionListeners_.end(),
328                            [&remoteObj](const sptr<ISessionListener> item) {
329                                return (item && item->AsObject() == remoteObj);
330                            });
331     if (it != sessionListeners_.end()) {
332         WLOGFI("Died Delete SessionListener");
333         sessionListeners_.erase(it);
334     }
335 }
336 
337 template<typename F, typename... Args>
CallListeners(F func,Args &&...args)338 void SessionListenerController::CallListeners(F func, Args&& ... args)
339 {
340     std::lock_guard<ffrt::mutex> guard(listenerLock_);
341     WLOGFD("size: %{public}d ", static_cast<int32_t>(sessionListeners_.size()));
342     for (auto listener : sessionListeners_) {
343         if (listener) {
344             (listener->*func)(std::forward<Args>(args)...);
345         }
346     }
347 }
348 
ListenerDeathRecipient(ListenerDiedHandler handler)349 SessionListenerController::ListenerDeathRecipient::ListenerDeathRecipient(ListenerDiedHandler handler)
350     : diedHandler_(handler)
351 {}
352 
OnRemoteDied(const wptr<IRemoteObject> & remote)353 void SessionListenerController::ListenerDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
354 {
355     if (diedHandler_) {
356         diedHandler_(remote);
357     }
358 }
359 } // namespace Rosen
360 } // namespace OHOS
361