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 (FwkRunningTaskCountManager::GetInstance()->HasObserver()) {
128 FwkRunningTaskCountManager::GetInstance()->AttachObserver(ob);
129 ob->OnRunningTaskCountUpdate(FwkRunningTaskCountManager::GetInstance()->GetCount());
130 return E_OK;
131 }
132
133 FwkRunningTaskCountManager::GetInstance()->AttachObserver(ob);
134 auto listener = RunCountNotifyStub::GetInstance();
135 RequestManagerImpl::GetInstance()->SubscribeSA();
136 int32_t ret = RequestManagerImpl::GetInstance()->SubRunCount(listener);
137 if (ret != E_OK) {
138 // IPC is failed, but observer has attached.
139 REQUEST_HILOGE("Subscribe running task count failed, ret: %{public}d.", ret);
140 return ret;
141 }
142 if (!FwkRunningTaskCountManager::GetInstance()->SaIsOnline()) {
143 ob->OnRunningTaskCountUpdate(0);
144 }
145 return E_OK;
146 }
147
UnsubscribeRunningTaskCount(std::shared_ptr<IRunningTaskObserver> ob)148 void UnsubscribeRunningTaskCount(std::shared_ptr<IRunningTaskObserver> ob)
149 {
150 FwkRunningTaskCountManager::GetInstance()->DetachObserver(ob);
151 if (FwkRunningTaskCountManager::GetInstance()->HasObserver()) {
152 REQUEST_HILOGD("Unsubscribe running task count success.");
153 return;
154 }
155
156 int32_t ret = RequestManagerImpl::GetInstance()->UnsubRunCount();
157 RequestManagerImpl::GetInstance()->UnsubscribeSA();
158 if (ret != E_OK) {
159 REQUEST_HILOGE("Unsubscribe running task count failed, ret: %{public}d.", ret);
160 }
161 }
162
163 } // namespace OHOS::Request