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 RSSEXE_LOGD("kill process receive pid = %{public}d", pid);
61 auto proxy = GetProxy();
62 if (proxy == nullptr) {
63 RSSEXE_LOGE("fail to get resource schedule executor");
64 return ResIpcErrCode::RSSEXE_CONNECT_FAIL;
65 }
66 return proxy->KillProcess(pid);
67 }
68
SendRequestInner(bool isSync,uint32_t resType,int64_t value,const nlohmann::json & context,nlohmann::json & reply)69 int32_t ResSchedExeClient::SendRequestInner(bool isSync, uint32_t resType, int64_t value,
70 const nlohmann::json& context, nlohmann::json& reply)
71 {
72 RSSEXE_LOGD("receive resType = %{public}u, value = %{public}lld.", resType, (long long)value);
73 auto proxy = GetProxy();
74 if (proxy == nullptr) {
75 RSSEXE_LOGE("fail to get resource schedule executor.");
76 return ResIpcErrCode::RSSEXE_CONNECT_FAIL;
77 }
78
79 RSSEXE_LOGD("send request.");
80 if (isSync) {
81 return proxy->SendRequestSync(resType, value, context, reply);
82 } else {
83 proxy->SendRequestAsync(resType, value, context);
84 return ResErrCode::RSSEXE_NO_ERR;
85 }
86 }
87
SendDebugCommand(bool isSync)88 void ResSchedExeClient::SendDebugCommand(bool isSync)
89 {
90 nlohmann::json tempJson;
91 SendRequestInner(isSync, ResExeType::RES_TYPE_DEBUG, 0, tempJson, tempJson);
92 }
93
GetProxy()94 sptr<IResSchedExeService> ResSchedExeClient::GetProxy()
95 {
96 if (TryConnect() == ResErrCode::RSSEXE_NO_ERR) {
97 std::lock_guard<std::mutex> lock(mutex_);
98 return resSchedExe_;
99 }
100 return nullptr;
101 }
102
TryConnect()103 ErrCode ResSchedExeClient::TryConnect()
104 {
105 std::lock_guard<std::mutex> lock(mutex_);
106 if (resSchedExe_) {
107 return ResErrCode::RSSEXE_NO_ERR;
108 }
109
110 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
111 if (!systemManager) {
112 RSSEXE_LOGE("Fail to get registry.");
113 return ResIpcErrCode::RSSEXE_GET_SERVICE_FAIL;
114 }
115
116 remoteObject_ = systemManager->CheckSystemAbility(RES_SCHED_EXE_ABILITY_ID);
117 if (!remoteObject_) {
118 RSSEXE_LOGE("Fail to connect resource schedule executor.");
119 return ResIpcErrCode::RSSEXE_GET_SERVICE_FAIL;
120 }
121
122 resSchedExe_ = iface_cast<IResSchedExeService>(remoteObject_);
123 if (!resSchedExe_) {
124 return ResIpcErrCode::RSSEXE_GET_SERVICE_FAIL;
125 }
126 recipient_ = new (std::nothrow) ResSchedExeDeathRecipient(*this);
127 if (!recipient_) {
128 RSSEXE_LOGE("New ResSchedDeathRecipient failed.");
129 return ResIpcErrCode::RSSEXE_GET_SERVICE_FAIL;
130 }
131 resSchedExe_->AsObject()->AddDeathRecipient(recipient_);
132 RSSEXE_LOGD("Connect resource schedule executor success.");
133 return ResErrCode::RSSEXE_NO_ERR;
134 }
135
StopRemoteObject()136 void ResSchedExeClient::StopRemoteObject()
137 {
138 std::lock_guard<std::mutex> lock(mutex_);
139 if (resSchedExe_ && resSchedExe_->AsObject()) {
140 resSchedExe_->AsObject()->RemoveDeathRecipient(recipient_);
141 }
142 resSchedExe_ = nullptr;
143 }
144
ResSchedExeDeathRecipient(ResSchedExeClient & resSchedExeClient)145 ResSchedExeClient::ResSchedExeDeathRecipient::ResSchedExeDeathRecipient(ResSchedExeClient& resSchedExeClient)
146 : resSchedExeClient_(resSchedExeClient) {}
147
~ResSchedExeDeathRecipient()148 ResSchedExeClient::ResSchedExeDeathRecipient::~ResSchedExeDeathRecipient() {}
149
OnRemoteDied(const wptr<IRemoteObject> & remote)150 void ResSchedExeClient::ResSchedExeDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
151 {
152 resSchedExeClient_.StopRemoteObject();
153 }
154 } // namespace ResourceSchedule
155 } // namespace OHOS
156