• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "hisysevent.h"
19 
20 namespace OHOS {
21 namespace BackgroundTaskMgr {
22 namespace {
23     const int32_t RESOURCE_TYPE_SHIFTS = 16; // 能效资源类型左移位数
24 }
ResourcesSubscriberMgr()25 ResourcesSubscriberMgr::ResourcesSubscriberMgr()
26 {
27     deathRecipient_ = new (std::nothrow) ObserverDeathRecipient();
28 }
29 
~ResourcesSubscriberMgr()30 ResourcesSubscriberMgr::~ResourcesSubscriberMgr() {}
31 
AddSubscriber(const sptr<IBackgroundTaskSubscriber> & subscriber)32 ErrCode ResourcesSubscriberMgr::AddSubscriber(const sptr<IBackgroundTaskSubscriber>& subscriber)
33 {
34     BGTASK_LOGD("ResourcesSubscriberMgr start subscriber");
35     if (subscriber == NULL) {
36         BGTASK_LOGI("subscriber is null");
37         return ERR_BGTASK_INVALID_PARAM;
38     }
39     auto remote = subscriber->AsObject();
40     if (remote == nullptr) {
41         BGTASK_LOGE("remote in subscriber is null");
42         return ERR_BGTASK_INVALID_PARAM;
43     }
44 
45     if (deathRecipient_ == nullptr) {
46         BGTASK_LOGE("create death recipient failed");
47         return ERR_BGTASK_INVALID_PARAM;
48     }
49     std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
50     auto subscriberIter = std::find_if(subscriberList_.begin(), subscriberList_.end(),
51         [&remote](const auto &subscriber) { return subscriber->AsObject() == remote; });
52     if (subscriberIter != subscriberList_.end()) {
53         BGTASK_LOGE("subscriber has already exist");
54         return ERR_BGTASK_OBJECT_EXISTS;
55     }
56 
57     subscriberList_.emplace_back(subscriber);
58     remote->AddDeathRecipient(deathRecipient_);
59     BGTASK_LOGD("add resources to efficiency resources mgr succeed!"\
60         " suscriber efficient resources, list.size() is %{public}d",
61         static_cast<int32_t>(subscriberList_.size()));
62     return ERR_OK;
63 }
64 
RemoveSubscriber(const sptr<IBackgroundTaskSubscriber> & subscriber)65 ErrCode ResourcesSubscriberMgr::RemoveSubscriber(const sptr<IBackgroundTaskSubscriber>& subscriber)
66 {
67     if (deathRecipient_ == nullptr) {
68         BGTASK_LOGE("deathRecipient is null");
69         return ERR_BGTASK_OBJECT_EXISTS;
70     }
71     if (subscriber == nullptr) {
72         BGTASK_LOGE("subscriber is null");
73         return ERR_BGTASK_INVALID_PARAM;
74     }
75     auto remote = subscriber->AsObject();
76     if (remote == nullptr) {
77         BGTASK_LOGE("apply efficiency resources failed, remote in subscriber is null");
78         return ERR_BGTASK_INVALID_PARAM;
79     }
80     std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
81     auto findSuscriber = [&remote](const auto& subscriberList) {
82         return subscriberList->AsObject() == remote;
83     };
84     auto subscriberIter = std::find_if(subscriberList_.begin(), subscriberList_.end(), findSuscriber);
85     if (subscriberIter == subscriberList_.end()) {
86         BGTASK_LOGE("request subscriber is not exists");
87         return ERR_BGTASK_OBJECT_EXISTS;
88     }
89     subscriberList_.erase(subscriberIter);
90     remote->RemoveDeathRecipient(deathRecipient_);
91     BGTASK_LOGD("remove subscriber from efficiency resources succeed");
92     return ERR_OK;
93 }
94 
OnResourceChanged(const std::shared_ptr<ResourceCallbackInfo> & callbackInfo,EfficiencyResourcesEventType type)95 void ResourcesSubscriberMgr::OnResourceChanged(const std::shared_ptr<ResourceCallbackInfo> &callbackInfo,
96     EfficiencyResourcesEventType type)
97 {
98     BGTASK_LOGD("start OnResourceChanged");
99     if (callbackInfo == nullptr) {
100         BGTASK_LOGW("ResourceCallbackInfo is null");
101         return;
102     }
103     std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
104     if (subscriberList_.empty()) {
105         BGTASK_LOGW("Background Task Subscriber List is empty");
106         return;
107     }
108     HiSysEventResources(callbackInfo, type);
109     const ResourceCallbackInfo& callbackInfoRef = *callbackInfo;
110     switch (type) {
111         case EfficiencyResourcesEventType::APP_RESOURCE_APPLY:
112             BGTASK_LOGD("start callback function of app resources application");
113             for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); ++iter) {
114                 (*iter)->OnAppEfficiencyResourcesApply(callbackInfoRef);
115             }
116             break;
117         case EfficiencyResourcesEventType::RESOURCE_APPLY:
118             BGTASK_LOGD("start callback function of proc resources application");
119             for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); ++iter) {
120                 (*iter)->OnProcEfficiencyResourcesApply(callbackInfoRef);
121             }
122             break;
123         case EfficiencyResourcesEventType::APP_RESOURCE_RESET:
124             BGTASK_LOGD("start callback function of app resources reset");
125             for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); ++iter) {
126                 (*iter)->OnAppEfficiencyResourcesReset(callbackInfoRef);
127             }
128             break;
129         case EfficiencyResourcesEventType::RESOURCE_RESET:
130             BGTASK_LOGD("start callback function of proc resources reset");
131             for (auto iter = subscriberList_.begin(); iter != subscriberList_.end(); ++iter) {
132                 (*iter)->OnProcEfficiencyResourcesReset(callbackInfoRef);
133             }
134             break;
135     }
136     BGTASK_LOGD("efficiency resources on resources changed function succeed");
137 }
138 
HiSysEventResources(const std::shared_ptr<ResourceCallbackInfo> callbackInfo,EfficiencyResourcesEventType type)139 void ResourcesSubscriberMgr::HiSysEventResources(const std::shared_ptr<ResourceCallbackInfo> callbackInfo,
140     EfficiencyResourcesEventType type)
141 {
142     if (callbackInfo == nullptr) {
143         BGTASK_LOGE("ResourceCallbackInfo is null");
144         return;
145     }
146     switch (type) {
147         case EfficiencyResourcesEventType::APP_RESOURCE_APPLY:
148             HiSysEventSubmit(callbackInfo, HISYSEVENT_APP_RESOURCE_APPLY, "CONTINUOUS_TASK_APPLY");
149             break;
150         case EfficiencyResourcesEventType::RESOURCE_APPLY:
151             HiSysEventSubmit(callbackInfo, HISYSEVENT_RESOURCE_APPLY, "CONTINUOUS_TASK_APPLY");
152             break;
153         case EfficiencyResourcesEventType::APP_RESOURCE_RESET:
154             HiSysEventSubmit(callbackInfo, HISYSEVENT_APP_RESOURCE_RESET, "CONTINUOUS_TASK_CANCEL");
155             break;
156         case EfficiencyResourcesEventType::RESOURCE_RESET:
157             HiSysEventSubmit(callbackInfo, HISYSEVENT_RESOURCE_RESET, "CONTINUOUS_TASK_CANCEL");
158             break;
159     }
160 }
161 
HiSysEventSubmit(const std::shared_ptr<ResourceCallbackInfo> callbackInfo,int32_t hiSysEventType,const std::string & eventType)162 void ResourcesSubscriberMgr::HiSysEventSubmit(const std::shared_ptr<ResourceCallbackInfo> callbackInfo,
163     int32_t hiSysEventType, const std::string &eventType)
164 {
165     uint32_t resourceType = callbackInfo->GetResourceNumber() << RESOURCE_TYPE_SHIFTS;
166     HiSysEventWrite(HiviewDFX::HiSysEvent::Domain::BACKGROUND_TASK, eventType.c_str(),
167         HiviewDFX::HiSysEvent::EventType::STATISTIC, "APP_UID", callbackInfo->GetUid(),
168         "APP_PID", callbackInfo->GetPid(), "APP_NAME", callbackInfo->GetBundleName(),
169         "BGMODE", resourceType,
170         "UIABILITY_IDENTITY", hiSysEventType);
171 }
172 
HandleSubscriberDeath(const wptr<IRemoteObject> & remote)173 void ResourcesSubscriberMgr::HandleSubscriberDeath(const wptr<IRemoteObject>& remote)
174 {
175     if (remote == nullptr) {
176         BGTASK_LOGE("suscriber death, remote in suscriber is null");
177         return;
178     }
179     sptr<IRemoteObject> proxy = remote.promote();
180     if (!proxy) {
181         BGTASK_LOGE("get remote proxy failed");
182         return;
183     }
184     std::lock_guard<std::mutex> subcriberLock(subscriberLock_);
185     auto findSuscriber = [&proxy](const auto& subscriber) {
186         return subscriber->AsObject() == proxy;
187     };
188     auto subscriberIter = std::find_if(subscriberList_.begin(), subscriberList_.end(), findSuscriber);
189     if (subscriberIter == subscriberList_.end()) {
190         BGTASK_LOGI("suscriber death, remote in suscriber not found");
191         return;
192     }
193     subscriberList_.erase(subscriberIter);
194     BGTASK_LOGD("suscriber death, remove it from list");
195 }
196 
197 
ObserverDeathRecipient()198 ObserverDeathRecipient::ObserverDeathRecipient() {}
199 
~ObserverDeathRecipient()200 ObserverDeathRecipient::~ObserverDeathRecipient() {}
201 
OnRemoteDied(const wptr<IRemoteObject> & remote)202 void ObserverDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
203 {
204     DelayedSingleton<ResourcesSubscriberMgr>::GetInstance()->HandleSubscriberDeath(remote);
205 }
206 }  // namespace BackgroundTaskMgr
207 }  // namespace OHOS