• 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 
16 #include "request_running_task_count.h"
17 
18 #include <fcntl.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <unistd.h>
22 
23 #include <cstdint>
24 #include <memory>
25 
26 #include "download_server_ipc_interface_code.h"
27 #include "iremote_broker.h"
28 #include "parcel_helper.h"
29 #include "request_manager_impl.h"
30 #include "runcount_notify_stub.h"
31 
32 namespace OHOS::Request {
33 using namespace OHOS::HiviewDFX;
34 // impl FwkIRunningTaskObserver
FwkIRunningTaskObserver(std::shared_ptr<IRunningTaskObserver> ob)35 FwkIRunningTaskObserver::FwkIRunningTaskObserver(std::shared_ptr<IRunningTaskObserver> ob)
36 {
37     pInnerOb_ = ob;
38 }
39 
UpdateRunningTaskCount()40 void FwkIRunningTaskObserver::UpdateRunningTaskCount()
41 {
42     pInnerOb_->OnRunningTaskCountUpdate(FwkRunningTaskCountManager::GetInstance()->GetCount());
43 }
44 
GetInnerObserver()45 std::shared_ptr<IRunningTaskObserver> FwkIRunningTaskObserver::GetInnerObserver()
46 {
47     return pInnerOb_;
48 }
49 
50 // impl FwkRunningTaskCountManager
GetInstance()51 std::unique_ptr<FwkRunningTaskCountManager> &FwkRunningTaskCountManager::GetInstance()
52 {
53     static std::unique_ptr<FwkRunningTaskCountManager> instance(new FwkRunningTaskCountManager());
54     return instance;
55 }
56 
GetCount()57 int FwkRunningTaskCountManager::GetCount()
58 {
59     return count_;
60 }
61 
SetCount(int runCount)62 void FwkRunningTaskCountManager::SetCount(int runCount)
63 {
64     std::lock_guard<std::mutex> lock(countLock_);
65     count_ = runCount;
66 }
67 
AttachObserver(std::shared_ptr<IRunningTaskObserver> ob)68 void FwkRunningTaskCountManager::AttachObserver(std::shared_ptr<IRunningTaskObserver> ob)
69 {
70     auto pNewFwkOb = std::make_shared<FwkIRunningTaskObserver>(ob);
71     std::lock_guard<std::mutex> lock(observersLock_);
72     observers_.push_back(pNewFwkOb);
73     REQUEST_HILOGD("Fwk runcount manager has push observer, now has %{public}d observers",
74         static_cast<int32_t>(observers_.size()));
75 }
76 
DetachObserver(std::shared_ptr<IRunningTaskObserver> ob)77 void FwkRunningTaskCountManager::DetachObserver(std::shared_ptr<IRunningTaskObserver> ob)
78 {
79     int32_t eraseCnt = 0;
80     std::lock_guard<std::mutex> lock(observersLock_);
81     auto it = observers_.begin();
82     while (it != observers_.end()) {
83         if ((*it)->GetInnerObserver().get() == ob.get()) {
84             // Just erase shared_ptr from vector, no need to delete.
85             it = observers_.erase(it);
86             eraseCnt++;
87         } else {
88             it++;
89         }
90     }
91 
92     if (!eraseCnt) {
93         REQUEST_HILOGE("Detach observer failed, not found the unsubscribe ob in obervers");
94         return;
95     }
96 }
97 
HasObserver()98 bool FwkRunningTaskCountManager::HasObserver()
99 {
100     return !observers_.empty();
101 }
102 
SaIsOnline()103 bool FwkRunningTaskCountManager::SaIsOnline()
104 {
105     return saIsOnline_.load();
106 }
107 
SetSaStatus(bool isOnline)108 void FwkRunningTaskCountManager::SetSaStatus(bool isOnline)
109 {
110     saIsOnline_.store(isOnline);
111 }
112 
NotifyAllObservers()113 void FwkRunningTaskCountManager::NotifyAllObservers()
114 {
115     REQUEST_HILOGD("Notify runcount to %{public}d observers.", static_cast<int32_t>(observers_.size()));
116     std::lock_guard<std::mutex> observer_lock(observersLock_);
117     auto it = observers_.begin();
118     while (it != observers_.end()) {
119         (*it)->UpdateRunningTaskCount();
120         it++;
121     }
122 }
123 
124 // impl Sub && UnSub
SubscribeRunningTaskCount(std::shared_ptr<IRunningTaskObserver> ob)125 int32_t SubscribeRunningTaskCount(std::shared_ptr<IRunningTaskObserver> ob)
126 {
127     if (!ob) {
128         REQUEST_HILOGE("Subscribe failed because of null observer");
129         return E_OTHER;
130     }
131     if (FwkRunningTaskCountManager::GetInstance()->HasObserver()) {
132         FwkRunningTaskCountManager::GetInstance()->AttachObserver(ob);
133         ob->OnRunningTaskCountUpdate(FwkRunningTaskCountManager::GetInstance()->GetCount());
134         return E_OK;
135     }
136 
137     FwkRunningTaskCountManager::GetInstance()->AttachObserver(ob);
138     auto listener = RunCountNotifyStub::GetInstance();
139     RequestManagerImpl::GetInstance()->SubscribeSA();
140     int32_t ret = RequestManagerImpl::GetInstance()->SubRunCount(listener);
141     if (ret != E_OK) {
142         // IPC is failed, but observer has attached.
143         REQUEST_HILOGE("Subscribe running task count failed, ret: %{public}d.", ret);
144         return ret;
145     }
146     if (!FwkRunningTaskCountManager::GetInstance()->SaIsOnline()) {
147         ob->OnRunningTaskCountUpdate(0);
148     }
149     return E_OK;
150 }
151 
UnsubscribeRunningTaskCount(std::shared_ptr<IRunningTaskObserver> ob)152 void UnsubscribeRunningTaskCount(std::shared_ptr<IRunningTaskObserver> ob)
153 {
154     FwkRunningTaskCountManager::GetInstance()->DetachObserver(ob);
155     if (FwkRunningTaskCountManager::GetInstance()->HasObserver()) {
156         REQUEST_HILOGD("Unsubscribe running task count success.");
157         return;
158     }
159 
160     int32_t ret = RequestManagerImpl::GetInstance()->UnsubRunCount();
161     RequestManagerImpl::GetInstance()->UnsubscribeSA();
162     if (ret != E_OK) {
163         REQUEST_HILOGE("Unsubscribe running task count failed, ret: %{public}d.", ret);
164     }
165 }
166 
167 } // namespace OHOS::Request