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