1 /*
2  * Copyright (c) 2021-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 
16 #include "mission_listener_controller.h"
17 
18 #include "hilog_tag_wrapper.h"
19 
20 namespace OHOS {
21 namespace AAFwk {
22 namespace {
23 const std::string THREAD_NAME = "MissionListener";
24 }
25 using Cmd = IMissionListener::MissionListenerCmd;
26 
MissionListenerController()27 MissionListenerController::MissionListenerController()
28 {
29 }
30 
~MissionListenerController()31 MissionListenerController::~MissionListenerController()
32 {}
33 
Init()34 void MissionListenerController::Init()
35 {
36     if (!handler_) {
37         handler_ = TaskHandlerWrap::CreateQueueHandler("mission_listener_task_queue");
38     }
39 }
40 
AddMissionListener(const sptr<IMissionListener> & listener)41 int MissionListenerController::AddMissionListener(const sptr<IMissionListener> &listener)
42 {
43     if (!listener) {
44         TAG_LOGE(AAFwkTag::ABILITYMGR, "listener is invalid");
45         return -1;
46     }
47 
48     std::lock_guard<ffrt::mutex> guard(listenerLock_);
49     auto it = std::find_if(missionListeners_.begin(), missionListeners_.end(),
50         [&listener](const sptr<IMissionListener> &item) {
51             return (item && item->AsObject() == listener->AsObject());
52         });
53     if (it != missionListeners_.end()) {
54         TAG_LOGW(AAFwkTag::ABILITYMGR, "listener was already added, do not add again");
55         return 0;
56     }
57 
58     if (!listenerDeathRecipient_) {
59         std::weak_ptr<MissionListenerController> thisWeakPtr(shared_from_this());
60         listenerDeathRecipient_ =
61             new ListenerDeathRecipient([thisWeakPtr](const wptr<IRemoteObject> &remote) {
62                 auto controller = thisWeakPtr.lock();
63                 if (controller) {
64                     controller->OnListenerDied(remote);
65                 }
66             });
67     }
68     auto listenerObject = listener->AsObject();
69     if (listenerObject) {
70         listenerObject->AddDeathRecipient(listenerDeathRecipient_);
71     }
72     missionListeners_.emplace_back(listener);
73 
74     return 0;
75 }
76 
DelMissionListener(const sptr<IMissionListener> & listener)77 void MissionListenerController::DelMissionListener(const sptr<IMissionListener> &listener)
78 {
79     if (!listener) {
80         TAG_LOGE(AAFwkTag::ABILITYMGR, "listener is invalid");
81         return;
82     }
83 
84     std::lock_guard<ffrt::mutex> guard(listenerLock_);
85     auto it = std::find_if(missionListeners_.begin(), missionListeners_.end(),
86         [&listener](const sptr<IMissionListener> item) {
87             return (item && item->AsObject() == listener->AsObject());
88         });
89     if (it != missionListeners_.end()) {
90         missionListeners_.erase(it);
91     }
92 }
93 
NotifyMissionCreated(int32_t missionId)94 void MissionListenerController::NotifyMissionCreated(int32_t missionId)
95 {
96     if (!handler_) {
97         TAG_LOGE(AAFwkTag::ABILITYMGR, "handler not init");
98         return;
99     }
100     auto task = [weak = weak_from_this(), missionId]() {
101         auto self = weak.lock();
102         if (self == nullptr) {
103             TAG_LOGE(AAFwkTag::ABILITYMGR, "self is nullptr, NotifyMissionCreated failed.");
104             return;
105         }
106         TAG_LOGI(AAFwkTag::ABILITYMGR, "notify listeners mission is created, missionId:%{public}d.", missionId);
107         self->CallListeners(&IMissionListener::OnMissionCreated, missionId);
108     };
109     handler_->SubmitTask(task);
110 }
111 
NotifyMissionDestroyed(int32_t missionId)112 void MissionListenerController::NotifyMissionDestroyed(int32_t missionId)
113 {
114     if (!handler_) {
115         TAG_LOGE(AAFwkTag::ABILITYMGR, "handler not init");
116         return;
117     }
118     auto task = [weak = weak_from_this(), missionId]() {
119         auto self = weak.lock();
120         if (self == nullptr) {
121             TAG_LOGE(AAFwkTag::ABILITYMGR, "self is nullptr, NotifyMissionDestroyed failed.");
122             return;
123         }
124         TAG_LOGI(AAFwkTag::ABILITYMGR, "notify listeners mission is destroyed, missionId:%{public}d.", missionId);
125         self->CallListeners(&IMissionListener::OnMissionDestroyed, missionId);
126     };
127     handler_->SubmitTask(task);
128 }
129 
HandleUnInstallApp(const std::list<int32_t> & missions)130 void MissionListenerController::HandleUnInstallApp(const std::list<int32_t> &missions)
131 {
132     if (!handler_) {
133         TAG_LOGE(AAFwkTag::ABILITYMGR, "handler not init");
134         return;
135     }
136 
137     if (missions.empty()) {
138         return;
139     }
140 
141     auto task = [weak = weak_from_this(), missions]() {
142         auto self = weak.lock();
143         if (self == nullptr) {
144             TAG_LOGE(AAFwkTag::ABILITYMGR, "self is nullptr, NotifyMissionDestroyed failed.");
145             return;
146         }
147         for (auto id : missions) {
148             self->CallListeners(&IMissionListener::OnMissionDestroyed, id);
149         }
150     };
151     handler_->SubmitTask(task);
152 }
153 
NotifyMissionSnapshotChanged(int32_t missionId)154 void MissionListenerController::NotifyMissionSnapshotChanged(int32_t missionId)
155 {
156     if (!handler_) {
157         TAG_LOGE(AAFwkTag::ABILITYMGR, "handler not init.");
158         return;
159     }
160 
161     auto task = [weak = weak_from_this(), missionId]() {
162         auto self = weak.lock();
163         if (self == nullptr) {
164             TAG_LOGE(AAFwkTag::ABILITYMGR, "self is nullptr, NotifyMissionSnapshotChanged failed.");
165             return;
166         }
167         TAG_LOGI(AAFwkTag::ABILITYMGR, "notify listeners mission snapshot changed, missionId:%{public}d.", missionId);
168         self->CallListeners(&IMissionListener::OnMissionSnapshotChanged, missionId);
169     };
170     handler_->SubmitTask(task);
171 }
172 
NotifyMissionMovedToFront(int32_t missionId)173 void MissionListenerController::NotifyMissionMovedToFront(int32_t missionId)
174 {
175     if (!handler_) {
176         TAG_LOGE(AAFwkTag::ABILITYMGR, "handler not init!");
177         return;
178     }
179 
180     auto task = [weak = weak_from_this(), missionId]() {
181         auto self = weak.lock();
182         if (self == nullptr) {
183             TAG_LOGE(AAFwkTag::ABILITYMGR, "self is nullptr, NotifyMissionSnapshotChanged failed!");
184             return;
185         }
186         TAG_LOGI(AAFwkTag::ABILITYMGR, "notify listeners mission is moved to front, missionId:%{public}d.", missionId);
187         self->CallListeners(&IMissionListener::OnMissionMovedToFront, missionId);
188     };
189     handler_->SubmitTask(task);
190 }
191 
NotifyMissionFocused(int32_t missionId)192 void MissionListenerController::NotifyMissionFocused(int32_t missionId)
193 {
194     if (missionId == -1) {
195         return;
196     }
197 
198     if (!handler_) {
199         TAG_LOGE(AAFwkTag::ABILITYMGR, "handler is null.");
200         return;
201     }
202     auto task = [weak = weak_from_this(), missionId]() {
203         auto self = weak.lock();
204         if (self == nullptr) {
205             TAG_LOGE(AAFwkTag::ABILITYMGR, "self is nullptr, NotifyMissionFocused failed.");
206             return;
207         }
208         TAG_LOGI(AAFwkTag::ABILITYMGR, "NotifyMissionFocused, missionId:%{public}d.", missionId);
209         self->CallListeners(&IMissionListener::OnMissionFocused, missionId);
210     };
211     handler_->SubmitTask(task);
212 }
213 
NotifyMissionUnfocused(int32_t missionId)214 void MissionListenerController::NotifyMissionUnfocused(int32_t missionId)
215 {
216     if (missionId == -1) {
217         return;
218     }
219 
220     if (!handler_) {
221         TAG_LOGE(AAFwkTag::ABILITYMGR, "handler is null!");
222         return;
223     }
224     auto task = [weak = weak_from_this(), missionId]() {
225         auto self = weak.lock();
226         if (self == nullptr) {
227             TAG_LOGE(AAFwkTag::ABILITYMGR, "self is nullptr, NotifyMissionUnfocused failed!");
228             return;
229         }
230         TAG_LOGI(AAFwkTag::ABILITYMGR, "NotifyMissionUnfocused, missionId:%{public}d.", missionId);
231         self->CallListeners(&IMissionListener::OnMissionUnfocused, missionId);
232     };
233     handler_->SubmitTask(task);
234 }
235 
236 #ifdef SUPPORT_GRAPHICS
NotifyMissionIconChanged(int32_t missionId,const std::shared_ptr<OHOS::Media::PixelMap> & icon)237 void MissionListenerController::NotifyMissionIconChanged(int32_t missionId,
238     const std::shared_ptr<OHOS::Media::PixelMap> &icon)
239 {
240     if (!handler_) {
241         TAG_LOGE(AAFwkTag::ABILITYMGR, "handler not init when notify mission icon changed");
242         return;
243     }
244 
245     auto task = [weak = weak_from_this(), missionId, icon]() {
246         auto self = weak.lock();
247         if (self == nullptr) {
248             TAG_LOGE(AAFwkTag::ABILITYMGR, "self is nullptr, NotifyMissionIconChanged failed.");
249             return;
250         }
251         TAG_LOGI(AAFwkTag::ABILITYMGR, "notify listeners mission icon has changed, missionId:%{public}d.", missionId);
252         self->CallListeners(&IMissionListener::OnMissionIconUpdated, missionId, icon);
253     };
254     handler_->SubmitTask(task);
255 }
256 #endif
257 
NotifyMissionClosed(int32_t missionId)258 void MissionListenerController::NotifyMissionClosed(int32_t missionId)
259 {
260     if (!handler_) {
261         TAG_LOGE(AAFwkTag::ABILITYMGR, "handler not init");
262         return;
263     }
264     auto task = [weak = weak_from_this(), missionId]() {
265         auto self = weak.lock();
266         if (self == nullptr) {
267             TAG_LOGE(AAFwkTag::ABILITYMGR, "self is nullptr, NotifyMissionClosed failed.");
268             return;
269         }
270         TAG_LOGI(AAFwkTag::ABILITYMGR, "NotifyMissionClosed, missionId:%{public}d.", missionId);
271         self->CallListeners(&IMissionListener::OnMissionClosed, missionId);
272     };
273     handler_->SubmitTask(task);
274 }
275 
NotifyMissionLabelUpdated(int32_t missionId)276 void MissionListenerController::NotifyMissionLabelUpdated(int32_t missionId)
277 {
278     if (!handler_) {
279         TAG_LOGE(AAFwkTag::ABILITYMGR, "NotifyMissionLabelUpdated, handler not init");
280         return;
281     }
282     auto task = [weak = weak_from_this(), missionId]() {
283         auto self = weak.lock();
284         if (self == nullptr) {
285             TAG_LOGE(AAFwkTag::ABILITYMGR, "self is nullptr, NotifyMissionLabelUpdated failed.");
286             return;
287         }
288         TAG_LOGI(AAFwkTag::ABILITYMGR, "notify listeners mission label has updated, missionId:%{public}d.", missionId);
289         self->CallListeners(&IMissionListener::OnMissionLabelUpdated, missionId);
290     };
291     handler_->SubmitTask(task);
292 }
293 
OnListenerDied(const wptr<IRemoteObject> & remote)294 void MissionListenerController::OnListenerDied(const wptr<IRemoteObject> &remote)
295 {
296     TAG_LOGD(AAFwkTag::ABILITYMGR, "On mission listener died.");
297     auto remoteObj = remote.promote();
298     if (!remoteObj) {
299         TAG_LOGD(AAFwkTag::ABILITYMGR, "invalid remote object.");
300         return;
301     }
302     remoteObj->RemoveDeathRecipient(listenerDeathRecipient_);
303 
304     std::lock_guard<ffrt::mutex> guard(listenerLock_);
305     auto it = std::find_if(missionListeners_.begin(), missionListeners_.end(),
306         [&remoteObj](const sptr<IMissionListener> item) {
307             return (item && item->AsObject() == remoteObj);
308         });
309     if (it != missionListeners_.end()) {
310         missionListeners_.erase(it);
311     }
312 }
313 
ListenerDeathRecipient(ListenerDiedHandler handler)314 MissionListenerController::ListenerDeathRecipient::ListenerDeathRecipient(ListenerDiedHandler handler)
315     : diedHandler_(handler)
316 {}
317 
OnRemoteDied(const wptr<IRemoteObject> & remote)318 void MissionListenerController::ListenerDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
319 {
320     if (diedHandler_) {
321         diedHandler_(remote);
322     }
323 }
324 } // namespace AAFwk
325 } // namespace OHOS
326