1 /*
2 * Copyright (c) 2022-2023 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_client.h"
16 #include <string> // for to_string
17 #include <unistd.h> // for getpid
18 #include <new> // for nothrow, operator new
19 #include <unordered_map> // for unordered_map, __hash_map_con...
20 #include <utility> // for pair
21 #include "if_system_ability_manager.h" // for ISystemAbilityManager
22 #include "iremote_broker.h" // for iface_cast
23 #include "iservice_registry.h" // for SystemAbilityManagerClient
24 #include "res_sched_errors.h" // for GET_RES_SCHED_SERVICE_FAILED
25 #include "res_sched_log.h" // for RESSCHED_LOGE, RESSCHED_LOGD
26 #include "system_ability_definition.h" // for RES_SCHED_SYS_ABILITY_ID
27
28 namespace OHOS {
29 namespace ResourceSchedule {
GetInstance()30 ResSchedClient& ResSchedClient::GetInstance()
31 {
32 static ResSchedClient instance;
33 return instance;
34 }
35
ReportData(uint32_t resType,int64_t value,const std::unordered_map<std::string,std::string> & mapPayload)36 void ResSchedClient::ReportData(uint32_t resType, int64_t value,
37 const std::unordered_map<std::string, std::string>& mapPayload)
38 {
39 if (TryConnect() != ERR_OK) {
40 return;
41 }
42 RESSCHED_LOGD("ResSchedClient::ReportData receive resType = %{public}u, value = %{public}lld.",
43 resType, (long long)value);
44 nlohmann::json payload;
45 payload["clientPid"] = std::to_string(getpid());
46 for (auto it = mapPayload.begin(); it != mapPayload.end(); ++it) {
47 payload[it->first] = it->second;
48 }
49 rss_->ReportData(resType, value, payload);
50 }
51
KillProcess(const std::unordered_map<std::string,std::string> & mapPayload)52 int32_t ResSchedClient::KillProcess(const std::unordered_map<std::string, std::string>& mapPayload)
53 {
54 if (TryConnect() != ERR_OK) {
55 return RES_SCHED_CONNECT_FAIL;
56 }
57 RESSCHED_LOGD("ResSchedClient::KillProcess receive mission.");
58 nlohmann::json payload;
59 for (auto it = mapPayload.begin(); it != mapPayload.end(); ++it) {
60 payload[it->first] = it->second;
61 }
62 return rss_->KillProcess(payload);
63 }
64
TryConnect()65 ErrCode ResSchedClient::TryConnect()
66 {
67 std::lock_guard<std::mutex> lock(mutex_);
68 if (rss_) {
69 return ERR_OK;
70 }
71
72 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
73 if (!systemManager) {
74 RESSCHED_LOGE("ResSchedClient::Fail to get registry.");
75 return GET_RES_SCHED_SERVICE_FAILED;
76 }
77
78 remoteObject_ = systemManager->CheckSystemAbility(RES_SCHED_SYS_ABILITY_ID);
79 if (!remoteObject_) {
80 RESSCHED_LOGE("ResSchedClient::Fail to connect resource schedule service.");
81 return GET_RES_SCHED_SERVICE_FAILED;
82 }
83
84 rss_ = iface_cast<IResSchedService>(remoteObject_);
85 if (!rss_) {
86 return GET_RES_SCHED_SERVICE_FAILED;
87 }
88 recipient_ = new (std::nothrow) ResSchedDeathRecipient(*this);
89 if (!recipient_) {
90 RESSCHED_LOGE("ResSchedClient::New ResSchedDeathRecipient failed.");
91 return GET_RES_SCHED_SERVICE_FAILED;
92 }
93 rss_->AsObject()->AddDeathRecipient(recipient_);
94 RESSCHED_LOGD("ResSchedClient::Connect resource schedule service success.");
95 return ERR_OK;
96 }
97
StopRemoteObject()98 void ResSchedClient::StopRemoteObject()
99 {
100 if (rss_ && rss_->AsObject()) {
101 rss_->AsObject()->RemoveDeathRecipient(recipient_);
102 }
103 rss_ = nullptr;
104 }
105
ResSchedDeathRecipient(ResSchedClient & resSchedClient)106 ResSchedClient::ResSchedDeathRecipient::ResSchedDeathRecipient(ResSchedClient &resSchedClient)
107 : resSchedClient_(resSchedClient) {}
108
~ResSchedDeathRecipient()109 ResSchedClient::ResSchedDeathRecipient::~ResSchedDeathRecipient() {}
110
OnRemoteDied(const wptr<IRemoteObject> & remote)111 void ResSchedClient::ResSchedDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
112 {
113 resSchedClient_.StopRemoteObject();
114 }
115
ReportData(uint32_t resType,int64_t value,const std::unordered_map<std::string,std::string> & mapPayload)116 extern "C" void ReportData(uint32_t resType, int64_t value,
117 const std::unordered_map<std::string, std::string>& mapPayload)
118 {
119 ResSchedClient::GetInstance().ReportData(resType, value, mapPayload);
120 }
121
KillProcess(const std::unordered_map<std::string,std::string> & mapPayload)122 extern "C" void KillProcess(const std::unordered_map<std::string, std::string>& mapPayload)
123 {
124 ResSchedClient::GetInstance().KillProcess(mapPayload);
125 }
126 } // namespace ResourceSchedule
127 } // namespace OHOS
128