* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <gtest/gtest.h>
#include <regex>
#include <bundle_mgr_interface.h>
#include <bundlemgr/launcher_service.h>
#include "context.h"
#include "interfaces/include/ws_common.h"
#include "iremote_object_mocker.h"
#include "libxml/parser.h"
#include "libxml/tree.h"
#include "mock/mock_session_stage.h"
#include "mock/mock_window_event_channel.h"
#include "session_info.h"
#include "session_manager.h"
#include "session_manager/include/scene_session_manager.h"
#include "session/host/include/scene_session.h"
#include "session/host/include/main_session.h"
#include "window_manager_agent.h"
#include "zidl/window_manager_agent_interface.h"
using namespace testing;
using namespace testing::ext;
namespace OHOS {
namespace Rosen {
namespace {
static constexpr uint32_t WAIT_SYNC_IN_NS = 200000U;
using ConfigItem = WindowSceneConfig::ConfigItem;
ConfigItem ReadConfig(const std::string& xmlStr)
{
ConfigItem config;
xmlDocPtr docPtr = xmlParseMemory(xmlStr.c_str(), xmlStr.length());
if (docPtr == nullptr) {
return config;
}
xmlNodePtr rootPtr = xmlDocGetRootElement(docPtr);
if (rootPtr == nullptr || rootPtr->name == nullptr ||
xmlStrcmp(rootPtr->name, reinterpret_cast<const xmlChar*>("Configs"))) {
xmlFreeDoc(docPtr);
return config;
}
std::map<std::string, ConfigItem> configMap;
config.SetValue(configMap);
WindowSceneConfig::ReadConfig(rootPtr, *config.mapValue_);
xmlFreeDoc(docPtr);
return config;
}
}
class SSMgrSpecificWindowTest : public testing::Test {
public:
static void SetUpTestCase();
static void TearDownTestCase();
void SetUp() override;
void TearDown() override;
static sptr<SceneSessionManager> ssm_;
private:
};
sptr<SceneSessionManager> SSMgrSpecificWindowTest::ssm_ = nullptr;
void SSMgrSpecificWindowTest::SetUpTestCase()
{
ssm_ = &SceneSessionManager::GetInstance();
}
void SSMgrSpecificWindowTest::TearDownTestCase()
{
ssm_ = nullptr;
}
void SSMgrSpecificWindowTest::SetUp() {}
void SSMgrSpecificWindowTest::TearDown()
{
usleep(WAIT_SYNC_IN_NS);
}
namespace {
* @tc.name: ConfigKeyboardAnimation01
* @tc.desc: call ConfigKeyboardAnimation default
* @tc.type: FUNC
*/
HWTEST_F(SSMgrSpecificWindowTest, ConfigKeyboardAnimation01, TestSize.Level1)
{
std::string xmlStr =
"<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<keyboardAnimation>"
"<animationIn>"
"<timing>"
"<duration>abv</duration>"
"<curve name=\"cubic\">0.2 0.0 0.2 1.0</curve>"
"</timing>"
"</animationIn>"
"<animationOut>"
"<timing>"
"<duration>abv</duration>"
"<curve name=\"cubic\">0.2 0.0 0.2 1.0</curve>"
"</timing>"
"</animationOut>"
"</keyboardAnimation>"
"</Configs>";
WindowSceneConfig::config_ = ReadConfig(xmlStr);
ssm_->ConfigWindowSceneXml();
std::string xmlStr1 =
"<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<keyboardAnimation>"
"<animationIn>"
"<timing>"
"<duration>500</duration>"
"<curve name=\"cubic\">0.2 0.0 0.2 1.0</curve>"
"</timing>"
"</animationIn>"
"<animationOut>"
"<timing>"
"<duration>300</duration>"
"<curve name=\"cubic\">0.2 0.0 0.2 1.0</curve>"
"</timing>"
"</animationOut>"
"</keyboardAnimation>"
"</Configs>";
WindowSceneConfig::config_ = ReadConfig(xmlStr1);
ssm_->ConfigWindowSceneXml();
ASSERT_EQ(ssm_->systemConfig_.animationIn_.duration_, static_cast<uint32_t>(500));
ASSERT_EQ(ssm_->systemConfig_.animationOut_.duration_, static_cast<uint32_t>(300));
}
* @tc.name: ConfigKeyboardAnimation02
* @tc.desc: call ConfigKeyboardAnimation default
* @tc.type: FUNC
*/
HWTEST_F(SSMgrSpecificWindowTest, ConfigKeyboardAnimation02, TestSize.Level1)
{
std::string xmlStr =
"<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<keyboardAnimation>"
"<animationIn>"
"<timing>"
"<duration>500</duration>"
"<duration>600</duration>"
"</timing>"
"</animationIn>"
"<animationOut>"
"<timing>"
"<duration>300</duration>"
"</timing>"
"</animationOut>"
"</keyboardAnimation>"
"</Configs>";
WindowSceneConfig::config_ = ReadConfig(xmlStr);
ssm_->ConfigWindowSceneXml();
ASSERT_EQ(ssm_->systemConfig_.animationOut_.duration_, static_cast<uint32_t>(300));
}
* @tc.name: ConfigKeyboardAnimation03
* @tc.desc: call ConfigKeyboardAnimation default
* @tc.type: FUNC
*/
HWTEST_F(SSMgrSpecificWindowTest, ConfigKeyboardAnimation03, TestSize.Level1)
{
std::string xmlStr =
"<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<keyboardAnimation>"
"<animationIn>"
"<timing>"
"<duration>500</duration>"
"</timing>"
"</animationIn>"
"<animationOut>"
"<timing>"
"<duration>300</duration>"
"<duration>400</duration>"
"</timing>"
"</animationOut>"
"</keyboardAnimation>"
"</Configs>";
WindowSceneConfig::config_ = ReadConfig(xmlStr);
ssm_->ConfigWindowSceneXml();
ASSERT_EQ(ssm_->systemConfig_.animationIn_.duration_, static_cast<uint32_t>(500));
}
* @tc.name: ConfigKeyboardAnimation04
* @tc.desc: call ConfigKeyboardAnimation default
* @tc.type: FUNC
*/
HWTEST_F(SSMgrSpecificWindowTest, ConfigKeyboardAnimation04, TestSize.Level1)
{
std::string xmlStr =
"<?xml version='1.0' encoding=\"utf-8\"?>"
"<Configs>"
"<keyboardAnimation>"
"<animationIn>"
"<timing>"
"<duration>500</duration>"
"</timing>"
"</animationIn>"
"</keyboardAnimation>"
"</Configs>";
WindowSceneConfig::config_ = ReadConfig(xmlStr);
ssm_->ConfigWindowSceneXml();
ASSERT_EQ(ssm_->systemConfig_.animationIn_.duration_, static_cast<uint32_t>(500));
}
* @tc.name: IsKeyboardForeground
* @tc.desc: IsKeyboardForeground
* @tc.type: FUNC
*/
HWTEST_F(SSMgrSpecificWindowTest, IsKeyboardForeground, TestSize.Level1)
{
ASSERT_NE(nullptr, ssm_);
SessionInfo info;
sptr<SceneSession::SpecificSessionCallback> specificCallback = nullptr;
sptr<SceneSession> sceneSession = sptr<SceneSession>::MakeSptr(info, specificCallback);
ASSERT_NE(sceneSession, nullptr);
sptr<Session> session = sptr<Session>::MakeSptr(info);
ASSERT_NE(session, nullptr);
session->property_ = nullptr;
auto result = ssm_->IsKeyboardForeground();
ASSERT_EQ(result, false);
}
* @tc.name: ProcessSubSessionForeground
* @tc.desc: ProcessSubSessionForeground
* @tc.type: FUNC
*/
HWTEST_F(SSMgrSpecificWindowTest, ProcessSubSessionForeground, TestSize.Level1)
{
sptr<SceneSession> sceneSession = nullptr;
ASSERT_NE(nullptr, ssm_);
ssm_->ProcessSubSessionForeground(sceneSession);
SessionInfo sessionInfo;
sessionInfo.bundleName_ = "SceneSessionManagerTest2";
sessionInfo.abilityName_ = "DumpSessionWithId";
sceneSession = sptr<SceneSession>::MakeSptr(sessionInfo, nullptr);
ASSERT_NE(nullptr, sceneSession);
ASSERT_NE(nullptr, ssm_);
ssm_->ProcessSubSessionForeground(sceneSession);
sptr<SceneSession> subSession = sptr<SceneSession>::MakeSptr(sessionInfo, nullptr);
ASSERT_NE(nullptr, sceneSession);
ASSERT_NE(nullptr, subSession);
sceneSession->AddSubSession(subSession);
ASSERT_NE(nullptr, ssm_);
ssm_->ProcessSubSessionForeground(sceneSession);
ASSERT_NE(nullptr, subSession);
subSession->SetSessionState(SessionState::STATE_FOREGROUND);
ASSERT_NE(nullptr, ssm_);
ssm_->ProcessSubSessionForeground(sceneSession);
ASSERT_NE(nullptr, subSession);
subSession->SetSessionState(SessionState::STATE_ACTIVE);
ASSERT_NE(nullptr, ssm_);
ssm_->ProcessSubSessionForeground(sceneSession);
ASSERT_NE(nullptr, subSession);
subSession->SetSessionState(SessionState::STATE_INACTIVE);
ASSERT_NE(nullptr, ssm_);
ssm_->ProcessSubSessionForeground(sceneSession);
}
* @tc.name: ProcessSubSessionBackground
* @tc.desc: ProcessSubSessionBackground
* @tc.type: FUNC
*/
HWTEST_F(SSMgrSpecificWindowTest, ProcessSubSessionBackground, TestSize.Level1)
{
sptr<SceneSession> sceneSession = nullptr;
ASSERT_NE(nullptr, ssm_);
ssm_->ProcessSubSessionBackground(sceneSession);
SessionInfo sessionInfo;
sessionInfo.bundleName_ = "SceneSessionManagerTest2";
sessionInfo.abilityName_ = "DumpSessionWithId";
sceneSession = sptr<SceneSession>::MakeSptr(sessionInfo, nullptr);
ASSERT_NE(nullptr, sceneSession);
ASSERT_NE(nullptr, ssm_);
ssm_->ProcessSubSessionBackground(sceneSession);
sptr<SceneSession> subSession = sptr<SceneSession>::MakeSptr(sessionInfo, nullptr);
ASSERT_NE(nullptr, sceneSession);
ASSERT_NE(nullptr, subSession);
sceneSession->AddSubSession(subSession);
subSession->state_ = SessionState::STATE_FOREGROUND;
ASSERT_NE(nullptr, ssm_);
ssm_->ProcessSubSessionBackground(sceneSession);
ASSERT_NE(nullptr, subSession);
subSession->state_ = SessionState::STATE_ACTIVE;
ASSERT_NE(nullptr, ssm_);
ssm_->ProcessSubSessionBackground(sceneSession);
ASSERT_NE(nullptr, subSession);
subSession->state_ = SessionState::STATE_INACTIVE;
ASSERT_NE(nullptr, ssm_);
ssm_->ProcessSubSessionBackground(sceneSession);
}
* @tc.name: ProcessSubSessionBackground01
* @tc.desc: ProcessSubSessionBackground01
* @tc.type: FUNC
*/
HWTEST_F(SSMgrSpecificWindowTest, ProcessSubSessionBackground01, TestSize.Level1)
{
SessionInfo sessionInfo;
sessionInfo.bundleName_ = "SceneSessionManagerTest2";
sessionInfo.abilityName_ = "DumpSessionWithId";
sptr<SceneSession> sceneSession = sptr<SceneSession>::MakeSptr(sessionInfo, nullptr);
ASSERT_NE(nullptr, sceneSession);
sceneSession->dialogVec_.clear();
ASSERT_NE(nullptr, ssm_);
ssm_->ProcessSubSessionBackground(sceneSession);
sptr<SceneSession> sceneSession1 = sptr<SceneSession>::MakeSptr(sessionInfo, nullptr);
ASSERT_NE(nullptr, sceneSession1);
ASSERT_NE(nullptr, sceneSession);
sceneSession->dialogVec_.push_back(sceneSession1);
ASSERT_NE(nullptr, ssm_);
ssm_->sceneSessionMap_.clear();
sceneSession1->persistentId_ = 1;
ssm_->sceneSessionMap_.insert(std::make_pair(0, sceneSession));
ssm_->ProcessSubSessionBackground(sceneSession);
ssm_->sceneSessionMap_.insert(std::make_pair(1, sceneSession));
ssm_->ProcessSubSessionBackground(sceneSession);
sptr<SceneSession> toastSession = sptr<SceneSession>::MakeSptr(sessionInfo, nullptr);
ASSERT_NE(nullptr, toastSession);
ASSERT_NE(nullptr, sceneSession);
sceneSession->AddToastSession(toastSession);
toastSession->state_ = SessionState::STATE_FOREGROUND;
ASSERT_NE(nullptr, ssm_);
ssm_->ProcessSubSessionBackground(sceneSession);
toastSession->state_ = SessionState::STATE_ACTIVE;
ssm_->ProcessSubSessionBackground(sceneSession);
toastSession->state_ = SessionState::STATE_INACTIVE;
ssm_->ProcessSubSessionBackground(sceneSession);
}
* @tc.name: DestroyDialogWithMainWindow
* @tc.desc: DestroyDialogWithMainWindow
* @tc.type: FUNC
*/
HWTEST_F(SSMgrSpecificWindowTest, DestroyDialogWithMainWindow, TestSize.Level1)
{
sptr<SceneSession> sceneSession = nullptr;
auto result = ssm_->DestroyDialogWithMainWindow(sceneSession);
ASSERT_EQ(result, WSError::WS_ERROR_NULLPTR);
SessionInfo info;
sptr<SceneSession::SpecificSessionCallback> specificCallback = nullptr;
sceneSession = sptr<SceneSession>::MakeSptr(info, specificCallback);
ASSERT_NE(sceneSession, nullptr);
sptr<Session> session = sptr<Session>::MakeSptr(info);
ASSERT_NE(session, nullptr);
session->GetDialogVector().clear();
result = ssm_->DestroyDialogWithMainWindow(sceneSession);
ASSERT_EQ(result, WSError::WS_OK);
ssm_->sceneSessionMap_.insert({ 0, sceneSession });
ssm_->GetSceneSession(1);
result = ssm_->DestroyDialogWithMainWindow(sceneSession);
ASSERT_EQ(result, WSError::WS_OK);
}
* @tc.name: DestroyDialogWithMainWindow02
* @tc.desc: DestroyDialogWithMainWindow02
* @tc.type: FUNC
*/
HWTEST_F(SSMgrSpecificWindowTest, DestroyDialogWithMainWindow02, TestSize.Level1)
{
SessionInfo info;
sptr<SceneSession::SpecificSessionCallback> specificCallback = nullptr;
sptr<SceneSession> sceneSession = sptr<SceneSession>::MakeSptr(info, specificCallback);
ASSERT_NE(sceneSession, nullptr);
sptr<Session> dialogSession1 = sptr<Session>::MakeSptr(info);
sptr<Session> dialogSession2 = sptr<Session>::MakeSptr(info);
ASSERT_NE(dialogSession1, nullptr);
ASSERT_NE(dialogSession2, nullptr);
dialogSession1->persistentId_ = 0;
dialogSession2->persistentId_ = 1;
sceneSession->dialogVec_.push_back(dialogSession1);
sceneSession->dialogVec_.push_back(dialogSession2);
ASSERT_NE(ssm_, nullptr);
ssm_->sceneSessionMap_.clear();
ssm_->sceneSessionMap_.insert({ 0, nullptr });
ssm_->sceneSessionMap_.insert({ 0, sceneSession });
auto ret = ssm_->DestroyDialogWithMainWindow(sceneSession);
ASSERT_EQ(ret, WSError::WS_ERROR_INVALID_SESSION);
ssm_->sceneSessionMap_.clear();
}
* @tc.name: ConfigKeyboardAnimation
* @tc.desc: SceneSesionManager config keyboard animation
* @tc.type: FUNC
*/
HWTEST_F(SSMgrSpecificWindowTest, ConfigKeyboardAnimation, TestSize.Level1)
{
WindowSceneConfig::ConfigItem animationConfig;
WindowSceneConfig::ConfigItem itemCurve;
WindowSceneConfig::ConfigItem itemDuration;
WindowSceneConfig::ConfigItem nameProp;
std::string name = "cubic";
nameProp.SetValue(name);
itemCurve.SetProperty({ { "name", nameProp } });
std::vector<int> durationVec = { 39 };
itemDuration.SetValue(durationVec);
WindowSceneConfig::ConfigItem timing;
WindowSceneConfig::ConfigItem timingObj;
timingObj.SetValue({ { "curve", itemCurve }, { "duration", itemDuration } });
timing.SetValue({ { "timing", timingObj } });
WindowSceneConfig::ConfigItem timing2(timing);
animationConfig.SetValue({ { "animationIn", timing }, { "animationOut", timing2 } });
ssm_->ConfigKeyboardAnimation(animationConfig);
ASSERT_EQ(ssm_->systemConfig_.animationIn_.curveType_, "cubic");
ASSERT_EQ(ssm_->systemConfig_.animationIn_.duration_, durationVec.at(0));
uint32_t result = 150;
KeyboardSceneAnimationConfig animationIn;
KeyboardSceneAnimationConfig animationOut;
ssm_->systemConfig_.animationIn_.curveType_ = "";
ssm_->ConfigDefaultKeyboardAnimation(animationIn, animationOut);
ASSERT_EQ(animationIn.duration_, result);
}
* @tc.name: UpdateParentSessionForDialog
* @tc.desc: SceneSesionManager UpdateParentSessionForDialog
* @tc.type: FUNC
*/
HWTEST_F(SSMgrSpecificWindowTest, UpdateParentSessionForDialog, TestSize.Level1)
{
WSError result = ssm_->UpdateParentSessionForDialog(nullptr, nullptr);
EXPECT_EQ(result, WSError::WS_ERROR_NULLPTR);
sptr<WindowSessionProperty> property = sptr<WindowSessionProperty>::MakeSptr();
ASSERT_NE(nullptr, property);
result = ssm_->UpdateParentSessionForDialog(nullptr, property);
EXPECT_EQ(result, WSError::WS_ERROR_NULLPTR);
SessionInfo info;
info.abilityName_ = "test1";
info.bundleName_ = "test2";
info.moduleName_ = "test3";
info.appIndex_ = 10;
sptr<SceneSession> sceneSession = sptr<SceneSession>::MakeSptr(info, nullptr);
ASSERT_NE(nullptr, sceneSession);
result = ssm_->UpdateParentSessionForDialog(sceneSession, property);
EXPECT_EQ(result, WSError::WS_OK);
property->SetWindowType(WindowType::WINDOW_TYPE_DIALOG);
result = ssm_->UpdateParentSessionForDialog(sceneSession, property);
EXPECT_EQ(result, WSError::WS_OK);
SessionInfo info1;
info1.abilityName_ = "test2";
info1.bundleName_ = "test3";
sptr<SceneSession> sceneSession2 = sptr<SceneSession>::MakeSptr(info1, nullptr);
ASSERT_NE(nullptr, sceneSession2);
ssm_->sceneSessionMap_.insert({ 2, sceneSession2 });
property->SetParentPersistentId(2);
result = ssm_->UpdateParentSessionForDialog(sceneSession, property);
EXPECT_EQ(result, WSError::WS_OK);
}
* @tc.name: DestroyAndDisconnectSpecificSession
* @tc.desc: SceneSesionManager destroy and disconnect specific session
* @tc.type: FUNC
*/
HWTEST_F(SSMgrSpecificWindowTest, DestroyAndDisconnectSpecificSession, TestSize.Level1)
{
int32_t persistentId = 0;
WSErrorResult result = ssm_->DestroyAndDisconnectSpecificSession(persistentId);
ASSERT_EQ(result.errCode, WSError::WS_ERROR_NULLPTR);
}
* @tc.name: DestroyAndDisconnectSpecificSessionWithDetachCallback
* @tc.desc: SceneSesionManager destroy and disconnect specific session with detach callback
* @tc.type: FUNC
*/
HWTEST_F(SSMgrSpecificWindowTest, DestroyAndDisconnectSpecificSessionWithDetachCallback, TestSize.Level1)
{
int32_t persistentId = 0;
WSErrorResult result = ssm_->DestroyAndDisconnectSpecificSessionWithDetachCallback(persistentId, nullptr);
ASSERT_EQ(result.errCode, WSError::WS_ERROR_NULLPTR);
}
}
}
}