1 /*
2 * Copyright (c) 2025 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_refresh/refresh_impl/form_timer_refresh_impl.h"
17
18 #include "ffrt.h"
19 #include "form_refresh/strategy/refresh_check_mgr.h"
20 #include "form_refresh/strategy/refresh_control_mgr.h"
21 #include "form_refresh/strategy/refresh_exec_mgr.h"
22 #include "form_refresh/strategy/refresh_cache_mgr.h"
23 #include "data_center/form_data_mgr.h"
24
25 namespace OHOS {
26 namespace AppExecFwk {
27
FormTimerRefreshImpl()28 FormTimerRefreshImpl::FormTimerRefreshImpl() {}
~FormTimerRefreshImpl()29 FormTimerRefreshImpl::~FormTimerRefreshImpl() {}
30
31 const static std::map<int32_t, int32_t> refreshTypeMap = {
32 { RefreshType::TYPE_INTERVAL, Constants::REFRESHTYPE_INTERVAL },
33 { RefreshType::TYPE_UPDATETIMES, Constants::REFRESHTYPE_UPDATETIMES },
34 { RefreshType::TYPE_UPDATENEXTTIME, Constants::REFRESHTYPE_UPDATENEXTTIME },
35 };
36
RefreshFormRequest(RefreshData & data)37 int FormTimerRefreshImpl::RefreshFormRequest(RefreshData &data)
38 {
39 FormRecord record;
40 bool flag = FormDataMgr::GetInstance().GetFormRecord(data.formId, record);
41 if (!flag) {
42 HILOG_ERROR("not exist such form:%{public}" PRId64 "", data.formId);
43 return ERR_APPEXECFWK_FORM_NOT_EXIST_ID;
44 }
45
46 Want reqWant;
47 BuildTimerWant(data.formTimer, reqWant);
48 auto task = [data, reqWant, record]() {
49 RefreshData newData(data);
50 newData.want = reqWant;
51 newData.record = record;
52 FormTimerRefreshImpl::GetInstance().DealRefresh(newData);
53 };
54 ffrt::submit(task);
55 return ERR_OK;
56 }
57
DealRefresh(const RefreshData & data)58 int FormTimerRefreshImpl::DealRefresh(const RefreshData &data)
59 {
60 const std::vector<int32_t> checkTypes = { TYPE_UNTRUST_APP, TYPE_ACTIVE_USER, TYPE_ADD_FINISH };
61 CheckValidFactor factor;
62 factor.formId = data.formId;
63 factor.record = data.record;
64 factor.want = data.want;
65 int ret = RefreshCheckMgr::GetInstance().IsBaseValidPass(checkTypes, factor);
66 if (ret != ERR_OK) {
67 return ret;
68 }
69
70 if (RefreshControlMgr::GetInstance().IsSystemOverload()) {
71 RefreshCacheMgr::GetInstance().AddToOverloadTaskQueue(data.formTimer);
72 return ERR_OK;
73 }
74
75 RefreshData newData(data);
76 if (RefreshControlMgr::GetInstance().IsHealthyControl(newData.record)) {
77 RefreshCacheMgr::GetInstance().AddFlagByHealthyControl(newData.formId, true);
78 return ERR_OK;
79 }
80
81 bool isCountTimerRefresh = newData.want.GetBoolParam(Constants::KEY_IS_TIMER, false);
82 bool isTimerRefresh = newData.want.GetBoolParam(Constants::KEY_TIMER_REFRESH, false);
83 newData.want.RemoveParam(Constants::KEY_IS_TIMER);
84 newData.want.RemoveParam(Constants::KEY_TIMER_REFRESH);
85 if (!DetectControlPoint(newData, isCountTimerRefresh, isTimerRefresh)) {
86 return ERR_OK;
87 }
88
89 if (!RefreshControlMgr::GetInstance().IsNeedToFresh(newData.record, false)) {
90 FormDataMgr::GetInstance().SetNeedRefresh(newData.formId, true);
91 return ERR_OK;
92 }
93
94 FormRecord refreshRecord = FormDataMgr::GetInstance().GetFormAbilityInfo(newData.record);
95 refreshRecord.isCountTimerRefresh = isCountTimerRefresh;
96 refreshRecord.isTimerRefresh = isTimerRefresh;
97 ret = RefreshExecMgr::AskForProviderData(newData.formId, refreshRecord, newData.want);
98 if (ret != ERR_OK) {
99 HILOG_ERROR("ask for provider data failed, ret:%{public}d, formId:%{public}" PRId64, ret, newData.formId);
100 return ret;
101 }
102
103 return ERR_OK;
104 }
105
DetectControlPoint(RefreshData & newData,const bool isCountTimerRefresh,const bool isTimerRefresh)106 bool FormTimerRefreshImpl::DetectControlPoint(
107 RefreshData &newData, const bool isCountTimerRefresh, const bool isTimerRefresh)
108 {
109 int refreshType = newData.want.GetIntParam(Constants::PARAM_FORM_REFRESH_TYPE, Constants::REFRESHTYPE_DEFAULT);
110 if (isTimerRefresh) {
111 FormDataMgr::GetInstance().SetTimerRefresh(newData.formId, true);
112 }
113
114 if (RefreshControlMgr::GetInstance().IsFormInvisible(newData.record)) {
115 RefreshCacheMgr::GetInstance().AddFlagByInvisible(newData.formId, refreshType);
116 return false;
117 }
118
119 if (!newData.record.isSystemApp) {
120 newData.want.RemoveParam(Constants::PARAM_FORM_REFRESH_TYPE);
121 }
122
123 if (isCountTimerRefresh) {
124 FormDataMgr::GetInstance().SetCountTimerRefresh(newData.formId, true);
125 }
126
127 if (RefreshControlMgr::GetInstance().IsScreenOff(newData.record)) {
128 RefreshCacheMgr::GetInstance().AddFlagByScreenOff(newData.formId, newData.want, newData.record);
129 return false;
130 }
131
132 return true;
133 }
134
BuildTimerWant(const FormTimer & timerTask,Want & want)135 void FormTimerRefreshImpl::BuildTimerWant(const FormTimer &timerTask, Want &want)
136 {
137 if (timerTask.isCountTimer) {
138 want.SetParam(Constants::KEY_IS_TIMER, true);
139 }
140 if (timerTask.isCountTimer || timerTask.isUpdateAt) {
141 want.SetParam(Constants::KEY_TIMER_REFRESH, true);
142 }
143 // multi user
144 if (FormUtil::IsActiveUser(timerTask.userId)) {
145 want.SetParam(Constants::PARAM_FORM_USER_ID, timerTask.userId);
146 }
147 auto it = refreshTypeMap.find(timerTask.refreshType);
148 if (it != refreshTypeMap.end()) {
149 want.SetParam(Constants::PARAM_FORM_REFRESH_TYPE, it->second);
150 }
151 }
152
153 } // namespace AppExecFwk
154 } // namespace OHOS