1 /*
2 * Copyright (c) 2022 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 RESSCHED_LOGD("ResSchedClient::ReportData receive resType = %{public}u, value = %{public}lld.",
40 resType, (long long)value);
41 if (TryConnect() != ERR_OK) {
42 return;
43 }
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
TryConnect()52 ErrCode ResSchedClient::TryConnect()
53 {
54 std::lock_guard<std::mutex> lock(mutex_);
55 if (rss_) {
56 return ERR_OK;
57 }
58
59 sptr<ISystemAbilityManager> systemManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
60 if (!systemManager) {
61 RESSCHED_LOGE("ResSchedClient::Fail to get registry.");
62 return GET_RES_SCHED_SERVICE_FAILED;
63 }
64
65 remoteObject_ = systemManager->CheckSystemAbility(RES_SCHED_SYS_ABILITY_ID);
66 if (!remoteObject_) {
67 RESSCHED_LOGE("ResSchedClient::Fail to connect resource schedule service.");
68 return GET_RES_SCHED_SERVICE_FAILED;
69 }
70
71 rss_ = iface_cast<IResSchedService>(remoteObject_);
72 if (!rss_) {
73 return GET_RES_SCHED_SERVICE_FAILED;
74 }
75 recipient_ = new (std::nothrow) ResSchedDeathRecipient(*this);
76 if (!recipient_) {
77 RESSCHED_LOGE("ResSchedClient::New ResSchedDeathRecipient failed.");
78 return GET_RES_SCHED_SERVICE_FAILED;
79 }
80 rss_->AsObject()->AddDeathRecipient(recipient_);
81 RESSCHED_LOGD("ResSchedClient::Connect resource schedule service success.");
82 return ERR_OK;
83 }
84
StopRemoteObject()85 void ResSchedClient::StopRemoteObject()
86 {
87 if (rss_ && rss_->AsObject()) {
88 rss_->AsObject()->RemoveDeathRecipient(recipient_);
89 }
90 rss_ = nullptr;
91 }
92
ResSchedDeathRecipient(ResSchedClient & resSchedClient)93 ResSchedClient::ResSchedDeathRecipient::ResSchedDeathRecipient(ResSchedClient &resSchedClient)
94 : resSchedClient_(resSchedClient) {}
95
~ResSchedDeathRecipient()96 ResSchedClient::ResSchedDeathRecipient::~ResSchedDeathRecipient() {}
97
OnRemoteDied(const wptr<IRemoteObject> & remote)98 void ResSchedClient::ResSchedDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &remote)
99 {
100 resSchedClient_.StopRemoteObject();
101 }
102
ReportData(uint32_t resType,int64_t value,const std::unordered_map<std::string,std::string> & mapPayload)103 extern "C" void ReportData(uint32_t resType, int64_t value,
104 const std::unordered_map<std::string, std::string>& mapPayload)
105 {
106 ResSchedClient::GetInstance().ReportData(resType, value, mapPayload);
107 }
108 } // namespace ResourceSchedule
109 } // namespace OHOS
110