• 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 #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