已开启
分辨率/刷新率 #21
wangdi创建于  6月6日
wangdi成员
6月6日 创建

分辨率/刷新率

likedislike
wangdi成员
6月6日 评论:

数据库存储格式:
keyword:user_set_resolution_mode
value: ["F0468A2B3BAA19CE;9 2560 1440 60"]
F0468A2B3BAA19CE是serialnumber,9是modeindex,2560 1400是刷新率,60是分辨率,第二条记录用,隔开

单屏:
1、开机无屏→连接屏幕(数据库无配置),屏幕连接后,设置默认分辨率/刷新率
2、开机无屏→连接屏幕(数据库有配置),从数据库恢复分辨率/刷新率
3、带1个屏幕启动,如果数据库有配置,恢复数据库配置分辨率;如果数据库没配置,设置默认分辨率
4、单屏断开后连接,如果没配置过,设置默认;如果配置过,恢复数据库里的值

双屏:
1、已连接屏幕A,连接屏幕B
1)数据库有B的记录,首先看数据库中的和A当前刷新率是否匹配,如果与A的刷新率相等,再看两者之一是否有4k屏,有就统一60hz(底层带宽不支持),无4k屏就直接恢复;
如果与A的刷新率不等,那么执行共同刷新率算法;
2)如果数据库没有B的记录,执行共同刷新率算法;

2、开机连接两个屏幕启动,从数据库读取配置后
1)主屏数据库有配置,副屏数据库没配置,恢复A屏刷新率/分辨率后,按上面连接流程设置A/B刷新率分辨率;
2)主副屏数据库均有配置,恢复A屏刷新率/分辨率后,按上面连接流程设置A/B刷新率分辨率;
3)主副屏数据库均无配置,设置A屏刷新率/分辨率后,按上面连接流程设置A/B刷新率分辨率;

3、双屏断开副屏或者主屏
剩下那个屏幕的刷新率/分辨率不变

4、如果值有更新,都要写数据库

共同刷新率算法:
1、找A/B共有刷新率,刷新率取60或者以下刷新率最高的交集
2、刷新率确定后,分辨率取最高的,尽量保证已经插入的屏幕分辨率不变

likedislike
wangdi成员
6月6日 评论:

数据库存储格式:
keyword:user_set_multi_screen_orientation
value:["2AEF8DDE0B25DB8C 2","F0468A2B3BAA19CE 1"]
2AEF8DDE0B25DB8C是serialnumber,2是方向,1是VERTICAL,2是HORIZONTAL

旋转方向恢复
单屏:
1、开机无屏→连接屏幕,数据库有配置,恢复数据库配置方向,没有默认横HORIZONTAL
2、带一个屏幕启动,数据库有配置,恢复数据库配置方向,没有默认横HORIZONTAL
3、单屏断开后连接,数据库有配置,恢复数据库配置方向,没有默认横HORIZONTAL

双屏:
1、开机无屏→依次连接主副屏(均有配置),从数据库恢复主屏/副屏方向,没有则默认横屏
2、带两个屏启动,如果数据库有配置,按数据库配置恢复两个屏幕
3、双屏断开其中一个屏幕,不影响另一个屏幕方向

likedislike
wangdi成员
6月7日 评论:
void ScreenSessionManager::RecoverDesktopScreenConfig()
{
    if (HasInternalScreen()) {
        return;
    }
    for (auto& iter : screenSessionMap_) {
        if (!iter.second || iter.second->GetScreenProperty().GetScreenType() != ScreenType::REAL) {
            continue;
        }
        RecoverScreenActiveMode(iter.second->GetScreenId());
        TLOGNFI(WmsLogTag::DMS, "Desktop screen config recovered, screenId = %{public}" PRIu64"",
            iter.second->GetScreenId());
    }
    return;
}
likedislike
wangdi成员
6月7日 评论:
["F0468A2B3BAA19CE;9 2560 1440 60","2AEF8DDE0B25DB8C;7 1920 1080 60"]
likedislike
wangdi成员
6月8日 评论:

① 获取物理尺寸(毫米) → 转换为英寸
② 获取原始物理分辨率 → 计算原始比例
③ 获取当前分辨率 → 计算当前比例
④ 比例差异调整 → 动态计算有效物理尺寸
⑤ 对角线计算 → sqrt(width² + height²)
⑥ PPI = 像素对角线 / 物理对角线

likedislike
wangdi成员
6月9日 评论:
****
likedislike
wangdi成员
6月14日 评论:

void ScreenSessionManager::RecoverMultiScreenRelativePositionForDesktop(ScreenId screenId)
{
#ifdef WM_MULTI_SCREEN_ENABLE
    TLOGNFI(WmsLogTag::DMS, "RecoverMultiScreenRelativePositionForDesktop enter, rsId=%{public}" PRIu64, screenId);
    sptr<ScreenSession> screenSession = GetScreenSessionByRsId(screenId);
    if (!screenSession || screenSession->GetScreenProperty().GetScreenType() != ScreenType::REAL ||
        !CheckPhysicalScreenReady(screenSession)) {
        return;
    }

    sptr<ScreenSession> defaultScreen = FindOtherPhysicalScreen(screenSession);
    if (defaultScreen == nullptr) {
        TLOGE(WmsLogTag::DMS, "no other physical screen found, skip recovery");
        return;
    }
    std::map<std::string, MultiScreenModeInfo> desktopInfoMap = ScreenSettingHelper::GetMultiScreenModeInfo();
    std::string connectSerialNumber = screenSession->GetSerialNumber();
    std::string defaultSerialNumber = defaultScreen->GetSerialNumber();
    std::string recoveryKey = (connectSerialNumber < defaultSerialNumber) ? 
        connectSerialNumber + " " + defaultSerialNumber : defaultSerialNumber + " " + connectSerialNumber;
    TLOGNFI(WmsLogTag::DMS, "recoveryKey: %{public}s", recoveryKey.c_str());
    if (!CheckMapHasKey(desktopInfoMap, recoveryKey)) {
        SetMultiScreenDefaultRelativePosition();
        return;
    }
    MultiScreenModeInfo info = desktopInfoMap[recoveryKey];
    if (info.mainScreen.empty()) {
        TLOGE(WmsLogTag::DMS, "mainScreen is empty, skip recovery");
        return;
    }
    auto resolveResult = ResolveScreenIds(desktopInfoMap[recoveryKey], defaultScreen, screenSession);
    if (resolveResult.mainScreenId == SCREEN_ID_INVALID ||
        resolveResult.otherScreenDetail.screenMode == MultiScreenSourceMode::SCREEN_MIRROR ||
        resolveResult.otherScreenDetail.screenMode == MultiScreenSourceMode::SCREEN_UNUSED) {
        TLOGNFI(WmsLogTag::DMS, "MIRROR or unused mode or invalid main screenId, no need recover relative position");
        return;
    }
    TLOGNFI(WmsLogTag::DMS,  "mainScreenId: %{public}" PRIu64 ", secondaryScreenId: %{public}" PRIu64,
        resolveResult.mainScreenId, resolveResult.secondaryScreenId);
    auto ret = SetMultiScreenRelativePosition(resolveResult.mainScreenDetail.position, resolveResult.otherScreenDetail.position);
    if (ret != DMError::DM_OK) {
        TLOGNFI(WmsLogTag::DMS, "SetMultiScreenRelativePosition failed, fallback to default position");
        SetMultiScreenDefaultRelativePosition();
    }
#else
    TLOGNFI(WmsLogTag::DMS, "WM_MULTI_SCREEN_ENABLE not defined, skip");
#endif
}
```
likedislike
wangdi成员
6月14日 评论:
/**
 * @tc.name: RecoverMultiScreenRelativePositionForDesktop01
 * @tc.desc: Recover extend mode screen relative position successfully
 * @tc.type: FUNC
 */
HWTEST_F(ScreenSessionManagerTest, RecoverMultiScreenRelativePositionForDesktop01, TestSize.Level1)
{
    ASSERT_NE(ssm_, nullptr);
    // Setup: create two physical screens
    ScreenId mainScreenId = 0;
    ScreenId extendScreenId = 1;
    ScreenId mainRsId = 15;
    ScreenId extendRsId = 9;
    sptr<ScreenSession> mainSession = new ScreenSession(mainScreenId, ScreenProperty(), mainRsId);
    sptr<ScreenSession> extendSession = new ScreenSession(extendScreenId, ScreenProperty(), extendRsId);
    mainSession->GetScreenProperty().SetScreenType(ScreenType::REAL);
    mainSession->GetScreenProperty().SetBounds(RRect{0, 0, 2560, 1440, 0});
    mainSession->SetSerialNumber("serialA");
    
    extendSession->GetScreenProperty().SetScreenType(ScreenType::REAL);
    extendSession->GetScreenProperty().SetBounds(RRect{2560, 0, 1920, 1080, 0});
    extendSession->SetSerialNumber("serialB");
    ssm_->screenSessionMap_[mainScreenId] = mainSession;
    ssm_->screenSessionMap_[extendScreenId] = extendSession;
    // Inject mock config (need to mock ScreenSettingHelper::GetMultiScreenModeInfo)
    // Or use test-specific setting provider
    
    // Mock log callback to verify SetMultiScreenRelativePosition is called
    g_logMsg.clear();
    LOG_SetCallback(MyLogCallback);
    ssm_->RecoverMultiScreenRelativePositionForDesktop(mainRsId);
    // Expect: log contains "mainScreenId" and "secondaryScreenId"
    EXPECT_TRUE(g_logMsg.find("mainScreenId") != std::string::npos);
    EXPECT_TRUE(g_logMsg.find("secondaryScreenId") != std::string::npos);
    LOG_SetCallback(nullptr);
    ssm_->screenSessionMap_.erase(mainScreenId);
    ssm_->screenSessionMap_.erase(extendScreenId);
}
/**
 * @tc.name: RecoverMultiScreenRelativePositionForDesktop02
 * @tc.desc: Skip position recovery for mirror mode
 * @tc.type: FUNC
 */
HWTEST_F(ScreenSessionManagerTest, RecoverMultiScreenRelativePositionForDesktop02, TestSize.Level1)
{
    ASSERT_NE(ssm_, nullptr);
    ScreenId screenId = 0;
    ScreenId otherScreenId = 1;
    ScreenId rsId = 15;
    sptr<ScreenSession> screenSession = new ScreenSession(screenId, ScreenProperty(), rsId);
    sptr<ScreenSession> otherSession = new ScreenSession(otherScreenId, ScreenProperty(), 9);
    screenSession->GetScreenProperty().SetScreenType(ScreenType::REAL);
    screenSession->SetSerialNumber("serialA");
    otherSession->GetScreenProperty().SetScreenType(ScreenType::REAL);
    otherSession->SetSerialNumber("serialB");
    ssm_->screenSessionMap_[screenId] = screenSession;
    ssm_->screenSessionMap_[otherScreenId] = otherSession;
    g_logMsg.clear();
    LOG_SetCallback(MyLogCallback);
    ssm_->RecoverMultiScreenRelativePositionForDesktop(rsId);
    // Expect: log contains "MIRROR" or "no need recover relative position"
    EXPECT_TRUE(g_logMsg.find("MIRROR") != std::string::npos ||
                g_logMsg.find("no need recover") != std::string::npos);
    LOG_SetCallback(nullptr);
    ssm_->screenSessionMap_.erase(screenId);
    ssm_->screenSessionMap_.erase(otherScreenId);
}
/**
 * @tc.name: RecoverMultiScreenRelativePositionForDesktop03
 * @tc.desc: Skip position recovery for unused mode
 * @tc.type: FUNC
 */
HWTEST_F(ScreenSessionManagerTest, RecoverMultiScreenRelativePositionForDesktop03, TestSize.Level1)
{
    ASSERT_NE(ssm_, nullptr);
    ScreenId screenId = 0;
    ScreenId rsId = 15;
    sptr<ScreenSession> screenSession = new ScreenSession(screenId, ScreenProperty(), rsId);
    sptr<ScreenSession> otherSession = new ScreenSession(1, ScreenProperty(), 9);
    screenSession->GetScreenProperty().SetScreenType(ScreenType::REAL);
    screenSession->SetSerialNumber("serialA");
    otherSession->GetScreenProperty().SetScreenType(ScreenType::REAL);
    otherSession->SetSerialNumber("serialB");
    ssm_->screenSessionMap_[screenId] = screenSession;
    ssm_->screenSessionMap_[1] = otherSession;
    g_logMsg.clear();
    LOG_SetCallback(MyLogCallback);
    ssm_->RecoverMultiScreenRelativePositionForDesktop(rsId);
    // Expect: log contains "unused" mode skip message
    EXPECT_TRUE(g_logMsg.find("unused") != std::string::npos ||
                g_logMsg.find("no need recover") != std::string::npos);
    LOG_SetCallback(nullptr);
    ssm_->screenSessionMap_.erase(screenId);
    ssm_->screenSessionMap_.erase(1);
}
/**
 * @tc.name: RecoverMultiScreenRelativePositionForDesktop04
 * @tc.desc: Fallback to default position when config not found
 * @tc.type: FUNC
 */
HWTEST_F(ScreenSessionManagerTest, RecoverMultiScreenRelativePositionForDesktop04, TestSize.Level1)
{
    ASSERT_NE(ssm_, nullptr);
    ScreenId screenId = 0;
    ScreenId rsId = 15;
    sptr<ScreenSession> screenSession = new ScreenSession(screenId, ScreenProperty(), rsId);
    sptr<ScreenSession> otherSession = new ScreenSession(1, ScreenProperty(), 9);
    screenSession->GetScreenProperty().SetScreenType(ScreenType::REAL);
    screenSession->SetSerialNumber("serialNotExist"); // Serial not in config
    otherSession->GetScreenProperty().SetScreenType(ScreenType::REAL);
    otherSession->SetSerialNumber("serialNotExist2");
    ssm_->screenSessionMap_[screenId] = screenSession;
    ssm_->screenSessionMap_[1] = otherSession;
    g_logMsg.clear();
    LOG_SetCallback(MyLogCallback);
    ssm_->RecoverMultiScreenRelativePositionForDesktop(rsId);
    // Expect: SetMultiScreenDefaultRelativePosition was called (verify by log)
    EXPECT_TRUE(g_logMsg.find("recoveryKey not found") != std::string::npos ||
                g_logMsg.find("default position") != std::string::npos);
    LOG_SetCallback(nullptr);
    ssm_->screenSessionMap_.erase(screenId);
    ssm_->screenSessionMap_.erase(1);
}
/**
 * @tc.name: RecoverMultiScreenRelativePositionForDesktop05
 * @tc.desc: Skip recovery when mainScreen is empty in config
 * @tc.type: FUNC
 */
HWTEST_F(ScreenSessionManagerTest, RecoverMultiScreenRelativePositionForDesktop05, TestSize.Level1)
{
    ASSERT_NE(ssm_, nullptr);
    ScreenId screenId = 0;
    ScreenId rsId = 15;
    sptr<ScreenSession> screenSession = new ScreenSession(screenId, ScreenProperty(), rsId);
    sptr<ScreenSession> otherSession = new ScreenSession(1, ScreenProperty(), 9);
    screenSession->GetScreenProperty().SetScreenType(ScreenType::REAL);
    screenSession->SetSerialNumber("serialA");
    otherSession->GetScreenProperty().SetScreenType(ScreenType::REAL);
    otherSession->SetSerialNumber("serialB");
    ssm_->screenSessionMap_[screenId] = screenSession;
    ssm_->screenSessionMap_[1] = otherSession;
    g_logMsg.clear();
    LOG_SetCallback(MyLogCallback);
    ssm_->RecoverMultiScreenRelativePositionForDesktop(rsId);
    // Expect: log contains "mainScreen is empty"
    EXPECT_TRUE(g_logMsg.find("mainScreen is empty") != std::string::npos ||
                g_logMsg.find("skip recovery") != std::string::npos);
    LOG_SetCallback(nullptr);
    ssm_->screenSessionMap_.erase(screenId);
    ssm_->screenSessionMap_.erase(1);
}
/**
 * @tc.name: RecoverMultiScreenRelativePositionForDesktop06
 * @tc.desc: Return without crash when screenSession is null
 * @tc.type: FUNC
 */
HWTEST_F(ScreenSessionManagerTest, RecoverMultiScreenRelativePositionForDesktop06, TestSize.Level1)
{
    ASSERT_NE(ssm_, nullptr);
    ScreenId invalidRsId = 999;
    g_errLog.clear();
    LOG_SetCallback(MyLogCallback);
    // Expect: no crash, method returns safely
    ssm_->RecoverMultiScreenRelativePositionForDesktop(invalidRsId);
    EXPECT_TRUE(true); // If we reach here, no crash occurred
    // Optional: verify error log if method logs "screenSession is nullptr"
    // EXPECT_TRUE(g_errLog.find("nullptr") != std::string::npos);
    LOG_SetCallback(nullptr);
}
/**
 * @tc.name: RecoverMultiScreenRelativePositionForDesktop07
 * @tc.desc: Return for non-REAL screen type
 * @tc.type: FUNC
 */
HWTEST_F(ScreenSessionManagerTest, RecoverMultiScreenRelativePositionForDesktop07, TestSize.Level1)
{
    ASSERT_NE(ssm_, nullptr);
    ScreenId screenId = 0;
    ScreenId rsId = 15;
    sptr<ScreenSession> screenSession = new ScreenSession(screenId, ScreenProperty(), rsId);
    screenSession->GetScreenProperty().SetScreenType(ScreenType::VIRTUAL);
    ssm_->screenSessionMap_[screenId] = screenSession;
    g_logMsg.clear();
    LOG_SetCallback(MyLogCallback);
    ssm_->RecoverMultiScreenRelativePositionForDesktop(rsId);
    // Expect: method returns early (no "mainScreenId" log)
    EXPECT_TRUE(g_logMsg.find("mainScreenId") == std::string::npos);
    LOG_SetCallback(nullptr);
    ssm_->screenSessionMap_.erase(screenId);
}
/**
 * @tc.name: RecoverMultiScreenRelativePositionForDesktop08
 * @tc.desc: Return when physical screen not ready
 * @tc.type: FUNC
 */
HWTEST_F(ScreenSessionManagerTest, RecoverMultiScreenRelativePositionForDesktop08, TestSize.Level1)
{
    ASSERT_NE(ssm_, nullptr);
    ScreenId screenId = 0;
    ScreenId rsId = 15;
    sptr<ScreenSession> screenSession = new ScreenSession(screenId, ScreenProperty(), rsId);
    screenSession->GetScreenProperty().SetScreenType(ScreenType::REAL);
    // Set screen to uninitialized state to make CheckPhysicalScreenReady return false
    screenSession->GetScreenProperty().SetBounds(RRect{0, 0, 0, 0, 0}); // Invalid bounds
    ssm_->screenSessionMap_[screenId] = screenSession;
    g_logMsg.clear();
    LOG_SetCallback(MyLogCallback);
    ssm_->RecoverMultiScreenRelativePositionForDesktop(rsId);
    // Expect: log contains "physical screen not ready"
    EXPECT_TRUE(g_logMsg.find("not ready") != std::string::npos);
    LOG_SetCallback(nullptr);
    ssm_->screenSessionMap_.erase(screenId);
}
/**
 * @tc.name: RecoverMultiScreenRelativePositionForDesktop09
 * @tc.desc: Return when no other physical screen found
 * @tc.type: FUNC
 */
HWTEST_F(ScreenSessionManagerTest, RecoverMultiScreenRelativePositionForDesktop09, TestSize.Level1)
{
    ASSERT_NE(ssm_, nullptr);
    ScreenId screenId = 0;
    ScreenId rsId = 15;
    sptr<ScreenSession> screenSession = new ScreenSession(screenId, ScreenProperty(), rsId);
    screenSession->GetScreenProperty().SetScreenType(ScreenType::REAL);
    ssm_->screenSessionMap_[screenId] = screenSession;
    // Only one screen in map
    g_errLog.clear();
    LOG_SetCallback(MyLogCallback);
    ssm_->RecoverMultiScreenRelativePositionForDesktop(rsId);
    // Expect: error log contains "no other physical screen"
    EXPECT_TRUE(g_errLog.find("no other") != std::string::npos ||
                g_errLog.find("physical screen found") != std::string::npos);
    LOG_SetCallback(nullptr);
    ssm_->screenSessionMap_.erase(screenId);
}
/**
 * @tc.name: RecoverMultiScreenRelativePositionForDesktop10
 * @tc.desc: Fallback to default when SetMultiScreenRelativePosition fails
 * @tc.type: FUNC
 */
HWTEST_F(ScreenSessionManagerTest, RecoverMultiScreenRelativePositionForDesktop10, TestSize.Level1)
{
    ASSERT_NE(ssm_, nullptr);
    ScreenId mainScreenId = 0;
    ScreenId extendScreenId = 1;
    ScreenId mainRsId = 15;
    ScreenId extendRsId = 9;
    sptr<ScreenSession> mainSession = new ScreenSession(mainScreenId, ScreenProperty(), mainRsId);
    sptr<ScreenSession> extendSession = new ScreenSession(extendScreenId, ScreenProperty(), extendRsId);
    mainSession->GetScreenProperty().SetScreenType(ScreenType::REAL);
    mainSession->GetScreenProperty().SetBounds(RRect{0, 0, 2560, 1440, 0});
    mainSession->SetSerialNumber("serialA");
    
    extendSession->GetScreenProperty().SetScreenType(ScreenType::REAL);
    // Set invalid bounds that will cause AreScreensTouching check to fail
    extendSession->GetScreenProperty().SetBounds(RRect{9999, 9999, 1920, 1080, 0});
    extendSession->SetSerialNumber("serialB");
    ssm_->screenSessionMap_[mainScreenId] = mainSession;
    ssm_->screenSessionMap_[extendScreenId] = extendSession;
    g_logMsg.clear();
    LOG_SetCallback(MyLogCallback);
    ssm_->RecoverMultiScreenRelativePositionForDesktop(mainRsId);
    // Expect: log contains "failed" and "default position"
    EXPECT_TRUE(g_logMsg.find("failed") != std::string::npos ||
                g_logMsg.find("default position") != std::string::npos);
    LOG_SetCallback(nullptr);
    ssm_->screenSessionMap_.erase(mainScreenId);
    ssm_->screenSessionMap_.erase(extendScreenId);
}
/**
 * @tc.name: RecoverMultiScreenRelativePositionForDesktop11
 * @tc.desc: Return when ResolveScreenIds returns invalid mainScreenId
 * @tc.type: FUNC
 */
HWTEST_F(ScreenSessionManagerTest, RecoverMultiScreenRelativePositionForDesktop11, TestSize.Level1)
{
    ASSERT_NE(ssm_, nullptr);
    ScreenId screenId = 0;
    ScreenId rsId = 15;
    sptr<ScreenSession> screenSession = new ScreenSession(screenId, ScreenProperty(), rsId);
    sptr<ScreenSession> otherSession = new ScreenSession(1, ScreenProperty(), 9);
    screenSession->GetScreenProperty().SetScreenType(ScreenType::REAL);
    screenSession->SetSerialNumber("unknownSerial"); // Serial that won't match config
    otherSession->GetScreenProperty().SetScreenType(ScreenType::REAL);
    otherSession->SetSerialNumber("unknownSerial2");
    ssm_->screenSessionMap_[screenId] = screenSession;
    ssm_->screenSessionMap_[1] = otherSession;
    g_logMsg.clear();
    LOG_SetCallback(MyLogCallback);
    ssm_->RecoverMultiScreenRelativePositionForDesktop(rsId);
    // Expect: log contains "ResolveScreenIds failed" or early return message
    EXPECT_TRUE(g_logMsg.find("ResolveScreenIds") != std::string::npos ||
                g_logMsg.find("invalid") != std::string::npos ||
                g_logMsg.find("no need recover") != std::string::npos);
    LOG_SetCallback(nullptr);
    ssm_->screenSessionMap_.erase(screenId);
    ssm_->screenSessionMap_.erase(1);
}
/**
 * @tc.name: RecoverMultiScreenRelativePositionForDesktop12
 * @tc.desc: Multiple screen recovery scenario
 * @tc.type: FUNC
 */
HWTEST_F(ScreenSessionManagerTest, RecoverMultiScreenRelativePositionForDesktop12, TestSize.Level1)
{
    ASSERT_NE(ssm_, nullptr);
    // Setup 3 screens (though method only handles 2 screens from config)
    ScreenId screen1Id = 0;
    ScreenId screen2Id = 1;
    ScreenId screen3Id = 2;
    ScreenId rsId1 = 15;
    ScreenId rsId2 = 9;
    ScreenId rsId3 = 20;
    sptr<ScreenSession> session1 = new ScreenSession(screen1Id, ScreenProperty(), rsId1);
    sptr<ScreenSession> session2 = new ScreenSession(screen2Id, ScreenProperty(), rsId2);
    sptr<ScreenSession> session3 = new ScreenSession(screen3Id, ScreenProperty(), rsId3);
    session1->GetScreenProperty().SetScreenType(ScreenType::REAL);
    session1->SetSerialNumber("serialA");
    session2->GetScreenProperty().SetScreenType(ScreenType::REAL);
    session2->SetSerialNumber("serialB");
    session3->GetScreenProperty().SetScreenType(ScreenType::REAL);
    session3->SetSerialNumber("serialC");
    ssm_->screenSessionMap_[screen1Id] = session1;
    ssm_->screenSessionMap_[screen2Id] = session2;
    ssm_->screenSessionMap_[screen3Id] = session3;
    g_logMsg.clear();
    LOG_SetCallback(MyLogCallback);
    // Recovery for rsId1 - should find screen2 (from config) as other screen
    ssm_->RecoverMultiScreenRelativePositionForDesktop(rsId1);
    // Expect: recovery succeeded for first two screens
    EXPECT_TRUE(g_logMsg.find("mainScreenId") != std::string::npos ||
                g_logMsg.find("no need recover") != std::string::npos);
    LOG_SetCallback(nullptr);
    ssm_->screenSessionMap_.erase(screen1Id);
    ssm_->screenSessionMap_.erase(screen2Id);
    ssm_->screenMap_.erase(screen3Id);
}
likedislike