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 #include "res_sched_exe_client.h"
16
17 #include <new>
18 #include <string>
19 #include <unistd.h>
20 #include <unordered_map>
21 #include <utility>
22
23 #include "if_system_ability_manager.h"
24 #include "iremote_broker.h"
25 #include "iservice_registry.h"
26 #include "system_ability_definition.h"
27
28 #include "res_exe_type.h"
29 #include "res_sched_exe_constants.h"
30 #include "res_sched_exe_log.h"
31
32 namespace OHOS {
33 namespace ResourceSchedule {
GetInstance()34 ResSchedExeClient& ResSchedExeClient::GetInstance()
35 {
36 static ResSchedExeClient instance;
37 return instance;
38 }
39
~ResSchedExeClient()40 ResSchedExeClient::~ResSchedExeClient()
41 {
42 StopRemoteObject();
43 }
44
SendRequestSync(uint32_t resType,int64_t value,const nlohmann::json & context,nlohmann::json & reply)45 int32_t ResSchedExeClient::SendRequestSync(uint32_t resType, int64_t value,
46 const nlohmann::json& context, nlohmann::json& reply)
47 {
48 return SendRequestInner(true, resType, value, context, reply);
49 }
50
SendRequestAsync(uint32_t resType,int64_t value,const nlohmann::json & context)51 void ResSchedExeClient::SendRequestAsync(uint32_t resType, int64_t value,
52 const nlohmann::json& context)
53 {
54 nlohmann::json reply;
55 SendRequestInner(false, resType, value, context, reply);
56 }
57
KillProcess(pid_t pid)58 int32_t ResSchedExeClient::KillProcess(pid_t pid)
59 {
60 if (TryConnect() != ResErrCode::RSSEXE_NO_ERR) {
61 RSSEXE_LOGE("connect executor failed!");
62 return ResIpcErrCode::RSSEXE_CONNECT_FAIL;
63 }
64 RSSEXE_LOGD("kill process receive pid = %{public}d", pid);
65 std::lock_guard<std::mutex> lock(mutex_);
66 if (resSchedExe_ == nullptr) {
67 RSSEXE_LOGE("fail to get resource schedule executor.");
68 return ResIpcErrCode::RSSEXE_REQUEST_FAIL;
69 }
70 return resSchedExe_->KillProcess(pid);
71 }
72
SendRequestInner(bool isSync,uint32_t resType,int64_t value,const nlohmann::json & context,nlohmann::json & reply)73 int32_t ResSchedExeClient::SendRequestInner(bool isSync, uint32_t resType, int64_t value,
74 const nlohmann::json& context, nlohmann::json& reply)
75 {
76 if (TryConnect() != ResErrCode::RSSEXE_NO_ERR) {
77 return ResIpcErrCode::RSSEXE_CONNECT_FAIL;
78 }
79 RSSEXE_LOGD("receive resType = %{public}u, value = %{public}lld.", resType, (long long)value);
80
81 std::lock_guard<std::mutex> lock(mutex_);
82 if (resSchedExe_ == nullptr) {
83 RSSEXE_LOGE("fail to get resource schedule executor.");
84 return ResIpcErrCode::RSSEXE_REQUEST_FAIL;
85 }
86
87 RSSEXE_LOGD("send request.");
88 if (isSync) {
89 return resSchedExe_->SendRequestSync(resType, value, context, reply);
90 } else {
91 resSchedExe_->SendRequestAsync(resType, value, context);
92 return ResErrCode::RSSEXE_NO_ERR;
93 }
94 }
95
SendDebugCommand(bool isSync)96 void ResSchedExeClient::SendDebugCommand(bool isSync)
97 {
98 nlohmann::json tempJson;
99 SendRequestInner(isSync, ResExeType::RES_TYPE_DEBUG, 0, tempJson, tempJson);
100 }
101
TryConnect()102 ErrCode ResSchedExeClient::TryConnect()
103 {
104 std::lock_guard<std::mutex> lock(mutex_);
105 if (resSchedExe_) {
106 return ResErrCode::RSSEXE_NO_ERR;
107 }
108
109 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
110 if (!systemManager) {
111 RSSEXE_LOGE("Fail to get registry.");
112 return ResIpcErrCode::RSSEXE_GET_SERVICE_FAIL;
113 }
114
115 remoteObject_ = systemManager->CheckSystemAbility(RES_SCHED_EXE_ABILITY_ID);
116 if (!remoteObject_) {
117 RSSEXE_LOGE("Fail to connect resource schedule executor.");
118 return ResIpcErrCode::RSSEXE_GET_SERVICE_FAIL;
119 }
120
121 resSchedExe_ = iface_cast<IResSchedExeService>(remoteObject_);
122 if (!resSchedExe_) {
123 return ResIpcErrCode::RSSEXE_GET_SERVICE_FAIL;
124 }
125 recipient_ = new (std::nothrow) ResSchedExeDeathRecipient(*this);
126 if (!recipient_) {
127 RSSEXE_LOGE("New ResSchedDeathRecipient failed.");
128 return ResIpcErrCode::RSSEXE_GET_SERVICE_FAIL;
129 }
130 resSchedExe_->AsObject()->AddDeathRecipient(recipient_);
131 RSSEXE_LOGD("Connect resource schedule executor success.");
132 return ResErrCode::RSSEXE_NO_ERR;
133 }
134
StopRemoteObject()135 void ResSchedExeClient::StopRemoteObject()
136 {
137 std::lock_guard<std::mutex> lock(mutex_);
138 if (resSchedExe_ && resSchedExe_->AsObject()) {
139 resSchedExe_->AsObject()->RemoveDeathRecipient(recipient_);
140 }
141 resSchedExe_ = nullptr;
142 }
143
ResSchedExeDeathRecipient(ResSchedExeClient & resSchedExeClient)144 ResSchedExeClient::ResSchedExeDeathRecipient::ResSchedExeDeathRecipient(ResSchedExeClient &resSchedExeClient)
145 : resSchedExeClient_(resSchedExeClient) {}
146
~ResSchedExeDeathRecipient()147 ResSchedExeClient::ResSchedExeDeathRecipient::~ResSchedExeDeathRecipient() {}
148
OnRemoteDied(const wptr<IRemoteObject> & remote)149 void ResSchedExeClient::ResSchedExeDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
150 {
151 resSchedExeClient_.StopRemoteObject();
152 }
153 } // namespace ResourceSchedule
154 } // namespace OHOS
155