1 /*
2 * Copyright (c) 2025-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 #include "res_sched_service.h"
16 #include "res_sched_errors.h"
17 #include "res_type.h"
18
19 #include "accesstoken_kit.h"
20 #include "ipc_skeleton.h"
21 #include "suspend_manager_base_observer.h"
22 #include "suspend_manager_base_log.h"
23
24 namespace OHOS {
25 namespace ResourceSchedule {
26 namespace {
27 const std::string GET_SUSPEND_STATE_PERMISSION = "ohos.permission.GET_SUSPEND_STATE";
28 }
29
CheckSuspendPermission()30 bool ResSchedService::CheckSuspendPermission()
31 {
32 Security::AccessToken::AccessTokenID tokenId = OHOS::IPCSkeleton::GetCallingTokenID();
33 auto tokenFlag = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
34 if (tokenFlag != Security::AccessToken::TypeATokenTypeEnum::TOKEN_NATIVE) {
35 SUSPEND_MSG_LOGE("Invalid calling token!");
36 return false;
37 }
38
39 int32_t status = Security::AccessToken::AccessTokenKit::VerifyAccessToken(tokenId, GET_SUSPEND_STATE_PERMISSION);
40 if (status != Security::AccessToken::PermissionState::PERMISSION_GRANTED) {
41 SUSPEND_MSG_LOGE("Verify permission denied!");
42 return false;
43 }
44 return true;
45 }
46
GetSuspendStateByUid(const int32_t uid,bool & isFrozen,int32_t & funcResult)47 ErrCode ResSchedService::GetSuspendStateByUid(const int32_t uid, bool &isFrozen, int32_t &funcResult)
48 {
49 funcResult = ERR_OK;
50 auto isValid = CheckSuspendPermission();
51 if (!isValid) {
52 SUSPEND_MSG_LOGE("CheckSuspendPermission failed!");
53 funcResult = ERR_INVALID_OPERATION;
54 return ERR_OK;
55 }
56
57 nlohmann::json payload;
58 payload["uid"] = uid;
59 std::string payloadValue = payload.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
60
61 std::string replyValue = "";
62 int32_t ret = ERR_OK;
63 ReportSyncEvent(
64 ResType::SYNC_RES_TYPE_GET_SUSPEND_STATE_BY_UID, 0, payloadValue, replyValue, ret);
65
66 nlohmann::json reply {};
67 reply = StringToJsonObj(replyValue);
68 if (ret == ERR_OK && !reply.is_null() && reply.contains("isFrozen") && reply.at("isFrozen").is_boolean()) {
69 isFrozen = reply["isFrozen"].get<bool>();
70 return ERR_OK;
71 }
72 funcResult = RES_SCHED_ACCESS_TOKEN_FAIL;
73 return ERR_OK;
74 }
75
GetSuspendStateByPid(const int32_t pid,bool & isFrozen,int32_t & funcResult)76 ErrCode ResSchedService::GetSuspendStateByPid(const int32_t pid, bool &isFrozen, int32_t &funcResult)
77 {
78 funcResult = ERR_OK;
79 auto isValid = CheckSuspendPermission();
80 if (!isValid) {
81 SUSPEND_MSG_LOGE("CheckSuspendPermission failed!");
82 funcResult = ERR_INVALID_OPERATION;
83 return ERR_OK;
84 }
85
86 nlohmann::json payload;
87 payload["pid"] = pid;
88 std::string payloadValue = payload.dump(-1, ' ', false, nlohmann::detail::error_handler_t::replace);
89
90 std::string replyValue = "";
91 int32_t ret = ERR_OK;
92 ReportSyncEvent(
93 ResType::SYNC_RES_TYPE_GET_SUSPEND_STATE_BY_PID, 0, payloadValue, replyValue, ret);
94
95 nlohmann::json reply {};
96 reply = StringToJsonObj(replyValue);
97 if (ret == ERR_OK && !reply.is_null() && reply.contains("isFrozen") && reply.at("isFrozen").is_boolean()) {
98 isFrozen = reply["isFrozen"].get<bool>();
99 return ERR_OK;
100 }
101 funcResult = RES_SCHED_ACCESS_TOKEN_FAIL;
102 return ERR_OK;
103 }
104
RegisterSuspendObserver(const sptr<ISuspendStateObserverBase> & observer,int32_t & funcResult)105 ErrCode ResSchedService::RegisterSuspendObserver(const sptr<ISuspendStateObserverBase> &observer, int32_t &funcResult)
106 {
107 SUSPEND_MSG_LOGI("called");
108 auto isValid = CheckSuspendPermission();
109 if (!isValid) {
110 SUSPEND_MSG_LOGE("CheckSuspendPermission failed!");
111 funcResult = ERR_INVALID_OPERATION;
112 return ERR_OK;
113 }
114
115 funcResult = SuspendManagerBaseObserver::GetInstance().RegisterSuspendObserver(observer);
116 return ERR_OK;
117 }
118
UnregisterSuspendObserver(const sptr<ISuspendStateObserverBase> & observer,int32_t & funcResult)119 ErrCode ResSchedService::UnregisterSuspendObserver(const sptr<ISuspendStateObserverBase> &observer, int32_t &funcResult)
120 {
121 SUSPEND_MSG_LOGI("called");
122 auto isValid = CheckSuspendPermission();
123 if (!isValid) {
124 SUSPEND_MSG_LOGE("CheckSuspendPermission failed!");
125 funcResult = ERR_INVALID_OPERATION;
126 return ERR_OK;
127 }
128
129 funcResult = SuspendManagerBaseObserver::GetInstance().UnregisterSuspendObserver(observer);
130 return ERR_OK;
131 }
132 } // namespace ResourceSchedule
133 } // namespace OHOS