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