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