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 "process_optimizer_uba.h"
17 #include "app_log_wrapper.h"
18
19 namespace OHOS {
20 namespace AppExecFwk {
BaseAbilityAction(const AbilityPtr & ability)21 ProcessOptimizerUBA::BaseAbilityAction::BaseAbilityAction(const AbilityPtr &ability)
22 : time_(Clock::now()), name_(ability->GetName())
23 {}
24
GetTime() const25 ProcessOptimizerUBA::TimePoint ProcessOptimizerUBA::BaseAbilityAction::GetTime() const
26 {
27 return time_;
28 }
29
GetTimeString() const30 std::string ProcessOptimizerUBA::BaseAbilityAction::GetTimeString() const
31 {
32 std::time_t tmp = Clock::to_time_t(time_);
33 char *pTime = std::ctime(&tmp);
34 return (pTime == nullptr) ? "" : std::string(pTime);
35 }
36
GetName() const37 const std::string &ProcessOptimizerUBA::BaseAbilityAction::GetName() const
38 {
39 return name_;
40 }
41
StartAbilityAction(const AbilityPtr & ability,const AbilityPtr & preAbility)42 ProcessOptimizerUBA::StartAbilityAction::StartAbilityAction(const AbilityPtr &ability, const AbilityPtr &preAbility)
43 : BaseAbilityAction(ability), preName_(preAbility ? preAbility->GetName() : std::string())
44 {}
45
GetPreName() const46 const std::string &ProcessOptimizerUBA::StartAbilityAction::GetPreName() const
47 {
48 return preName_;
49 }
50
ConnectAbilityAction(const AbilityPtr & ability,const AbilityPtr & targetAbility)51 ProcessOptimizerUBA::ConnectAbilityAction::ConnectAbilityAction(
52 const AbilityPtr &ability, const AbilityPtr &targetAbility)
53 : BaseAbilityAction(ability), targetName_(targetAbility->GetName())
54 {}
55
GetTargetName() const56 const std::string &ProcessOptimizerUBA::ConnectAbilityAction::GetTargetName() const
57 {
58 return targetName_;
59 }
60
DisconnectAbilityAction(const AbilityPtr & ability,const AbilityPtr & targetAbility)61 ProcessOptimizerUBA::DisconnectAbilityAction::DisconnectAbilityAction(
62 const AbilityPtr &ability, const AbilityPtr &targetAbility)
63 : BaseAbilityAction(ability), targetName_(targetAbility->GetName())
64 {}
65
GetTargetName() const66 const std::string &ProcessOptimizerUBA::DisconnectAbilityAction::GetTargetName() const
67 {
68 return targetName_;
69 }
70
ChangeAbilityStateAction(const AbilityPtr & ability,const AbilityState oldState)71 ProcessOptimizerUBA::ChangeAbilityStateAction::ChangeAbilityStateAction(
72 const AbilityPtr &ability, const AbilityState oldState)
73 : BaseAbilityAction(ability), oldState_(oldState), newState_(ability->GetState())
74 {}
75
GetOldState() const76 AbilityState ProcessOptimizerUBA::ChangeAbilityStateAction::GetOldState() const
77 {
78 return oldState_;
79 }
80
GetNewState() const81 AbilityState ProcessOptimizerUBA::ChangeAbilityStateAction::GetNewState() const
82 {
83 return newState_;
84 }
85
ChangeAbilityVisible(const AbilityPtr & ability)86 ProcessOptimizerUBA::ChangeAbilityVisible::ChangeAbilityVisible(const AbilityPtr &ability)
87 : BaseAbilityAction(ability){};
88
ChangeAbilityPerceptible(const AbilityPtr & ability)89 ProcessOptimizerUBA::ChangeAbilityPerceptible::ChangeAbilityPerceptible(const AbilityPtr &ability)
90 : BaseAbilityAction(ability){};
91
RemoveAbilityAction(const AbilityPtr & ability)92 ProcessOptimizerUBA::RemoveAbilityAction::RemoveAbilityAction(const AbilityPtr &ability) : BaseAbilityAction(ability)
93 {}
94
ProcessOptimizerUBA(const UbaServicePtr & ubaService,const LmksClientPtr & lmksClient,int suspendTimeout)95 ProcessOptimizerUBA::ProcessOptimizerUBA(
96 const UbaServicePtr &ubaService, const LmksClientPtr &lmksClient, int suspendTimeout)
97 : ProcessOptimizer(lmksClient, suspendTimeout), ubaService_(ubaService), abilityActionCount_(0)
98 {
99 APP_LOGI("%{public}s(%{public}d) constructed.", __func__, __LINE__);
100 }
101
~ProcessOptimizerUBA()102 ProcessOptimizerUBA::~ProcessOptimizerUBA()
103 {
104 if (abilityActionCount_ > 0) {
105 CommitAbilityActions();
106 }
107
108 APP_LOGI("%{public}s(%{public}d) destructed.", __func__, __LINE__);
109 }
110
OnAppAdded(const AppPtr & app)111 void ProcessOptimizerUBA::OnAppAdded(const AppPtr &app)
112 {
113 auto ubaService = GetUbaService();
114 if (ubaService) {
115 APP_LOGD("%{public}s(%{public}d) ubaService implement.", __func__, __LINE__);
116 } else {
117 ProcessOptimizer::OnAppAdded(app);
118 }
119 }
120
OnAppRemoved(const AppPtr & app)121 void ProcessOptimizerUBA::OnAppRemoved(const AppPtr &app)
122 {
123 auto ubaService = GetUbaService();
124 if (ubaService) {
125 APP_LOGD("%{public}s(%{public}d) ubaService implement.", __func__, __LINE__);
126 } else {
127 ProcessOptimizer::OnAppRemoved(app);
128 }
129 }
130
OnAppStateChanged(const AppPtr & app,const ApplicationState oldState)131 void ProcessOptimizerUBA::OnAppStateChanged(const AppPtr &app, const ApplicationState oldState)
132 {
133 auto ubaService = GetUbaService();
134 if (ubaService) {
135 APP_LOGD("%{public}s(%{public}d) ubaService implement.", __func__, __LINE__);
136 } else {
137 ProcessOptimizer::OnAppStateChanged(app, oldState);
138 }
139 }
140
OnAbilityStarted(const AbilityPtr & ability)141 void ProcessOptimizerUBA::OnAbilityStarted(const AbilityPtr &ability)
142 {
143 if (!ability) {
144 APP_LOGE("%{public}s(%{public}d) invalid ability.", __func__, __LINE__);
145 return;
146 }
147
148 AbilityPtr preAbility;
149 auto preToken = ability->GetPreToken();
150
151 if (GetAbilityByToken) {
152 // 'preAbility' can be a nullptr.
153 preAbility = GetAbilityByToken(preToken);
154 } else {
155 APP_LOGW("%{public}s(%{public}d) 'GetAbilityByToken' is not registered.", __func__, __LINE__);
156 }
157
158 RecordAbilityAction<StartAbilityAction>(ability, preAbility);
159
160 auto ubaService = GetUbaService();
161 if (ubaService) {
162 APP_LOGD("%{public}s(%{public}d) ubaService implement.", __func__, __LINE__);
163 } else {
164 ProcessOptimizer::OnAbilityStarted(ability);
165 }
166 }
167
OnAbilityConnected(const AbilityPtr & ability,const AbilityPtr & targetAbility)168 void ProcessOptimizerUBA::OnAbilityConnected(const AbilityPtr &ability, const AbilityPtr &targetAbility)
169 {
170 if (!ability) {
171 APP_LOGE("%{public}s(%{public}d) invalid ability.", __func__, __LINE__);
172 return;
173 }
174
175 if (!targetAbility) {
176 APP_LOGE("%{public}s(%{public}d) invalid targetAbility.", __func__, __LINE__);
177 return;
178 }
179
180 RecordAbilityAction<ConnectAbilityAction>(ability, targetAbility);
181
182 auto ubaService = GetUbaService();
183 if (ubaService) {
184 APP_LOGD("%{public}s(%{public}d) ubaService implement.", __func__, __LINE__);
185 } else {
186 ProcessOptimizer::OnAbilityConnected(ability, targetAbility);
187 }
188 }
189
OnAbilityDisconnected(const AbilityPtr & ability,const AbilityPtr & targetAbility)190 void ProcessOptimizerUBA::OnAbilityDisconnected(const AbilityPtr &ability, const AbilityPtr &targetAbility)
191 {
192 if (!ability) {
193 APP_LOGE("%{public}s(%{public}d) invalid ability.", __func__, __LINE__);
194 return;
195 }
196
197 if (!targetAbility) {
198 APP_LOGE("%{public}s(%{public}d) invalid targetAbility.", __func__, __LINE__);
199 return;
200 }
201
202 RecordAbilityAction<DisconnectAbilityAction>(ability, targetAbility);
203
204 auto ubaService = GetUbaService();
205 if (ubaService) {
206 APP_LOGD("%{public}s(%{public}d) ubaService implement.", __func__, __LINE__);
207 } else {
208 ProcessOptimizer::OnAbilityDisconnected(ability, targetAbility);
209 }
210 }
211
OnAbilityStateChanged(const AbilityPtr & ability,const AbilityState oldState)212 void ProcessOptimizerUBA::OnAbilityStateChanged(const AbilityPtr &ability, const AbilityState oldState)
213 {
214 if (!ability) {
215 APP_LOGE("%{public}s(%{public}d) invalid ability.", __func__, __LINE__);
216 return;
217 }
218
219 RecordAbilityAction<ChangeAbilityStateAction>(ability, oldState);
220 auto ubaService = GetUbaService();
221 if (ubaService) {
222 APP_LOGD("%{public}s(%{public}d) ubaService implement.", __func__, __LINE__);
223 } else {
224 ProcessOptimizer::OnAbilityStateChanged(ability, oldState);
225 }
226 }
227
OnAbilityVisibleChanged(const AbilityPtr & ability)228 void ProcessOptimizerUBA::OnAbilityVisibleChanged(const AbilityPtr &ability)
229 {
230 if (!ability) {
231 APP_LOGE("%{public}s(%{public}d) invalid ability.", __func__, __LINE__);
232 return;
233 }
234
235 RecordAbilityAction<ChangeAbilityVisible>(ability);
236 auto ubaService = GetUbaService();
237 if (ubaService) {
238 APP_LOGD("%{public}s(%{public}d) ubaService implement.", __func__, __LINE__);
239 } else {
240 ProcessOptimizer::OnAbilityVisibleChanged(ability);
241 }
242 }
243
OnAbilityPerceptibleChanged(const AbilityPtr & ability)244 void ProcessOptimizerUBA::OnAbilityPerceptibleChanged(const AbilityPtr &ability)
245 {
246 if (!ability) {
247 APP_LOGE("%{public}s(%{public}d) invalid ability.", __func__, __LINE__);
248 return;
249 }
250
251 RecordAbilityAction<ChangeAbilityPerceptible>(ability);
252 auto ubaService = GetUbaService();
253 if (ubaService) {
254 APP_LOGD("%{public}s(%{public}d) ubaService implement.", __func__, __LINE__);
255 } else {
256 ProcessOptimizer::OnAbilityPerceptibleChanged(ability);
257 }
258 }
259
OnAbilityRemoved(const AbilityPtr & ability)260 void ProcessOptimizerUBA::OnAbilityRemoved(const AbilityPtr &ability)
261 {
262 if (!ability) {
263 APP_LOGE("%{public}s(%{public}d) invalid ability.", __func__, __LINE__);
264 return;
265 }
266
267 RecordAbilityAction<RemoveAbilityAction>(ability);
268
269 auto ubaService = GetUbaService();
270 if (ubaService) {
271 APP_LOGD("%{public}s(%{public}d) ubaService implement.", __func__, __LINE__);
272 } else {
273 ProcessOptimizer::OnAbilityRemoved(ability);
274 }
275 }
276
OnLowMemoryAlert(const CgroupManager::LowMemoryLevel level)277 void ProcessOptimizerUBA::OnLowMemoryAlert(const CgroupManager::LowMemoryLevel level)
278 {
279 auto ubaService = GetUbaService();
280 if (ubaService) {
281 APP_LOGD("%{public}s(%{public}d) ubaService implement.", __func__, __LINE__);
282 } else {
283 ProcessOptimizer::OnLowMemoryAlert(level);
284 }
285 }
286
CommitAbilityActions()287 void ProcessOptimizerUBA::CommitAbilityActions()
288 {
289 auto n = abilityActionCount_;
290 abilityActionCount_ = 0;
291 auto ubaService = GetUbaService();
292 if (!ubaService) {
293 APP_LOGE("%{public}s(%{pubic}d) uba is not available.", __func__, __LINE__);
294 return;
295 }
296
297 APP_LOGI("%{public}s(%{pubic}d) committing %{public}zu actions...", __func__, __LINE__, n);
298
299 for (size_t i = 0; i < n; ++i) {
300 auto &abilityAction = abilityActionCache_[i];
301
302 auto startAbilityAction = std::get_if<StartAbilityAction>(&abilityAction);
303 if (startAbilityAction) {
304 CommitStartAbilityAction(*startAbilityAction, i);
305 continue;
306 }
307 auto connectAbilityAction = std::get_if<ConnectAbilityAction>(&abilityAction);
308 if (connectAbilityAction) {
309 CommitConnectAbilityAction(*connectAbilityAction, i);
310 continue;
311 }
312 auto disconnectAbilityAction = std::get_if<DisconnectAbilityAction>(&abilityAction);
313 if (disconnectAbilityAction) {
314 CommitDisconnectAbilityAction(*disconnectAbilityAction, i);
315 continue;
316 }
317 auto changedAbilityStateAction = std::get_if<ChangeAbilityStateAction>(&abilityAction);
318 if (changedAbilityStateAction) {
319 CommitChangedAbilityStateAction(*changedAbilityStateAction, i);
320 continue;
321 }
322 auto removeAbilityAction = std::get_if<RemoveAbilityAction>(&abilityAction);
323 if (removeAbilityAction) {
324 CommitRemoveAbilityAction(*removeAbilityAction, i);
325 continue;
326 }
327 }
328 }
329
CommitStartAbilityAction(const StartAbilityAction & action,size_t index)330 void ProcessOptimizerUBA::CommitStartAbilityAction(const StartAbilityAction& action, size_t index)
331 {
332 APP_LOGD(" [%{public}zu] %{public}s ability '%{public}s' starts '%{public}s'",
333 index,
334 action.GetTimeString().c_str(),
335 action.GetPreName().c_str(),
336 action.GetName().c_str());
337 // commit action
338 }
339
CommitConnectAbilityAction(const ConnectAbilityAction & action,size_t index)340 void ProcessOptimizerUBA::CommitConnectAbilityAction(const ConnectAbilityAction& action, size_t index)
341 {
342 APP_LOGD(" [%{public}zu] %{public}s ability '%{public}s' connect to '%{public}s'",
343 index,
344 action.GetTimeString().c_str(),
345 action.GetName().c_str(),
346 action.GetTargetName().c_str());
347 // commit action
348 }
349
CommitDisconnectAbilityAction(const DisconnectAbilityAction & action,size_t index)350 void ProcessOptimizerUBA::CommitDisconnectAbilityAction(const DisconnectAbilityAction& action, size_t index)
351 {
352 APP_LOGD(" [%{public}zu] %{public}s '%{public}s' ability disconnect with '%{public}s'",
353 index,
354 action.GetTimeString().c_str(),
355 action.GetName().c_str(),
356 action.GetTargetName().c_str());
357 // commit action
358 }
359
CommitChangedAbilityStateAction(const ChangeAbilityStateAction & action,size_t index)360 void ProcessOptimizerUBA::CommitChangedAbilityStateAction(const ChangeAbilityStateAction& action, size_t index)
361 {
362 APP_LOGD(" [%{public}zu] %{public}s ability '%{public}s' state changed from %{public}d to %{public}d.",
363 index,
364 action.GetTimeString().c_str(),
365 action.GetName().c_str(),
366 action.GetOldState(),
367 action.GetNewState());
368 // commit action
369 }
370
CommitRemoveAbilityAction(const RemoveAbilityAction & action,size_t index)371 void ProcessOptimizerUBA::CommitRemoveAbilityAction(const RemoveAbilityAction& action, size_t index)
372 {
373 APP_LOGD(" [%{public}zu] %{public}s '%{public}s' removed.",
374 index,
375 action.GetTimeString().c_str(),
376 action.GetName().c_str());
377 // commit action
378 }
379
GetUbaService()380 UbaServicePtr ProcessOptimizerUBA::GetUbaService()
381 {
382 if (ubaService_) {
383 return ubaService_;
384 }
385
386 // try to get uba service here.
387 return nullptr;
388 }
389
SetAppFreezingTime(int time)390 void ProcessOptimizerUBA::SetAppFreezingTime(int time)
391 {
392 auto ubaService = GetUbaService();
393 if (ubaService) {
394 APP_LOGD("%{public}s(%{public}d) ubaService implement.", __func__, __LINE__);
395 } else {
396 ProcessOptimizer::SetAppFreezingTime(time);
397 }
398 }
399
GetAppFreezingTime(int & time)400 void ProcessOptimizerUBA::GetAppFreezingTime(int &time)
401 {
402 auto ubaService = GetUbaService();
403 if (ubaService) {
404 APP_LOGD("%{public}s(%{public}d) ubaService implement.", __func__, __LINE__);
405 } else {
406 ProcessOptimizer::GetAppFreezingTime(time);
407 }
408 }
409 } // namespace AppExecFwk
410 } // namespace OHOS
411