1 /*
2  * Copyright (c) 2021-2022 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_sys_event_receiver.h"
17 
18 #include <cinttypes>
19 
20 #include "common_event_support.h"
21 #include "fms_log_wrapper.h"
22 #include "form_bms_helper.h"
23 #include "form_constants.h"
24 #include "form_data_mgr.h"
25 #include "form_db_cache.h"
26 #include "form_info_mgr.h"
27 #include "form_mgr_errors.h"
28 #include "form_mgr_adapter.h"
29 #include "form_render_mgr.h"
30 #include "form_serial_queue.h"
31 #include "form_timer_mgr.h"
32 #include "form_util.h"
33 #include "in_process_call_wrapper.h"
34 #include "want.h"
35 
36 namespace OHOS {
37 namespace AppExecFwk {
38 namespace {
39 const int32_t MAIN_USER_ID = 100;
40 constexpr int32_t TASK_DELAY_TIME = 30; // ms
41 } // namespace
42 /**
43  * @brief Receiver Constructor.
44  * @param subscriberInfo Subscriber info.
45  */
FormSysEventReceiver(const EventFwk::CommonEventSubscribeInfo & subscriberInfo)46 FormSysEventReceiver::FormSysEventReceiver(const EventFwk::CommonEventSubscribeInfo &subscriberInfo)
47     : EventFwk::CommonEventSubscriber(subscriberInfo)
48 {}
49 
HandleAbilityUpdate(const AAFwk::Want & want,std::string & bundleName)50 void FormSysEventReceiver::HandleAbilityUpdate(const AAFwk::Want& want, std::string &bundleName)
51 {
52     if (!serialQueue_) {
53         HILOG_ERROR("null serialQueue");
54         return;
55     }
56 
57     auto task = [want, bundleName]() {
58         HILOG_INFO("bundle updated, bundleName:%{public}s", bundleName.c_str());
59         int userId = want.GetIntParam(KEY_USER_ID, 0);
60         FormEventUtil::HandleProviderUpdated(bundleName, userId);
61     };
62     serialQueue_->ScheduleTask(0, task);
63 }
64 
HandlePackageDataCleared(std::string & bundleName,int32_t userId)65 void FormSysEventReceiver::HandlePackageDataCleared(std::string &bundleName, int32_t userId)
66 {
67     if (!serialQueue_) {
68         HILOG_ERROR("null serialQueue");
69         return;
70     }
71 
72     auto task = [bundleName, userId]() {
73         FormEventUtil::HandleBundleDataCleared(bundleName, userId);
74     };
75     serialQueue_->ScheduleTask(0, task);
76 }
77 
HandleScreenUnlocked()78 void FormSysEventReceiver::HandleScreenUnlocked()
79 {
80     if (!serialQueue_) {
81         HILOG_ERROR("null serialQueue");
82         return;
83     }
84 
85     auto task = []() {
86         FormRenderMgr::GetInstance().OnScreenUnlock();
87     };
88     serialQueue_->ScheduleTask(0, task);
89 }
90 
HandleUserUnlocked()91 void FormSysEventReceiver::HandleUserUnlocked()
92 {
93     if (!serialQueue_) {
94         HILOG_ERROR("null serialQueue");
95         return;
96     }
97 
98     auto task = []() {
99         FormEventUtil::HandleOnUnlock();
100     };
101     serialQueue_->ScheduleTask(0, task);
102 }
103 
104 /**
105  * @brief Receive common event.
106  * @param eventData Common event data.
107  */
OnReceiveEvent(const EventFwk::CommonEventData & eventData)108 void FormSysEventReceiver::OnReceiveEvent(const EventFwk::CommonEventData &eventData)
109 {
110     const AAFwk::Want& want = eventData.GetWant();
111     std::string action = want.GetAction();
112     std::string bundleName = want.GetElement().GetBundleName();
113     if (action.empty()) {
114         HILOG_ERROR("empty action");
115         return;
116     }
117     if (bundleName.empty() && action != EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED &&
118         action != EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_SCAN_FINISHED &&
119         action != EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED &&
120         action != EventFwk::CommonEventSupport::COMMON_EVENT_SECOND_MOUNTED &&
121         action != EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON &&
122         action != EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED) {
123         HILOG_ERROR("invalid param, action:%{public}s, bundleName:%{public}s",
124             action.c_str(), bundleName.c_str());
125         return;
126     }
127     if (serialQueue_ == nullptr) {
128         HILOG_ERROR("null serialQueue_");
129         return;
130     }
131     HILOG_INFO("action:%{public}s", action.c_str());
132     std::weak_ptr<FormSysEventReceiver> weakThis = shared_from_this();
133     if (action == EventFwk::CommonEventSupport::COMMON_EVENT_ABILITY_UPDATED) {
134         HandleAbilityUpdate(want, bundleName);
135     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_REMOVED) {
136         int32_t userId = eventData.GetCode();
137         HandleUserIdRemoved(userId);
138     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_BUNDLE_SCAN_FINISHED) {
139         HandleBundleScanFinished();
140     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_USER_SWITCHED) {
141         HandleUserSwitched(eventData);
142     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_DATA_CLEARED) {
143         int userId = want.GetIntParam(KEY_USER_ID, Constants::DEFAULT_USERID);
144         HandlePackageDataCleared(bundleName, userId);
145     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_UNLOCKED) {
146         // el2 path maybe not unlocked
147         HandleScreenUnlocked();
148     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SECOND_MOUNTED) {
149         // el2 path is unlocked when receive SECOND_MOUNTED
150         HandleUserUnlocked();
151     } else if (action == EventFwk::CommonEventSupport::COMMON_EVENT_SCREEN_ON) {
152         HandleScreenOn();
153     } else {
154         HILOG_WARN("invalid action");
155     }
156 }
157 
158 // multiuser
HandleUserIdRemoved(const int32_t userId)159 void FormSysEventReceiver::HandleUserIdRemoved(const int32_t userId)
160 {
161     if (userId == -1) {
162         HILOG_ERROR("invalid userId: -1");
163         return;
164     }
165 
166     if (!serialQueue_) {
167         HILOG_ERROR("null serialQueue");
168         return;
169     }
170 
171     serialQueue_->ScheduleTask(0, [userId]() {
172         std::vector<int64_t> removedFormIds;
173         FormDataMgr::GetInstance().DeleteFormsByUserId(userId, removedFormIds);
174         FormDbCache::GetInstance().DeleteDBFormsByUserId(userId);
175 
176         // delete form timer
177         std::vector<int64_t>::iterator itRemoved;
178         for (itRemoved = removedFormIds.begin(); itRemoved != removedFormIds.end(); ++itRemoved) {
179             FormTimerMgr::GetInstance().RemoveFormTimer(*itRemoved);
180         }
181     });
182 }
183 
HandleBundleScanFinished()184 void FormSysEventReceiver::HandleBundleScanFinished()
185 {
186     InitFormInfosAndRegister();
187 }
188 
InitFormInfosAndRegister()189 void FormSysEventReceiver::InitFormInfosAndRegister()
190 {
191     if (!serialQueue_) {
192         HILOG_ERROR("null serialQueue");
193         return;
194     }
195 
196     serialQueue_->ScheduleTask(TASK_DELAY_TIME, []() {
197         int32_t currUserId = FormUtil::GetCurrentAccountId();
198         if (currUserId == Constants::ANY_USERID) {
199             HILOG_INFO("use MAIN_USER_ID(%{public}d) instead of current userId: ANY_USERID(%{public}d)",
200                 MAIN_USER_ID, currUserId);
201             currUserId = MAIN_USER_ID;
202         }
203         FormBmsHelper::GetInstance().RegisterBundleEventCallback();
204         if (!FormInfoMgr::GetInstance().HasReloadedFormInfos()) {
205             FormInfoMgr::GetInstance().ReloadFormInfos(currUserId);
206         }
207     });
208 }
209 
HandleUserSwitched(const EventFwk::CommonEventData & eventData)210 void FormSysEventReceiver::HandleUserSwitched(const EventFwk::CommonEventData &eventData)
211 {
212     int32_t userId = eventData.GetCode();
213     if (userId < 0) {
214         HILOG_ERROR("invalid switched userId:%{public}d", userId);
215         return;
216     }
217 
218     if (lastUserId_ == 0) {
219         HILOG_INFO("reboot init lastUserId");
220         lastUserId_ = userId;
221         return;
222     }
223 
224     if (lastUserId_ == userId) {
225         HILOG_WARN("same userId");
226         return;
227     }
228 
229     if (!serialQueue_) {
230         HILOG_ERROR("null serialQueue");
231         return;
232     }
233 
234     int32_t lastUserId = lastUserId_;
235     lastUserId_ = userId;
236     HILOG_INFO("switch to userId: (%{public}d)", userId);
237 
238     serialQueue_->ScheduleTask(0, [userId, lastUserId, this]() {
239         if (userId != MAIN_USER_ID) {
240             FormInfoMgr::GetInstance().ReloadFormInfos(userId);
241         }
242         HandleUserIdForms(userId, lastUserId);
243     });
244 
245     FormTimerMgr::GetInstance().UpdateLimiterAlarm();
246     FormTimerMgr::GetInstance().UpdateAtTimerAlarm();
247     FormTimerMgr::GetInstance().UpdateDynamicAlarm();
248 }
249 
HandleScreenOn()250 void FormSysEventReceiver::HandleScreenOn()
251 {
252     if (!serialQueue_) {
253         HILOG_ERROR("null serialQueue");
254         return;
255     }
256 
257     serialQueue_->ScheduleTask(0, []() {
258         FormRenderMgr::GetInstance().NotifyScreenOn();
259     });
260 }
261 
HandleUserIdForms(int32_t currentUserId,int32_t lastUserId)262 void FormSysEventReceiver::HandleUserIdForms(int32_t currentUserId, int32_t lastUserId)
263 {
264     HILOG_INFO("currentUserId: %{public}d.", currentUserId);
265     FormRenderMgr::GetInstance().RerenderAllFormsImmediate(currentUserId);
266 
267     HILOG_INFO("recycle forms and stop FRS lastUserId:%{public}d.", lastUserId);
268     RecycleForms(lastUserId);
269     FormRenderMgr::GetInstance().DisconnectAllRenderConnections(lastUserId);
270 }
271 
RecycleForms(int32_t userId)272 void FormSysEventReceiver::RecycleForms(int32_t userId)
273 {
274     std::vector<int64_t> formIds;
275     FormDataMgr::GetInstance().GetFormIdsByUserId(userId, formIds);
276     Want want;
277     want.SetParam(Constants::RECYCLE_FORMS_USER_ID, userId);
278     FormMgrAdapter::GetInstance().RecycleForms(formIds, want, false);
279 }
280 }  // namespace AppExecFwk
281 }  // namespace OHOS
282