123b3eb3cSopenharmony_ci/* 223b3eb3cSopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd. 323b3eb3cSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 423b3eb3cSopenharmony_ci * you may not use this file except in compliance with the License. 523b3eb3cSopenharmony_ci * You may obtain a copy of the License at 623b3eb3cSopenharmony_ci * 723b3eb3cSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 823b3eb3cSopenharmony_ci * 923b3eb3cSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1023b3eb3cSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1123b3eb3cSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1223b3eb3cSopenharmony_ci * See the License for the specific language governing permissions and 1323b3eb3cSopenharmony_ci * limitations under the License. 1423b3eb3cSopenharmony_ci */ 1523b3eb3cSopenharmony_ci 1623b3eb3cSopenharmony_ci#include "core/common/layout_inspector.h" 1723b3eb3cSopenharmony_ci 1823b3eb3cSopenharmony_ci#include <mutex> 1923b3eb3cSopenharmony_ci#include <string> 2023b3eb3cSopenharmony_ci 2123b3eb3cSopenharmony_ci#include "include/core/SkImage.h" 2223b3eb3cSopenharmony_ci#include "include/core/SkString.h" 2323b3eb3cSopenharmony_ci#include "include/core/SkColorSpace.h" 2423b3eb3cSopenharmony_ci#include "include/utils/SkBase64.h" 2523b3eb3cSopenharmony_ci 2623b3eb3cSopenharmony_ci#include "wm/window.h" 2723b3eb3cSopenharmony_ci 2823b3eb3cSopenharmony_ci#include "adapter/ohos/osal/pixel_map_ohos.h" 2923b3eb3cSopenharmony_ci#include "adapter/ohos/entrance/ace_container.h" 3023b3eb3cSopenharmony_ci#include "adapter/ohos/entrance/subwindow/subwindow_ohos.h" 3123b3eb3cSopenharmony_ci#include "base/subwindow/subwindow_manager.h" 3223b3eb3cSopenharmony_ci#include "base/thread/background_task_executor.h" 3323b3eb3cSopenharmony_ci#include "base/utils/utils.h" 3423b3eb3cSopenharmony_ci#include "base/json/json_util.h" 3523b3eb3cSopenharmony_ci#include "base/utils/system_properties.h" 3623b3eb3cSopenharmony_ci#include "core/common/ace_engine.h" 3723b3eb3cSopenharmony_ci#include "core/common/connect_server_manager.h" 3823b3eb3cSopenharmony_ci#include "core/common/container.h" 3923b3eb3cSopenharmony_ci#include "core/common/container_scope.h" 4023b3eb3cSopenharmony_ci#include "core/components_ng/base/inspector.h" 4123b3eb3cSopenharmony_ci#include "core/components_v2/inspector/inspector.h" 4223b3eb3cSopenharmony_ci#include "core/pipeline_ng/pipeline_context.h" 4323b3eb3cSopenharmony_ci#include "dm/display_manager.h" 4423b3eb3cSopenharmony_ci#include "foundation/ability/ability_runtime/frameworks/native/runtime/connect_server_manager.h" 4523b3eb3cSopenharmony_ci 4623b3eb3cSopenharmony_cinamespace OHOS::Ace { 4723b3eb3cSopenharmony_ci 4823b3eb3cSopenharmony_cinamespace { 4923b3eb3cSopenharmony_ci 5023b3eb3cSopenharmony_cisk_sp<SkColorSpace> ColorSpaceToSkColorSpace(const RefPtr<PixelMap>& pixmap) 5123b3eb3cSopenharmony_ci{ 5223b3eb3cSopenharmony_ci return SkColorSpace::MakeSRGB(); 5323b3eb3cSopenharmony_ci} 5423b3eb3cSopenharmony_ci 5523b3eb3cSopenharmony_ciSkAlphaType AlphaTypeToSkAlphaType(const RefPtr<PixelMap>& pixmap) 5623b3eb3cSopenharmony_ci{ 5723b3eb3cSopenharmony_ci switch (pixmap->GetAlphaType()) { 5823b3eb3cSopenharmony_ci case AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN: 5923b3eb3cSopenharmony_ci return SkAlphaType::kUnknown_SkAlphaType; 6023b3eb3cSopenharmony_ci case AlphaType::IMAGE_ALPHA_TYPE_OPAQUE: 6123b3eb3cSopenharmony_ci return SkAlphaType::kOpaque_SkAlphaType; 6223b3eb3cSopenharmony_ci case AlphaType::IMAGE_ALPHA_TYPE_PREMUL: 6323b3eb3cSopenharmony_ci return SkAlphaType::kPremul_SkAlphaType; 6423b3eb3cSopenharmony_ci case AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL: 6523b3eb3cSopenharmony_ci return SkAlphaType::kUnpremul_SkAlphaType; 6623b3eb3cSopenharmony_ci default: 6723b3eb3cSopenharmony_ci return SkAlphaType::kUnknown_SkAlphaType; 6823b3eb3cSopenharmony_ci } 6923b3eb3cSopenharmony_ci} 7023b3eb3cSopenharmony_ci 7123b3eb3cSopenharmony_ciSkColorType PixelFormatToSkColorType(const RefPtr<PixelMap>& pixmap) 7223b3eb3cSopenharmony_ci{ 7323b3eb3cSopenharmony_ci switch (pixmap->GetPixelFormat()) { 7423b3eb3cSopenharmony_ci case PixelFormat::RGB_565: 7523b3eb3cSopenharmony_ci return SkColorType::kRGB_565_SkColorType; 7623b3eb3cSopenharmony_ci case PixelFormat::RGBA_8888: 7723b3eb3cSopenharmony_ci return SkColorType::kRGBA_8888_SkColorType; 7823b3eb3cSopenharmony_ci case PixelFormat::BGRA_8888: 7923b3eb3cSopenharmony_ci return SkColorType::kBGRA_8888_SkColorType; 8023b3eb3cSopenharmony_ci case PixelFormat::ALPHA_8: 8123b3eb3cSopenharmony_ci return SkColorType::kAlpha_8_SkColorType; 8223b3eb3cSopenharmony_ci case PixelFormat::RGBA_F16: 8323b3eb3cSopenharmony_ci return SkColorType::kRGBA_F16_SkColorType; 8423b3eb3cSopenharmony_ci case PixelFormat::UNKNOWN: 8523b3eb3cSopenharmony_ci case PixelFormat::ARGB_8888: 8623b3eb3cSopenharmony_ci case PixelFormat::RGB_888: 8723b3eb3cSopenharmony_ci case PixelFormat::NV21: 8823b3eb3cSopenharmony_ci case PixelFormat::NV12: 8923b3eb3cSopenharmony_ci case PixelFormat::CMYK: 9023b3eb3cSopenharmony_ci default: 9123b3eb3cSopenharmony_ci return SkColorType::kUnknown_SkColorType; 9223b3eb3cSopenharmony_ci } 9323b3eb3cSopenharmony_ci} 9423b3eb3cSopenharmony_ci 9523b3eb3cSopenharmony_ciSkImageInfo MakeSkImageInfoFromPixelMap(const RefPtr<PixelMap>& pixmap) 9623b3eb3cSopenharmony_ci{ 9723b3eb3cSopenharmony_ci SkColorType colorType = PixelFormatToSkColorType(pixmap); 9823b3eb3cSopenharmony_ci SkAlphaType alphaType = AlphaTypeToSkAlphaType(pixmap); 9923b3eb3cSopenharmony_ci sk_sp<SkColorSpace> colorSpace = ColorSpaceToSkColorSpace(pixmap); 10023b3eb3cSopenharmony_ci return SkImageInfo::Make(pixmap->GetWidth(), pixmap->GetHeight(), colorType, alphaType, colorSpace); 10123b3eb3cSopenharmony_ci} 10223b3eb3cSopenharmony_ci 10323b3eb3cSopenharmony_ciconst OHOS::sptr<OHOS::Rosen::Window> GetWindow(int32_t containerId) 10423b3eb3cSopenharmony_ci{ 10523b3eb3cSopenharmony_ci auto container = AceEngine::Get().GetContainer(containerId); 10623b3eb3cSopenharmony_ci if (containerId >= MIN_SUBCONTAINER_ID && containerId < MIN_PLUGIN_SUBCONTAINER_ID) { 10723b3eb3cSopenharmony_ci auto subwindow = SubwindowManager::GetInstance()->GetSubwindow( 10823b3eb3cSopenharmony_ci SubwindowManager::GetInstance()->GetParentContainerId(containerId)); 10923b3eb3cSopenharmony_ci CHECK_NULL_RETURN(subwindow, nullptr); 11023b3eb3cSopenharmony_ci if (AceType::InstanceOf<SubwindowOhos>(subwindow)) { 11123b3eb3cSopenharmony_ci auto subWindowOhos = AceType::DynamicCast<SubwindowOhos>(subwindow); 11223b3eb3cSopenharmony_ci CHECK_NULL_RETURN(subWindowOhos, nullptr); 11323b3eb3cSopenharmony_ci return subWindowOhos->GetSubWindow(); 11423b3eb3cSopenharmony_ci } 11523b3eb3cSopenharmony_ci } else { 11623b3eb3cSopenharmony_ci auto aceContainer = AceType::DynamicCast<Platform::AceContainer>(container); 11723b3eb3cSopenharmony_ci if (aceContainer != nullptr) { 11823b3eb3cSopenharmony_ci return OHOS::Rosen::Window::Find(aceContainer->GetWindowName()); 11923b3eb3cSopenharmony_ci } 12023b3eb3cSopenharmony_ci return OHOS::Rosen::Window::GetTopWindowWithId(container->GetWindowId()); 12123b3eb3cSopenharmony_ci } 12223b3eb3cSopenharmony_ci return nullptr; 12323b3eb3cSopenharmony_ci} 12423b3eb3cSopenharmony_ci} // namespace 12523b3eb3cSopenharmony_ci 12623b3eb3cSopenharmony_ciconstexpr static char RECNODE_SELFID[] = "selfId"; 12723b3eb3cSopenharmony_ciconstexpr static char RECNODE_NODEID[] = "nodeID"; 12823b3eb3cSopenharmony_ciconstexpr static char RECNODE_NAME[] = "value"; 12923b3eb3cSopenharmony_ciconstexpr static char RECNODE_DEBUGLINE[] = "debugLine"; 13023b3eb3cSopenharmony_ciconstexpr static char RECNODE_CHILDREN[] = "RSNode"; 13123b3eb3cSopenharmony_ci 13223b3eb3cSopenharmony_cibool LayoutInspector::stateProfilerStatus_ = false; 13323b3eb3cSopenharmony_cibool LayoutInspector::layoutInspectorStatus_ = false; 13423b3eb3cSopenharmony_cistd::mutex LayoutInspector::recMutex_; 13523b3eb3cSopenharmony_ciProfilerStatusCallback LayoutInspector::jsStateProfilerStatusCallback_ = nullptr; 13623b3eb3cSopenharmony_ciRsProfilerNodeMountCallback LayoutInspector::rsProfilerNodeMountCallback_ = nullptr; 13723b3eb3cSopenharmony_ciconst char PNG_TAG[] = "png"; 13823b3eb3cSopenharmony_ciNG::InspectorTreeMap LayoutInspector::recNodeInfos_; 13923b3eb3cSopenharmony_ci 14023b3eb3cSopenharmony_civoid LayoutInspector::SupportInspector() 14123b3eb3cSopenharmony_ci{ 14223b3eb3cSopenharmony_ci auto container = Container::Current(); 14323b3eb3cSopenharmony_ci CHECK_NULL_VOID(container); 14423b3eb3cSopenharmony_ci if (!layoutInspectorStatus_) { 14523b3eb3cSopenharmony_ci return; 14623b3eb3cSopenharmony_ci } 14723b3eb3cSopenharmony_ci std::string treeJsonStr; 14823b3eb3cSopenharmony_ci GetInspectorTreeJsonStr(treeJsonStr, ContainerScope::CurrentId()); 14923b3eb3cSopenharmony_ci if (treeJsonStr.empty()) { 15023b3eb3cSopenharmony_ci return; 15123b3eb3cSopenharmony_ci } 15223b3eb3cSopenharmony_ci auto message = JsonUtil::Create(true); 15323b3eb3cSopenharmony_ci GetSnapshotJson(ContainerScope::CurrentId(), message); 15423b3eb3cSopenharmony_ci CHECK_NULL_VOID(message); 15523b3eb3cSopenharmony_ci 15623b3eb3cSopenharmony_ci auto sendTask = [treeJsonStr, jsonSnapshotStr = message->ToString(), container]() { 15723b3eb3cSopenharmony_ci if (container->IsUseStageModel()) { 15823b3eb3cSopenharmony_ci OHOS::AbilityRuntime::ConnectServerManager::Get().SendInspector(treeJsonStr, jsonSnapshotStr); 15923b3eb3cSopenharmony_ci } else { 16023b3eb3cSopenharmony_ci OHOS::Ace::ConnectServerManager::Get().SendInspector(treeJsonStr, jsonSnapshotStr); 16123b3eb3cSopenharmony_ci } 16223b3eb3cSopenharmony_ci }; 16323b3eb3cSopenharmony_ci BackgroundTaskExecutor::GetInstance().PostTask(std::move(sendTask)); 16423b3eb3cSopenharmony_ci} 16523b3eb3cSopenharmony_ci 16623b3eb3cSopenharmony_civoid LayoutInspector::SetStatus(bool layoutInspectorStatus) 16723b3eb3cSopenharmony_ci{ 16823b3eb3cSopenharmony_ci layoutInspectorStatus_ = layoutInspectorStatus; 16923b3eb3cSopenharmony_ci} 17023b3eb3cSopenharmony_ci 17123b3eb3cSopenharmony_civoid LayoutInspector::TriggerJsStateProfilerStatusCallback(bool status) 17223b3eb3cSopenharmony_ci{ 17323b3eb3cSopenharmony_ci if (jsStateProfilerStatusCallback_) { 17423b3eb3cSopenharmony_ci stateProfilerStatus_ = status; 17523b3eb3cSopenharmony_ci jsStateProfilerStatusCallback_(status); 17623b3eb3cSopenharmony_ci } 17723b3eb3cSopenharmony_ci} 17823b3eb3cSopenharmony_ci 17923b3eb3cSopenharmony_civoid LayoutInspector::SetJsStateProfilerStatusCallback(ProfilerStatusCallback&& callback) 18023b3eb3cSopenharmony_ci{ 18123b3eb3cSopenharmony_ci jsStateProfilerStatusCallback_ = callback; 18223b3eb3cSopenharmony_ci} 18323b3eb3cSopenharmony_ci 18423b3eb3cSopenharmony_cibool LayoutInspector::GetStateProfilerStatus() 18523b3eb3cSopenharmony_ci{ 18623b3eb3cSopenharmony_ci return stateProfilerStatus_; 18723b3eb3cSopenharmony_ci} 18823b3eb3cSopenharmony_ci 18923b3eb3cSopenharmony_ciRsProfilerNodeMountCallback LayoutInspector::GetRsProfilerNodeMountCallback() 19023b3eb3cSopenharmony_ci{ 19123b3eb3cSopenharmony_ci return rsProfilerNodeMountCallback_; 19223b3eb3cSopenharmony_ci} 19323b3eb3cSopenharmony_ci 19423b3eb3cSopenharmony_civoid LayoutInspector::SetRsProfilerNodeMountCallback(RsProfilerNodeMountCallback&& callback) 19523b3eb3cSopenharmony_ci{ 19623b3eb3cSopenharmony_ci rsProfilerNodeMountCallback_ = callback; 19723b3eb3cSopenharmony_ci} 19823b3eb3cSopenharmony_ci 19923b3eb3cSopenharmony_civoid LayoutInspector::SendStateProfilerMessage(const std::string& message) 20023b3eb3cSopenharmony_ci{ 20123b3eb3cSopenharmony_ci OHOS::AbilityRuntime::ConnectServerManager::Get().SendArkUIStateProfilerMessage(message); 20223b3eb3cSopenharmony_ci} 20323b3eb3cSopenharmony_ci 20423b3eb3cSopenharmony_civoid LayoutInspector::SetStateProfilerStatus(bool status) 20523b3eb3cSopenharmony_ci{ 20623b3eb3cSopenharmony_ci auto taskExecutor = Container::CurrentTaskExecutorSafely(); 20723b3eb3cSopenharmony_ci CHECK_NULL_VOID(taskExecutor); 20823b3eb3cSopenharmony_ci auto task = [status]() { LayoutInspector::TriggerJsStateProfilerStatusCallback(status); }; 20923b3eb3cSopenharmony_ci taskExecutor->PostTask(std::move(task), TaskExecutor::TaskType::UI, "ArkUISetStateProfilerStatus"); 21023b3eb3cSopenharmony_ci} 21123b3eb3cSopenharmony_ci 21223b3eb3cSopenharmony_civoid LayoutInspector::SetCallback(int32_t instanceId) 21323b3eb3cSopenharmony_ci{ 21423b3eb3cSopenharmony_ci auto container = AceEngine::Get().GetContainer(instanceId); 21523b3eb3cSopenharmony_ci CHECK_NULL_VOID(container); 21623b3eb3cSopenharmony_ci if (container->IsUseStageModel()) { 21723b3eb3cSopenharmony_ci OHOS::AbilityRuntime::ConnectServerManager::Get().SetLayoutInspectorCallback( 21823b3eb3cSopenharmony_ci [](int32_t containerId) { return CreateLayoutInfo(containerId); }, 21923b3eb3cSopenharmony_ci [](bool status) { return SetStatus(status); }); 22023b3eb3cSopenharmony_ci OHOS::AbilityRuntime::ConnectServerManager::Get().SetRecordCallback( 22123b3eb3cSopenharmony_ci LayoutInspector::HandleStartRecord, LayoutInspector::HandleStopRecord); 22223b3eb3cSopenharmony_ci } else { 22323b3eb3cSopenharmony_ci OHOS::Ace::ConnectServerManager::Get().SetLayoutInspectorCallback( 22423b3eb3cSopenharmony_ci [](int32_t containerId) { return CreateLayoutInfo(containerId); }, 22523b3eb3cSopenharmony_ci [](bool status) { return SetStatus(status); }); 22623b3eb3cSopenharmony_ci } 22723b3eb3cSopenharmony_ci 22823b3eb3cSopenharmony_ci OHOS::AbilityRuntime::ConnectServerManager::Get().SetStateProfilerCallback( 22923b3eb3cSopenharmony_ci [](bool status) { return SetStateProfilerStatus(status); }); 23023b3eb3cSopenharmony_ci} 23123b3eb3cSopenharmony_ci 23223b3eb3cSopenharmony_civoid LayoutInspector::CreateLayoutInfo(int32_t containerId) 23323b3eb3cSopenharmony_ci{ 23423b3eb3cSopenharmony_ci auto container = Container::GetFoucsed(); 23523b3eb3cSopenharmony_ci CHECK_NULL_VOID(container); 23623b3eb3cSopenharmony_ci if (container->IsDynamicRender()) { 23723b3eb3cSopenharmony_ci container = Container::CurrentSafely(); 23823b3eb3cSopenharmony_ci CHECK_NULL_VOID(container); 23923b3eb3cSopenharmony_ci } 24023b3eb3cSopenharmony_ci containerId = container->GetInstanceId(); 24123b3eb3cSopenharmony_ci ContainerScope socpe(containerId); 24223b3eb3cSopenharmony_ci auto context = PipelineContext::GetCurrentContext(); 24323b3eb3cSopenharmony_ci CHECK_NULL_VOID(context); 24423b3eb3cSopenharmony_ci auto getInspectorTask = [container, containerId]() { 24523b3eb3cSopenharmony_ci std::string treeJson; 24623b3eb3cSopenharmony_ci GetInspectorTreeJsonStr(treeJson, containerId); 24723b3eb3cSopenharmony_ci auto message = JsonUtil::Create(true); 24823b3eb3cSopenharmony_ci GetSnapshotJson(containerId, message); 24923b3eb3cSopenharmony_ci CHECK_NULL_VOID(message); 25023b3eb3cSopenharmony_ci auto sendResultTask = [treeJsonStr = std::move(treeJson), jsonSnapshotStr = message->ToString(), container]() { 25123b3eb3cSopenharmony_ci if (container->IsUseStageModel()) { 25223b3eb3cSopenharmony_ci OHOS::AbilityRuntime::ConnectServerManager::Get().SendInspector(treeJsonStr, jsonSnapshotStr); 25323b3eb3cSopenharmony_ci } else { 25423b3eb3cSopenharmony_ci OHOS::Ace::ConnectServerManager::Get().SendInspector(treeJsonStr, jsonSnapshotStr); 25523b3eb3cSopenharmony_ci } 25623b3eb3cSopenharmony_ci }; 25723b3eb3cSopenharmony_ci BackgroundTaskExecutor::GetInstance().PostTask(std::move(sendResultTask)); 25823b3eb3cSopenharmony_ci }; 25923b3eb3cSopenharmony_ci context->GetTaskExecutor()->PostTask( 26023b3eb3cSopenharmony_ci std::move(getInspectorTask), TaskExecutor::TaskType::UI, "ArkUIGetInspectorTreeJson"); 26123b3eb3cSopenharmony_ci} 26223b3eb3cSopenharmony_ci 26323b3eb3cSopenharmony_civoid LayoutInspector::GetInspectorTreeJsonStr(std::string& treeJsonStr, int32_t containerId) 26423b3eb3cSopenharmony_ci{ 26523b3eb3cSopenharmony_ci auto container = AceEngine::Get().GetContainer(containerId); 26623b3eb3cSopenharmony_ci CHECK_NULL_VOID(container); 26723b3eb3cSopenharmony_ci#ifdef NG_BUILD 26823b3eb3cSopenharmony_ci treeJsonStr = NG::Inspector::GetInspector(true); 26923b3eb3cSopenharmony_ci#else 27023b3eb3cSopenharmony_ci if (container->IsUseNewPipeline()) { 27123b3eb3cSopenharmony_ci if (containerId >= MIN_SUBCONTAINER_ID && containerId < MIN_PLUGIN_SUBCONTAINER_ID) { 27223b3eb3cSopenharmony_ci treeJsonStr = NG::Inspector::GetSubWindowInspector(true); 27323b3eb3cSopenharmony_ci } else { 27423b3eb3cSopenharmony_ci treeJsonStr = NG::Inspector::GetInspector(true); 27523b3eb3cSopenharmony_ci } 27623b3eb3cSopenharmony_ci } else { 27723b3eb3cSopenharmony_ci auto pipelineContext = AceType::DynamicCast<PipelineContext>(container->GetPipelineContext()); 27823b3eb3cSopenharmony_ci CHECK_NULL_VOID(pipelineContext); 27923b3eb3cSopenharmony_ci treeJsonStr = V2::Inspector::GetInspectorTree(pipelineContext, true); 28023b3eb3cSopenharmony_ci } 28123b3eb3cSopenharmony_ci#endif 28223b3eb3cSopenharmony_ci} 28323b3eb3cSopenharmony_ci 28423b3eb3cSopenharmony_civoid LayoutInspector::GetSnapshotJson(int32_t containerId, std::unique_ptr<JsonValue>& message) 28523b3eb3cSopenharmony_ci{ 28623b3eb3cSopenharmony_ci auto container = AceEngine::Get().GetContainer(containerId); 28723b3eb3cSopenharmony_ci CHECK_NULL_VOID(container); 28823b3eb3cSopenharmony_ci OHOS::sptr<OHOS::Rosen::Window> window = GetWindow(containerId); 28923b3eb3cSopenharmony_ci CHECK_NULL_VOID(window); 29023b3eb3cSopenharmony_ci auto pixelMap = window->Snapshot(); 29123b3eb3cSopenharmony_ci CHECK_NULL_VOID(pixelMap); 29223b3eb3cSopenharmony_ci auto acePixelMap = AceType::MakeRefPtr<PixelMapOhos>(pixelMap); 29323b3eb3cSopenharmony_ci CHECK_NULL_VOID(acePixelMap); 29423b3eb3cSopenharmony_ci auto imageInfo = MakeSkImageInfoFromPixelMap(acePixelMap); 29523b3eb3cSopenharmony_ci SkPixmap imagePixmap( 29623b3eb3cSopenharmony_ci imageInfo, reinterpret_cast<const void*>(acePixelMap->GetPixels()), acePixelMap->GetRowBytes()); 29723b3eb3cSopenharmony_ci sk_sp<SkImage> image; 29823b3eb3cSopenharmony_ci image = SkImage::MakeFromRaster(imagePixmap, &PixelMap::ReleaseProc, PixelMap::GetReleaseContext(acePixelMap)); 29923b3eb3cSopenharmony_ci CHECK_NULL_VOID(image); 30023b3eb3cSopenharmony_ci auto data = image->encodeToData(SkEncodedImageFormat::kPNG, 100); 30123b3eb3cSopenharmony_ci CHECK_NULL_VOID(data); 30223b3eb3cSopenharmony_ci auto defaultDisplay = Rosen::DisplayManager::GetInstance().GetDefaultDisplay(); 30323b3eb3cSopenharmony_ci CHECK_NULL_VOID(defaultDisplay); 30423b3eb3cSopenharmony_ci auto deviceDpi = defaultDisplay->GetDpi(); 30523b3eb3cSopenharmony_ci auto deviceWidth = defaultDisplay->GetWidth(); 30623b3eb3cSopenharmony_ci auto deviceHeight = defaultDisplay->GetHeight(); 30723b3eb3cSopenharmony_ci message->Put("type", "snapShot"); 30823b3eb3cSopenharmony_ci message->Put("format", PNG_TAG); 30923b3eb3cSopenharmony_ci message->Put("width", (*pixelMap).GetWidth()); 31023b3eb3cSopenharmony_ci message->Put("height", (*pixelMap).GetHeight()); 31123b3eb3cSopenharmony_ci message->Put("posX", container->GetViewPosX()); 31223b3eb3cSopenharmony_ci message->Put("posY", container->GetViewPosY()); 31323b3eb3cSopenharmony_ci message->Put("deviceWidth", deviceWidth); 31423b3eb3cSopenharmony_ci message->Put("deviceHeight", deviceHeight); 31523b3eb3cSopenharmony_ci message->Put("deviceDpi", deviceDpi); 31623b3eb3cSopenharmony_ci int32_t encodeLength = static_cast<int32_t>(SkBase64::Encode(data->data(), data->size(), nullptr)); 31723b3eb3cSopenharmony_ci message->Put("size", data->size()); 31823b3eb3cSopenharmony_ci SkString info(encodeLength); 31923b3eb3cSopenharmony_ci SkBase64::Encode(data->data(), data->size(), info.writable_str()); 32023b3eb3cSopenharmony_ci message->Put("pixelMapBase64", info.c_str()); 32123b3eb3cSopenharmony_ci} 32223b3eb3cSopenharmony_ci 32323b3eb3cSopenharmony_civoid LayoutInspector::HandleStopRecord() 32423b3eb3cSopenharmony_ci{ 32523b3eb3cSopenharmony_ci std::unique_lock<std::mutex> lock(recMutex_); 32623b3eb3cSopenharmony_ci SetRsProfilerNodeMountCallback(nullptr); 32723b3eb3cSopenharmony_ci auto jsonRoot = JsonUtil::Create(true); 32823b3eb3cSopenharmony_ci auto jsonNodeArray = JsonUtil::CreateArray(true); 32923b3eb3cSopenharmony_ci for (auto& uiNode : recNodeInfos_) { 33023b3eb3cSopenharmony_ci if (uiNode.second != nullptr) { 33123b3eb3cSopenharmony_ci auto jsonNode = JsonUtil::Create(true); 33223b3eb3cSopenharmony_ci jsonNode->Put(RECNODE_NODEID, std::to_string(uiNode.second->GetSelfId()).c_str()); 33323b3eb3cSopenharmony_ci jsonNode->Put(RECNODE_SELFID, uiNode.second->GetNodeId()); 33423b3eb3cSopenharmony_ci jsonNode->Put(RECNODE_NAME, uiNode.second->GetName().c_str()); 33523b3eb3cSopenharmony_ci jsonNode->Put(RECNODE_DEBUGLINE, uiNode.second->GetDebugLine().c_str()); 33623b3eb3cSopenharmony_ci jsonNodeArray->PutRef(std::move(jsonNode)); 33723b3eb3cSopenharmony_ci } 33823b3eb3cSopenharmony_ci } 33923b3eb3cSopenharmony_ci recNodeInfos_.clear(); 34023b3eb3cSopenharmony_ci lock.unlock(); 34123b3eb3cSopenharmony_ci if (jsonNodeArray->GetArraySize()) { 34223b3eb3cSopenharmony_ci jsonRoot->PutRef(RECNODE_CHILDREN, std::move(jsonNodeArray)); 34323b3eb3cSopenharmony_ci } 34423b3eb3cSopenharmony_ci std::string arrayJsonStr = jsonRoot->ToString(); 34523b3eb3cSopenharmony_ci auto sendResultTask = [arrayJsonStr]() { 34623b3eb3cSopenharmony_ci OHOS::AbilityRuntime::ConnectServerManager::Get().SetRecordResults(arrayJsonStr); 34723b3eb3cSopenharmony_ci }; 34823b3eb3cSopenharmony_ci BackgroundTaskExecutor::GetInstance().PostTask(std::move(sendResultTask)); 34923b3eb3cSopenharmony_ci} 35023b3eb3cSopenharmony_ci 35123b3eb3cSopenharmony_civoid LayoutInspector::HandleStartRecord() 35223b3eb3cSopenharmony_ci{ 35323b3eb3cSopenharmony_ci // regist inner callback function 35423b3eb3cSopenharmony_ci std::unique_lock<std::mutex> lock(recMutex_); 35523b3eb3cSopenharmony_ci SetRsProfilerNodeMountCallback(LayoutInspector::HandleInnerCallback); 35623b3eb3cSopenharmony_ci lock.unlock(); 35723b3eb3cSopenharmony_ci auto container = Container::GetFoucsed(); 35823b3eb3cSopenharmony_ci CHECK_NULL_VOID(container); 35923b3eb3cSopenharmony_ci if (container->IsDynamicRender()) { 36023b3eb3cSopenharmony_ci container = Container::CurrentSafely(); 36123b3eb3cSopenharmony_ci CHECK_NULL_VOID(container); 36223b3eb3cSopenharmony_ci } 36323b3eb3cSopenharmony_ci auto containerId = container->GetInstanceId(); 36423b3eb3cSopenharmony_ci ContainerScope socpe(containerId); 36523b3eb3cSopenharmony_ci auto context = PipelineContext::GetCurrentContext(); 36623b3eb3cSopenharmony_ci CHECK_NULL_VOID(context); 36723b3eb3cSopenharmony_ci auto startRecordTask = []() { 36823b3eb3cSopenharmony_ci std::lock_guard<std::mutex> lock(LayoutInspector::recMutex_); 36923b3eb3cSopenharmony_ci NG::InspectorTreeMap recTreeNodes; 37023b3eb3cSopenharmony_ci NG::InspectorTreeMap offScreenTreeNodes; 37123b3eb3cSopenharmony_ci NG::Inspector::GetInspectorTree(recTreeNodes); 37223b3eb3cSopenharmony_ci TAG_LOGD(AceLogTag::ACE_LAYOUT_INSPECTOR, "Get nodes size:%{public}zu", recTreeNodes.size()); 37323b3eb3cSopenharmony_ci NG::Inspector::GetOffScreenTreeNodes(offScreenTreeNodes); 37423b3eb3cSopenharmony_ci TAG_LOGD(AceLogTag::ACE_LAYOUT_INSPECTOR, "Get offscreen nodes size:%{public}zu", offScreenTreeNodes.size()); 37523b3eb3cSopenharmony_ci LayoutInspector::recNodeInfos_.swap(recTreeNodes); 37623b3eb3cSopenharmony_ci for (auto& item : offScreenTreeNodes) { 37723b3eb3cSopenharmony_ci recNodeInfos_.emplace(item); 37823b3eb3cSopenharmony_ci } 37923b3eb3cSopenharmony_ci }; 38023b3eb3cSopenharmony_ci context->GetTaskExecutor()->PostTask( 38123b3eb3cSopenharmony_ci std::move(startRecordTask), TaskExecutor::TaskType::UI, "ArkUIGetInspectorTree"); 38223b3eb3cSopenharmony_ci} 38323b3eb3cSopenharmony_ci 38423b3eb3cSopenharmony_civoid LayoutInspector::HandleInnerCallback(FrameNodeInfo node) 38523b3eb3cSopenharmony_ci{ 38623b3eb3cSopenharmony_ci // convert FrameNodeInfo --> recNode 38723b3eb3cSopenharmony_ci TAG_LOGD(AceLogTag::ACE_LAYOUT_INSPECTOR, 38823b3eb3cSopenharmony_ci "FrameNodeInfo:selfid:%{public}" PRIu64 ",nodid:%{public}d,type:%{public}s,debugline:%{public}s", 38923b3eb3cSopenharmony_ci node.rsNodeId, node.frameNodeId, node.nodeType.c_str(), node.debugline.c_str()); 39023b3eb3cSopenharmony_ci auto recNode = AceType::MakeRefPtr<NG::RecNode>(); 39123b3eb3cSopenharmony_ci CHECK_NULL_VOID(recNode); 39223b3eb3cSopenharmony_ci recNode->SetSelfId(node.rsNodeId); 39323b3eb3cSopenharmony_ci recNode->SetNodeId(node.frameNodeId); 39423b3eb3cSopenharmony_ci recNode->SetName(node.nodeType); 39523b3eb3cSopenharmony_ci recNode->SetDebugLine(node.debugline); 39623b3eb3cSopenharmony_ci std::lock_guard<std::mutex> lock(recMutex_); 39723b3eb3cSopenharmony_ci recNodeInfos_.emplace(node.rsNodeId, recNode); 39823b3eb3cSopenharmony_ci} 39923b3eb3cSopenharmony_ci} // namespace OHOS::Ace 400