自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

OpenHarmony系統(tǒng)解決方案 - 接入多個(gè)顯示設(shè)備卡開機(jī)Logo

系統(tǒng) OpenHarmony
在窗口子系統(tǒng)中AbstractDisplayController控制器的初始化與屏幕連接事件的接收存在時(shí)序問題,啟動(dòng)成功時(shí)窗口子系統(tǒng)收到屏幕連接事件的時(shí)機(jī)均在AbstractDisplayController控制器的初始化之后,所以可以正常進(jìn)入系統(tǒng)。

想了解更多關(guān)于開源的內(nèi)容,請(qǐng)?jiān)L問:

51CTO 開源基礎(chǔ)軟件社區(qū)

https://ost.51cto.com

問題描述

問題環(huán)境

系統(tǒng)版本:OpenHarmony-3.2-Release。

問題現(xiàn)象

接入多個(gè)顯示設(shè)備后,啟動(dòng)系統(tǒng)偶現(xiàn)卡開機(jī)Logo。

異常效果:

系統(tǒng)卡在開機(jī)Logo界面,長時(shí)間無法顯示開機(jī)動(dòng)畫,并且無法進(jìn)入系統(tǒng)。

OpenHarmony系統(tǒng)解決方案 - 接入多個(gè)顯示設(shè)備卡開機(jī)Logo-開源基礎(chǔ)軟件社區(qū)OpenHarmony系統(tǒng)解決方案 - 接入多個(gè)顯示設(shè)備卡開機(jī)Logo-開源基礎(chǔ)軟件社區(qū)

正常效果:

系統(tǒng)啟動(dòng)成功,顯示開機(jī)動(dòng)畫,開機(jī)動(dòng)畫結(jié)束后顯示鎖屏界面。

OpenHarmony系統(tǒng)解決方案 - 接入多個(gè)顯示設(shè)備卡開機(jī)Logo-開源基礎(chǔ)軟件社區(qū)OpenHarmony系統(tǒng)解決方案 - 接入多個(gè)顯示設(shè)備卡開機(jī)Logo-開源基礎(chǔ)軟件社區(qū)

問題原因

  • 在窗口子系統(tǒng)中AbstractDisplayController控制器的初始化與屏幕連接事件的接收存在時(shí)序問題,啟動(dòng)成功時(shí)窗口子系統(tǒng)收到屏幕連接事件的時(shí)機(jī)均在AbstractDisplayController控制器的初始化之后,所以可以正常進(jìn)入系統(tǒng)。
  • 當(dāng)先接收到屏幕連接事件,再進(jìn)行AbstractDisplayController控制器的初始化操作時(shí),則會(huì)由于OnAbstractScreenConnect函數(shù)的處理邏輯導(dǎo)致設(shè)置默認(rèn)屏幕操作失敗。

解決方案

修改默認(rèn)屏幕設(shè)置條件,解決AbstractDisplayController控制器加載慢于Display通知屏幕連接事件時(shí),造成的無法設(shè)置默認(rèn)屏幕問題。

修改文件:foundation/window/window_manager/dmserver/src/abstract_display_controller.cpp

AbstractDisplayController::OnAbstractScreenConnect函數(shù)中,將以下代碼:

if (group->combination_ == ScreenCombination::SCREEN_ALONE || group->GetChildCount() == 1) {

替換為:

ScreenId dmsScreenId = abstractScreenController_->GetDefaultAbstractScreenId();
sptr<AbstractDisplay> display = GetAbstractDisplayByScreen(dmsScreenId);
if (group->combination_ == ScreenCombination::SCREEN_ALONE || group->GetChildCount() == 1 || display == nullptr) {

替換后完整函數(shù)代碼:

void AbstractDisplayController::OnAbstractScreenConnect(sptr<AbstractScreen> absScreen)
{
    if (absScreen == nullptr) {
        WLOGFE("absScreen is null");
        return;
    }
    WLOGI("connect new screen. id:%{public}" PRIu64"", absScreen->dmsId_);
    std::lock_guard<std::recursive_mutex> lock(mutex_);
    sptr<AbstractScreenGroup> group = absScreen->GetGroup();
    if (group == nullptr) {
        WLOGE("the group information of the screen is wrong");
        return;
    }
    ScreenId dmsScreenId = abstractScreenController_->GetDefaultAbstractScreenId();
    sptr<AbstractDisplay> display = GetAbstractDisplayByScreen(dmsScreenId);
    if (group->combination_ == ScreenCombination::SCREEN_ALONE || group->GetChildCount() == 1 || display == nullptr) {
        BindAloneScreenLocked(absScreen);
    } else if (group->combination_ == ScreenCombination::SCREEN_MIRROR) {
        WLOGI("OnAbstractScreenConnect, ScreenCombination::SCREEN_MIRROR, AddScreenToMirrorLocked");
        AddScreenToMirrorLocked(absScreen);
    } else if (group->combination_ == ScreenCombination::SCREEN_EXPAND) {
        WLOGI("OnAbstractScreenConnect, ScreenCombination::SCREEN_EXPAND, AddScreenToExpandLocked");
        AddScreenToExpandLocked(absScreen);
    } else {
        WLOGE("support in future. combination:%{public}u", group->combination_);
    }
}

定位過程

落盤異常開機(jī)日志,發(fā)現(xiàn)Launcher和SystemUI等系統(tǒng)應(yīng)用在啟動(dòng)過程中報(bào)錯(cuò),無法獲取DefaultDisplayInfo。

08-05 17:18:29.046   521  1088 D C04201/AbstractScreenController: <177>GetDefaultAbstractScreenId: GetDefaultAbstractScreenId, screen:0
08-05 17:18:29.046   521  1088 D C04201/DisplayManagerService: <190>GetDefaultDisplayInfo: GetDefaultDisplayInfo 0
08-05 17:18:29.046   521  1088 E C04201/AbstractDisplayController: <105>GetAbstractDisplayByScreen: fail to get AbstractDisplay 0
08-05 17:18:29.047   521  1088 E C04201/DisplayManagerService: <193>GetDefaultDisplayInfo: fail to get displayInfo by id: invalid display
08-05 17:18:29.047   240  1090 I C01800/SAMGR: SystemAbilityManagerStub::OnReceived, code = 12, callerPid = 1156, flags= 0
08-05 17:18:29.047  1156  1156 W C04201/DisplayManagerProxy: <52>GetDefaultDisplayInfo: DisplayManagerProxy::GetDefaultDisplayInfo SendRequest nullptr.
08-05 17:18:29.047  1156  1156 D C03f00/ArkCompiler: [ecmascript] Throw error: JsDisplayManager::OnGetDefaultDisplay failed.

查找默認(rèn)屏幕設(shè)置邏輯,追蹤Log發(fā)現(xiàn)默認(rèn)屏幕信息從abstractDisplayMap_中獲取。

// foundation/window/window_manager/dmserver/src/abstract_display_controller.cpp
sptr<AbstractDisplay> AbstractDisplayController::GetAbstractDisplayByScreen(ScreenId screenId) const
{
    if (screenId == SCREEN_ID_INVALID) {
        WLOGFE("screen id is invalid.");
        return nullptr;
    }
    std::lock_guard<std::recursive_mutex> lock(mutex_);
    for (auto iter : abstractDisplayMap_) {
        sptr<AbstractDisplay> display = iter.second;
        if (display->GetAbstractScreenId() == screenId) {
            return display;
        }
    }
    WLOGFE("fail to get AbstractDisplay %{public}" PRIu64"", screenId);
    return nullptr;
}

abstractDisplayMap_對(duì)象會(huì)在兩個(gè)位置被insert數(shù)據(jù),BindAloneScreenLocked函數(shù)和AddScreenToExpandLocked函數(shù)。而兩個(gè)函數(shù)擁有同一個(gè)入口函數(shù)AbstractDisplayController::OnAbstractScreenConnect。

// foundation/window/window_manager/dmserver/src/abstract_display_controller.cpp
void AbstractDisplayController::OnAbstractScreenConnect(sptr<AbstractScreen> absScreen)
{
    if (absScreen == nullptr) {
        WLOGFE("absScreen is null");
        return;
    }
    WLOGI("connect new screen. id:%{public}" PRIu64"", absScreen->dmsId_);
    std::lock_guard<std::recursive_mutex> lock(mutex_);
    sptr<AbstractScreenGroup> group = absScreen->GetGroup();
    if (group == nullptr) {
        WLOGE("the group information of the screen is wrong");
        return;
    }
    if (group->combination_ == ScreenCombination::SCREEN_ALONE || group->GetChildCount() == 1) {
        BindAloneScreenLocked(absScreen);
    } else if (group->combination_ == ScreenCombination::SCREEN_MIRROR) {
        WLOGI("OnAbstractScreenConnect, ScreenCombination::SCREEN_MIRROR, AddScreenToMirrorLocked");
        AddScreenToMirrorLocked(absScreen);
    } else if (group->combination_ == ScreenCombination::SCREEN_EXPAND) {
        WLOGI("OnAbstractScreenConnect, ScreenCombination::SCREEN_EXPAND, AddScreenToExpandLocked");
        AddScreenToExpandLocked(absScreen);
    } else {
        WLOGE("support in future. combination:%{public}u", group->combination_);
    }
}

查看源碼對(duì)應(yīng)Log,發(fā)現(xiàn)異常情況下屏幕OnAbstractScreenConnect函數(shù)的執(zhí)行操作是一起完成的,此時(shí)ScrrenID為0的屏幕ScreenCombination屬性為ScreenCombination::SCREEN_MIRROR。而在正常情況下OnAbstractScreenConnect函數(shù)是分開執(zhí)行的。

異常Log:

08-05 17:18:26.923   521   923 I C04201/AbstractDisplayController: <152>connect new screen. id:0
08-05 17:18:26.923   521   923 I C04201/AbstractDisplayController: <162>OnAbstractScreenConnect, ScreenCombination::SCREEN_MIRROR, AddScreenToMirrorLocked
08-05 17:18:26.923   521   656 I C04201/AbstractScreenController: <1161>operator(): screenId:2, trigger:[foundation]
08-05 17:18:26.923   332   430 I C01799/MemMgr: MultiAccountManager::Init The manager initial succeed, accountCount = 0.
08-05 17:18:26.923   521   923 I C04201/AbstractDisplayController: <558>bind display to mirror. screen:0
08-05 17:18:26.923   521   656 I C04200/ClientAgentContainer: <98>GetAgentsByType: no such type of agent registered! type:2
08-05 17:18:26.923   521   923 I C04201/AbstractScreenController: <203>RegisterAbstractScreenCallback: dmsScreenId :1
08-05 17:18:26.923   521   923 I C04201/AbstractDisplayController: <152>connect new screen. id:1
08-05 17:18:26.923   521   923 E C04201/AbstractScreenController: <159>did not find screen:18446744073709551615
08-05 17:18:26.923   521   923 E C04201/AbstractDisplayController: <156>the group information of the screen is wrong
08-05 17:18:26.923   521   923 I C04201/AbstractScreenController: <203>RegisterAbstractScreenCallback: dmsScreenId :2
08-05 17:18:26.923   521   923 I C04201/AbstractDisplayController: <152>connect new screen. id:2
08-05 17:18:26.923   521   923 I C04201/AbstractDisplayController: <162>OnAbstractScreenConnect, ScreenCombination::SCREEN_MIRROR, AddScreenToMirrorLocked
08-05 17:18:26.923   521   923 I C04201/AbstractDisplayController: <558>bind display to mirror. screen:2

正常Log:

08-05 17:23:07.081   547   770 I C04201/AbstractDisplayController: <152>connect new screen. id:0
08-05 17:23:07.081   547   770 D C04201/AbstractScreenController: <177>GetDefaultAbstractScreenId: GetDefaultAbstractScreenId, screen:0

08-05 17:23:07.088   547   770 I C04201/AbstractDisplayController: <152>connect new screen. id:2
08-05 17:23:07.088   547   770 I C04201/AbstractDisplayController: <162>OnAbstractScreenConnect, ScreenCombination::SCREEN_MIRROR, AddScreenToMirrorLocked
08-05 17:23:07.088   547   770 I C04201/AbstractDisplayController: <558>bind display to mirror. screen:2

查看OnAbstractScreenConnect的觸發(fā)邏輯有兩種。

第一種,AbstractDisplayController初始化時(shí)注冊(cè)屏幕事件回調(diào),注冊(cè)后遍歷dmsScreenMap_調(diào)用AbstractDisplayController::OnAbstractScreenConnect初始化在回調(diào)注冊(cè)前記錄的屏幕數(shù)據(jù)。

// foundation/window/window_manager/dmserver/src/abstract_screen_controller.cpp
void AbstractDisplayController::Init(sptr<AbstractScreenController> abstractScreenController)
{
    WLOGFD("display controller init");
    displayCount_ = 0;
    abstractScreenController_ = abstractScreenController;
    abstractScreenCallback_ = new(std::nothrow) AbstractScreenController::AbstractScreenCallback();
    if (abstractScreenCallback_ == nullptr) {
        WLOGFE("abstractScreenCallback init failed");
        return;
    }
    abstractScreenCallback_->onConnect_
        = std::bind(&AbstractDisplayController::OnAbstractScreenConnect, this, std::placeholders::_1);
    abstractScreenCallback_->onDisconnect_
        = std::bind(&AbstractDisplayController::OnAbstractScreenDisconnect, this, std::placeholders::_1);
    abstractScreenCallback_->onChange_
        = std::bind(&AbstractDisplayController::OnAbstractScreenChange, this, std::placeholders::_1,
        std::placeholders::_2);
    abstractScreenController->RegisterAbstractScreenCallback(abstractScreenCallback_);
}

void AbstractScreenController::RegisterAbstractScreenCallback(sptr<AbstractScreenCallback> cb)
{
    std::lock_guard<std::recursive_mutex> lock(mutex_);
    abstractScreenCallback_ = cb;
    for (auto& iter : dmsScreenMap_) {
        if (iter.second != nullptr && abstractScreenCallback_ != nullptr) {
            WLOGFI("dmsScreenId :%{public}" PRIu64"", iter.first);
            abstractScreenCallback_->onConnect_(iter.second);
        }
    }
}

第二種,當(dāng)窗口子系統(tǒng)觸發(fā)OnRsScreenConnectionChange回調(diào)時(shí),會(huì)調(diào)用ProcessScreenConnected函數(shù)。如果abstractScreenCallback_回調(diào)函數(shù)注冊(cè)則執(zhí)行AbstractDisplayController::OnAbstractScreenConnect。

// foundation/window/window_manager/dmserver/src/abstract_screen_controller.cpp
void AbstractScreenController::OnRsScreenConnectionChange(ScreenId rsScreenId, ScreenEvent screenEvent)
{
    WLOGFI("rs screen event. id:%{public}, event:%{public}u", rsScreenId, static_cast<uint32_t>(screenEvent));
    if (screenEvent == ScreenEvent::CONNECTED) {
        auto task = [this, rsScreenId] {
            ProcessScreenConnected(rsScreenId);
        };
        controllerHandler_->PostTask(task, AppExecFwk::EventQueue::Priority::HIGH);
    }
    ···
}

void AbstractScreenController::ProcessScreenConnected(ScreenId rsScreenId)
{
    std::lock_guard<std::recursive_mutex> lock(mutex_);
    if (screenIdManager_.HasRsScreenId(rsScreenId)) {
        WLOGE("reconnect screen, screenId=%{public}" PRIu64"", rsScreenId);
        return;
    }
    WLOGFD("connect new screen");
    auto absScreen = InitAndGetScreen(rsScreenId);
    if (absScreen == nullptr) {
        return;
    }
    sptr<AbstractScreenGroup> screenGroup = AddToGroupLocked(absScreen);
    if (screenGroup == nullptr) {
        return;
    }
    ···
    if (abstractScreenCallback_ != nullptr) {
        abstractScreenCallback_->onConnect_(absScreen);
    }
    ···
}

如果OnAbstractScreenConnect在第二種情況執(zhí)行,加載第一個(gè)屏幕時(shí),則在group->GetChildCount() == 1時(shí)進(jìn)入判斷,執(zhí)行BindAloneScreenLocked(absScreen);函數(shù),系統(tǒng)正常運(yùn)行。

如果OnAbstractScreenConnect在第一種情況執(zhí)行,加載第一個(gè)屏幕時(shí),會(huì)創(chuàng)建screenGroup。創(chuàng)建的group也會(huì)insert進(jìn)dmsScreenMap_,此操作會(huì)導(dǎo)致異常Log中ScreenId為1的屏幕綁定異常。

// foundation/window/window_manager/dmserver/src/abstract_screen_controller.cpp
sptr<AbstractScreenGroup> AbstractScreenController::AddToGroupLocked(sptr<AbstractScreen> newScreen)
{
    sptr<AbstractScreenGroup> res;
    if (dmsScreenGroupMap_.empty()) {
        WLOGI("connect the first screen");
        // 第一塊顯示設(shè)備連接時(shí)進(jìn)入
        res = AddAsFirstScreenLocked(newScreen); 
    } else {
        // 后續(xù)顯示設(shè)備連接時(shí)進(jìn)入
        res = AddAsSuccedentScreenLocked(newScreen);
    }
    return res;
}
sptr<AbstractScreenGroup> AbstractScreenController::AddAsFirstScreenLocked(sptr<AbstractScreen> newScreen)
{
    ScreenId dmsGroupScreenId = screenIdManager_.CreateAndGetNewScreenId(SCREEN_ID_INVALID);
    ···
    dmsScreenGroupMap_.insert(std::make_pair(dmsGroupScreenId, screenGroup));
    dmsScreenMap_.insert(std::make_pair(dmsGroupScreenId, screenGroup));
    ···
}

當(dāng)?shù)诙K顯示設(shè)備連接時(shí),尋找第一塊設(shè)備創(chuàng)建的group,并把自己添加進(jìn)group中。

// foundation/window/window_manager/dmserver/src/abstract_screen_controller.cpp
sptr<AbstractScreenGroup> AbstractScreenController::AddAsSuccedentScreenLocked(sptr<AbstractScreen> newScreen)
{
    ScreenId defaultScreenId = GetDefaultAbstractScreenId();
    auto iter = dmsScreenMap_.find(defaultScreenId);
    if (iter == dmsScreenMap_.end()) {
        WLOGE("AddAsSuccedentScreenLocked. defaultScreenId:%{public}" PRIu64" is not in dmsScreenMap_.",
            defaultScreenId);
        return nullptr;
    }
    auto screen = iter->second;
    auto screenGroupIter = dmsScreenGroupMap_.find(screen->groupDmsId_);
    if (screenGroupIter == dmsScreenGroupMap_.end()) {
        WLOGE("AddAsSuccedentScreenLocked. groupDmsId:%{public}" PRIu64" is not in dmsScreenGroupMap_.",
            screen->groupDmsId_);
        return nullptr;
    }
    auto screenGroup = screenGroupIter->second;
    Point point;
    if (screenGroup->combination_ == ScreenCombination::SCREEN_EXPAND) {
        point = {screen->GetActiveScreenMode()->width_, 0};
    }
    screenGroup->AddChild(newScreen, point);
    return screenGroup;
}

當(dāng)OnAbstractScreenConnect被執(zhí)行時(shí),獲取到ScreenID為0的Group,此時(shí)Group內(nèi)的屏幕數(shù)為2,所以無法進(jìn)入BindAloneScreenLocked函數(shù)所在的判斷,造成異常。

// foundation/window/window_manager/dmserver/src/abstract_display_controller.cpp
void AbstractDisplayController::OnAbstractScreenConnect(sptr<AbstractScreen> absScreen)
{
    if (absScreen == nullptr) {
        WLOGFE("absScreen is null");
        return;
    }
    WLOGI("connect new screen. id:%{public}" PRIu64"", absScreen->dmsId_);
    std::lock_guard<std::recursive_mutex> lock(mutex_);
    sptr<AbstractScreenGroup> group = absScreen->GetGroup();
    if (group == nullptr) {
        WLOGE("the group information of the screen is wrong");
        return;
    }
    if (group->combination_ == ScreenCombination::SCREEN_ALONE || group->GetChildCount() == 1) {
        BindAloneScreenLocked(absScreen);
    } else if (group->combination_ == ScreenCombination::SCREEN_MIRROR) {
        WLOGI("OnAbstractScreenConnect, ScreenCombination::SCREEN_MIRROR, AddScreenToMirrorLocked");
        AddScreenToMirrorLocked(absScreen);
    } else if (group->combination_ == ScreenCombination::SCREEN_EXPAND) {
        WLOGI("OnAbstractScreenConnect, ScreenCombination::SCREEN_EXPAND, AddScreenToExpandLocked");
        AddScreenToExpandLocked(absScreen);
    } else {
        WLOGE("support in future. combination:%{public}u", group->combination_);
    }
}

想了解更多關(guān)于開源的內(nèi)容,請(qǐng)?jiān)L問:

51CTO 開源基礎(chǔ)軟件社區(qū)

https://ost.51cto.com

責(zé)任編輯:jianghua 來源: 51CTO 開源基礎(chǔ)軟件社區(qū)
相關(guān)推薦

2023-07-10 16:06:50

鴻蒙檢測(cè)鎖屏應(yīng)用

2023-07-18 14:05:30

鴻蒙

2011-11-18 14:59:47

Aruba

2009-12-31 15:43:32

寬帶接入網(wǎng)

2010-12-21 17:36:12

2009-10-30 16:42:27

無線接入解決方案

2009-10-29 13:54:33

遠(yuǎn)程接入解決方案

2009-11-02 18:10:39

綜合接入解決方案

2009-12-30 15:08:17

無線接入技術(shù)

2009-07-29 09:43:15

銀行網(wǎng)絡(luò)無線接入

2009-10-27 15:35:08

2009-10-29 13:46:30

ADSL接入解決方案

2011-05-18 15:30:13

2009-02-19 10:13:00

2009-11-05 09:42:44

智能小區(qū)寬帶接入

2009-10-27 17:07:34

無線寬帶接入解決方案

2012-12-20 15:07:15

銳捷無線網(wǎng)絡(luò)金融網(wǎng)絡(luò)

2009-10-28 17:39:58

光接入網(wǎng)解決方案

2009-10-29 10:32:17

接入網(wǎng)解決方案

2009-10-27 15:49:43

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)