1 /*
2 * Copyright (c) 2023-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 "app_debug_manager.h"
17
18 #include "hilog_tag_wrapper.h"
19 #include "ipc_types.h"
20
21 namespace OHOS {
22 namespace AppExecFwk {
RegisterAppDebugListener(const sptr<IAppDebugListener> & listener)23 int32_t AppDebugManager::RegisterAppDebugListener(const sptr<IAppDebugListener> &listener)
24 {
25 TAG_LOGD(AAFwkTag::APPMGR, "called");
26 if (listener == nullptr) {
27 TAG_LOGE(AAFwkTag::APPMGR, "Listener is nullptr.");
28 return ERR_INVALID_DATA;
29 }
30
31 std::unique_lock<std::mutex> lock(mutex_);
32 const auto &finder =
33 std::find_if(listeners_.begin(), listeners_.end(), [&listener](const sptr<IAppDebugListener> &element) {
34 if (element != nullptr && listener != nullptr) {
35 return element->AsObject() == listener->AsObject();
36 }
37 return false;
38 });
39 if (finder == listeners_.end()) {
40 listeners_.emplace(listener);
41 }
42
43 if (!debugInfos_.empty()) {
44 listener->OnAppDebugStarted(debugInfos_);
45 }
46 return ERR_OK;
47 }
48
UnregisterAppDebugListener(const sptr<IAppDebugListener> & listener)49 int32_t AppDebugManager::UnregisterAppDebugListener(const sptr<IAppDebugListener> &listener)
50 {
51 TAG_LOGD(AAFwkTag::APPMGR, "called");
52 if (listener == nullptr) {
53 TAG_LOGE(AAFwkTag::APPMGR, "Listener is nullptr.");
54 return ERR_INVALID_DATA;
55 }
56
57 std::unique_lock<std::mutex> lock(mutex_);
58 const auto &finder =
59 std::find_if(listeners_.begin(), listeners_.end(), [&listener](const sptr<IAppDebugListener> &element) {
60 if (element != nullptr && listener != nullptr) {
61 return element->AsObject() == listener->AsObject();
62 }
63 return false;
64 });
65 if (finder != listeners_.end()) {
66 listeners_.erase(finder);
67 }
68 return ERR_OK;
69 }
70
StartDebug(const std::vector<AppDebugInfo> & infos)71 void AppDebugManager::StartDebug(const std::vector<AppDebugInfo> &infos)
72 {
73 TAG_LOGD(AAFwkTag::APPMGR, "called");
74 std::lock_guard<std::mutex> lock(mutex_);
75 std::vector<AppDebugInfo> incrementInfos;
76 GetIncrementAppDebugInfos(infos, incrementInfos);
77 if (incrementInfos.empty()) {
78 return;
79 }
80
81 for (const auto &listener : listeners_) {
82 if (listener == nullptr) {
83 continue;
84 }
85 listener->OnAppDebugStarted(incrementInfos);
86 }
87 }
88
StopDebug(const std::vector<AppDebugInfo> & infos)89 void AppDebugManager::StopDebug(const std::vector<AppDebugInfo> &infos)
90 {
91 TAG_LOGD(AAFwkTag::APPMGR, "called");
92 std::lock_guard<std::mutex> lock(mutex_);
93 std::vector<AppDebugInfo> debugInfos;
94 for (auto &it : infos) {
95 auto isExist = [this, it](const AppDebugInfo &info) {
96 return (info.bundleName == it.bundleName && info.pid == it.pid &&
97 info.uid == it.uid && info.isDebugStart == it.isDebugStart);
98 };
99
100 auto finder = std::find_if(debugInfos_.begin(), debugInfos_.end(), isExist);
101 if (finder != debugInfos_.end()) {
102 debugInfos_.erase(finder);
103 debugInfos.emplace_back(it);
104 }
105 }
106
107 if (!debugInfos.empty()) {
108 for (const auto &listener : listeners_) {
109 if (listener == nullptr) {
110 continue;
111 }
112 listener->OnAppDebugStoped(debugInfos);
113 }
114 }
115 }
116
IsAttachDebug(const std::string & bundleName)117 bool AppDebugManager::IsAttachDebug(const std::string &bundleName)
118 {
119 std::lock_guard<std::mutex> lock(mutex_);
120 for (auto &iter : debugInfos_) {
121 if (iter.bundleName == bundleName && !iter.isDebugStart) {
122 return true;
123 }
124 }
125 return false;
126 }
127
GetIncrementAppDebugInfos(const std::vector<AppDebugInfo> & infos,std::vector<AppDebugInfo> & incrementInfos)128 void AppDebugManager::GetIncrementAppDebugInfos(
129 const std::vector<AppDebugInfo> &infos, std::vector<AppDebugInfo> &incrementInfos)
130 {
131 for (auto &it : infos) {
132 auto isExist = [this, it](const AppDebugInfo &info) {
133 return (info.bundleName == it.bundleName && info.pid == it.pid && info.uid == it.uid);
134 };
135
136 auto finder = std::find_if(debugInfos_.begin(), debugInfos_.end(), isExist);
137 if (finder == debugInfos_.end()) {
138 incrementInfos.emplace_back(it);
139 } else {
140 if (!finder->isDebugStart && it.isDebugStart) {
141 finder->isDebugStart = it.isDebugStart;
142 }
143 }
144 }
145
146 debugInfos_.insert(debugInfos_.end(), incrementInfos.begin(), incrementInfos.end());
147 }
148
RemoveAppDebugInfo(const AppDebugInfo & info)149 void AppDebugManager::RemoveAppDebugInfo(const AppDebugInfo &info)
150 {
151 TAG_LOGD(AAFwkTag::APPMGR, "called");
152 std::lock_guard<std::mutex> lock(mutex_);
153 auto isExist = [this, info](const AppDebugInfo &debugInfo) {
154 return (debugInfo.bundleName == info.bundleName && debugInfo.pid == info.pid &&
155 debugInfo.uid == info.uid && debugInfo.isDebugStart == info.isDebugStart);
156 };
157
158 auto finder = std::find_if(debugInfos_.begin(), debugInfos_.end(), isExist);
159 if (finder == debugInfos_.end()) {
160 return;
161 }
162 debugInfos_.erase(finder);
163
164 std::vector<AppDebugInfo> debugInfos;
165 debugInfos.emplace_back(info);
166 for (const auto &listener : listeners_) {
167 if (listener == nullptr) {
168 continue;
169 }
170 listener->OnAppDebugStoped(debugInfos);
171 }
172 }
173 } // namespace AppExecFwk
174 } // namespace OHOS
175