1e509ee18Sopenharmony_ci/* 2e509ee18Sopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 3e509ee18Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4e509ee18Sopenharmony_ci * you may not use this file except in compliance with the License. 5e509ee18Sopenharmony_ci * You may obtain a copy of the License at 6e509ee18Sopenharmony_ci * 7e509ee18Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8e509ee18Sopenharmony_ci * 9e509ee18Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10e509ee18Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11e509ee18Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12e509ee18Sopenharmony_ci * See the License for the specific language governing permissions and 13e509ee18Sopenharmony_ci * limitations under the License. 14e509ee18Sopenharmony_ci */ 15e509ee18Sopenharmony_ci 16e509ee18Sopenharmony_ci#include "connect_inspector.h" 17e509ee18Sopenharmony_ci#include <mutex> 18e509ee18Sopenharmony_ci#include "common/log_wrapper.h" 19e509ee18Sopenharmony_cinamespace OHOS::ArkCompiler::Toolchain { 20e509ee18Sopenharmony_cistd::mutex g_connectMutex; 21e509ee18Sopenharmony_cistd::unique_ptr<ConnectInspector> g_inspector = nullptr; 22e509ee18Sopenharmony_cistatic constexpr char CONNECTED_MESSAGE[] = "connected"; 23e509ee18Sopenharmony_cistatic constexpr char OPEN_MESSAGE[] = "layoutOpen"; 24e509ee18Sopenharmony_cistatic constexpr char CLOSE_MESSAGE[] = "layoutClose"; 25e509ee18Sopenharmony_cistatic constexpr char REQUEST_MESSAGE[] = "tree"; 26e509ee18Sopenharmony_cistatic constexpr char STOPDEBUGGER_MESSAGE[] = "stopDebugger"; 27e509ee18Sopenharmony_cistatic constexpr char OPEN_ARKUI_STATE_PROFILER[] = "ArkUIStateProfilerOpen"; 28e509ee18Sopenharmony_cistatic constexpr char CLOSE_ARKUI_STATE_PROFILER[] = "ArkUIStateProfilerClose"; 29e509ee18Sopenharmony_cistatic constexpr char START_RECORD_MESSAGE[] = "rsNodeStartRecord"; 30e509ee18Sopenharmony_cistatic constexpr char STOP_RECORD_MESSAGE[] = "rsNodeStopRecord"; 31e509ee18Sopenharmony_cistd::function<void(bool)> g_setConnectCallBack; 32e509ee18Sopenharmony_ci 33e509ee18Sopenharmony_civoid* HandleDebugManager(void* const server) 34e509ee18Sopenharmony_ci{ 35e509ee18Sopenharmony_ci if (server == nullptr) { 36e509ee18Sopenharmony_ci LOGE("HandleDebugManager server nullptr"); 37e509ee18Sopenharmony_ci return nullptr; 38e509ee18Sopenharmony_ci } 39e509ee18Sopenharmony_ci#if defined(IOS_PLATFORM) || defined(MAC_PLATFORM) 40e509ee18Sopenharmony_ci pthread_setname_np("OS_DbgConThread"); 41e509ee18Sopenharmony_ci#else 42e509ee18Sopenharmony_ci pthread_setname_np(pthread_self(), "OS_DbgConThread"); 43e509ee18Sopenharmony_ci#endif 44e509ee18Sopenharmony_ci 45e509ee18Sopenharmony_ci static_cast<ConnectServer*>(server)->RunServer(); 46e509ee18Sopenharmony_ci return nullptr; 47e509ee18Sopenharmony_ci} 48e509ee18Sopenharmony_ci 49e509ee18Sopenharmony_civoid OnConnectedMessage(const std::string& message) 50e509ee18Sopenharmony_ci{ 51e509ee18Sopenharmony_ci if (message.find(CONNECTED_MESSAGE, 0) != std::string::npos) { 52e509ee18Sopenharmony_ci g_inspector->waitingForDebugger_ = false; 53e509ee18Sopenharmony_ci if (g_setConnectCallBack != nullptr) { 54e509ee18Sopenharmony_ci g_setConnectCallBack(true); 55e509ee18Sopenharmony_ci } 56e509ee18Sopenharmony_ci for (auto& info : g_inspector->infoBuffer_) { 57e509ee18Sopenharmony_ci g_inspector->connectServer_->SendMessage(info.second); 58e509ee18Sopenharmony_ci } 59e509ee18Sopenharmony_ci } 60e509ee18Sopenharmony_ci} 61e509ee18Sopenharmony_ci 62e509ee18Sopenharmony_civoid OnOpenMessage(const std::string& message) 63e509ee18Sopenharmony_ci{ 64e509ee18Sopenharmony_ci if (message.find(OPEN_MESSAGE, 0) != std::string::npos) { 65e509ee18Sopenharmony_ci if (g_inspector->setSwitchStatus_ != nullptr) { 66e509ee18Sopenharmony_ci LOGI("layoutOpen start"); 67e509ee18Sopenharmony_ci g_inspector->setSwitchStatus_(true); 68e509ee18Sopenharmony_ci } 69e509ee18Sopenharmony_ci } 70e509ee18Sopenharmony_ci} 71e509ee18Sopenharmony_ci 72e509ee18Sopenharmony_civoid OnInspectorRecordMessage(const std::string& message) 73e509ee18Sopenharmony_ci{ 74e509ee18Sopenharmony_ci if (message.find(START_RECORD_MESSAGE, 0) != std::string::npos) { 75e509ee18Sopenharmony_ci if (g_inspector->startRecord_ != nullptr && !g_inspector->isRecording_) { 76e509ee18Sopenharmony_ci LOGI("record start"); 77e509ee18Sopenharmony_ci g_inspector->startRecord_(); 78e509ee18Sopenharmony_ci g_inspector->isRecording_ = true; 79e509ee18Sopenharmony_ci } 80e509ee18Sopenharmony_ci } 81e509ee18Sopenharmony_ci 82e509ee18Sopenharmony_ci if (message.find(STOP_RECORD_MESSAGE, 0) != std::string::npos) { 83e509ee18Sopenharmony_ci if (g_inspector->stopRecord_ != nullptr && g_inspector->isRecording_) { 84e509ee18Sopenharmony_ci LOGI("record stop"); 85e509ee18Sopenharmony_ci g_inspector->stopRecord_(); 86e509ee18Sopenharmony_ci g_inspector->isRecording_ = false; 87e509ee18Sopenharmony_ci } 88e509ee18Sopenharmony_ci } 89e509ee18Sopenharmony_ci} 90e509ee18Sopenharmony_ci 91e509ee18Sopenharmony_civoid OnMessage(const std::string& message) 92e509ee18Sopenharmony_ci{ 93e509ee18Sopenharmony_ci std::lock_guard<std::mutex> lock(g_connectMutex); 94e509ee18Sopenharmony_ci if (message.empty()) { 95e509ee18Sopenharmony_ci LOGE("message is empty"); 96e509ee18Sopenharmony_ci return; 97e509ee18Sopenharmony_ci } 98e509ee18Sopenharmony_ci 99e509ee18Sopenharmony_ci LOGI("ConnectServer OnMessage: %{public}s", message.c_str()); 100e509ee18Sopenharmony_ci if (g_inspector != nullptr && g_inspector->connectServer_ != nullptr) { 101e509ee18Sopenharmony_ci g_inspector->ideMsgQueue_.push(message); 102e509ee18Sopenharmony_ci OnConnectedMessage(message); 103e509ee18Sopenharmony_ci 104e509ee18Sopenharmony_ci OnOpenMessage(message); 105e509ee18Sopenharmony_ci if (message.find(CLOSE_MESSAGE, 0) != std::string::npos) { 106e509ee18Sopenharmony_ci if (g_setConnectCallBack != nullptr) { 107e509ee18Sopenharmony_ci g_setConnectCallBack(false); 108e509ee18Sopenharmony_ci } 109e509ee18Sopenharmony_ci if (g_inspector->setSwitchStatus_ != nullptr) { 110e509ee18Sopenharmony_ci LOGI("layoutClose start"); 111e509ee18Sopenharmony_ci g_inspector->setSwitchStatus_(false); 112e509ee18Sopenharmony_ci } 113e509ee18Sopenharmony_ci } 114e509ee18Sopenharmony_ci if (message.find(OPEN_ARKUI_STATE_PROFILER, 0) != std::string::npos) { 115e509ee18Sopenharmony_ci if (g_inspector->setArkUIStateProfilerStatus_ != nullptr) { 116e509ee18Sopenharmony_ci LOGI("state profiler open"); 117e509ee18Sopenharmony_ci g_inspector->setArkUIStateProfilerStatus_(true); 118e509ee18Sopenharmony_ci } 119e509ee18Sopenharmony_ci } 120e509ee18Sopenharmony_ci if (message.find(CLOSE_ARKUI_STATE_PROFILER, 0) != std::string::npos) { 121e509ee18Sopenharmony_ci if (g_inspector->setArkUIStateProfilerStatus_ != nullptr) { 122e509ee18Sopenharmony_ci LOGI("state profiler close"); 123e509ee18Sopenharmony_ci g_inspector->setArkUIStateProfilerStatus_(false); 124e509ee18Sopenharmony_ci } 125e509ee18Sopenharmony_ci } 126e509ee18Sopenharmony_ci if (message.find(REQUEST_MESSAGE, 0) != std::string::npos) { 127e509ee18Sopenharmony_ci if (g_inspector->createLayoutInfo_ != nullptr) { 128e509ee18Sopenharmony_ci LOGI("tree start"); 129e509ee18Sopenharmony_ci g_inspector->createLayoutInfo_(g_inspector->instanceId_); 130e509ee18Sopenharmony_ci } 131e509ee18Sopenharmony_ci } 132e509ee18Sopenharmony_ci if (message.find(STOPDEBUGGER_MESSAGE, 0) != std::string::npos) { 133e509ee18Sopenharmony_ci g_inspector->waitingForDebugger_ = true; 134e509ee18Sopenharmony_ci if (g_inspector->setDebugMode_ != nullptr) { 135e509ee18Sopenharmony_ci LOGI("stopDebugger start"); 136e509ee18Sopenharmony_ci g_inspector->setDebugMode_(); 137e509ee18Sopenharmony_ci } 138e509ee18Sopenharmony_ci } 139e509ee18Sopenharmony_ci OnInspectorRecordMessage(message); 140e509ee18Sopenharmony_ci } 141e509ee18Sopenharmony_ci} 142e509ee18Sopenharmony_ci 143e509ee18Sopenharmony_civoid SetSwitchCallBack(const std::function<void(bool)>& setSwitchStatus, 144e509ee18Sopenharmony_ci const std::function<void(int32_t)>& createLayoutInfo, int32_t instanceId) 145e509ee18Sopenharmony_ci{ 146e509ee18Sopenharmony_ci std::lock_guard<std::mutex> lock(g_connectMutex); 147e509ee18Sopenharmony_ci if (g_inspector == nullptr) { 148e509ee18Sopenharmony_ci g_inspector = std::make_unique<ConnectInspector>(); 149e509ee18Sopenharmony_ci } 150e509ee18Sopenharmony_ci g_inspector->setSwitchStatus_ = setSwitchStatus; 151e509ee18Sopenharmony_ci g_inspector->createLayoutInfo_ = createLayoutInfo; 152e509ee18Sopenharmony_ci g_inspector->instanceId_ = instanceId; 153e509ee18Sopenharmony_ci} 154e509ee18Sopenharmony_ci 155e509ee18Sopenharmony_civoid SetConnectCallback(const std::function<void(bool)>& callback) 156e509ee18Sopenharmony_ci{ 157e509ee18Sopenharmony_ci g_setConnectCallBack = callback; 158e509ee18Sopenharmony_ci} 159e509ee18Sopenharmony_ci 160e509ee18Sopenharmony_ci// stop debugger but the application continues to run 161e509ee18Sopenharmony_civoid SetDebugModeCallBack(const std::function<void()>& setDebugMode) 162e509ee18Sopenharmony_ci{ 163e509ee18Sopenharmony_ci std::lock_guard<std::mutex> lock(g_connectMutex); 164e509ee18Sopenharmony_ci if (g_inspector != nullptr) { 165e509ee18Sopenharmony_ci g_inspector->setDebugMode_ = setDebugMode; 166e509ee18Sopenharmony_ci } 167e509ee18Sopenharmony_ci} 168e509ee18Sopenharmony_ci 169e509ee18Sopenharmony_civoid ResetService() 170e509ee18Sopenharmony_ci{ 171e509ee18Sopenharmony_ci if (g_inspector != nullptr && g_inspector->connectServer_ != nullptr) { 172e509ee18Sopenharmony_ci g_inspector->connectServer_->StopServer(); 173e509ee18Sopenharmony_ci g_inspector->connectServer_.reset(); 174e509ee18Sopenharmony_ci } 175e509ee18Sopenharmony_ci} 176e509ee18Sopenharmony_ci 177e509ee18Sopenharmony_cibool StartServerForSocketPair(int socketfd) 178e509ee18Sopenharmony_ci{ 179e509ee18Sopenharmony_ci LOGI("StartServerForSocketPair, socketfd = %{private}d", socketfd); 180e509ee18Sopenharmony_ci if (g_inspector == nullptr) { 181e509ee18Sopenharmony_ci g_inspector = std::make_unique<ConnectInspector>(); 182e509ee18Sopenharmony_ci } 183e509ee18Sopenharmony_ci if (g_inspector->connectServer_ != nullptr) { 184e509ee18Sopenharmony_ci LOGW("ConnectServer is not nullptr!"); 185e509ee18Sopenharmony_ci return true; 186e509ee18Sopenharmony_ci } 187e509ee18Sopenharmony_ci g_inspector->connectServer_ = std::make_unique<ConnectServer>(socketfd, 188e509ee18Sopenharmony_ci std::bind(&OnMessage, std::placeholders::_1)); 189e509ee18Sopenharmony_ci 190e509ee18Sopenharmony_ci pthread_t tid; 191e509ee18Sopenharmony_ci if (pthread_create(&tid, nullptr, &HandleDebugManager, 192e509ee18Sopenharmony_ci static_cast<void*>(g_inspector->connectServer_.get())) != 0) { 193e509ee18Sopenharmony_ci LOGE("pthread_create fail!"); 194e509ee18Sopenharmony_ci ResetService(); 195e509ee18Sopenharmony_ci return false; 196e509ee18Sopenharmony_ci } 197e509ee18Sopenharmony_ci return true; 198e509ee18Sopenharmony_ci} 199e509ee18Sopenharmony_ci 200e509ee18Sopenharmony_civoid StartServer(const std::string& componentName) 201e509ee18Sopenharmony_ci{ 202e509ee18Sopenharmony_ci LOGI("StartServer, componentName = %{private}s", componentName.c_str()); 203e509ee18Sopenharmony_ci g_inspector = std::make_unique<ConnectInspector>(); 204e509ee18Sopenharmony_ci#ifdef PANDA_TARGET_ARM32 205e509ee18Sopenharmony_ci g_inspector->connectServer_ = std::make_unique<ConnectServer>(componentName, 206e509ee18Sopenharmony_ci std::bind(&OnMessage, std::placeholders::_1)); 207e509ee18Sopenharmony_ci 208e509ee18Sopenharmony_ci pthread_t tid; 209e509ee18Sopenharmony_ci if (pthread_create(&tid, nullptr, &HandleDebugManager, 210e509ee18Sopenharmony_ci static_cast<void*>(g_inspector->connectServer_.get())) != 0) { 211e509ee18Sopenharmony_ci LOGE("pthread_create fail!"); 212e509ee18Sopenharmony_ci ResetService(); 213e509ee18Sopenharmony_ci return; 214e509ee18Sopenharmony_ci } 215e509ee18Sopenharmony_ci#endif 216e509ee18Sopenharmony_ci} 217e509ee18Sopenharmony_ci 218e509ee18Sopenharmony_civoid StopServer([[maybe_unused]] const std::string& componentName) 219e509ee18Sopenharmony_ci{ 220e509ee18Sopenharmony_ci LOGI("StopServer, componentName = %{private}s", componentName.c_str()); 221e509ee18Sopenharmony_ci ResetService(); 222e509ee18Sopenharmony_ci} 223e509ee18Sopenharmony_ci 224e509ee18Sopenharmony_civoid StoreMessage(int32_t instanceId, const std::string& message) 225e509ee18Sopenharmony_ci{ 226e509ee18Sopenharmony_ci std::lock_guard<std::mutex> lock(g_connectMutex); 227e509ee18Sopenharmony_ci if (g_inspector == nullptr) { 228e509ee18Sopenharmony_ci g_inspector = std::make_unique<ConnectInspector>(); 229e509ee18Sopenharmony_ci } 230e509ee18Sopenharmony_ci if (g_inspector->infoBuffer_.count(instanceId) == 1) { 231e509ee18Sopenharmony_ci LOGE("The message with the current instance id has existed."); 232e509ee18Sopenharmony_ci return; 233e509ee18Sopenharmony_ci } 234e509ee18Sopenharmony_ci g_inspector->infoBuffer_[instanceId] = message; 235e509ee18Sopenharmony_ci} 236e509ee18Sopenharmony_ci 237e509ee18Sopenharmony_civoid StoreInspectorInfo(const std::string& jsonTreeStr, const std::string& jsonSnapshotStr) 238e509ee18Sopenharmony_ci{ 239e509ee18Sopenharmony_ci std::lock_guard<std::mutex> lock(g_connectMutex); 240e509ee18Sopenharmony_ci g_inspector->layoutInspectorInfo_.tree = jsonTreeStr; 241e509ee18Sopenharmony_ci g_inspector->layoutInspectorInfo_.snapShot = jsonSnapshotStr; 242e509ee18Sopenharmony_ci} 243e509ee18Sopenharmony_ci 244e509ee18Sopenharmony_civoid RemoveMessage(int32_t instanceId) 245e509ee18Sopenharmony_ci{ 246e509ee18Sopenharmony_ci std::lock_guard<std::mutex> lock(g_connectMutex); 247e509ee18Sopenharmony_ci if (g_inspector == nullptr) { 248e509ee18Sopenharmony_ci return; 249e509ee18Sopenharmony_ci } 250e509ee18Sopenharmony_ci if (g_inspector->infoBuffer_.count(instanceId) != 1) { 251e509ee18Sopenharmony_ci LOGE("The message with the current instance id does not exist."); 252e509ee18Sopenharmony_ci return; 253e509ee18Sopenharmony_ci } 254e509ee18Sopenharmony_ci g_inspector->infoBuffer_.erase(instanceId); 255e509ee18Sopenharmony_ci} 256e509ee18Sopenharmony_ci 257e509ee18Sopenharmony_civoid SendLayoutMessage(const std::string& message) 258e509ee18Sopenharmony_ci{ 259e509ee18Sopenharmony_ci LOGI("SendLayoutMessage start to send message"); 260e509ee18Sopenharmony_ci if (g_inspector != nullptr && g_inspector->connectServer_ != nullptr) { 261e509ee18Sopenharmony_ci g_inspector->connectServer_->SendMessage(message); 262e509ee18Sopenharmony_ci } 263e509ee18Sopenharmony_ci} 264e509ee18Sopenharmony_ci 265e509ee18Sopenharmony_civoid SendMessage(const std::string& message) 266e509ee18Sopenharmony_ci{ 267e509ee18Sopenharmony_ci if (g_inspector != nullptr && g_inspector->connectServer_ != nullptr && !g_inspector->waitingForDebugger_) { 268e509ee18Sopenharmony_ci g_inspector->connectServer_->SendMessage(message); 269e509ee18Sopenharmony_ci } 270e509ee18Sopenharmony_ci} 271e509ee18Sopenharmony_ci 272e509ee18Sopenharmony_cibool WaitForConnection() 273e509ee18Sopenharmony_ci{ 274e509ee18Sopenharmony_ci if (g_inspector == nullptr) { 275e509ee18Sopenharmony_ci return true; 276e509ee18Sopenharmony_ci } 277e509ee18Sopenharmony_ci return g_inspector->waitingForDebugger_; 278e509ee18Sopenharmony_ci} 279e509ee18Sopenharmony_ci 280e509ee18Sopenharmony_ci// profiler methods 281e509ee18Sopenharmony_ci 282e509ee18Sopenharmony_civoid SendProfilerMessage(const std::string &message) 283e509ee18Sopenharmony_ci{ 284e509ee18Sopenharmony_ci LOGI("SendStateProfilerMessage start to send message"); 285e509ee18Sopenharmony_ci if (g_inspector != nullptr && g_inspector->connectServer_ != nullptr) { 286e509ee18Sopenharmony_ci g_inspector->connectServer_->SendMessage(message); 287e509ee18Sopenharmony_ci } 288e509ee18Sopenharmony_ci} 289e509ee18Sopenharmony_ci 290e509ee18Sopenharmony_civoid SetProfilerCallback(const std::function<void(bool)> &setArkUIStateProfilerStatus) 291e509ee18Sopenharmony_ci{ 292e509ee18Sopenharmony_ci std::lock_guard<std::mutex> lock(g_connectMutex); 293e509ee18Sopenharmony_ci if (g_inspector == nullptr) { 294e509ee18Sopenharmony_ci g_inspector = std::make_unique<ConnectInspector>(); 295e509ee18Sopenharmony_ci } 296e509ee18Sopenharmony_ci g_inspector->setArkUIStateProfilerStatus_ = setArkUIStateProfilerStatus; 297e509ee18Sopenharmony_ci} 298e509ee18Sopenharmony_ci 299e509ee18Sopenharmony_civoid SetRecordCallback(const std::function<void(void)> &startRecordFunc, 300e509ee18Sopenharmony_ci const std::function<void(void)> &stopRecordFunc) 301e509ee18Sopenharmony_ci{ 302e509ee18Sopenharmony_ci std::lock_guard<std::mutex> lock(g_connectMutex); 303e509ee18Sopenharmony_ci if (g_inspector == nullptr) { 304e509ee18Sopenharmony_ci g_inspector = std::make_unique<ConnectInspector>(); 305e509ee18Sopenharmony_ci } 306e509ee18Sopenharmony_ci g_inspector->startRecord_ = startRecordFunc; 307e509ee18Sopenharmony_ci g_inspector->stopRecord_ = stopRecordFunc; 308e509ee18Sopenharmony_ci} 309e509ee18Sopenharmony_ci} // OHOS::ArkCompiler::Toolchain 310