1 /*
2 * Copyright (c) 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 "res_type.h"
17 #include "ressched_utils.h"
18 #include "app_startup_scene_rec.h"
19 #include "cgroup_sched_log.h"
20 namespace OHOS {
21 namespace ResourceSchedule {
22 static const int32_t CONTINUOUS_START_TIME_OUT = 15 * 1000 * 1000;
23 static const int32_t MAX_NO_REPEAT_APP_COUNT = 4;
24 static const int32_t MAX_CONTINUOUS_START_NUM = 5;
25 static const int32_t APP_START_UP = 0;
26 static const std::string RUNNER_NAME = "AppStartupSceneRecQueue";
AppStartupSceneRec()27 AppStartupSceneRec::AppStartupSceneRec()
28 {
29 }
~AppStartupSceneRec()30 AppStartupSceneRec::~AppStartupSceneRec()
31 {
32 }
Init()33 void AppStartupSceneRec::Init()
34 {
35 ffrtQueue_ = std::make_shared<ffrt::queue>(RUNNER_NAME.c_str(),
36 ffrt::queue_attr().qos(ffrt::qos_user_initiated));
37 }
Deinit()38 void AppStartupSceneRec::Deinit()
39 {
40 if (exitContinuousStartupTask != nullptr) {
41 ffrtQueue_->cancel(exitContinuousStartupTask);
42 exitContinuousStartupTask = nullptr;
43 }
44 ffrtQueue_.reset();
45 startPkgs_.clear();
46 startUidSet_.clear();
47 startIgnorePkgs_.clear();
48 }
GetInstance()49 AppStartupSceneRec& AppStartupSceneRec::GetInstance()
50 {
51 static AppStartupSceneRec instance;
52 return instance;
53 }
54
IsAppStartUp(int32_t abilityState)55 bool AppStartupSceneRec::IsAppStartUp(int32_t abilityState)
56 {
57 return abilityState == APP_START_UP;
58 }
59
RecordIsContinuousStartup(const int32_t abilityState,const std::string uid,const std::string bundleName)60 void AppStartupSceneRec::RecordIsContinuousStartup(const int32_t abilityState, const std::string uid,
61 const std::string bundleName)
62 {
63 if (!IsAppStartUp(abilityState)) {
64 CGS_LOGE("abilityState is not app startUp");
65 return;
66 }
67 if (startIgnorePkgs_.find(bundleName) != startIgnorePkgs_.end()) {
68 CGS_LOGE("recordIsContinuousStartup bundleName: %{public}s is IgnorePkg", bundleName.c_str());
69 return;
70 }
71 if (exitContinuousStartupTask != nullptr) {
72 ffrtQueue_->cancel(exitContinuousStartupTask);
73 exitContinuousStartupTask = nullptr;
74 }
75 auto tarEndTimePoint = std::chrono::steady_clock::now();
76 auto tarDuration = std::chrono::duration_cast<std::chrono::microseconds>(tarEndTimePoint.time_since_epoch());
77 int64_t curTime = tarDuration.count();
78 CGS_LOGI("recordIsContinuousStartup uid: %{public}s bundleName: %{public}s",
79 uid.c_str(), bundleName.c_str());
80 if (curTime - lastAppStartTime_ >= CONTINUOUS_START_TIME_OUT) {
81 CleanRecordSceneData();
82 }
83 UpdateAppStartupNum(uid, curTime, bundleName);
84 if (IsContinuousStartup() && !isReportContinuousStartup_.load()) {
85 nlohmann::json payload;
86 ResSchedUtils::GetInstance().ReportDataInProcess(
87 ResType::RES_TYPE_CONTINUOUS_STARTUP, ResType::ContinuousStartupStatus::START_CONTINUOUS_STARTUP, payload);
88 isReportContinuousStartup_ = true;
89 }
90 exitContinuousStartupTask = ffrtQueue_->submit_h([this] {
91 CleanRecordSceneData();
92 }, ffrt::task_attr().delay(CONTINUOUS_START_TIME_OUT));
93 }
CleanRecordSceneData()94 void AppStartupSceneRec::CleanRecordSceneData()
95 {
96 CGS_LOGI("CleanRecordSceneData");
97 std::unique_lock<ffrt::mutex> lock(mutex_);
98 appStartCount_ = 0;
99 startPkgs_.clear();
100 startUidSet_.clear();
101 exitContinuousStartupTask = nullptr;
102 if (isReportContinuousStartup_.load()) {
103 nlohmann::json payload;
104 ResSchedUtils::GetInstance().ReportDataInProcess(
105 ResType::RES_TYPE_CONTINUOUS_STARTUP, ResType::ContinuousStartupStatus::STOP_CONTINUOUS_STARTUP, payload);
106 isReportContinuousStartup_ = false;
107 }
108 }
UpdateAppStartupNum(const std::string uid,const int64_t curTime,const std::string bundleName)109 void AppStartupSceneRec::UpdateAppStartupNum(const std::string uid, const int64_t curTime,
110 const std::string bundleName)
111 {
112 std::unique_lock<ffrt::mutex> lock(mutex_);
113 lastAppStartTime_ = curTime;
114 appStartCount_++;
115 if (isReportContinuousStartup_.load()) {
116 CGS_LOGI("UpdateAppStartupNum appStartCount_:%{public}d", appStartCount_);
117 return;
118 }
119 startPkgs_.emplace_back(bundleName);
120 startUidSet_.insert(uid);
121 }
IsContinuousStartup()122 bool AppStartupSceneRec::IsContinuousStartup()
123 {
124 std::unique_lock<ffrt::mutex> lock(mutex_);
125 if (startPkgs_.size() >= MAX_CONTINUOUS_START_NUM && startUidSet_.size() >= MAX_NO_REPEAT_APP_COUNT) {
126 return true;
127 }
128 return false;
129 }
130 }
131 }