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
16 #include "resources_subscriber_mgr.h"
17 #include "efficiency_resource_log.h"
18
19 namespace OHOS {
20 namespace BackgroundTaskMgr {
ResourcesSubscriberMgr()21 ResourcesSubscriberMgr::ResourcesSubscriberMgr()
22 {
23 deathRecipient_ = new (std::nothrow) ObserverDeathRecipient();
24 }
25
~ResourcesSubscriberMgr()26 ResourcesSubscriberMgr::~ResourcesSubscriberMgr() {}
27
AddSubscriber(const sptr<IBackgroundTaskSubscriber> & subscriber)28 ErrCode ResourcesSubscriberMgr::AddSubscriber(const sptr<IBackgroundTaskSubscriber>& subscriber)
29 {
30 BGTASK_LOGD("ResourcesSubscriberMgr start subscriber");
31 if (subscriber == NULL) {
32 BGTASK_LOGI("subscriber is null");
33 return ERR_BGTASK_INVALID_PARAM;
34 }
35 auto remote = subscriber->AsObject();
36 if (remote == nullptr) {
37 BGTASK_LOGE("remote in subscriber is null");
38 return ERR_BGTASK_INVALID_PARAM;
39 }
40
41 if (deathRecipient_ == nullptr) {
42 BGTASK_LOGE("create death recipient failed");
43 return ERR_BGTASK_INVALID_PARAM;
44 }
45 std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
46 auto subscriberIter = std::find_if(subscriberList_.begin(), subscriberList_.end(),
47 [&remote](const auto &subscriber) { return subscriber->AsObject() == remote; });
48 if (subscriberIter != subscriberList_.end()) {
49 BGTASK_LOGE("subscriber has already exist");
50 return ERR_BGTASK_OBJECT_EXISTS;
51 }
52
53 subscriberList_.emplace_back(subscriber);
54 remote->AddDeathRecipient(deathRecipient_);
55 BGTASK_LOGD("add resources to efficiency resources mgr succeed!"\
56 " suscriber efficient resources, list.size() is %{public}d",
57 static_cast<int32_t>(subscriberList_.size()));
58 return ERR_OK;
59 }
60
RemoveSubscriber(const sptr<IBackgroundTaskSubscriber> & subscriber)61 ErrCode ResourcesSubscriberMgr::RemoveSubscriber(const sptr<IBackgroundTaskSubscriber>& subscriber)
62 {
63 if (deathRecipient_ == nullptr) {
64 BGTASK_LOGE("deathRecipient is null");
65 return ERR_BGTASK_OBJECT_EXISTS;
66 }
67 if (subscriber == nullptr) {
68 BGTASK_LOGE("subscriber is null");
69 return ERR_BGTASK_INVALID_PARAM;
70 }
71 auto remote = subscriber->AsObject();
72 if (remote == nullptr) {
73 BGTASK_LOGE("apply efficiency resources failed, remote in subscriber is null");
74 return ERR_BGTASK_INVALID_PARAM;
75 }
76 std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
77 auto findSuscriber = [&remote](const auto& subscriberList) {
78 return subscriberList->AsObject() == remote;
79 };
80 auto subscriberIter = std::find_if(subscriberList_.begin(), subscriberList_.end(), findSuscriber);
81 if (subscriberIter == subscriberList_.end()) {
82 BGTASK_LOGE("request subscriber is not exists");
83 return ERR_BGTASK_OBJECT_EXISTS;
84 }
85 subscriberList_.erase(subscriberIter);
86 remote->RemoveDeathRecipient(deathRecipient_);
87 BGTASK_LOGD("remove subscriber from efficiency resources succeed");
88 return ERR_OK;
89 }
90
OnResourceChanged(const std::shared_ptr<ResourceCallbackInfo> & callbackInfo,EfficiencyResourcesEventType type)91 void ResourcesSubscriberMgr::OnResourceChanged(const std::shared_ptr<ResourceCallbackInfo> &callbackInfo,
92 EfficiencyResourcesEventType type)
93 {
94 BGTASK_LOGI("start OnResourceChanged");
95 if (callbackInfo == nullptr) {
96 BGTASK_LOGW("ResourceCallbackInfo is null");
97 return;
98 }
99 std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
100 if (subscriberList_.empty()) {
101 BGTASK_LOGW("Background Task Subscriber List is empty");
102 return;
103 }
104 switch (type) {
105 case EfficiencyResourcesEventType::APP_RESOURCE_APPLY:
106 BGTASK_LOGD("start callback function of app resources application");
107 for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); ++iter) {
108 (*iter)->OnAppEfficiencyResourcesApply(callbackInfo);
109 }
110 break;
111 case EfficiencyResourcesEventType::RESOURCE_APPLY:
112 BGTASK_LOGD("start callback function of proc resources application");
113 for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); ++iter) {
114 (*iter)->OnProcEfficiencyResourcesApply(callbackInfo);
115 }
116 break;
117 case EfficiencyResourcesEventType::APP_RESOURCE_RESET:
118 BGTASK_LOGD("start callback function of app resources reset");
119 for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); ++iter) {
120 (*iter)->OnAppEfficiencyResourcesReset(callbackInfo);
121 }
122 break;
123 case EfficiencyResourcesEventType::RESOURCE_RESET:
124 BGTASK_LOGD("start callback function of proc resources reset");
125 for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); ++iter) {
126 (*iter)->OnProcEfficiencyResourcesReset(callbackInfo);
127 }
128 break;
129 }
130 BGTASK_LOGD("efficiency resources on resources changed function succeed");
131 }
132
HandleSubscriberDeath(const wptr<IRemoteObject> & remote)133 void ResourcesSubscriberMgr::HandleSubscriberDeath(const wptr<IRemoteObject>& remote)
134 {
135 if (remote == nullptr) {
136 BGTASK_LOGE("suscriber death, remote in suscriber is null");
137 return;
138 }
139 sptr<IRemoteObject> proxy = remote.promote();
140 if (!proxy) {
141 BGTASK_LOGE("get remote proxy failed");
142 return;
143 }
144 std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
145 auto findSuscriber = [&proxy](const auto& subscriber) {
146 return subscriber->AsObject() == proxy;
147 };
148 auto subscriberIter = std::find_if(subscriberList_.begin(), subscriberList_.end(), findSuscriber);
149 if (subscriberIter == subscriberList_.end()) {
150 BGTASK_LOGI("suscriber death, remote in suscriber not found");
151 return;
152 }
153 subscriberList_.erase(subscriberIter);
154 BGTASK_LOGD("suscriber death, remove it from list");
155 }
156
157
ObserverDeathRecipient()158 ObserverDeathRecipient::ObserverDeathRecipient() {}
159
~ObserverDeathRecipient()160 ObserverDeathRecipient::~ObserverDeathRecipient() {}
161
OnRemoteDied(const wptr<IRemoteObject> & remote)162 void ObserverDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
163 {
164 DelayedSingleton<ResourcesSubscriberMgr>::GetInstance()->HandleSubscriberDeath(remote);
165 }
166 } // namespace BackgroundTaskMgr
167 } // namespace OHOS