166f3657fSopenharmony_ci/*
266f3657fSopenharmony_ci * Copyright (c) 2022-2024 Huawei Device Co., Ltd.
366f3657fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
466f3657fSopenharmony_ci * you may not use this file except in compliance with the License.
566f3657fSopenharmony_ci * You may obtain a copy of the License at
666f3657fSopenharmony_ci *
766f3657fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
866f3657fSopenharmony_ci *
966f3657fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1066f3657fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1166f3657fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1266f3657fSopenharmony_ci * See the License for the specific language governing permissions and
1366f3657fSopenharmony_ci * limitations under the License.
1466f3657fSopenharmony_ci */
1566f3657fSopenharmony_ci
1666f3657fSopenharmony_ci#include "dscreen_handler.h"
1766f3657fSopenharmony_ci
1866f3657fSopenharmony_ci#include "avcodec_info.h"
1966f3657fSopenharmony_ci#include "avcodec_list.h"
2066f3657fSopenharmony_ci#include "nlohmann/json.hpp"
2166f3657fSopenharmony_ci#include "screen.h"
2266f3657fSopenharmony_ci#include "histreamer_query_tool.h"
2366f3657fSopenharmony_ci
2466f3657fSopenharmony_ci#include "dscreen_constants.h"
2566f3657fSopenharmony_ci#include "dscreen_errcode.h"
2666f3657fSopenharmony_ci#include "dscreen_log.h"
2766f3657fSopenharmony_ci#include "dscreen_util.h"
2866f3657fSopenharmony_ci
2966f3657fSopenharmony_ciusing json = nlohmann::json;
3066f3657fSopenharmony_ci
3166f3657fSopenharmony_cinamespace OHOS {
3266f3657fSopenharmony_cinamespace DistributedHardware {
3366f3657fSopenharmony_cinamespace {
3466f3657fSopenharmony_ciconst std::string KEY_HISTREAMER_VIDEO_ENCODER = "histmVidEnc";
3566f3657fSopenharmony_ciconst std::string KEY_HISTREAMER_VIDEO_DECODER = "histmVidDec";
3666f3657fSopenharmony_ci}
3766f3657fSopenharmony_ciIMPLEMENT_SINGLE_INSTANCE(DScreenHandler);
3866f3657fSopenharmony_ci
3966f3657fSopenharmony_ciDScreenHandler::DScreenHandler()
4066f3657fSopenharmony_ci{
4166f3657fSopenharmony_ci    DHLOGI("DScreenHandler constructor.");
4266f3657fSopenharmony_ci}
4366f3657fSopenharmony_ci
4466f3657fSopenharmony_ciDScreenHandler::~DScreenHandler()
4566f3657fSopenharmony_ci{
4666f3657fSopenharmony_ci    DHLOGI("~DScreenHandler");
4766f3657fSopenharmony_ci    Rosen::ScreenManager::GetInstance().UnregisterScreenListener(screenListener_);
4866f3657fSopenharmony_ci}
4966f3657fSopenharmony_ci
5066f3657fSopenharmony_ciint32_t DScreenHandler::Initialize()
5166f3657fSopenharmony_ci{
5266f3657fSopenharmony_ci    DHLOGI("DScreenHandler Initialize");
5366f3657fSopenharmony_ci    if (screenListener_ == nullptr) {
5466f3657fSopenharmony_ci        screenListener_ = new (std::nothrow) ScreenListener();
5566f3657fSopenharmony_ci    }
5666f3657fSopenharmony_ci    Rosen::DMError ret = Rosen::ScreenManager::GetInstance().RegisterScreenListener(screenListener_);
5766f3657fSopenharmony_ci    if (ret != Rosen::DMError::DM_OK) {
5866f3657fSopenharmony_ci        DHLOGE("register screen listener failed.");
5966f3657fSopenharmony_ci        return DSCREEN_INIT_ERR;
6066f3657fSopenharmony_ci    }
6166f3657fSopenharmony_ci    return DH_SUCCESS;
6266f3657fSopenharmony_ci}
6366f3657fSopenharmony_ci
6466f3657fSopenharmony_ciuint32_t ScreenListener::ByteCalculate(std::uint32_t screenWidth)
6566f3657fSopenharmony_ci{
6666f3657fSopenharmony_ci    if (screenWidth % BYTE_ALIGNMENT == 0) {
6766f3657fSopenharmony_ci        return screenWidth;
6866f3657fSopenharmony_ci    }
6966f3657fSopenharmony_ci    uint32_t alignedInt = (screenWidth + BYTE_ALIGNMENT_CALCULATION) / BYTE_ALIGNMENT * BYTE_ALIGNMENT;
7066f3657fSopenharmony_ci    return alignedInt;
7166f3657fSopenharmony_ci}
7266f3657fSopenharmony_ci
7366f3657fSopenharmony_civoid ScreenListener::OnConnect(uint64_t screenId)
7466f3657fSopenharmony_ci{
7566f3657fSopenharmony_ci    DHLOGI("on screen connect");
7666f3657fSopenharmony_ci    if (screenId != SCREEN_ID_DEFAULT) {
7766f3657fSopenharmony_ci        DHLOGI("screenId is invalid, screenId is: %{public}" PRIu64, screenId);
7866f3657fSopenharmony_ci        return;
7966f3657fSopenharmony_ci    }
8066f3657fSopenharmony_ci    sptr<Rosen::Screen> screen = Rosen::ScreenManager::GetInstance().GetScreenById(screenId);
8166f3657fSopenharmony_ci    if (screen == nullptr) {
8266f3657fSopenharmony_ci        DHLOGE("screen not found, screenId is: %{public}" PRIu64, screenId);
8366f3657fSopenharmony_ci        return;
8466f3657fSopenharmony_ci    }
8566f3657fSopenharmony_ci    if (!screen->IsReal()) {
8666f3657fSopenharmony_ci        DHLOGI("screen is not real");
8766f3657fSopenharmony_ci        return;
8866f3657fSopenharmony_ci    }
8966f3657fSopenharmony_ci    std::string dhId = DSCREEN_PREFIX + SEPERATOR + std::to_string(screenId);
9066f3657fSopenharmony_ci    uint32_t screenWidth = screen->GetWidth();
9166f3657fSopenharmony_ci    screenWidth = ByteCalculate(screenWidth);
9266f3657fSopenharmony_ci    uint32_t screenHeight = screen->GetHeight();
9366f3657fSopenharmony_ci
9466f3657fSopenharmony_ci    json attrJson;
9566f3657fSopenharmony_ci    attrJson[KEY_VERSION] = DSCREEN_VERSION;
9666f3657fSopenharmony_ci    attrJson[KEY_SCREEN_WIDTH] = screenWidth;
9766f3657fSopenharmony_ci    attrJson[KEY_SCREEN_HEIGHT] = screenHeight;
9866f3657fSopenharmony_ci    attrJson[KEY_CODECTYPE] = DScreenHandler::GetInstance().QueryCodecInfo();
9966f3657fSopenharmony_ci    std::string subtype = "screen";
10066f3657fSopenharmony_ci
10166f3657fSopenharmony_ci    DScreenHandler::GetInstance().PluginHardware(dhId, attrJson.dump(), subtype);
10266f3657fSopenharmony_ci}
10366f3657fSopenharmony_ci
10466f3657fSopenharmony_civoid ScreenListener::OnDisconnect(uint64_t screenId)
10566f3657fSopenharmony_ci{
10666f3657fSopenharmony_ci    DHLOGI("on screen disconnect");
10766f3657fSopenharmony_ci    std::string dhId = DSCREEN_PREFIX + SEPERATOR + std::to_string(screenId);
10866f3657fSopenharmony_ci    DScreenHandler::GetInstance().UnPluginHardware(dhId);
10966f3657fSopenharmony_ci}
11066f3657fSopenharmony_ci
11166f3657fSopenharmony_civoid DScreenHandler::PluginHardware(const std::string &dhId, const std::string &attr, const std::string &subtype)
11266f3657fSopenharmony_ci{
11366f3657fSopenharmony_ci    DHLOGI("DScreenHandler PluginHardware");
11466f3657fSopenharmony_ci    if (listener_ != nullptr) {
11566f3657fSopenharmony_ci        listener_->PluginHardware(dhId, attr, subtype);
11666f3657fSopenharmony_ci    }
11766f3657fSopenharmony_ci}
11866f3657fSopenharmony_ci
11966f3657fSopenharmony_civoid DScreenHandler::UnPluginHardware(const std::string &dhId)
12066f3657fSopenharmony_ci{
12166f3657fSopenharmony_ci    DHLOGI("DScreenHandler UnPluginHardware");
12266f3657fSopenharmony_ci    if (listener_ != nullptr) {
12366f3657fSopenharmony_ci        listener_->UnPluginHardware(dhId);
12466f3657fSopenharmony_ci    }
12566f3657fSopenharmony_ci}
12666f3657fSopenharmony_ci
12766f3657fSopenharmony_cistd::vector<DHItem> DScreenHandler::QueryMeta()
12866f3657fSopenharmony_ci{
12966f3657fSopenharmony_ci    DHLOGI("DScreenHandler query meta hardware info");
13066f3657fSopenharmony_ci    return RealQuery();
13166f3657fSopenharmony_ci}
13266f3657fSopenharmony_ci
13366f3657fSopenharmony_cistd::vector<DHItem> DScreenHandler::Query()
13466f3657fSopenharmony_ci{
13566f3657fSopenharmony_ci    DHLOGI("DScreenHandler query full hardware info");
13666f3657fSopenharmony_ci    return RealQuery();
13766f3657fSopenharmony_ci}
13866f3657fSopenharmony_ci
13966f3657fSopenharmony_cistd::vector<DHItem> DScreenHandler::RealQuery()
14066f3657fSopenharmony_ci{
14166f3657fSopenharmony_ci    DHLOGI("DScreenHandler RealQuery");
14266f3657fSopenharmony_ci    std::vector<DHItem> dhItemVec;
14366f3657fSopenharmony_ci    std::vector<sptr<Rosen::Screen>> screens;
14466f3657fSopenharmony_ci    Rosen::ScreenManager::GetInstance().GetAllScreens(screens);
14566f3657fSopenharmony_ci    DHLOGI("screens size is: %{public}zu", screens.size());
14666f3657fSopenharmony_ci    for (const auto &screen : screens) {
14766f3657fSopenharmony_ci        if (screen == nullptr) {
14866f3657fSopenharmony_ci            DHLOGE("screen is nullptr.");
14966f3657fSopenharmony_ci            continue;
15066f3657fSopenharmony_ci        }
15166f3657fSopenharmony_ci        if (screen->GetWidth() <= 0) {
15266f3657fSopenharmony_ci            continue;
15366f3657fSopenharmony_ci        }
15466f3657fSopenharmony_ci        if (!screen->IsReal()) {
15566f3657fSopenharmony_ci            continue;
15666f3657fSopenharmony_ci        }
15766f3657fSopenharmony_ci        std::string dhId = DSCREEN_PREFIX + SEPERATOR + std::to_string(screen->GetId());
15866f3657fSopenharmony_ci        uint32_t screenWidth = screen->GetWidth();
15966f3657fSopenharmony_ci        if (screenListener_ == nullptr) {
16066f3657fSopenharmony_ci            screenListener_ = new (std::nothrow) ScreenListener();
16166f3657fSopenharmony_ci        }
16266f3657fSopenharmony_ci        screenWidth = screenListener_->ByteCalculate(screenWidth);
16366f3657fSopenharmony_ci        uint32_t screenHeight = screen->GetHeight();
16466f3657fSopenharmony_ci
16566f3657fSopenharmony_ci        json attrJson;
16666f3657fSopenharmony_ci        attrJson[KEY_VERSION] = DSCREEN_VERSION;
16766f3657fSopenharmony_ci        attrJson[KEY_SCREEN_WIDTH] = screenWidth;
16866f3657fSopenharmony_ci        attrJson[KEY_SCREEN_HEIGHT] = screenHeight;
16966f3657fSopenharmony_ci        attrJson[KEY_CODECTYPE] = QueryCodecInfo();
17066f3657fSopenharmony_ci        std::string videoEncoders =
17166f3657fSopenharmony_ci            HiStreamerQueryTool::GetInstance().QueryHiStreamerPluginInfo(HISTREAM_PLUGIN_TYPE::VIDEO_ENCODER);
17266f3657fSopenharmony_ci        DHLOGI("DScreen QueryVideoEncoderAbility info: %{public}s", videoEncoders.c_str());
17366f3657fSopenharmony_ci        attrJson[KEY_HISTREAMER_VIDEO_ENCODER] = videoEncoders;
17466f3657fSopenharmony_ci        std::string videoDecoders =
17566f3657fSopenharmony_ci            HiStreamerQueryTool::GetInstance().QueryHiStreamerPluginInfo(HISTREAM_PLUGIN_TYPE::VIDEO_DECODER);
17666f3657fSopenharmony_ci        DHLOGI("DScreen QueryVideoDecoderAbility info: %{public}s", videoDecoders.c_str());
17766f3657fSopenharmony_ci        attrJson[KEY_HISTREAMER_VIDEO_DECODER] = videoDecoders;
17866f3657fSopenharmony_ci
17966f3657fSopenharmony_ci        DHItem dhItem;
18066f3657fSopenharmony_ci        dhItem.dhId = dhId;
18166f3657fSopenharmony_ci        dhItem.subtype = "screen";
18266f3657fSopenharmony_ci        dhItem.attrs = attrJson.dump();
18366f3657fSopenharmony_ci        dhItemVec.push_back(dhItem);
18466f3657fSopenharmony_ci        DHLOGD("query result: dhId: %{public}s, attrs: %{public}s", dhId.c_str(), attrJson.dump().c_str());
18566f3657fSopenharmony_ci    }
18666f3657fSopenharmony_ci    return dhItemVec;
18766f3657fSopenharmony_ci}
18866f3657fSopenharmony_ci
18966f3657fSopenharmony_cistd::map<std::string, std::string> DScreenHandler::QueryExtraInfo()
19066f3657fSopenharmony_ci{
19166f3657fSopenharmony_ci    DHLOGD("DScreenHandler queryExtraInfo");
19266f3657fSopenharmony_ci    std::map<std::string, std::string> extraInfo;
19366f3657fSopenharmony_ci    return extraInfo;
19466f3657fSopenharmony_ci}
19566f3657fSopenharmony_ci
19666f3657fSopenharmony_cibool DScreenHandler::IsSupportPlugin()
19766f3657fSopenharmony_ci{
19866f3657fSopenharmony_ci    DHLOGD("DScreenHandler IsSupportPlugin");
19966f3657fSopenharmony_ci    return true;
20066f3657fSopenharmony_ci}
20166f3657fSopenharmony_ci
20266f3657fSopenharmony_civoid DScreenHandler::RegisterPluginListener(std::shared_ptr<PluginListener> listener)
20366f3657fSopenharmony_ci{
20466f3657fSopenharmony_ci    DHLOGD("DScreenHandler register plugin listener");
20566f3657fSopenharmony_ci    if (listener == nullptr) {
20666f3657fSopenharmony_ci        DHLOGE("DScreenHandler unregistering plugin listener");
20766f3657fSopenharmony_ci        return;
20866f3657fSopenharmony_ci    }
20966f3657fSopenharmony_ci    listener_ = listener;
21066f3657fSopenharmony_ci}
21166f3657fSopenharmony_ci
21266f3657fSopenharmony_civoid DScreenHandler::UnRegisterPluginListener()
21366f3657fSopenharmony_ci{
21466f3657fSopenharmony_ci    DHLOGI("DScreenHandler unRegister plugin listener");
21566f3657fSopenharmony_ci    listener_ = nullptr;
21666f3657fSopenharmony_ci}
21766f3657fSopenharmony_ci
21866f3657fSopenharmony_cistd::string DScreenHandler::QueryCodecInfo()
21966f3657fSopenharmony_ci{
22066f3657fSopenharmony_ci    DHLOGD("DScreenHandler QueryCodecInfo");
22166f3657fSopenharmony_ci    if (!codecInfoStr_.empty()) {
22266f3657fSopenharmony_ci        return codecInfoStr_;
22366f3657fSopenharmony_ci    }
22466f3657fSopenharmony_ci
22566f3657fSopenharmony_ci    // query codec info
22666f3657fSopenharmony_ci    std::shared_ptr<MediaAVCodec::AVCodecList> codecList = MediaAVCodec::AVCodecListFactory::CreateAVCodecList();
22766f3657fSopenharmony_ci    if (codecList == nullptr) {
22866f3657fSopenharmony_ci        DHLOGE("Create avCodecList failed.");
22966f3657fSopenharmony_ci        return codecInfoStr_;
23066f3657fSopenharmony_ci    }
23166f3657fSopenharmony_ci    const std::vector<std::string> encoderName = {std::string(MediaAVCodec::CodecMimeType::VIDEO_AVC),
23266f3657fSopenharmony_ci                                                  std::string(MediaAVCodec::CodecMimeType::VIDEO_HEVC)};
23366f3657fSopenharmony_ci    json codecTypeArray = json::array();
23466f3657fSopenharmony_ci
23566f3657fSopenharmony_ci    for (const auto &coder : encoderName) {
23666f3657fSopenharmony_ci        MediaAVCodec::CapabilityData *capData = codecList->GetCapability(coder, true,
23766f3657fSopenharmony_ci            MediaAVCodec::AVCodecCategory::AVCODEC_HARDWARE);
23866f3657fSopenharmony_ci            if (capData == nullptr) {
23966f3657fSopenharmony_ci                continue;
24066f3657fSopenharmony_ci            }
24166f3657fSopenharmony_ci        std::string mimeType = capData->mimeType;
24266f3657fSopenharmony_ci        codecTypeArray.push_back(mimeType);
24366f3657fSopenharmony_ci    }
24466f3657fSopenharmony_ci
24566f3657fSopenharmony_ci    codecInfoStr_ = codecTypeArray.dump();
24666f3657fSopenharmony_ci    return codecInfoStr_;
24766f3657fSopenharmony_ci}
24866f3657fSopenharmony_ci
24966f3657fSopenharmony_ciIHardwareHandler* GetHardwareHandler()
25066f3657fSopenharmony_ci{
25166f3657fSopenharmony_ci    DHLOGI("DScreenHandler::GetHardwareHandler");
25266f3657fSopenharmony_ci    return &DScreenHandler::GetInstance();
25366f3657fSopenharmony_ci}
25466f3657fSopenharmony_ci} // namespace DistributedHardware
25566f3657fSopenharmony_ci} // namespace OHOS