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