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