1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <gtest/gtest.h>
17 #include <regex>
18 #include <bundle_mgr_interface.h>
19 #include <bundlemgr/launcher_service.h>
20
21 #include "context.h"
22 #include "interfaces/include/ws_common.h"
23 #include "iremote_object_mocker.h"
24 #include "libxml/parser.h"
25 #include "libxml/tree.h"
26 #include "mock/mock_session_stage.h"
27 #include "mock/mock_window_event_channel.h"
28 #include "session_info.h"
29 #include "session_manager.h"
30 #include "session_manager/include/scene_session_manager.h"
31 #include "session/host/include/scene_session.h"
32 #include "session/host/include/main_session.h"
33 #include "window_manager_agent.h"
34 #include "zidl/window_manager_agent_interface.h"
35
36 using namespace testing;
37 using namespace testing::ext;
38
39 namespace OHOS {
40 namespace Rosen {
41 namespace {
42 static constexpr uint32_t WAIT_SYNC_IN_NS = 200000U;
43 using ConfigItem = WindowSceneConfig::ConfigItem;
ReadConfig(const std::string & xmlStr)44 ConfigItem ReadConfig(const std::string& xmlStr)
45 {
46 ConfigItem config;
47 xmlDocPtr docPtr = xmlParseMemory(xmlStr.c_str(), xmlStr.length() + 1);
48 if (docPtr == nullptr) {
49 return config;
50 }
51
52 xmlNodePtr rootPtr = xmlDocGetRootElement(docPtr);
53 if (rootPtr == nullptr || rootPtr->name == nullptr ||
54 xmlStrcmp(rootPtr->name, reinterpret_cast<const xmlChar*>("Configs"))) {
55 xmlFreeDoc(docPtr);
56 return config;
57 }
58
59 std::map<std::string, ConfigItem> configMap;
60 config.SetValue(configMap);
61 WindowSceneConfig::ReadConfig(rootPtr, *config.mapValue_);
62 xmlFreeDoc(docPtr);
63 return config;
64 }
65 }
66
67 class SSMgrSpecificWindowTest : public testing::Test {
68 public:
69 static void SetUpTestCase();
70
71 static void TearDownTestCase();
72
73 void SetUp() override;
74
75 void TearDown() override;
76
77 static sptr<SceneSessionManager> ssm_;
78 private:
79 };
80
81 sptr<SceneSessionManager> SSMgrSpecificWindowTest::ssm_ = nullptr;
82
SetUpTestCase()83 void SSMgrSpecificWindowTest::SetUpTestCase()
84 {
85 ssm_ = &SceneSessionManager::GetInstance();
86 }
87
TearDownTestCase()88 void SSMgrSpecificWindowTest::TearDownTestCase()
89 {
90 ssm_ = nullptr;
91 }
92
SetUp()93 void SSMgrSpecificWindowTest::SetUp()
94 {
95 }
96
TearDown()97 void SSMgrSpecificWindowTest::TearDown()
98 {
99 usleep(WAIT_SYNC_IN_NS);
100 }
101
102 namespace {
103 /**
104 * @tc.name: ConfigKeyboardAnimation01
105 * @tc.desc: call ConfigKeyboardAnimation default
106 * @tc.type: FUNC
107 */
108 HWTEST_F(SSMgrSpecificWindowTest, ConfigKeyboardAnimation01, Function | SmallTest | Level3)
109 {
110 std::string xmlStr = "<?xml version='1.0' encoding=\"utf-8\"?>"
111 "<Configs>"
112 "<keyboardAnimation>"
113 "<animationIn>"
114 "<timing>"
115 "<duration>abv</duration>"
116 "<curve name=\"cubic\">0.2 0.0 0.2 1.0</curve>"
117 "</timing>"
118 "</animationIn>"
119 "<animationOut>"
120 "<timing>"
121 "<duration>abv</duration>"
122 "<curve name=\"cubic\">0.2 0.0 0.2 1.0</curve>"
123 "</timing>"
124 "</animationOut>"
125 "</keyboardAnimation>"
126 "</Configs>";
127 WindowSceneConfig::config_ = ReadConfig(xmlStr);
128 ssm_->ConfigWindowSceneXml();
129
130 std::string xmlStr1 = "<?xml version='1.0' encoding=\"utf-8\"?>"
131 "<Configs>"
132 "<keyboardAnimation>"
133 "<animationIn>"
134 "<timing>"
135 "<duration>500</duration>"
136 "<curve name=\"cubic\">0.2 0.0 0.2 1.0</curve>"
137 "</timing>"
138 "</animationIn>"
139 "<animationOut>"
140 "<timing>"
141 "<duration>300</duration>"
142 "<curve name=\"cubic\">0.2 0.0 0.2 1.0</curve>"
143 "</timing>"
144 "</animationOut>"
145 "</keyboardAnimation>"
146 "</Configs>";
147 WindowSceneConfig::config_ = ReadConfig(xmlStr1);
148 ssm_->ConfigWindowSceneXml();
149 ASSERT_EQ(ssm_->systemConfig_.animationIn_.duration_, static_cast<uint32_t>(500));
150 ASSERT_EQ(ssm_->systemConfig_.animationOut_.duration_, static_cast<uint32_t>(300));
151 }
152
153 /**
154 * @tc.name: ConfigKeyboardAnimation02
155 * @tc.desc: call ConfigKeyboardAnimation default
156 * @tc.type: FUNC
157 */
158 HWTEST_F(SSMgrSpecificWindowTest, ConfigKeyboardAnimation02, Function | SmallTest | Level3)
159 {
160 std::string xmlStr = "<?xml version='1.0' encoding=\"utf-8\"?>"
161 "<Configs>"
162 "<keyboardAnimation>"
163 "<animationIn>"
164 "<timing>"
165 "<duration>500</duration>"
166 "<duration>600</duration>"
167 "</timing>"
168 "</animationIn>"
169 "<animationOut>"
170 "<timing>"
171 "<duration>300</duration>"
172 "</timing>"
173 "</animationOut>"
174 "</keyboardAnimation>"
175 "</Configs>";
176 WindowSceneConfig::config_ = ReadConfig(xmlStr);
177 ssm_->ConfigWindowSceneXml();
178 ASSERT_EQ(ssm_->systemConfig_.animationOut_.duration_, static_cast<uint32_t>(300));
179 }
180
181 /**
182 * @tc.name: ConfigKeyboardAnimation03
183 * @tc.desc: call ConfigKeyboardAnimation default
184 * @tc.type: FUNC
185 */
186 HWTEST_F(SSMgrSpecificWindowTest, ConfigKeyboardAnimation03, Function | SmallTest | Level3)
187 {
188 std::string xmlStr = "<?xml version='1.0' encoding=\"utf-8\"?>"
189 "<Configs>"
190 "<keyboardAnimation>"
191 "<animationIn>"
192 "<timing>"
193 "<duration>500</duration>"
194 "</timing>"
195 "</animationIn>"
196 "<animationOut>"
197 "<timing>"
198 "<duration>300</duration>"
199 "<duration>400</duration>"
200 "</timing>"
201 "</animationOut>"
202 "</keyboardAnimation>"
203 "</Configs>";
204 WindowSceneConfig::config_ = ReadConfig(xmlStr);
205 ssm_->ConfigWindowSceneXml();
206 ASSERT_EQ(ssm_->systemConfig_.animationIn_.duration_, static_cast<uint32_t>(500));
207 }
208
209 /**
210 * @tc.name: ConfigKeyboardAnimation04
211 * @tc.desc: call ConfigKeyboardAnimation default
212 * @tc.type: FUNC
213 */
214 HWTEST_F(SSMgrSpecificWindowTest, ConfigKeyboardAnimation04, Function | SmallTest | Level3)
215 {
216 std::string xmlStr = "<?xml version='1.0' encoding=\"utf-8\"?>"
217 "<Configs>"
218 "<keyboardAnimation>"
219 "<animationIn>"
220 "<timing>"
221 "<duration>500</duration>"
222 "</timing>"
223 "</animationIn>"
224 "</keyboardAnimation>"
225 "</Configs>";
226 WindowSceneConfig::config_ = ReadConfig(xmlStr);
227 ssm_->ConfigWindowSceneXml();
228 ASSERT_EQ(ssm_->systemConfig_.animationIn_.duration_, static_cast<uint32_t>(500));
229 }
230
231 /**
232 * @tc.name: IsKeyboardForeground
233 * @tc.desc: IsKeyboardForeground
234 * @tc.type: FUNC
235 */
236 HWTEST_F(SSMgrSpecificWindowTest, IsKeyboardForeground, Function | SmallTest | Level3)
237 {
238 ASSERT_NE(nullptr, ssm_);
239 SessionInfo info;
240 sptr<SceneSession::SpecificSessionCallback> specificCallback = nullptr;
241 sptr<SceneSession> sceneSession = sptr<SceneSession>::MakeSptr(info, specificCallback);
242 ASSERT_NE(sceneSession, nullptr);
243 sptr<Session> session = sptr<Session>::MakeSptr(info);
244 ASSERT_NE(session, nullptr);
245 session->property_ = nullptr;
246 auto result = ssm_->IsKeyboardForeground();
247 ASSERT_EQ(result, false);
248
249 ssm_->sceneSessionMap_.insert({0, sceneSession});
250 session->property_ = sptr<WindowSessionProperty>::MakeSptr();
251 ASSERT_NE(session->property_, nullptr);
252
253 if (session->property_) {
254 auto result1 = session->GetWindowType();
255 result1 = WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT;
256 ASSERT_EQ(result1, WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
257 }
258 result = ssm_->IsKeyboardForeground();
259 ASSERT_EQ(result, false);
260 }
261
262 /**
263 * @tc.name: ProcessSubSessionForeground
264 * @tc.desc: ProcessSubSessionForeground
265 * @tc.type: FUNC
266 */
267 HWTEST_F(SSMgrSpecificWindowTest, ProcessSubSessionForeground, Function | SmallTest | Level3)
268 {
269 sptr<SceneSession> sceneSession = nullptr;
270 ASSERT_NE(nullptr, ssm_);
271 ssm_->ProcessSubSessionForeground(sceneSession);
272 SessionInfo sessionInfo;
273 sessionInfo.bundleName_ = "SceneSessionManagerTest2";
274 sessionInfo.abilityName_ = "DumpSessionWithId";
275 sceneSession = sptr<SceneSession>::MakeSptr(sessionInfo, nullptr);
276 ASSERT_NE(nullptr, sceneSession);
277 ASSERT_NE(nullptr, ssm_);
278 ssm_->ProcessSubSessionForeground(sceneSession);
279 sptr<SceneSession> subSession = sptr<SceneSession>::MakeSptr(sessionInfo, nullptr);
280 ASSERT_NE(nullptr, sceneSession);
281 ASSERT_NE(nullptr, subSession);
282 sceneSession->AddSubSession(subSession);
283 ASSERT_NE(nullptr, ssm_);
284 ssm_->ProcessSubSessionForeground(sceneSession);
285 ASSERT_NE(nullptr, subSession);
286 subSession->SetSessionState(SessionState::STATE_FOREGROUND);
287 ASSERT_NE(nullptr, ssm_);
288 ssm_->ProcessSubSessionForeground(sceneSession);
289 ASSERT_NE(nullptr, subSession);
290 subSession->SetSessionState(SessionState::STATE_ACTIVE);
291 ASSERT_NE(nullptr, ssm_);
292 ssm_->ProcessSubSessionForeground(sceneSession);
293 ASSERT_NE(nullptr, subSession);
294 subSession->SetSessionState(SessionState::STATE_INACTIVE);
295 ASSERT_NE(nullptr, ssm_);
296 ssm_->ProcessSubSessionForeground(sceneSession);
297 }
298
299 /**
300 * @tc.name: ProcessSubSessionBackground
301 * @tc.desc: ProcessSubSessionBackground
302 * @tc.type: FUNC
303 */
304 HWTEST_F(SSMgrSpecificWindowTest, ProcessSubSessionBackground, Function | SmallTest | Level3)
305 {
306 sptr<SceneSession> sceneSession = nullptr;
307 ASSERT_NE(nullptr, ssm_);
308 ssm_->ProcessSubSessionBackground(sceneSession);
309 SessionInfo sessionInfo;
310 sessionInfo.bundleName_ = "SceneSessionManagerTest2";
311 sessionInfo.abilityName_ = "DumpSessionWithId";
312 sceneSession = sptr<SceneSession>::MakeSptr(sessionInfo, nullptr);
313 ASSERT_NE(nullptr, sceneSession);
314 ASSERT_NE(nullptr, ssm_);
315 ssm_->ProcessSubSessionBackground(sceneSession);
316 sptr<SceneSession> subSession = sptr<SceneSession>::MakeSptr(sessionInfo, nullptr);
317 ASSERT_NE(nullptr, sceneSession);
318 ASSERT_NE(nullptr, subSession);
319 sceneSession->AddSubSession(subSession);
320 subSession->state_ = SessionState::STATE_FOREGROUND;
321 ASSERT_NE(nullptr, ssm_);
322 ssm_->ProcessSubSessionBackground(sceneSession);
323 ASSERT_NE(nullptr, subSession);
324 subSession->state_ = SessionState::STATE_ACTIVE;
325 ASSERT_NE(nullptr, ssm_);
326 ssm_->ProcessSubSessionBackground(sceneSession);
327 ASSERT_NE(nullptr, subSession);
328 subSession->state_ = SessionState::STATE_INACTIVE;
329 ASSERT_NE(nullptr, ssm_);
330 ssm_->ProcessSubSessionBackground(sceneSession);
331 }
332
333 /**
334 * @tc.name: ProcessSubSessionBackground01
335 * @tc.desc: ProcessSubSessionBackground01
336 * @tc.type: FUNC
337 */
338 HWTEST_F(SSMgrSpecificWindowTest, ProcessSubSessionBackground01, Function | SmallTest | Level3)
339 {
340 SessionInfo sessionInfo;
341 sessionInfo.bundleName_ = "SceneSessionManagerTest2";
342 sessionInfo.abilityName_ = "DumpSessionWithId";
343 sptr<SceneSession> sceneSession = sptr<SceneSession>::MakeSptr(sessionInfo, nullptr);
344 ASSERT_NE(nullptr, sceneSession);
345 sceneSession->dialogVec_.clear();
346 ASSERT_NE(nullptr, ssm_);
347 ssm_->ProcessSubSessionBackground(sceneSession);
348 sptr<SceneSession> sceneSession1 = sptr<SceneSession>::MakeSptr(sessionInfo, nullptr);
349 ASSERT_NE(nullptr, sceneSession1);
350 ASSERT_NE(nullptr, sceneSession);
351 sceneSession->dialogVec_.push_back(sceneSession1);
352 ASSERT_NE(nullptr, ssm_);
353 ssm_->sceneSessionMap_.clear();
354 sceneSession1->persistentId_ = 1;
355 ssm_->sceneSessionMap_.insert(std::make_pair(0, sceneSession));
356 ssm_->ProcessSubSessionBackground(sceneSession);
357 ssm_->sceneSessionMap_.insert(std::make_pair(1, sceneSession));
358 ssm_->ProcessSubSessionBackground(sceneSession);
359 sptr<SceneSession> toastSession = sptr<SceneSession>::MakeSptr(sessionInfo, nullptr);
360 ASSERT_NE(nullptr, toastSession);
361 ASSERT_NE(nullptr, sceneSession);
362 sceneSession->AddToastSession(toastSession);
363 toastSession->state_ = SessionState::STATE_FOREGROUND;
364 ASSERT_NE(nullptr, ssm_);
365 ssm_->ProcessSubSessionBackground(sceneSession);
366 toastSession->state_ = SessionState::STATE_ACTIVE;
367 ssm_->ProcessSubSessionBackground(sceneSession);
368 toastSession->state_ = SessionState::STATE_INACTIVE;
369 ssm_->ProcessSubSessionBackground(sceneSession);
370 }
371
372 /**
373 * @tc.name: DestroyDialogWithMainWindow
374 * @tc.desc: DestroyDialogWithMainWindow
375 * @tc.type: FUNC
376 */
377 HWTEST_F(SSMgrSpecificWindowTest, DestroyDialogWithMainWindow, Function | SmallTest | Level3)
378 {
379 sptr<SceneSession> sceneSession = nullptr;
380 auto result = ssm_->DestroyDialogWithMainWindow(sceneSession);
381 ASSERT_EQ(result, WSError::WS_ERROR_NULLPTR);
382
383 SessionInfo info;
384 sptr<SceneSession::SpecificSessionCallback> specificCallback = nullptr;
385 sceneSession = sptr<SceneSession>::MakeSptr(info, specificCallback);
386 ASSERT_NE(sceneSession, nullptr);
387
388 sptr<Session> session = sptr<Session>::MakeSptr(info);
389 ASSERT_NE(session, nullptr);
390 session->GetDialogVector().clear();
391 result = ssm_->DestroyDialogWithMainWindow(sceneSession);
392 ASSERT_EQ(result, WSError::WS_OK);
393
394 ssm_->sceneSessionMap_.insert({0, sceneSession});
395 ssm_->GetSceneSession(1);
396 result = ssm_->DestroyDialogWithMainWindow(sceneSession);
397 ASSERT_EQ(result, WSError::WS_OK);
398 }
399
400 /**
401 * @tc.name: DestroyDialogWithMainWindow02
402 * @tc.desc: DestroyDialogWithMainWindow02
403 * @tc.type: FUNC
404 */
405 HWTEST_F(SSMgrSpecificWindowTest, DestroyDialogWithMainWindow02, Function | SmallTest | Level3)
406 {
407 SessionInfo info;
408 sptr<SceneSession::SpecificSessionCallback> specificCallback = nullptr;
409 sptr<SceneSession> sceneSession = sptr<SceneSession>::MakeSptr(info, specificCallback);
410 ASSERT_NE(sceneSession, nullptr);
411
412 sptr<Session> dialogSession1 = sptr<Session>::MakeSptr(info);
413 sptr<Session> dialogSession2 = sptr<Session>::MakeSptr(info);
414 ASSERT_NE(dialogSession1, nullptr);
415 ASSERT_NE(dialogSession2, nullptr);
416 dialogSession1->persistentId_ = 0;
417 dialogSession2->persistentId_ = 1;
418 sceneSession->dialogVec_.push_back(dialogSession1);
419 sceneSession->dialogVec_.push_back(dialogSession2);
420
421 ASSERT_NE(ssm_, nullptr);
422 ssm_->sceneSessionMap_.clear();
423 ssm_->sceneSessionMap_.insert({0, nullptr});
424 ssm_->sceneSessionMap_.insert({0, sceneSession});
425
426 auto ret = ssm_->DestroyDialogWithMainWindow(sceneSession);
427 ASSERT_EQ(ret, WSError::WS_ERROR_INVALID_SESSION);
428 ssm_->sceneSessionMap_.clear();
429 }
430
431 /**
432 * @tc.name: ConfigKeyboardAnimation
433 * @tc.desc: SceneSesionManager config keyboard animation
434 * @tc.type: FUNC
435 */
436 HWTEST_F(SSMgrSpecificWindowTest, ConfigKeyboardAnimation, Function | SmallTest | Level3)
437 {
438 WindowSceneConfig::ConfigItem animationConfig;
439 WindowSceneConfig::ConfigItem itemCurve;
440 WindowSceneConfig::ConfigItem itemDuration;
441 // prepare ItemName
442 WindowSceneConfig::ConfigItem nameProp;
443 std::string name = "cubic";
444 nameProp.SetValue(name);
445 itemCurve.SetProperty({{ "name", nameProp}});
446
447 // prepare duration
448 std::vector<int> durationVec = {39};
449 itemDuration.SetValue(durationVec);
450
451 // prepare timing
452 WindowSceneConfig::ConfigItem timing;
453 WindowSceneConfig::ConfigItem timingObj;
454 timingObj.SetValue({{ "curve", itemCurve }, { "duration", itemDuration}});
455 timing.SetValue({{ "timing", timingObj }});
456
457 WindowSceneConfig::ConfigItem timing2(timing);
458 // prepare animationConfig
459 animationConfig.SetValue({{ "animationIn", timing }, { "animationOut", timing2 }});
460
461 ssm_->ConfigKeyboardAnimation(animationConfig);
462 ASSERT_EQ(ssm_->systemConfig_.animationIn_.curveType_, "cubic");
463 ASSERT_EQ(ssm_->systemConfig_.animationIn_.duration_, durationVec.at(0));
464
465 uint32_t result = 150;
466 KeyboardSceneAnimationConfig animationIn;
467 KeyboardSceneAnimationConfig animationOut;
468 ssm_->ConfigDefaultKeyboardAnimation(animationIn, animationOut);
469 ASSERT_EQ(animationIn.duration_, result);
470 }
471
472 /**
473 * @tc.name: UpdateParentSessionForDialog
474 * @tc.desc: SceneSesionManager UpdateParentSessionForDialog
475 * @tc.type: FUNC
476 */
477 HWTEST_F(SSMgrSpecificWindowTest, UpdateParentSessionForDialog, Function | SmallTest | Level3)
478 {
479 WSError result = ssm_->UpdateParentSessionForDialog(nullptr, nullptr);
480 EXPECT_EQ(result, WSError::WS_ERROR_NULLPTR);
481
482 sptr<WindowSessionProperty> property = sptr<WindowSessionProperty>::MakeSptr();
483 ASSERT_NE(nullptr, property);
484 result = ssm_->UpdateParentSessionForDialog(nullptr, property);
485 EXPECT_EQ(result, WSError::WS_ERROR_NULLPTR);
486
487 SessionInfo info;
488 info.abilityName_ = "test1";
489 info.bundleName_ = "test2";
490 info.moduleName_ = "test3";
491 info.appIndex_ = 10;
492 sptr<SceneSession> sceneSession = sptr<SceneSession>::MakeSptr(info, nullptr);
493 ASSERT_NE(nullptr, sceneSession);
494 result = ssm_->UpdateParentSessionForDialog(sceneSession, property);
495 EXPECT_EQ(result, WSError::WS_OK);
496
497 property->SetWindowType(WindowType::WINDOW_TYPE_DIALOG);
498 result = ssm_->UpdateParentSessionForDialog(sceneSession, property);
499 EXPECT_EQ(result, WSError::WS_OK);
500
501 SessionInfo info1;
502 info1.abilityName_ = "test2";
503 info1.bundleName_ = "test3";
504 sptr<SceneSession> sceneSession2 = sptr<SceneSession>::MakeSptr(info1, nullptr);
505 ASSERT_NE(nullptr, sceneSession2);
506 ssm_->sceneSessionMap_.insert({2, sceneSession2});
507 property->SetParentPersistentId(2);
508 result = ssm_->UpdateParentSessionForDialog(sceneSession, property);
509 EXPECT_EQ(result, WSError::WS_OK);
510 }
511
512 /**
513 * @tc.name: DestroyAndDisconnectSpecificSession
514 * @tc.desc: SceneSesionManager destroy and disconnect specific session
515 * @tc.type: FUNC
516 */
517 HWTEST_F(SSMgrSpecificWindowTest, DestroyAndDisconnectSpecificSession, Function | SmallTest | Level3)
518 {
519 int32_t persistentId = 0;
520 WSError result = ssm_->DestroyAndDisconnectSpecificSession(persistentId);
521 ASSERT_EQ(result, WSError::WS_ERROR_NULLPTR);
522 }
523
524 /**
525 * @tc.name: DestroyAndDisconnectSpecificSessionWithDetachCallback
526 * @tc.desc: SceneSesionManager destroy and disconnect specific session with detach callback
527 * @tc.type: FUNC
528 */
529 HWTEST_F(SSMgrSpecificWindowTest,
530 DestroyAndDisconnectSpecificSessionWithDetachCallback,
531 Function | SmallTest | Level3)
532 {
533 int32_t persistentId = 0;
534 WSError result = ssm_->DestroyAndDisconnectSpecificSessionWithDetachCallback(persistentId, nullptr);
535 ASSERT_EQ(result, WSError::WS_ERROR_NULLPTR);
536 }
537 }
538 } // namespace Rosen
539 } // namespace OHOS
540