• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_sched_util.h"
17 
18 #include <string>
19 
20 #include "ability_info.h"
21 #include "hilog_tag_wrapper.h"
22 #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
23 #include "res_sched_client.h"
24 #include "res_type.h"
25 #endif
26 
27 namespace OHOS {
28 namespace AAFwk {
29 using AssociatedStartType = ResourceSchedule::ResType::AssociatedStartType;
GetInstance()30 ResSchedUtil &ResSchedUtil::GetInstance()
31 {
32     static ResSchedUtil instance;
33     return instance;
34 }
35 
convertType(int64_t resSchedType)36 int64_t ResSchedUtil::convertType(int64_t resSchedType)
37 {
38 #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
39     if (resSchedType == RES_TYPE_SCB_START_ABILITY) {
40         return static_cast<int64_t>(AssociatedStartType::SCB_START_ABILITY);
41     } else if (resSchedType == RES_TYPE_EXTENSION_START_ABILITY) {
42         return static_cast<int64_t>(AssociatedStartType::EXTENSION_START_ABILITY);
43     } else if (resSchedType == RES_TYPE_MISSION_LIST_START_ABILITY) {
44         return static_cast<int64_t>(AssociatedStartType::MISSION_LIST_START_ABILITY);
45     }
46 #endif
47     TAG_LOGE(AAFwkTag::DEFAULT, "sched invalid");
48     return -1;
49 }
50 
ReportAbilityStartInfoToRSS(const AbilityInfo & abilityInfo,int32_t pid,bool isColdStart)51 void ResSchedUtil::ReportAbilityStartInfoToRSS(const AbilityInfo &abilityInfo, int32_t pid, bool isColdStart)
52 {
53 #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
54     uint32_t resType = ResourceSchedule::ResType::RES_TYPE_APP_ABILITY_START;
55     std::unordered_map<std::string, std::string> eventParams {
56         { "name", "ability_start" },
57         { "uid", std::to_string(abilityInfo.applicationInfo.uid) },
58         { "bundleName", abilityInfo.applicationInfo.bundleName },
59         { "abilityName", abilityInfo.name },
60         { "pid", std::to_string(pid) }
61     };
62     TAG_LOGD(AAFwkTag::DEFAULT, "call");
63     ResourceSchedule::ResSchedClient::GetInstance().ReportData(resType, isColdStart ? 1 : 0, eventParams);
64 #endif
65 }
66 
ReportAbilityAssociatedStartInfoToRSS(const AbilityInfo & abilityInfo,int64_t resSchedType,int32_t callerUid,int32_t callerPid)67 void ResSchedUtil::ReportAbilityAssociatedStartInfoToRSS(
68     const AbilityInfo &abilityInfo, int64_t resSchedType, int32_t callerUid, int32_t callerPid)
69 {
70 #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
71     uint32_t resType = ResourceSchedule::ResType::RES_TYPE_APP_ASSOCIATED_START;
72     std::unordered_map<std::string, std::string> eventParams {
73         { "name", "associated_start" },
74         { "caller_uid", std::to_string(callerUid) },
75         { "caller_pid", std::to_string(callerPid) },
76         { "callee_uid", std::to_string(abilityInfo.applicationInfo.uid) },
77         { "callee_bundle_name", abilityInfo.applicationInfo.bundleName }
78     };
79     int64_t type = convertType(resSchedType);
80     TAG_LOGD(AAFwkTag::DEFAULT, "call");
81     ResourceSchedule::ResSchedClient::GetInstance().ReportData(resType, type, eventParams);
82 #endif
83 }
84 
ReportEventToRSS(const int32_t uid,const std::string & bundleName,const std::string & reason,const int32_t callerPid)85 void ResSchedUtil::ReportEventToRSS(const int32_t uid, const std::string &bundleName, const std::string &reason,
86     const int32_t callerPid)
87 {
88 #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
89     uint32_t resType = ResourceSchedule::ResType::SYNC_RES_TYPE_THAW_ONE_APP;
90     nlohmann::json payload;
91     payload.emplace("uid", uid);
92     payload.emplace("pid", -1);
93     payload.emplace("bundleName", bundleName);
94     payload.emplace("reason", reason);
95     payload.emplace("callerPid", callerPid);
96     nlohmann::json reply;
97     TAG_LOGD(AAFwkTag::DEFAULT, "call");
98     ResourceSchedule::ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
99 #endif
100 }
101 
GetAllFrozenPidsFromRSS(std::unordered_set<int32_t> & frozenPids)102 void ResSchedUtil::GetAllFrozenPidsFromRSS(std::unordered_set<int32_t> &frozenPids)
103 {
104 #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
105     uint32_t resType = ResourceSchedule::ResType::SYNC_RES_TYPE_GET_ALL_SUSPEND_STATE;
106     nlohmann::json payload;
107     nlohmann::json reply;
108     TAG_LOGD(AAFwkTag::DEFAULT, "call");
109     int32_t ret = ResourceSchedule::ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
110     if (ret != 0 || !reply.contains("allSuspendState") || !reply["allSuspendState"].is_array()) {
111         TAG_LOGE(AAFwkTag::DEFAULT, "ReportSyncEvent fail");
112         return;
113     }
114 
115     for (nlohmann::json &appObj : reply["allSuspendState"]) {
116         // Here can get uid if needed
117         if (!appObj.contains("pidsState") || !appObj["pidsState"].is_array()) {
118             continue;
119         }
120 
121         for (nlohmann::json &pidObj : appObj["pidsState"]) {
122             if (!pidObj.contains("pid") || !pidObj["pid"].is_number() ||
123                 !pidObj.contains("isFrozen") || !pidObj["isFrozen"].is_boolean()) {
124                 break;
125             }
126             int32_t pid = pidObj["pid"].get<int32_t>();
127             bool isFrozen = pidObj["isFrozen"].get<bool>();
128             if (isFrozen) {
129                 frozenPids.insert(pid);
130             }
131         }
132     }
133     if (frozenPids.empty()) {
134         TAG_LOGW(AAFwkTag::DEFAULT, "Get frozen pids empty");
135     }
136 #endif
137 }
138 
CheckShouldForceKillProcess(int32_t pid)139 bool ResSchedUtil::CheckShouldForceKillProcess(int32_t pid)
140 {
141 #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
142     uint32_t resType = ResourceSchedule::ResType::SYNC_RES_TYPE_SHOULD_FORCE_KILL_PROCESS;
143     nlohmann::json payload;
144     nlohmann::json reply;
145     payload.emplace("pid", pid);
146     ResourceSchedule::ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
147     if (!reply.contains("ShouldForceKillProcess") || !reply["ShouldForceKillProcess"].is_number_integer()) {
148         return true;
149     }
150     return reply["ShouldForceKillProcess"].get<int32_t>() == 1;
151 #else
152     return true;
153 #endif
154 }
155 
ReportLoadingEventToRss(LoadingStage stage,int32_t pid,int32_t uid,int64_t timeDuration,int64_t abilityRecordId)156 void ResSchedUtil::ReportLoadingEventToRss(LoadingStage stage, int32_t pid, int32_t uid,
157     int64_t timeDuration, int64_t abilityRecordId)
158 {
159 #ifdef RESOURCE_SCHEDULE_SERVICE_ENABLE
160     uint32_t resType = ResourceSchedule::ResType::RES_TYPE_KEY_PERF_SCENE;
161     std::unordered_map<std::string, std::string> eventParams {
162         { "extType", "10015"},
163         { "pid", std::to_string(pid) },
164         { "uid", std::to_string(uid) },
165     };
166     if (timeDuration > 0) { // millisecond
167         eventParams.emplace("timeoutDuration", std::to_string(timeDuration));
168     }
169     if (abilityRecordId > 0) {
170         eventParams.emplace("abilityRecordId", std::to_string(abilityRecordId));
171     }
172 
173     int64_t type = static_cast<int64_t>(stage);
174     TAG_LOGD(AAFwkTag::DEFAULT, "call");
175     ResourceSchedule::ResSchedClient::GetInstance().ReportData(resType, type, eventParams);
176 #endif
177 }
178 
GetNWebPreloadSet() const179 std::unordered_set<std::string> ResSchedUtil::GetNWebPreloadSet() const
180 {
181     uint32_t resType = ResourceSchedule::ResType::SYNC_RES_TYPE_GET_NWEB_PRELOAD_SET;
182     nlohmann::json payload;
183     nlohmann::json reply;
184     ResourceSchedule::ResSchedClient::GetInstance().ReportSyncEvent(resType, 0, payload, reply);
185     if (!reply.contains("NWebPreloadSet")) {
186         TAG_LOGW(AAFwkTag::DEFAULT, "does not get preload process set");
187         return {};
188     }
189     auto jsonObj = reply["NWebPreloadSet"];
190     return { jsonObj.begin(), jsonObj.end() };
191 }
192 } // namespace AAFwk
193 } // namespace OHOS