1 /*
2 * Copyright (c) 2023 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 "session_manager/include/scene_session_manager.h"
17
18 #include <cinttypes>
19 #include <csignal>
20 #include <cstdint>
21 #include <iomanip>
22 #include <map>
23 #include <memory>
24 #include <sstream>
25 #include <unistd.h>
26
27 #include <ability_context.h>
28 #include <ability_info.h>
29 #include <ability_manager_client.h>
30 #include <bundle_mgr_interface.h>
31 #include <ipc_skeleton.h>
32 #include <iservice_registry.h>
33 #include <hisysevent.h>
34 #include <parameters.h>
35 #include "parameter.h"
36 #include <pointer_event.h>
37 #include <resource_manager.h>
38 #include <running_lock.h>
39 #include <session_info.h>
40 #include <start_options.h>
41 #include <system_ability_definition.h>
42 #include <want.h>
43 #include <hitrace_meter.h>
44 #include <transaction/rs_interfaces.h>
45 #include <transaction/rs_transaction.h>
46 #include "transaction/rs_sync_transaction_controller.h"
47
48 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
49 #include <display_power_mgr_client.h>
50 #endif
51
52 #ifdef POWER_MANAGER_ENABLE
53 #include <power_mgr_client.h>
54 #endif
55
56 #ifdef RES_SCHED_ENABLE
57 #include "res_type.h"
58 #include "res_sched_client.h"
59 #endif
60
61 #include "ability_start_setting.h"
62 #include "anr_manager.h"
63 #include "color_parser.h"
64 #include "common/include/session_permission.h"
65 #include "display_manager.h"
66 #include "image_source.h"
67 #include "interfaces/include/ws_common.h"
68 #include "interfaces/include/ws_common_inner.h"
69 #include "scene_input_manager.h"
70 #include "session/host/include/main_session.h"
71 #include "session/host/include/scb_system_session.h"
72 #include "session/host/include/scene_persistent_storage.h"
73 #include "session/host/include/session_utils.h"
74 #include "session/host/include/sub_session.h"
75 #include "session/host/include/system_session.h"
76 #include "session_helper.h"
77 #include "window_helper.h"
78 #include "session/screen/include/screen_session.h"
79 #include "screen_session_manager/include/screen_session_manager_client.h"
80 #include "singleton_container.h"
81 #include "window_manager_hilog.h"
82 #include "wm_common.h"
83 #include "wm_math.h"
84 #include "xcollie/watchdog.h"
85 #include "zidl/window_manager_agent_interface.h"
86 #include "session_manager_agent_controller.h"
87 #include "distributed_client.h"
88 #include "softbus_bus_center.h"
89 #include "window_manager.h"
90 #include "perform_reporter.h"
91 #include "pip_util.h"
92 #include "focus_change_info.h"
93 #include "anr_manager.h"
94
95 #include "window_visibility_info.h"
96 #include "window_drawing_content_info.h"
97 #ifdef MEMMGR_WINDOW_ENABLE
98 #include "mem_mgr_client.h"
99 #include "mem_mgr_window_info.h"
100 #endif
101
102 #ifdef EFFICIENCY_MANAGER_ENABLE
103 #include "suspend_manager_client.h"
104 #endif // EFFICIENCY_MANAGER_ENABLE
105
106 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
107 #include "sec_comp_enhance_kit.h"
108 #endif
109
110 #ifdef IMF_ENABLE
111 #include <input_method_controller.h>
112 #endif // IMF_ENABLE
113
114 namespace OHOS::Rosen {
115 namespace {
116 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSessionManager" };
117 #ifdef RES_SCHED_ENABLE
118 const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
119 #endif
120 const std::string SCENE_SESSION_MANAGER_THREAD = "OS_SceneSessionManager";
121 const std::string WINDOW_INFO_REPORT_THREAD = "OS_WindowInfoReportThread";
122 constexpr const char* PREPARE_TERMINATE_ENABLE_PARAMETER = "persist.sys.prepare_terminate";
123 std::recursive_mutex g_instanceMutex;
124 constexpr uint32_t MAX_BRIGHTNESS = 255;
125 constexpr int32_t PREPARE_TERMINATE_ENABLE_SIZE = 6;
126 constexpr int32_t DEFAULT_USERID = -1;
127 constexpr int32_t SCALE_DIMENSION = 2;
128 constexpr int32_t TRANSLATE_DIMENSION = 2;
129 constexpr int32_t ROTAION_DIMENSION = 4;
130 constexpr int32_t CURVE_PARAM_DIMENSION = 4;
131 const std::string DM_PKG_NAME = "ohos.distributedhardware.devicemanager";
132 constexpr int32_t NON_ANONYMIZE_LENGTH = 6;
133 const std::string EMPTY_DEVICE_ID = "";
134 const int32_t MAX_NUMBER_OF_DISTRIBUTED_SESSIONS = 20;
135
136 constexpr int WINDOW_NAME_MAX_WIDTH = 21;
137 constexpr int DISPLAY_NAME_MAX_WIDTH = 10;
138 constexpr int VALUE_MAX_WIDTH = 5;
139 constexpr int ORIEN_MAX_WIDTH = 12;
140 constexpr int OFFSET_MAX_WIDTH = 8;
141 constexpr int PID_MAX_WIDTH = 8;
142 constexpr int PARENT_ID_MAX_WIDTH = 6;
143 constexpr int SCALE_MAX_WIDTH = 8;
144 constexpr int WINDOW_NAME_MAX_LENGTH = 20;
145 constexpr int32_t STATUS_BAR_AVOID_AREA = 0;
146 const std::string ARG_DUMP_ALL = "-a";
147 const std::string ARG_DUMP_WINDOW = "-w";
148 const std::string ARG_DUMP_SCREEN = "-s";
149 const std::string ARG_DUMP_DISPLAY = "-d";
150 constexpr uint64_t NANO_SECOND_PER_SEC = 1000000000; // ns
GetCurrentTime()151 std::string GetCurrentTime()
152 {
153 struct timespec tn;
154 clock_gettime(CLOCK_REALTIME, &tn);
155 uint64_t uTime = static_cast<uint64_t>(tn.tv_sec) * NANO_SECOND_PER_SEC +
156 static_cast<uint64_t>(tn.tv_nsec);
157 return std::to_string(uTime);
158 }
Comp(const std::pair<uint64_t,WindowVisibilityState> & a,const std::pair<uint64_t,WindowVisibilityState> & b)159 int Comp(const std::pair<uint64_t, WindowVisibilityState> &a, const std::pair<uint64_t, WindowVisibilityState> &b)
160 {
161 return a.first < b.first;
162 }
163 } // namespace
164
GetInstance()165 SceneSessionManager& SceneSessionManager::GetInstance()
166 {
167 std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
168 static SceneSessionManager* instance = nullptr;
169 if (instance == nullptr) {
170 instance = new SceneSessionManager();
171 instance->Init();
172 }
173 return *instance;
174 }
175
SceneSessionManager()176 SceneSessionManager::SceneSessionManager() : rsInterface_(RSInterfaces::GetInstance())
177 {
178 taskScheduler_ = std::make_shared<TaskScheduler>(SCENE_SESSION_MANAGER_THREAD);
179 currentUserId_ = DEFAULT_USERID;
180 }
181
Init()182 void SceneSessionManager::Init()
183 {
184 constexpr uint64_t interval = 5 * 1000; // 5 second
185 auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
186 auto mainEventHandler = std::make_shared<AppExecFwk::EventHandler>(mainEventRunner);
187 if (HiviewDFX::Watchdog::GetInstance().AddThread("MainThread", mainEventHandler, interval)) {
188 WLOGFW("Add thread MainThread to watchdog failed.");
189 }
190 if (HiviewDFX::Watchdog::GetInstance().AddThread(
191 SCENE_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
192 WLOGFW("Add thread %{public}s to watchdog failed.", SCENE_SESSION_MANAGER_THREAD.c_str());
193 }
194
195 InitScheduleUtils();
196
197 bundleMgr_ = GetBundleManager();
198 LoadWindowSceneXml();
199 sptr<IDisplayChangeListener> listener = new DisplayChangeListener();
200 ScreenSessionManagerClient::GetInstance().RegisterDisplayChangeListener(listener);
201 InitPrepareTerminateConfig();
202
203 // create handler for inner command at server
204 eventLoop_ = AppExecFwk::EventRunner::Create(WINDOW_INFO_REPORT_THREAD);
205 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
206 if (eventHandler_ == nullptr) {
207 WLOGFE("Invalid eventHander");
208 return ;
209 }
210 int ret = HiviewDFX::Watchdog::GetInstance().AddThread(WINDOW_INFO_REPORT_THREAD, eventHandler_);
211 if (ret != 0) {
212 WLOGFW("Add thread %{public}s to watchdog failed.", WINDOW_INFO_REPORT_THREAD.c_str());
213 }
214
215 listenerController_ = std::make_shared<SessionListenerController>();
216 listenerController_->Init();
217 scbSessionHandler_ = new ScbSessionHandler();
218 AAFwk::AbilityManagerClient::GetInstance()->RegisterSessionHandler(scbSessionHandler_);
219 StartWindowInfoReportLoop();
220 WLOGI("SceneSessionManager init success.");
221 RegisterAppListener();
222 openDebugTrace = std::atoi((system::GetParameter("persist.sys.graphic.openDebugTrace", "0")).c_str()) != 0;
223 }
224
InitScheduleUtils()225 void SceneSessionManager::InitScheduleUtils()
226 {
227 #ifdef RES_SCHED_ENABLE
228 std::unordered_map<std::string, std::string> payload {
229 { "pid", std::to_string(getprocpid()) },
230 { "tid", std::to_string(getproctid()) },
231 { "uid", std::to_string(getuid()) },
232 { "bundleName", SCENE_BOARD_BUNDLE_NAME },
233 };
234 uint32_t type = OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_SCENE_BOARD;
235 int64_t value = 0;
236 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, value, payload);
237 auto task = []() {
238 std::unordered_map<std::string, std::string> payload{
239 {"pid", std::to_string(getpid())},
240 {"tid", std::to_string(gettid())},
241 {"uid", std::to_string(getuid())},
242 {"bundleName", SCENE_BOARD_BUNDLE_NAME},
243 };
244 uint32_t type = OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_SCENE_BOARD;
245 int64_t value = 0;
246 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, value, payload);
247 WLOGFI("[WMSLife] set qos success");
248 };
249 taskScheduler_->PostAsyncTask(task, "changeQosTask");
250 #endif
251 }
252
RegisterAppListener()253 void SceneSessionManager::RegisterAppListener()
254 {
255 appAnrListener_ = new (std::nothrow) AppAnrListener();
256 auto appMgrClient_ = DelayedSingleton<AppExecFwk::AppMgrClient>::GetInstance();
257 if (appMgrClient_ == nullptr) {
258 WLOGFE("appMgrClient_ is nullptr.");
259 } else {
260 auto flag = static_cast<int32_t>(appMgrClient_->RegisterAppDebugListener(appAnrListener_));
261 if (flag != ERR_OK) {
262 WLOGFE("Register app debug listener failed.");
263 } else {
264 WLOGFI("Register app debug listener success.");
265 }
266 }
267 }
268
LoadWindowSceneXml()269 void SceneSessionManager::LoadWindowSceneXml()
270 {
271 if (WindowSceneConfig::LoadConfigXml()) {
272 if (WindowSceneConfig::GetConfig().IsMap()) {
273 WindowSceneConfig::DumpConfig(*WindowSceneConfig::GetConfig().mapValue_);
274 }
275 ConfigWindowSceneXml();
276 } else {
277 WLOGFE("Load window scene xml failed");
278 }
279 ConfigDefaultKeyboardAnimation();
280 }
281
InitPrepareTerminateConfig()282 void SceneSessionManager::InitPrepareTerminateConfig()
283 {
284 char value[PREPARE_TERMINATE_ENABLE_SIZE] = "false";
285 int32_t retSysParam = GetParameter(PREPARE_TERMINATE_ENABLE_PARAMETER, "false", value,
286 PREPARE_TERMINATE_ENABLE_SIZE);
287 WLOGFI("InitPrepareTerminateConfig, %{public}s value is %{public}s.", PREPARE_TERMINATE_ENABLE_PARAMETER, value);
288 if (retSysParam > 0 && !std::strcmp(value, "true")) {
289 isPrepareTerminateEnable_ = true;
290 }
291 }
292
ConfigWindowSceneXml()293 void SceneSessionManager::ConfigWindowSceneXml()
294 {
295 const auto& config = WindowSceneConfig::GetConfig();
296 WindowSceneConfig::ConfigItem item = config["windowEffect"];
297 if (item.IsMap()) {
298 ConfigWindowEffect(item);
299 }
300
301 item = config["decor"];
302 if (item.IsMap()) {
303 ConfigDecor(item);
304 }
305
306 item = config["backgroundswitch"];
307 if (item.IsInts()) {
308 auto numbers = *item.intsValue_;
309 if (numbers.size() == 1 && numbers[0] == 1) {
310 systemConfig_.backgroundswitch = true;
311 }
312 }
313 WLOGFD("Load ConfigWindowSceneXml backgroundswitch%{public}d", systemConfig_.backgroundswitch);
314
315 item = config["defaultWindowMode"];
316 if (item.IsInts()) {
317 auto numbers = *item.intsValue_;
318 if (numbers.size() == 1 &&
319 (numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
320 numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
321 systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(numbers[0]));
322 }
323 }
324
325 item = config["defaultMaximizeMode"];
326 if (item.IsInts()) {
327 auto numbers = *item.intsValue_;
328 if (numbers.size() == 1 &&
329 (numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
330 numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL))) {
331 SceneSession::maximizeMode_ = static_cast<MaximizeMode>(numbers[0]);
332 }
333 }
334
335 item = config["keyboardAnimation"];
336 if (item.IsMap()) {
337 ConfigKeyboardAnimation(item);
338 }
339
340 item = config["maxFloatingWindowSize"];
341 if (item.IsInts()) {
342 auto numbers = *item.intsValue_;
343 if (numbers.size() == 1) {
344 systemConfig_.maxFloatingWindowSize_ = static_cast<uint32_t>(numbers[0]);
345 }
346 }
347
348 item = config["windowAnimation"];
349 if (item.IsMap()) {
350 ConfigWindowAnimation(item);
351 }
352
353 item = config["startWindowTransitionAnimation"];
354 if (item.IsMap()) {
355 ConfigStartingWindowAnimation(item);
356 }
357
358 ConfigWindowSizeLimits();
359 ConfigSnapshotScale();
360 }
361
SetSessionContinueState(const sptr<IRemoteObject> & token,const ContinueState & continueState)362 WSError SceneSessionManager::SetSessionContinueState(const sptr<IRemoteObject> &token,
363 const ContinueState& continueState)
364 {
365 WLOGFI("run SetSessionContinueState");
366 auto task = [this, token, continueState]() {
367 sptr <SceneSession> sceneSession = FindSessionByToken(token);
368 if (sceneSession == nullptr) {
369 WLOGFI("fail to find session by token.");
370 return WSError::WS_ERROR_INVALID_PARAM;
371 }
372 sceneSession->SetSessionInfoContinueState(continueState);
373 DistributedClient dmsClient;
374 dmsClient.SetMissionContinueState(sceneSession->GetPersistentId(),
375 static_cast<AAFwk::ContinueState>(continueState));
376 WLOGFI("SetSessionContinueState sessionId:%{public}d, continueState:%{public}d",
377 sceneSession->GetPersistentId(), continueState);
378 return WSError::WS_OK;
379 };
380 return taskScheduler_->PostSyncTask(task, "SetSessionContinueState");
381 }
382
ConfigDecor(const WindowSceneConfig::ConfigItem & decorConfig)383 void SceneSessionManager::ConfigDecor(const WindowSceneConfig::ConfigItem& decorConfig)
384 {
385 WindowSceneConfig::ConfigItem item = decorConfig.GetProp("enable");
386 if (item.IsBool()) {
387 systemConfig_.isSystemDecorEnable_ = item.boolValue_;
388 std::vector<std::string> supportedModes;
389 item = decorConfig["supportedMode"];
390 if (item.IsStrings()) {
391 systemConfig_.decorModeSupportInfo_ = 0;
392 supportedModes = *item.stringsValue_;
393 }
394 for (auto mode : supportedModes) {
395 if (mode == "fullscreen") {
396 systemConfig_.decorModeSupportInfo_ |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN;
397 } else if (mode == "floating") {
398 systemConfig_.decorModeSupportInfo_ |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING;
399 } else if (mode == "pip") {
400 systemConfig_.decorModeSupportInfo_ |= WindowModeSupport::WINDOW_MODE_SUPPORT_PIP;
401 } else if (mode == "split") {
402 systemConfig_.decorModeSupportInfo_ |= WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
403 WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY;
404 } else {
405 WLOGFW("Invalid supporedMode");
406 systemConfig_.decorModeSupportInfo_ = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
407 break;
408 }
409 }
410 }
411 }
412
AddAlphaToColor(float alpha,std::string & color)413 static void AddAlphaToColor(float alpha, std::string& color)
414 {
415 if (color.size() == 9 || alpha > 1.0f) { // size 9: color is ARGB
416 return;
417 }
418
419 uint32_t alphaValue = 0xFF * alpha;
420 std::stringstream ss;
421 ss << std::hex << alphaValue;
422 std::string strAlpha = ss.str();
423 if (strAlpha.size() == 1) {
424 strAlpha.append(1, '0');
425 }
426
427 color.insert(1, strAlpha);
428 }
429
ConfigWindowEffect(const WindowSceneConfig::ConfigItem & effectConfig)430 void SceneSessionManager::ConfigWindowEffect(const WindowSceneConfig::ConfigItem& effectConfig)
431 {
432 AppWindowSceneConfig config;
433 // config corner radius
434 WindowSceneConfig::ConfigItem item = effectConfig["appWindows"]["cornerRadius"];
435 if (item.IsMap()) {
436 if (ConfigAppWindowCornerRadius(item["float"], config.floatCornerRadius_)) {
437 appWindowSceneConfig_ = config;
438 }
439 }
440
441 // config shadow
442 item = effectConfig["appWindows"]["shadow"]["focused"];
443 if (item.IsMap()) {
444 if (ConfigAppWindowShadow(item, config.focusedShadow_)) {
445 appWindowSceneConfig_.focusedShadow_ = config.focusedShadow_;
446 }
447 }
448
449 item = effectConfig["appWindows"]["shadow"]["unfocused"];
450 if (item.IsMap()) {
451 if (ConfigAppWindowShadow(item, config.unfocusedShadow_)) {
452 appWindowSceneConfig_.unfocusedShadow_ = config.unfocusedShadow_;
453 }
454 }
455
456 AddAlphaToColor(appWindowSceneConfig_.focusedShadow_.alpha_, appWindowSceneConfig_.focusedShadow_.color_);
457 AddAlphaToColor(appWindowSceneConfig_.unfocusedShadow_.alpha_, appWindowSceneConfig_.unfocusedShadow_.color_);
458
459 WLOGFI("Config window effect successfully");
460 }
461
ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem & item,float & out)462 bool SceneSessionManager::ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem& item, float& out)
463 {
464 std::map<std::string, float> stringToCornerRadius = {
465 {"off", 0.0f}, {"defaultCornerRadiusXS", 4.0f}, {"defaultCornerRadiusS", 8.0f},
466 {"defaultCornerRadiusM", 12.0f}, {"defaultCornerRadiusL", 16.0f}, {"defaultCornerRadiusXL", 24.0f}
467 };
468
469 if (item.IsString()) {
470 auto value = item.stringValue_;
471 if (stringToCornerRadius.find(value) != stringToCornerRadius.end()) {
472 out = stringToCornerRadius[value];
473 return true;
474 }
475 }
476 return false;
477 }
478
SetEnableInputEvent(bool enabled)479 void SceneSessionManager::SetEnableInputEvent(bool enabled)
480 {
481 WLOGFI("[WMSRecover] Set enable input event: %{public}u", enabled);
482 enableInputEvent_ = enabled;
483 }
484
IsInputEventEnabled()485 bool SceneSessionManager::IsInputEventEnabled()
486 {
487 return enableInputEvent_;
488 }
489
UpdateRecoveredSessionInfo(const std::vector<int32_t> & recoveredPersistentIds)490 void SceneSessionManager::UpdateRecoveredSessionInfo(const std::vector<int32_t>& recoveredPersistentIds)
491 {
492 WLOGFI("[WMSRecover] Number of persistentIds recovered = %{public}zu. CurrentUserId = "
493 "%{public}d",
494 recoveredPersistentIds.size(), currentUserId_);
495 std::vector<AAFwk::SessionInfo> abilitySessionInfos;
496
497 for (auto i = 0; i < static_cast<int32_t>(recoveredPersistentIds.size()); i++) {
498 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
499 auto search = sceneSessionMap_.find(recoveredPersistentIds.at(i));
500 if (search == sceneSessionMap_.end() || search->second == nullptr) {
501 continue;
502 }
503 WLOGFD("[WMSRecover] recovered persistentId = %{public}d", search->first);
504 auto sceneSession = search->second;
505 const auto& abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
506 if (!abilitySessionInfo) {
507 WLOGFW("[WMSRecover] abilitySessionInfo is null");
508 return;
509 }
510 abilitySessionInfos.emplace_back(*abilitySessionInfo);
511 }
512 auto task = [abilitySessionInfos]() {
513 AAFwk::AbilityManagerClient::GetInstance()->UpdateSessionInfoBySCB(
514 abilitySessionInfos, SceneSessionManager::GetInstance().GetCurrentUserId());
515 };
516 return taskScheduler_->PostAsyncTask(task, "UpdateSessionInfoBySCB");
517 }
518
ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem & shadowConfig,WindowShadowConfig & outShadow)519 bool SceneSessionManager::ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem& shadowConfig,
520 WindowShadowConfig& outShadow)
521 {
522 WindowSceneConfig::ConfigItem item = shadowConfig["color"];
523 if (item.IsString()) {
524 auto color = item.stringValue_;
525 uint32_t colorValue;
526 if (!ColorParser::Parse(color, colorValue)) {
527 return false;
528 }
529 outShadow.color_ = color;
530 }
531
532 item = shadowConfig["offsetX"];
533 if (item.IsFloats()) {
534 auto offsetX = *item.floatsValue_;
535 if (offsetX.size() != 1) {
536 return false;
537 }
538 outShadow.offsetX_ = offsetX[0];
539 }
540
541 item = shadowConfig["offsetY"];
542 if (item.IsFloats()) {
543 auto offsetY = *item.floatsValue_;
544 if (offsetY.size() != 1) {
545 return false;
546 }
547 outShadow.offsetY_ = offsetY[0];
548 }
549
550 item = shadowConfig["alpha"];
551 if (item.IsFloats()) {
552 auto alpha = *item.floatsValue_;
553 if (alpha.size() != 1 ||
554 (MathHelper::LessNotEqual(alpha[0], 0.0) && MathHelper::GreatNotEqual(alpha[0], 1.0))) {
555 return false;
556 }
557 outShadow.alpha_ = alpha[0];
558 }
559
560 item = shadowConfig["radius"];
561 if (item.IsFloats()) {
562 auto radius = *item.floatsValue_;
563 if (radius.size() != 1 || MathHelper::LessNotEqual(radius[0], 0.0)) {
564 return false;
565 }
566 outShadow.radius_ = radius[0];
567 }
568
569 return true;
570 }
571
ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem & animationConfig)572 void SceneSessionManager::ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem& animationConfig)
573 {
574 LoadKeyboardAnimation(animationConfig["animationIn"]["timing"], appWindowSceneConfig_.keyboardAnimationIn_);
575 LoadKeyboardAnimation(animationConfig["animationOut"]["timing"], appWindowSceneConfig_.keyboardAnimationOut_);
576
577 const auto& defaultAnimation = appWindowSceneConfig_.keyboardAnimationIn_;
578 systemConfig_.keyboardAnimationConfig_.curveType_ = defaultAnimation.curveType_;
579 systemConfig_.keyboardAnimationConfig_.curveParams_.assign({
580 defaultAnimation.ctrlX1_,
581 defaultAnimation.ctrlY1_,
582 defaultAnimation.ctrlX2_,
583 defaultAnimation.ctrlY2_,
584 });
585 systemConfig_.keyboardAnimationConfig_.durationIn_ = appWindowSceneConfig_.keyboardAnimationIn_.duration_;
586 systemConfig_.keyboardAnimationConfig_.durationOut_ = appWindowSceneConfig_.keyboardAnimationOut_.duration_;
587 }
588
LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem & item,KeyboardSceneAnimationConfig & config)589 void SceneSessionManager::LoadKeyboardAnimation(const WindowSceneConfig::ConfigItem& item,
590 KeyboardSceneAnimationConfig& config)
591 {
592 if (item.IsMap() && item.mapValue_->count("curve")) {
593 const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
594 config.curveType_ = curveType;
595 if (curveParams.size() == CURVE_PARAM_DIMENSION) {
596 config.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
597 config.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
598 config.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
599 config.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
600 }
601 }
602
603 const WindowSceneConfig::ConfigItem& duration = item["duration"];
604 if (duration.IsInts()) {
605 auto numbers = *duration.intsValue_;
606 if (numbers.size() == 1) {
607 config.duration_ = static_cast<uint32_t>(numbers[0]);
608 }
609 }
610 }
611
ConfigDefaultKeyboardAnimation()612 void SceneSessionManager::ConfigDefaultKeyboardAnimation()
613 {
614 constexpr char CURVETYPE[] = "interpolatingSpring";
615 constexpr float CTRLX1 = 0;
616 constexpr float CTRLY1 = 1;
617 constexpr float CTRLX2 = 342;
618 constexpr float CTRLY2 = 37;
619 constexpr uint32_t DURATION = 150;
620
621 if (!systemConfig_.keyboardAnimationConfig_.curveType_.empty()) {
622 return;
623 }
624
625 systemConfig_.keyboardAnimationConfig_.curveType_ = CURVETYPE;
626 std::vector<float> keyboardCurveParams = {CTRLX1, CTRLY1, CTRLX2, CTRLY2};
627 systemConfig_.keyboardAnimationConfig_.curveParams_.assign(
628 keyboardCurveParams.begin(), keyboardCurveParams.end());;
629 systemConfig_.keyboardAnimationConfig_.durationIn_ = DURATION;
630 systemConfig_.keyboardAnimationConfig_.durationOut_ = DURATION;
631 }
632
ConfigWindowAnimation(const WindowSceneConfig::ConfigItem & windowAnimationConfig)633 void SceneSessionManager::ConfigWindowAnimation(const WindowSceneConfig::ConfigItem& windowAnimationConfig)
634 {
635 WindowSceneConfig::ConfigItem item = windowAnimationConfig["timing"];
636 if (item.IsMap() && item.mapValue_->count("curve")) {
637 const auto& [curveType, curveParams] = CreateCurve(item["curve"]);
638 appWindowSceneConfig_.windowAnimation_.curveType_ = curveType;
639 if (curveParams.size() == CURVE_PARAM_DIMENSION) {
640 appWindowSceneConfig_.windowAnimation_.ctrlX1_ = curveParams[0]; // 0: ctrl x1 index
641 appWindowSceneConfig_.windowAnimation_.ctrlY1_ = curveParams[1]; // 1: ctrl y1 index
642 appWindowSceneConfig_.windowAnimation_.ctrlX2_ = curveParams[2]; // 2: ctrl x2 index
643 appWindowSceneConfig_.windowAnimation_.ctrlY2_ = curveParams[3]; // 3: ctrl y2 index
644 }
645 }
646 item = windowAnimationConfig["timing"]["duration"];
647 if (item.IsInts() && item.intsValue_->size() == 1) {
648 auto duration = *item.intsValue_;
649 appWindowSceneConfig_.windowAnimation_.duration_ = duration[0];
650 }
651 item = windowAnimationConfig["scale"];
652 if (item.IsFloats() && item.floatsValue_->size() == SCALE_DIMENSION) {
653 auto scales = *item.floatsValue_;
654 appWindowSceneConfig_.windowAnimation_.scaleX_ = scales[0];
655 appWindowSceneConfig_.windowAnimation_.scaleY_ = scales[1];
656 }
657 item = windowAnimationConfig["rotation"];
658 if (item.IsFloats() && item.floatsValue_->size() == ROTAION_DIMENSION) {
659 auto rotations = *item.floatsValue_;
660 appWindowSceneConfig_.windowAnimation_.rotationX_ = rotations[0]; // 0 ctrlX1
661 appWindowSceneConfig_.windowAnimation_.rotationY_ = rotations[1]; // 1 ctrlY1
662 appWindowSceneConfig_.windowAnimation_.rotationZ_ = rotations[2]; // 2 ctrlX2
663 appWindowSceneConfig_.windowAnimation_.angle_ = rotations[3]; // 3 ctrlY2
664 }
665 item = windowAnimationConfig["translate"];
666 if (item.IsFloats() && item.floatsValue_->size() == TRANSLATE_DIMENSION) {
667 auto translates = *item.floatsValue_;
668 appWindowSceneConfig_.windowAnimation_.translateX_ = translates[0];
669 appWindowSceneConfig_.windowAnimation_.translateY_ = translates[1];
670 }
671 item = windowAnimationConfig["opacity"];
672 if (item.IsFloats() && item.floatsValue_->size() == 1) {
673 auto opacity = *item.floatsValue_;
674 appWindowSceneConfig_.windowAnimation_.opacity_ = opacity[0];
675 }
676 }
677
ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem & configItem)678 void SceneSessionManager::ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem& configItem)
679 {
680 auto& config = appWindowSceneConfig_.startingWindowAnimationConfig_;
681 auto item = configItem.GetProp("enable");
682 if (item.IsBool()) {
683 config.enabled_ = item.boolValue_;
684 }
685 item = configItem["timing"];
686 if (item.IsMap() && item.mapValue_->count("curve")) {
687 config.curve_ = std::get<std::string>(CreateCurve(item["curve"]));
688 }
689 item = configItem["timing"]["duration"];
690 if (item.IsInts() && item.intsValue_->size() == 1) {
691 config.duration_ = (*item.intsValue_)[0];
692 }
693 item = configItem["opacityStart"];
694 if (item.IsFloats() && item.floatsValue_->size() == 1) {
695 config.opacityStart_ = (*item.floatsValue_)[0];
696 }
697 item = configItem["opacityEnd"];
698 if (item.IsFloats() && item.floatsValue_->size() == 1) {
699 config.opacityEnd_ = (*item.floatsValue_)[0];
700 }
701 }
702
CreateCurve(const WindowSceneConfig::ConfigItem & curveConfig)703 std::tuple<std::string, std::vector<float>> SceneSessionManager::CreateCurve(
704 const WindowSceneConfig::ConfigItem& curveConfig)
705 {
706 static std::unordered_set<std::string> curveSet = { "easeOut", "ease", "easeIn", "easeInOut", "default",
707 "linear", "spring", "interactiveSpring", "interpolatingSpring" };
708 static std::unordered_set<std::string> paramCurveSet = {
709 "spring", "interactiveSpring", "interpolatingSpring", "cubic" };
710
711 std::string curveName = "easeOut";
712 const auto& nameItem = curveConfig.GetProp("name");
713 if (!nameItem.IsString()) {
714 return {curveName, {}};
715 }
716
717 std::string name = nameItem.stringValue_;
718 std::vector<float> curveParams;
719
720 if (paramCurveSet.find(name) != paramCurveSet.end()) {
721 curveName = name;
722 curveParams = std::vector<float>(CURVE_PARAM_DIMENSION);
723 if (curveConfig.IsFloats() && curveConfig.floatsValue_->size() <= CURVE_PARAM_DIMENSION) {
724 std::copy(curveConfig.floatsValue_->begin(), curveConfig.floatsValue_->end(),
725 curveParams.begin());
726 }
727 } else {
728 auto iter = curveSet.find(name);
729 if (iter != curveSet.end()) {
730 curveName = name;
731 }
732 }
733
734 return {curveName, curveParams};
735 }
736
ConfigWindowSizeLimits()737 void SceneSessionManager::ConfigWindowSizeLimits()
738 {
739 const auto& config = WindowSceneConfig::GetConfig();
740 WindowSceneConfig::ConfigItem item = config["mainWindowSizeLimits"];
741 if (item.IsMap()) {
742 ConfigMainWindowSizeLimits(item);
743 }
744
745 item = config["subWindowSizeLimits"];
746 if (item.IsMap()) {
747 ConfigSubWindowSizeLimits(item);
748 }
749 }
750
ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem & mainWindowSizeConifg)751 void SceneSessionManager::ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem& mainWindowSizeConifg)
752 {
753 auto item = mainWindowSizeConifg["miniWidth"];
754 if (item.IsInts()) {
755 auto numbers = *item.intsValue_;
756 if (numbers.size() == 1) {
757 systemConfig_.miniWidthOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
758 }
759 }
760
761 item = mainWindowSizeConifg["miniHeight"];
762 if (item.IsInts()) {
763 auto numbers = *item.intsValue_;
764 if (numbers.size() == 1) {
765 systemConfig_.miniHeightOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
766 }
767 }
768 }
769
ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem & subWindowSizeConifg)770 void SceneSessionManager::ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem& subWindowSizeConifg)
771 {
772 auto item = subWindowSizeConifg["miniWidth"];
773 if (item.IsInts()) {
774 auto numbers = *item.intsValue_;
775 if (numbers.size() == 1) {
776 systemConfig_.miniWidthOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
777 }
778 }
779
780 item = subWindowSizeConifg["miniHeight"];
781 if (item.IsInts()) {
782 auto numbers = *item.intsValue_;
783 if (numbers.size() == 1) {
784 systemConfig_.miniHeightOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
785 }
786 }
787 }
788
ConfigSnapshotScale()789 void SceneSessionManager::ConfigSnapshotScale()
790 {
791 const auto& config = WindowSceneConfig::GetConfig();
792 WindowSceneConfig::ConfigItem item = config["snapshotScale"];
793 if (item.IsFloats()) {
794 auto snapshotScale = *item.floatsValue_;
795 if (snapshotScale.size() != 1 || snapshotScale[0] <= 0 || snapshotScale[0] > 1) {
796 return;
797 }
798 snapshotScale_ = snapshotScale[0];
799 }
800 }
801
SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context> & contextWeak)802 void SceneSessionManager::SetRootSceneContext(const std::weak_ptr<AbilityRuntime::Context>& contextWeak)
803 {
804 rootSceneContextWeak_ = contextWeak;
805 }
806
GetRootSceneSession()807 sptr<RootSceneSession> SceneSessionManager::GetRootSceneSession()
808 {
809 auto task = [this]() -> sptr<RootSceneSession> {
810 if (rootSceneSession_ != nullptr) {
811 return rootSceneSession_;
812 }
813 system::SetParameter("bootevent.wms.fullscreen.ready", "true");
814 rootSceneSession_ = new RootSceneSession();
815 rootSceneSession_->SetEventHandler(taskScheduler_->GetEventHandler());
816 AAFwk::AbilityManagerClient::GetInstance()->SetRootSceneSession(rootSceneSession_->AsObject());
817 return rootSceneSession_;
818 };
819
820 return taskScheduler_->PostSyncTask(task, "GetRootSceneSession");
821 }
822
GetSceneSession(int32_t persistentId)823 sptr<SceneSession> SceneSessionManager::GetSceneSession(int32_t persistentId)
824 {
825 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
826 auto iter = sceneSessionMap_.find(persistentId);
827 if (iter == sceneSessionMap_.end()) {
828 WLOGFD("Error found scene session with id: %{public}d", persistentId);
829 return nullptr;
830 }
831 return iter->second;
832 }
833
GetSceneSessionByName(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName,const int32_t appIndex)834 sptr<SceneSession> SceneSessionManager::GetSceneSessionByName(const std::string& bundleName,
835 const std::string& moduleName, const std::string& abilityName, const int32_t appIndex)
836 {
837 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
838 for (const auto &item : sceneSessionMap_) {
839 auto sceneSession = item.second;
840 if (sceneSession->GetSessionInfo().bundleName_ == bundleName &&
841 sceneSession->GetSessionInfo().moduleName_ == moduleName &&
842 sceneSession->GetSessionInfo().abilityName_ == abilityName &&
843 sceneSession->GetSessionInfo().appIndex_ == appIndex) {
844 return sceneSession;
845 }
846 }
847 return nullptr;
848 }
849
GetSceneSessionVectorByType(WindowType type)850 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByType(WindowType type)
851 {
852 std::vector<sptr<SceneSession>> sceneSessionVector;
853 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
854 for (const auto &item : sceneSessionMap_) {
855 auto sceneSession = item.second;
856 if (sceneSession->GetWindowType() == type) {
857 sceneSessionVector.emplace_back(sceneSession);
858 }
859 }
860
861 return sceneSessionVector;
862 }
863
UpdateParentSessionForDialog(const sptr<SceneSession> & sceneSession,sptr<WindowSessionProperty> property)864 WSError SceneSessionManager::UpdateParentSessionForDialog(const sptr<SceneSession>& sceneSession,
865 sptr<WindowSessionProperty> property)
866 {
867 if (property == nullptr) {
868 WLOGFD("[WMSDialog] Property is null, no need to update parent info");
869 return WSError::WS_ERROR_NULLPTR;
870 }
871 if (sceneSession == nullptr) {
872 WLOGFE("[WMSDialog] Session is nullptr");
873 return WSError::WS_ERROR_NULLPTR;
874 }
875 auto parentPersistentId = property->GetParentPersistentId();
876 if (property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && parentPersistentId != INVALID_SESSION_ID) {
877 auto parentSession = GetSceneSession(parentPersistentId);
878 if (parentSession == nullptr) {
879 WLOGFE("[WMSDialog] Parent session is nullptr, parentPersistentId:%{public}d", parentPersistentId);
880 return WSError::WS_ERROR_NULLPTR;
881 }
882 parentSession->BindDialogSessionTarget(sceneSession);
883 parentSession->BindDialogToParentSession(sceneSession);
884 sceneSession->SetParentSession(parentSession);
885 WLOGFI("[WMSDialog] Update parent of dialog success, id %{public}d, parentId %{public}d",
886 sceneSession->GetPersistentId(), parentPersistentId);
887 }
888 return WSError::WS_OK;
889 }
890
CreateSpecificSessionCallback()891 sptr<SceneSession::SpecificSessionCallback> SceneSessionManager::CreateSpecificSessionCallback()
892 {
893 sptr<SceneSession::SpecificSessionCallback> specificCb = new (std::nothrow)SceneSession::SpecificSessionCallback();
894 if (specificCb == nullptr) {
895 WLOGFE("SpecificSessionCallback is nullptr");
896 return nullptr;
897 }
898 specificCb->onCreate_ = std::bind(&SceneSessionManager::RequestSceneSession,
899 this, std::placeholders::_1, std::placeholders::_2);
900 specificCb->onDestroy_ = std::bind(&SceneSessionManager::DestroyAndDisconnectSpecificSession,
901 this, std::placeholders::_1);
902 specificCb->onCameraFloatSessionChange_ = std::bind(&SceneSessionManager::UpdateCameraFloatWindowStatus,
903 this, std::placeholders::_1, std::placeholders::_2);
904 specificCb->onGetSceneSessionVectorByType_ = std::bind(&SceneSessionManager::GetSceneSessionVectorByType,
905 this, std::placeholders::_1);
906 specificCb->onUpdateAvoidArea_ = std::bind(&SceneSessionManager::UpdateAvoidArea, this, std::placeholders::_1);
907 specificCb->onWindowInfoUpdate_ = std::bind(&SceneSessionManager::NotifyWindowInfoChange,
908 this, std::placeholders::_1, std::placeholders::_2);
909 specificCb->onWindowInputPidChangeCallback_ = std::bind(&SceneSessionManager::NotifyMMIWindowPidChange,
910 this, std::placeholders::_1, std::placeholders::_2);
911 specificCb->onSessionTouchOutside_ = std::bind(&SceneSessionManager::NotifySessionTouchOutside,
912 this, std::placeholders::_1);
913 specificCb->onGetAINavigationBarArea_ = std::bind(&SceneSessionManager::GetAINavigationBarArea, this);
914 specificCb->onRecoveryPullPiPMainWindow_ = std::bind(&SceneSessionManager::RecoveryPullPiPMainWindow,
915 this, std::placeholders::_1, std::placeholders::_2);
916 specificCb->onOutsideDownEvent_ = std::bind(&SceneSessionManager::OnOutsideDownEvent,
917 this, std::placeholders::_1, std::placeholders::_2);
918 return specificCb;
919 }
920
CheckWindowId(int32_t windowId,int32_t & pid)921 WMError SceneSessionManager::CheckWindowId(int32_t windowId, int32_t &pid)
922 {
923 auto task = [this, windowId, &pid]() -> WMError {
924 pid = INVALID_PID;
925 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
926 auto iter = sceneSessionMap_.find(windowId);
927 if (iter == sceneSessionMap_.end()) {
928 WLOGFE("Window(%{public}d) cannot set cursor style", windowId);
929 return WMError::WM_ERROR_INVALID_WINDOW;
930 }
931 auto sceneSession = iter->second;
932 if (sceneSession == nullptr) {
933 WLOGFE("sceneSession(%{public}d) is nullptr", windowId);
934 return WMError::WM_ERROR_INVALID_WINDOW;
935 }
936 pid = sceneSession->GetCallingPid();
937 WLOGFD("Window(%{public}d) to set the cursor style, pid:%{public}d", windowId, pid);
938 return WMError::WM_OK;
939 };
940 return taskScheduler_->PostSyncTask(task, "CheckWindowId:" + std::to_string(windowId));
941 }
942
CreateSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)943 sptr<SceneSession> SceneSessionManager::CreateSceneSession(const SessionInfo& sessionInfo,
944 sptr<WindowSessionProperty> property)
945 {
946 sptr<SceneSession::SpecificSessionCallback> specificCb = CreateSpecificSessionCallback();
947 sptr<SceneSession> sceneSession = nullptr;
948 if (sessionInfo.isSystem_) {
949 sceneSession = new (std::nothrow) SCBSystemSession(sessionInfo, specificCb);
950 WLOGFI("[WMSSCB]Create SCBSystemSession, type: %{public}d", sessionInfo.windowType_);
951 } else if (property == nullptr && SessionHelper::IsMainWindow(static_cast<WindowType>(sessionInfo.windowType_))) {
952 sceneSession = new (std::nothrow) MainSession(sessionInfo, specificCb);
953 WLOGFI("[WMSMain]Create MainSession");
954 } else if (property != nullptr && SessionHelper::IsSubWindow(property->GetWindowType())) {
955 sceneSession = new (std::nothrow) SubSession(sessionInfo, specificCb);
956 WLOGFI("[WMSSub]Create SubSession, type: %{public}d", property->GetWindowType());
957 } else if (property != nullptr && SessionHelper::IsSystemWindow(property->GetWindowType())) {
958 sceneSession = new (std::nothrow) SystemSession(sessionInfo, specificCb);
959 WLOGFI("[WMSSystem]Create SystemSession, type: %{public}d", property->GetWindowType());
960 } else {
961 WLOGFE("[WMSLife]Invalid window type");
962 }
963 if (sceneSession != nullptr) {
964 sceneSession->SetSessionInfoPersistentId(sceneSession->GetPersistentId());
965 }
966 return sceneSession;
967 }
968
RequestSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)969 sptr<SceneSession> SceneSessionManager::RequestSceneSession(const SessionInfo& sessionInfo,
970 sptr<WindowSessionProperty> property)
971 {
972 if (sessionInfo.persistentId_ != 0 && !sessionInfo.isPersistentRecover_ &&
973 sessionInfo.bundleName_.find("hmsapp.samplemanagement") == std::string::npos) {
974 auto session = GetSceneSession(sessionInfo.persistentId_);
975 if (session != nullptr) {
976 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
977 WLOGFD("[WMSLife] get exist session persistentId: %{public}d", sessionInfo.persistentId_);
978 return session;
979 }
980 }
981
982 auto task = [this, sessionInfo, property]() {
983 WLOGFI("[WMSLife] RequestSceneSession, appName: [%{public}s %{public}s %{public}s]"
984 "appIndex: %{public}d, type %{public}u isSystem:%{public}u, isPersistentRecover: %{public}u",
985 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
986 sessionInfo.abilityName_.c_str(), sessionInfo.appIndex_, sessionInfo.windowType_,
987 static_cast<uint32_t>(sessionInfo.isSystem_), static_cast<uint32_t>(sessionInfo.isPersistentRecover_));
988 sptr<SceneSession> sceneSession = CreateSceneSession(sessionInfo, property);
989 if (sceneSession == nullptr) {
990 WLOGFE("[WMSLife]sceneSession is nullptr!");
991 return sceneSession;
992 }
993 if (sceneSession->GetSessionProperty()) {
994 sceneSession->GetSessionProperty()->SetDisplayId(sessionInfo.screenId_);
995 WLOGFD("[WMSLife] RequestSceneSession, synchronous screenId with displayid %{public}" PRIu64"",
996 sessionInfo.screenId_);
997 }
998 sceneSession->SetEventHandler(taskScheduler_->GetEventHandler(), eventHandler_);
999 if (sessionInfo.isSystem_) {
1000 sceneSession->SetCallingPid(IPCSkeleton::GetCallingRealPid());
1001 sceneSession->SetCallingUid(IPCSkeleton::GetCallingUid());
1002 auto rootContext = rootSceneContextWeak_.lock();
1003 sceneSession->SetAbilityToken(rootContext != nullptr ? rootContext->GetToken() : nullptr);
1004 } else {
1005 WLOGFD("[WMSLife]RequestSceneSession, id %{public}d, bundleName: %{public}s, moduleName: %{public}s,"
1006 "abilityName: %{public}s want:%{public}s", sceneSession->GetPersistentId(),
1007 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
1008 sessionInfo.want == nullptr ? "nullptr" : sessionInfo.want->ToString().c_str());
1009 }
1010 RegisterSessionExceptionFunc(sceneSession);
1011 FillSessionInfo(sceneSession);
1012 auto persistentId = sceneSession->GetPersistentId();
1013 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSession(%d )", persistentId);
1014 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
1015 WindowInfoReporter::GetInstance().InsertCreateReportInfo(sessionInfo.bundleName_);
1016 }
1017 sceneSession->SetSystemConfig(systemConfig_);
1018 sceneSession->SetSnapshotScale(snapshotScale_);
1019 UpdateParentSessionForDialog(sceneSession, property);
1020 if (CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
1021 WLOGFD("ancoSceneState: %{public}d", sceneSession->GetSessionInfo().ancoSceneState);
1022 PreHandleCollaborator(sceneSession);
1023 }
1024 {
1025 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1026 sceneSessionMap_.insert({ persistentId, sceneSession });
1027 }
1028 PerformRegisterInRequestSceneSession(sceneSession);
1029 NotifySessionUpdate(sessionInfo, ActionType::SINGLE_START);
1030 WLOGFI("[WMSLife] RequestSceneSession, id: %{public}d, type: %{public}d",
1031 persistentId, sceneSession->GetWindowType());
1032 return sceneSession;
1033 };
1034 return taskScheduler_->PostSyncTask(task, "RequestSceneSession:PID" + std::to_string(sessionInfo.persistentId_));
1035 }
1036
NotifySessionUpdate(const SessionInfo & sessionInfo,ActionType action,ScreenId fromScreenId)1037 void SceneSessionManager::NotifySessionUpdate(const SessionInfo& sessionInfo, ActionType action, ScreenId fromScreenId)
1038 {
1039 sptr<DisplayChangeInfo> info = new (std::nothrow) DisplayChangeInfo();
1040 if (!info) {
1041 WLOGFE("new info failed");
1042 return;
1043 }
1044 info->action_ = action;
1045 info->abilityName_ = sessionInfo.abilityName_;
1046 info->bundleName_ = sessionInfo.bundleName_;
1047 info->toScreenId_ = sessionInfo.screenId_;
1048 info->fromScreenId_ = fromScreenId;
1049 ScreenSessionManagerClient::GetInstance().NotifyDisplayChangeInfoChanged(info);
1050 WLOGFI("Notify ability %{public}s bundle %{public}s update,toScreen id: %{public}" PRIu64"",
1051 info->abilityName_.c_str(), info->bundleName_.c_str(), info->toScreenId_);
1052 }
1053
PerformRegisterInRequestSceneSession(sptr<SceneSession> & sceneSession)1054 void SceneSessionManager::PerformRegisterInRequestSceneSession(sptr<SceneSession>& sceneSession)
1055 {
1056 RegisterSessionSnapshotFunc(sceneSession);
1057 RegisterSessionStateChangeNotifyManagerFunc(sceneSession);
1058 RegisterSessionInfoChangeNotifyManagerFunc(sceneSession);
1059 RegisterRequestFocusStatusNotifyManagerFunc(sceneSession);
1060 RegisterGetStateFromManagerFunc(sceneSession);
1061 RegisterInputMethodUpdateFunc(sceneSession);
1062 RegisterInputMethodShownFunc(sceneSession);
1063 RegisterInputMethodHideFunc(sceneSession);
1064 }
1065
UpdateSceneSessionWant(const SessionInfo & sessionInfo)1066 void SceneSessionManager::UpdateSceneSessionWant(const SessionInfo& sessionInfo)
1067 {
1068 if (sessionInfo.persistentId_ != 0) {
1069 auto session = GetSceneSession(sessionInfo.persistentId_);
1070 if (session != nullptr && sessionInfo.want != nullptr) {
1071 WLOGFI("get exist session persistentId: %{public}d", sessionInfo.persistentId_);
1072 if (!CheckCollaboratorType(session->GetCollaboratorType())) {
1073 session->SetSessionInfoWant(sessionInfo.want);
1074 WLOGFI("RequestSceneSession update want, persistentId:%{public}d", sessionInfo.persistentId_);
1075 } else {
1076 UpdateCollaboratorSessionWant(session, sessionInfo.persistentId_);
1077 }
1078 }
1079 }
1080 }
1081
UpdateCollaboratorSessionWant(sptr<SceneSession> & session,int32_t persistentId)1082 void SceneSessionManager::UpdateCollaboratorSessionWant(sptr<SceneSession>& session, int32_t persistentId)
1083 {
1084 if (session != nullptr) {
1085 if (session->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
1086 FillSessionInfo(session);
1087 if (CheckCollaboratorType(session->GetCollaboratorType())) {
1088 PreHandleCollaborator(session, persistentId);
1089 }
1090 }
1091 }
1092 }
1093
RegisterInputMethodUpdateFunc(const sptr<SceneSession> & sceneSession)1094 void SceneSessionManager::RegisterInputMethodUpdateFunc(const sptr<SceneSession>& sceneSession)
1095 {
1096 if (sceneSession == nullptr) {
1097 WLOGFE("[WMSInput] session is nullptr");
1098 return;
1099 }
1100 NotifyCallingSessionForegroundFunc onInputMethodUpdate = [this](int32_t persistentId) {
1101 this->OnInputMethodUpdate(persistentId);
1102 };
1103 sceneSession->SetNotifyCallingSessionUpdateRectFunc(onInputMethodUpdate);
1104 WLOGFD("[WMSInput] RegisterInputMethodUpdateFunc success");
1105 }
1106
OnInputMethodUpdate(const int32_t & persistentId)1107 void SceneSessionManager::OnInputMethodUpdate(const int32_t& persistentId)
1108 {
1109 auto scnSession = GetSceneSession(persistentId);
1110 if (scnSession == nullptr) {
1111 WLOGFE("[WMSInput] Input method is null");
1112 return;
1113 }
1114 WLOGFD("[WMSInput] persistentId: %{public}d, windowType: %{public}d", persistentId, scnSession->GetWindowType());
1115 ResizeSoftInputCallingSessionIfNeed(scnSession, true);
1116 }
1117
RegisterInputMethodShownFunc(const sptr<SceneSession> & sceneSession)1118 void SceneSessionManager::RegisterInputMethodShownFunc(const sptr<SceneSession>& sceneSession)
1119 {
1120 if (sceneSession == nullptr) {
1121 WLOGFE("[WMSInput] session is nullptr");
1122 return;
1123 }
1124 NotifyCallingSessionForegroundFunc onInputMethodShown = [this](int32_t persistentId) {
1125 this->OnInputMethodShown(persistentId);
1126 };
1127 sceneSession->SetNotifyCallingSessionForegroundFunc(onInputMethodShown);
1128 WLOGFD("[WMSInput] RegisterInputMethodShownFunc success");
1129 }
1130
OnInputMethodShown(const int32_t & persistentId)1131 void SceneSessionManager::OnInputMethodShown(const int32_t& persistentId)
1132 {
1133 auto scnSession = GetSceneSession(persistentId);
1134 if (scnSession == nullptr) {
1135 WLOGFE("[WMSInput] scnSession is null, persistentId: %{public}d", persistentId);
1136 return;
1137 }
1138
1139 WLOGFD("[WMSInput] persistentId: %{public}d, windowType: %{public}d", persistentId, scnSession->GetWindowType());
1140 if (callingSession_ == nullptr) {
1141 WLOGFI("[WMSInput] Calling session is null, using focusedSessionId_: %{public}d", focusedSessionId_);
1142 callingSession_ = GetSceneSession(focusedSessionId_);
1143 if (callingSession_ == nullptr) {
1144 WLOGFE("[WMSInput] Calling session obtained through focusedSessionId_ is null");
1145 return;
1146 }
1147 }
1148 callingSession_->SetTextFieldAvoidInfo(scnSession->textFieldPositionY_, scnSession->textFieldHeight_);
1149 ResizeSoftInputCallingSessionIfNeed(scnSession);
1150 }
1151
RegisterInputMethodHideFunc(const sptr<SceneSession> & sceneSession)1152 void SceneSessionManager::RegisterInputMethodHideFunc(const sptr<SceneSession>& sceneSession)
1153 {
1154 if (sceneSession == nullptr) {
1155 WLOGFE("[WMSInput] session is nullptr");
1156 return;
1157 }
1158 NotifyCallingSessionBackgroundFunc onInputMethodHide = [this]() {
1159 this->RestoreCallingSessionSizeIfNeed();
1160 this->callingSession_ = nullptr;
1161 };
1162 sceneSession->SetNotifyCallingSessionBackgroundFunc(onInputMethodHide);
1163 WLOGFD("[WMSInput] RegisterInputMethodHideFunc success");
1164 }
1165
SetAbilitySessionInfo(const sptr<SceneSession> & scnSession)1166 sptr<AAFwk::SessionInfo> SceneSessionManager::SetAbilitySessionInfo(const sptr<SceneSession>& scnSession)
1167 {
1168 sptr<AAFwk::SessionInfo> abilitySessionInfo = new (std::nothrow) AAFwk::SessionInfo();
1169 if (!abilitySessionInfo) {
1170 WLOGFE("abilitySessionInfo is nullptr");
1171 return nullptr;
1172 }
1173 auto sessionInfo = scnSession->GetSessionInfo();
1174 sptr<ISession> iSession(scnSession);
1175 abilitySessionInfo->sessionToken = iSession->AsObject();
1176 abilitySessionInfo->callerToken = sessionInfo.callerToken_;
1177 abilitySessionInfo->sessionName = SessionUtils::ConvertSessionName(sessionInfo.bundleName_,
1178 sessionInfo.abilityName_, sessionInfo.moduleName_, sessionInfo.appIndex_);
1179 abilitySessionInfo->persistentId = scnSession->GetPersistentId();
1180 abilitySessionInfo->requestCode = sessionInfo.requestCode;
1181 abilitySessionInfo->resultCode = sessionInfo.resultCode;
1182 abilitySessionInfo->uiAbilityId = sessionInfo.uiAbilityId_;
1183 abilitySessionInfo->startSetting = sessionInfo.startSetting;
1184 abilitySessionInfo->callingTokenId = sessionInfo.callingTokenId_;
1185 abilitySessionInfo->userId = currentUserId_;
1186 abilitySessionInfo->isClearSession = sessionInfo.isClearSession;
1187 if (sessionInfo.want != nullptr) {
1188 abilitySessionInfo->want = *sessionInfo.want;
1189 } else {
1190 abilitySessionInfo->want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
1191 sessionInfo.moduleName_);
1192 }
1193 return abilitySessionInfo;
1194 }
1195
PrepareTerminate(int32_t persistentId,bool & isPrepareTerminate)1196 WSError SceneSessionManager::PrepareTerminate(int32_t persistentId, bool& isPrepareTerminate)
1197 {
1198 auto task = [this, persistentId, &isPrepareTerminate]() {
1199 if (!isPrepareTerminateEnable_) { // not support prepareTerminate
1200 isPrepareTerminate = false;
1201 WLOGE("not support prepareTerminate, persistentId%{public}d", persistentId);
1202 return WSError::WS_OK;
1203 }
1204 auto scnSession = GetSceneSession(persistentId);
1205 if (scnSession == nullptr) {
1206 WLOGFE("scnSession is nullptr persistentId:%{public}d", persistentId);
1207 isPrepareTerminate = false;
1208 return WSError::WS_ERROR_NULLPTR;
1209 }
1210 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1211 if (scnSessionInfo == nullptr) {
1212 WLOGFE("scnSessionInfo is nullptr, persistentId:%{public}d", persistentId);
1213 isPrepareTerminate = false;
1214 return WSError::WS_ERROR_NULLPTR;
1215 }
1216 WLOGI("[WMSMain]PrepareTerminateAbilityBySCB persistentId:%{public}d", persistentId);
1217 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->
1218 PrepareTerminateAbilityBySCB(scnSessionInfo, isPrepareTerminate);
1219 WLOGI("[WMSMain]PrepareTerminateAbilityBySCB isPrepareTerminate:%{public}d errorCode:%{public}d",
1220 isPrepareTerminate, errorCode);
1221 return WSError::WS_OK;
1222 };
1223
1224 taskScheduler_->PostSyncTask(task, "PrepareTerminate:PID:" + std::to_string(persistentId));
1225 return WSError::WS_OK;
1226 }
1227
RequestSceneSessionActivation(const sptr<SceneSession> & sceneSession,bool isNewActive)1228 std::future<int32_t> SceneSessionManager::RequestSceneSessionActivation(
1229 const sptr<SceneSession>& sceneSession, bool isNewActive)
1230 {
1231 wptr<SceneSession> weakSceneSession(sceneSession);
1232 std::shared_ptr<std::promise<int32_t>> promise = std::make_shared<std::promise<int32_t>>();
1233 auto future = promise->get_future();
1234 auto task = [this, weakSceneSession, isNewActive, promise]() {
1235 sptr<SceneSession> scnSession = weakSceneSession.promote();
1236 if (scnSession == nullptr) {
1237 WLOGFE("[WMSMain]session is nullptr");
1238 promise->set_value(static_cast<int32_t>(WSError::WS_ERROR_NULLPTR));
1239 return WSError::WS_ERROR_INVALID_WINDOW;
1240 }
1241
1242 auto persistentId = scnSession->GetPersistentId();
1243 scnSession->NotifyForegroundInteractiveStatus(true);
1244 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionActivation(%d )", persistentId);
1245 WLOGFI("[WMSMain]active persistentId: %{public}d isSystem_:%{public}u",
1246 persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1247 if (!GetSceneSession(persistentId)) {
1248 WLOGFE("[WMSMain]session is invalid with %{public}d", persistentId);
1249 promise->set_value(static_cast<int32_t>(WSError::WS_ERROR_INVALID_SESSION));
1250 return WSError::WS_ERROR_INVALID_WINDOW;
1251 }
1252 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
1253 WLOGFI("collaborator use native session");
1254 scnSession = GetSceneSession(persistentId);
1255 }
1256 auto ret = RequestSceneSessionActivationInner(scnSession, isNewActive, promise);
1257 scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
1258 return ret;
1259 };
1260 std::string taskName = "RequestSceneSessionActivation:PID:" +
1261 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
1262 taskScheduler_->PostAsyncTask(task, taskName);
1263 return future;
1264 }
1265
RequestInputMethodCloseKeyboard(const int32_t persistentId)1266 void SceneSessionManager::RequestInputMethodCloseKeyboard(const int32_t persistentId)
1267 {
1268 auto sceneSession = GetSceneSession(persistentId);
1269 if (sceneSession == nullptr) {
1270 WLOGFE("[WMSInput] session is nullptr");
1271 return;
1272 }
1273 // When input method is shown and another app is cold started, the input method is hidden.
1274 if (!sceneSession->IsSessionValid() && callingSession_ != nullptr) {
1275 sceneSession->RequestHideKeyboard(true);
1276 }
1277 }
1278
RequestSceneSessionActivationInner(sptr<SceneSession> & scnSession,bool isNewActive,const std::shared_ptr<std::promise<int32_t>> & promise)1279 WSError SceneSessionManager::RequestSceneSessionActivationInner(
1280 sptr<SceneSession>& scnSession, bool isNewActive, const std::shared_ptr<std::promise<int32_t>>& promise)
1281 {
1282 auto persistentId = scnSession->GetPersistentId();
1283 RequestInputMethodCloseKeyboard(persistentId);
1284 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
1285 RequestSessionFocusImmediately(persistentId);
1286 }
1287 if (scnSession->GetSessionInfo().ancoSceneState < AncoSceneState::NOTIFY_CREATE) {
1288 FillSessionInfo(scnSession);
1289 PreHandleCollaborator(scnSession, persistentId);
1290 }
1291 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1292 if (!scnSessionInfo) {
1293 promise->set_value(static_cast<int32_t>(WSError::WS_ERROR_NULLPTR));
1294 return WSError::WS_ERROR_INVALID_WINDOW;
1295 }
1296 scnSession->NotifyActivation();
1297 scnSessionInfo->isNewWant = isNewActive;
1298 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
1299 scnSessionInfo->want.SetParam(AncoConsts::ANCO_MISSION_ID, scnSessionInfo->persistentId);
1300 scnSessionInfo->collaboratorType = scnSession->GetCollaboratorType();
1301 }
1302 WLOGFI("[WMSLife]RequestSceneSessionActivationInner: want info - \
1303 abilityName: %{public}s, bundleName: %{public}s, moduleName: %{public}s, uri: %{public}s",
1304 scnSessionInfo->want.GetElement().GetAbilityName().c_str(),
1305 scnSessionInfo->want.GetElement().GetBundleName().c_str(),
1306 scnSessionInfo->want.GetElement().GetModuleName().c_str(),
1307 scnSessionInfo->want.GetElement().GetURI().c_str());
1308 int32_t errCode = ERR_OK;
1309 if (systemConfig_.backgroundswitch == false) {
1310 WLOGFI("[WMSMain]begin StartUIAbility: %{public}d isSystem:%{public}u", persistentId,
1311 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1312 errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo);
1313 } else {
1314 WLOGFD("[WMSMain]RequestSceneSessionActivationInner: %{public}d", systemConfig_.backgroundswitch);
1315 if (isNewActive || scnSession->GetSessionState() == SessionState::STATE_DISCONNECT ||
1316 scnSession->GetSessionState() == SessionState::STATE_END) {
1317 WLOGFI("[WMSMain]begin StartUIAbility: %{public}d isSystem:%{public}u", persistentId,
1318 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1319 errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo);
1320 } else {
1321 scnSession->NotifySessionForeground(1, true);
1322 }
1323 }
1324 auto sessionInfo = scnSession->GetSessionInfo();
1325 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
1326 WindowInfoReporter::GetInstance().InsertShowReportInfo(sessionInfo.bundleName_);
1327 }
1328 NotifyCollaboratorAfterStart(scnSession, scnSessionInfo);
1329 promise->set_value(static_cast<int32_t>(errCode));
1330
1331 if (errCode != ERR_OK) {
1332 WLOGFE("session activate failed. errCode: %{public}d", errCode);
1333 scnSession->NotifySessionException(scnSessionInfo, true);
1334 if (startUIAbilityErrorFunc_ && static_cast<WSError>(errCode) == WSError::WS_ERROR_EDM_CONTROLLED) {
1335 startUIAbilityErrorFunc_(
1336 static_cast<uint32_t>(WS_JS_TO_ERROR_CODE_MAP.at(WSError::WS_ERROR_EDM_CONTROLLED)));
1337 }
1338 }
1339 return WSError::WS_OK;
1340 }
1341
NotifyCollaboratorAfterStart(sptr<SceneSession> & scnSession,sptr<AAFwk::SessionInfo> & scnSessionInfo)1342 void SceneSessionManager::NotifyCollaboratorAfterStart(sptr<SceneSession>& scnSession,
1343 sptr<AAFwk::SessionInfo>& scnSessionInfo)
1344 {
1345 if (scnSession == nullptr || scnSessionInfo == nullptr) {
1346 return;
1347 }
1348 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
1349 NotifyLoadAbility(scnSession->GetCollaboratorType(),
1350 scnSessionInfo, scnSession->GetSessionInfo().abilityInfo);
1351 NotifyUpdateSessionInfo(scnSession);
1352 NotifyMoveSessionToForeground(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
1353 scnSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_FOREGROUND);
1354 }
1355 }
1356
RequestSceneSessionBackground(const sptr<SceneSession> & sceneSession,const bool isDelegator,const bool isToDesktop)1357 WSError SceneSessionManager::RequestSceneSessionBackground(const sptr<SceneSession>& sceneSession,
1358 const bool isDelegator, const bool isToDesktop)
1359 {
1360 wptr<SceneSession> weakSceneSession(sceneSession);
1361 auto task = [this, weakSceneSession, isDelegator, isToDesktop]() {
1362 auto scnSession = weakSceneSession.promote();
1363 if (scnSession == nullptr) {
1364 WLOGFE("[WMSMain]session is nullptr");
1365 return WSError::WS_ERROR_NULLPTR;
1366 }
1367 auto persistentId = scnSession->GetPersistentId();
1368 WLOGFI("[WMSMain]background session persistentId: %{public}d", persistentId);
1369 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionBackground (%d )", persistentId);
1370 scnSession->SetActive(false);
1371
1372 if (isToDesktop) {
1373 auto info = scnSession->GetSessionInfo();
1374 info.callerToken_ = nullptr;
1375 info.callingTokenId_ = 0;
1376 scnSession->SetSessionInfo(info);
1377 }
1378
1379 scnSession->Background();
1380 if (!GetSceneSession(persistentId)) {
1381 WLOGFE("[WMSMain]session is invalid with %{public}d", persistentId);
1382 return WSError::WS_ERROR_INVALID_SESSION;
1383 }
1384 if (persistentId == brightnessSessionId_) {
1385 UpdateBrightness(focusedSessionId_);
1386 }
1387 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1388 if (!scnSessionInfo) {
1389 return WSError::WS_ERROR_NULLPTR;
1390 }
1391
1392 if (systemConfig_.backgroundswitch) {
1393 WLOGFD("[WMSMain]RequestSceneSessionBackground: %{public}d", systemConfig_.backgroundswitch);
1394 scnSession->NotifySessionBackground(1, true, true);
1395 } else {
1396 WLOGFI("[WMSMain]begin MinimzeUIAbility: %{public}d isSystem:%{public}u",
1397 persistentId, static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1398 if (!isDelegator) {
1399 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo);
1400 } else {
1401 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo, true);
1402 }
1403 }
1404
1405 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
1406 auto sessionInfo = scnSession->GetSessionInfo();
1407 WindowInfoReporter::GetInstance().InsertHideReportInfo(sessionInfo.bundleName_);
1408 }
1409 return WSError::WS_OK;
1410 };
1411 std::string taskName = "RequestSceneSessionBackground:PID:" +
1412 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
1413 taskScheduler_->PostAsyncTask(task, taskName);
1414 return WSError::WS_OK;
1415 }
1416
NotifyForegroundInteractiveStatus(const sptr<SceneSession> & sceneSession,bool interactive)1417 void SceneSessionManager::NotifyForegroundInteractiveStatus(const sptr<SceneSession>& sceneSession, bool interactive)
1418 {
1419 wptr<SceneSession> weakSceneSession(sceneSession);
1420 auto task = [this, weakSceneSession, interactive]() {
1421 auto scnSession = weakSceneSession.promote();
1422 if (scnSession == nullptr) {
1423 WLOGFE("session is nullptr");
1424 return;
1425 }
1426 auto persistentId = scnSession->GetPersistentId();
1427 WLOGFI("notify interactive session persistentId: %{public}d", persistentId);
1428 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:NotifyForegroundInteractiveStatus (%d )", persistentId);
1429 if (!GetSceneSession(persistentId)) {
1430 WLOGFE("session is invalid with %{public}d", persistentId);
1431 return;
1432 }
1433 scnSession->NotifyForegroundInteractiveStatus(interactive);
1434 };
1435
1436 taskScheduler_->PostAsyncTask(task, "NotifyForegroundInteractiveStatus");
1437 }
1438
DestroyDialogWithMainWindow(const sptr<SceneSession> & scnSession)1439 WSError SceneSessionManager::DestroyDialogWithMainWindow(const sptr<SceneSession>& scnSession)
1440 {
1441 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyDialogWithMainWindow");
1442 if (scnSession == nullptr) {
1443 WLOGFE("[WMSDialog] scnSession is nullptr");
1444 return WSError::WS_ERROR_NULLPTR;
1445 }
1446 if (scnSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1447 WLOGFI("[WMSDialog] Begin to destroy its dialog, parentId: %{public}d", scnSession->GetPersistentId());
1448 auto dialogVec = scnSession->GetDialogVector();
1449 for (auto dialog : dialogVec) {
1450 if (dialog == nullptr) {
1451 WLOGFE("[WMSDialog] dialog is nullptr");
1452 continue;
1453 }
1454 auto sceneSession = GetSceneSession(dialog->GetPersistentId());
1455 if (sceneSession == nullptr) {
1456 WLOGFE("[WMSDialog] dialog is invalid, id: %{public}d", dialog->GetPersistentId());
1457 return WSError::WS_ERROR_INVALID_SESSION;
1458 }
1459 WindowDestroyNotifyVisibility(sceneSession);
1460 dialog->NotifyDestroy();
1461 dialog->Disconnect();
1462
1463 auto dialogSceneSession = GetSceneSession(dialog->GetPersistentId());
1464 if (dialogSceneSession != nullptr) {
1465 dialogSceneSession->ClearSpecificSessionCbMap();
1466 }
1467 {
1468 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1469 sceneSessionMap_.erase(dialog->GetPersistentId());
1470 systemTopSceneSessionMap_.erase(dialog->GetPersistentId());
1471 nonSystemFloatSceneSessionMap_.erase(dialog->GetPersistentId());
1472 }
1473 }
1474 scnSession->ClearDialogVector();
1475 return WSError::WS_OK;
1476 }
1477 return WSError::WS_ERROR_INVALID_SESSION;
1478 }
1479
DestroySubSession(const sptr<SceneSession> & sceneSession)1480 void SceneSessionManager::DestroySubSession(const sptr<SceneSession>& sceneSession)
1481 {
1482 if (sceneSession == nullptr) {
1483 WLOGFW("sceneSession is nullptr");
1484 return;
1485 }
1486 for (const auto& elem : sceneSession->GetSubSession()) {
1487 if (elem != nullptr) {
1488 const auto& persistentId = elem->GetPersistentId();
1489 WLOGFI("[WMSSub] DestroySubSession, id: %{public}d", persistentId);
1490 DestroyAndDisconnectSpecificSessionInner(elem);
1491 }
1492 }
1493 }
1494
EraseSceneSessionMapById(int32_t persistentId)1495 void SceneSessionManager::EraseSceneSessionMapById(int32_t persistentId)
1496 {
1497 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1498 sceneSessionMap_.erase(persistentId);
1499 systemTopSceneSessionMap_.erase(persistentId);
1500 nonSystemFloatSceneSessionMap_.erase(persistentId);
1501 }
1502
RequestSceneSessionDestruction(const sptr<SceneSession> & sceneSession,const bool needRemoveSession)1503 WSError SceneSessionManager::RequestSceneSessionDestruction(
1504 const sptr<SceneSession>& sceneSession, const bool needRemoveSession)
1505 {
1506 wptr<SceneSession> weakSceneSession(sceneSession);
1507 auto task = [this, weakSceneSession, needRemoveSession]() {
1508 auto scnSession = weakSceneSession.promote();
1509 if (scnSession == nullptr) {
1510 WLOGFE("[WMSMain]session is nullptr");
1511 return WSError::WS_ERROR_NULLPTR;
1512 }
1513 auto persistentId = scnSession->GetPersistentId();
1514 RequestSessionUnfocus(persistentId);
1515 lastUpdatedAvoidArea_.erase(persistentId);
1516 DestroyDialogWithMainWindow(scnSession);
1517 DestroySubSession(scnSession); // destroy sub session by destruction
1518 WLOGFI("[WMSMain] destroy session persistentId: %{public}d", persistentId);
1519 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionDestruction (%" PRIu32" )", persistentId);
1520 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
1521 auto sessionInfo = scnSession->GetSessionInfo();
1522 WindowInfoReporter::GetInstance().InsertDestroyReportInfo(sessionInfo.bundleName_);
1523 }
1524 WindowDestroyNotifyVisibility(scnSession);
1525 scnSession->Disconnect();
1526 if (!GetSceneSession(persistentId)) {
1527 WLOGFE("[WMSMain]session is invalid with %{public}d", persistentId);
1528 return WSError::WS_ERROR_INVALID_SESSION;
1529 }
1530 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1531 if (!scnSessionInfo) {
1532 return WSError::WS_ERROR_NULLPTR;
1533 }
1534 scnSession->GetCloseAbilityWantAndClean(scnSessionInfo->want);
1535 if (scnSessionInfo->isClearSession) {
1536 scnSessionInfo->resultCode = -1;
1537 }
1538 if (scnSessionInfo->resultCode == -1) {
1539 OHOS::AAFwk::Want want;
1540 scnSessionInfo->want = want;
1541 }
1542 return RequestSceneSessionDestructionInner(scnSession, scnSessionInfo, needRemoveSession);
1543 };
1544 std::string taskName = "RequestSceneSessionDestruction:PID:" +
1545 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
1546 taskScheduler_->PostAsyncTask(task, taskName);
1547 return WSError::WS_OK;
1548 }
1549
RequestSceneSessionDestructionInner(sptr<SceneSession> & scnSession,sptr<AAFwk::SessionInfo> scnSessionInfo,const bool needRemoveSession)1550 WSError SceneSessionManager::RequestSceneSessionDestructionInner(
1551 sptr<SceneSession> &scnSession, sptr<AAFwk::SessionInfo> scnSessionInfo, const bool needRemoveSession)
1552 {
1553 auto persistentId = scnSession->GetPersistentId();
1554 NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::SINGLE_CLOSE);
1555 WLOGFI("[WMSMain]begin CloseUIAbility: %{public}d isSystem:%{public}u",
1556 persistentId,
1557 static_cast<uint32_t>(scnSession->GetSessionInfo().isSystem_));
1558 AAFwk::AbilityManagerClient::GetInstance()->CloseUIAbilityBySCB(scnSessionInfo);
1559 scnSession->SetSessionInfoAncoSceneState(AncoSceneState::DEFAULT_STATE);
1560 if (needRemoveSession) {
1561 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
1562 NotifyClearSession(scnSession->GetCollaboratorType(), scnSessionInfo->persistentId);
1563 }
1564 EraseSceneSessionMapById(persistentId);
1565 } else {
1566 // if terminate, set want to null. so start from recent, start a new one.
1567 scnSession->SetSessionInfoWant(nullptr);
1568 }
1569 if (listenerController_ != nullptr) {
1570 NotifySessionForCallback(scnSession, needRemoveSession);
1571 }
1572 scnSession->RemoveLifeCycleTask(LifeCycleTaskType::STOP);
1573 return WSError::WS_OK;
1574 }
1575
AddClientDeathRecipient(const sptr<ISessionStage> & sessionStage,const sptr<SceneSession> & sceneSession)1576 void SceneSessionManager::AddClientDeathRecipient(const sptr<ISessionStage>& sessionStage,
1577 const sptr<SceneSession>& sceneSession)
1578 {
1579 if (sceneSession == nullptr || sessionStage == nullptr) {
1580 WLOGFE("[WMSLife]sessionStage or sceneSession is nullptr");
1581 return;
1582 }
1583
1584 auto remoteObject = sessionStage->AsObject();
1585 remoteObjectMap_.insert(std::make_pair(remoteObject, sceneSession->GetPersistentId()));
1586 if (windowDeath_ == nullptr) {
1587 WLOGFE("[WMSLife]failed to create death recipient");
1588 return;
1589 }
1590 if (!remoteObject->AddDeathRecipient(windowDeath_)) {
1591 WLOGFE("[WMSLife]failed to add death recipient");
1592 return;
1593 }
1594 WLOGFD("Id: %{public}d", sceneSession->GetPersistentId());
1595 }
1596
DestroySpecificSession(const sptr<IRemoteObject> & remoteObject)1597 void SceneSessionManager::DestroySpecificSession(const sptr<IRemoteObject>& remoteObject)
1598 {
1599 auto task = [this, remoteObject] {
1600 auto iter = remoteObjectMap_.find(remoteObject);
1601 if (iter == remoteObjectMap_.end()) {
1602 WLOGFE("Invalid remoteObject");
1603 return;
1604 }
1605 WLOGFD("Remote died, id: %{public}d", iter->second);
1606 auto sceneSession = GetSceneSession(iter->second);
1607 if (sceneSession == nullptr) {
1608 WLOGFW("Remote died, session is nullptr, id: %{public}d", iter->second);
1609 return;
1610 }
1611 DestroyAndDisconnectSpecificSessionInner(sceneSession);
1612 remoteObjectMap_.erase(iter);
1613 };
1614 taskScheduler_->PostAsyncTask(task, "DestroySpecificSession");
1615 }
1616
CreateAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,int32_t & persistentId,sptr<ISession> & session,sptr<IRemoteObject> token)1617 WSError SceneSessionManager::CreateAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
1618 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
1619 sptr<WindowSessionProperty> property, int32_t& persistentId, sptr<ISession>& session,
1620 sptr<IRemoteObject> token)
1621 {
1622 if (property == nullptr) {
1623 WLOGFE("property is nullptr");
1624 return WSError::WS_ERROR_NULLPTR;
1625 }
1626
1627 if (!CheckSystemWindowPermission(property)) {
1628 WLOGFE("create system window permission denied!");
1629 return WSError::WS_ERROR_NOT_SYSTEM_APP;
1630 }
1631
1632 // WINDOW_TYPE_SYSTEM_ALARM_WINDOW has been deprecated, will be deleted after 5 versions.
1633 if (property->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW) {
1634 WLOGFE("The alarm window has been deprecated!");
1635 return WSError::WS_ERROR_INVALID_WINDOW;
1636 }
1637
1638 WLOGFI("[WMSLife] create specific start, name: %{public}s, type: %{public}d",
1639 property->GetWindowName().c_str(), property->GetWindowType());
1640
1641 // Get pid and uid before posting task.
1642 auto pid = IPCSkeleton::GetCallingRealPid();
1643 auto uid = IPCSkeleton::GetCallingUid();
1644 auto task = [this, sessionStage, eventChannel, surfaceNode, property,
1645 &persistentId, &session, token, pid, uid]() {
1646 if (property == nullptr) {
1647 return WSError::WS_ERROR_NULLPTR;
1648 }
1649 const auto& type = property->GetWindowType();
1650 // create specific session
1651 SessionInfo info;
1652 info.windowType_ = static_cast<uint32_t>(type);
1653 ClosePipWindowIfExist(type);
1654 sptr<SceneSession> newSession = RequestSceneSession(info, property);
1655 if (newSession == nullptr) {
1656 WLOGFE("[WMSSub][WMSSystem] session is nullptr");
1657 return WSError::WS_ERROR_NULLPTR;
1658 }
1659 auto errCode = newSession->Connect(
1660 sessionStage, eventChannel, surfaceNode, systemConfig_, property, token, pid, uid);
1661 if (property) {
1662 persistentId = property->GetPersistentId();
1663 }
1664
1665 NotifyCreateSpecificSession(newSession, property, type);
1666 session = newSession;
1667 AddClientDeathRecipient(sessionStage, newSession);
1668 WLOGFI("[WMSLife] create specific session success, id: %{public}d, parentId: %{public}d, type: %{public}d",
1669 newSession->GetPersistentId(), newSession->GetParentPersistentId(), type);
1670 return errCode;
1671 };
1672
1673 return taskScheduler_->PostSyncTask(task, "CreateAndConnectSpecificSession");
1674 }
1675
ClosePipWindowIfExist(WindowType type)1676 void SceneSessionManager::ClosePipWindowIfExist(WindowType type)
1677 {
1678 if (type != WindowType::WINDOW_TYPE_PIP) {
1679 return;
1680 }
1681 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1682 for (const auto& iter: sceneSessionMap_) {
1683 auto& session = iter.second;
1684 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
1685 session->NotifyCloseExistPipWindow();
1686 break;
1687 }
1688 }
1689 }
1690
CheckSystemWindowPermission(const sptr<WindowSessionProperty> & property)1691 bool SceneSessionManager::CheckSystemWindowPermission(const sptr<WindowSessionProperty>& property)
1692 {
1693 WindowType type = property->GetWindowType();
1694 if (!WindowHelper::IsSystemWindow(type)) {
1695 // type is not system
1696 return true;
1697 }
1698 if (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT && SessionPermission::IsStartedByInputMethod()) {
1699 // WINDOW_TYPE_INPUT_METHOD_FLOAT could be created by input method app
1700 WLOGFD("check create permission success, input method app create input method window.");
1701 return true;
1702 }
1703 if (type == WindowType::WINDOW_TYPE_DRAGGING_EFFECT ||
1704 type == WindowType::WINDOW_TYPE_TOAST || type == WindowType::WINDOW_TYPE_DIALOG ||
1705 type == WindowType::WINDOW_TYPE_PIP) {
1706 // some system types could be created by normal app
1707 return true;
1708 }
1709 if (type == WindowType::WINDOW_TYPE_FLOAT &&
1710 SessionPermission::VerifyCallingPermission("ohos.permission.SYSTEM_FLOAT_WINDOW")) {
1711 // WINDOW_TYPE_FLOAT could be created with the corresponding permission
1712 return true;
1713 }
1714 if (SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd()) {
1715 WLOGFD("check create permission success, create with system calling.");
1716 return true;
1717 }
1718 WLOGFE("check system window permission failed.");
1719 return false;
1720 }
1721
SetAlivePersistentIds(const std::vector<int32_t> & alivePersistentIds)1722 void SceneSessionManager::SetAlivePersistentIds(const std::vector<int32_t>& alivePersistentIds)
1723 {
1724 WLOGFI("[WMSRecover] Number of persistentIds need to be recovered = %{public}zu. CurrentUserId = "
1725 "%{public}d", alivePersistentIds.size(), currentUserId_);
1726 alivePersistentIds_ = alivePersistentIds;
1727 }
1728
isNeedRecover(const int32_t persistentId)1729 bool SceneSessionManager::isNeedRecover(const int32_t persistentId)
1730 {
1731 auto it = std::find(alivePersistentIds_.begin(), alivePersistentIds_.end(), persistentId);
1732 if (it == alivePersistentIds_.end()) {
1733 WLOGFW("[WMSRecover] recovered persistentId=%{public}d is not in alivePersistentIds_", persistentId);
1734 return false;
1735 }
1736 return true;
1737 }
1738
RecoverAndConnectSpecificSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,sptr<ISession> & session,sptr<IRemoteObject> token)1739 WSError SceneSessionManager::RecoverAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
1740 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
1741 sptr<WindowSessionProperty> property, sptr<ISession>& session, sptr<IRemoteObject> token)
1742 {
1743 if (property == nullptr) {
1744 WLOGFE("[WMSRecover] property is nullptr");
1745 return WSError::WS_ERROR_NULLPTR;
1746 }
1747 if (property->GetParentPersistentId() > 0 && !isNeedRecover(property->GetParentPersistentId())) {
1748 return WSError::WS_ERROR_INVALID_PARAM;
1749 }
1750 auto pid = IPCSkeleton::GetCallingPid();
1751 auto uid = IPCSkeleton::GetCallingUid();
1752 auto task = [this, sessionStage, eventChannel, surfaceNode, property, &session, token, pid, uid]() {
1753 // recover specific session
1754 const auto& type = property->GetWindowType();
1755 SessionInfo info = property->GetSessionInfo();
1756 info.isPersistentRecover_ = true;
1757 info.persistentId_ = property->GetPersistentId();
1758 info.windowMode = static_cast<int32_t>(property->GetWindowMode());
1759 info.windowType_ = static_cast<uint32_t>(type);
1760 info.requestOrientation_ = static_cast<uint32_t>(property->GetRequestedOrientation());
1761 info.sessionState_ = (property->GetWindowState() == WindowState::STATE_SHOWN) ? SessionState::STATE_ACTIVE
1762 : SessionState::STATE_BACKGROUND;
1763
1764 WLOGI("[WMSRecover] RecoverAndConnectSpecificSession windowName = %{public}s, windowMode = %{public}d, "
1765 "windowType = %{public}u, persistentId = %{public}d, windowState = %{public}u, "
1766 "callingWindowId = %{public}" PRIu32, property->GetWindowName().c_str(), info.windowMode,
1767 info.windowType_, info.persistentId_, property->GetWindowState(), property->GetCallingWindow());
1768
1769 ClosePipWindowIfExist(type);
1770 sptr<SceneSession> sceneSession = RequestSceneSession(info, property);
1771 if (sceneSession == nullptr) {
1772 WLOGFE("[WMSRecover] RequestSceneSession failed");
1773 return WSError::WS_ERROR_NULLPTR;
1774 }
1775
1776 auto persistentId = sceneSession->GetPersistentId();
1777 if (persistentId != info.persistentId_) {
1778 WLOGFW("[WMSRecover] PersistentId changed, from %{public}" PRId32 " to %{public}" PRId32,
1779 info.persistentId_, persistentId);
1780 }
1781
1782 auto errCode = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
1783 if (errCode != WSError::WS_OK) {
1784 WLOGFE("[WMSRecover] SceneSession reconnect failed");
1785 EraseSceneSessionMapById(persistentId);
1786 return errCode;
1787 }
1788
1789 NotifyCreateSpecificSession(sceneSession, property, type);
1790 CacheSubSessionForRecovering(sceneSession, property);
1791 RecoverWindowSessionProperty(sceneSession, property);
1792 AddClientDeathRecipient(sessionStage, sceneSession);
1793 session = sceneSession;
1794 return errCode;
1795 };
1796
1797 return taskScheduler_->PostSyncTask(task, "RecoverAndConnectSpecificSession");
1798 }
1799
NotifyRecoveringFinished()1800 void SceneSessionManager::NotifyRecoveringFinished()
1801 {
1802 taskScheduler_->PostAsyncTask([this]() {
1803 WLOGFI("[WMSRecover] RecoverFinished clear recoverSubSessionCacheMap");
1804 recoveringFinished_ = true;
1805 recoverSubSessionCacheMap_.clear();
1806 }, "NotifyRecoveringFinished");
1807 }
1808
CacheSubSessionForRecovering(sptr<SceneSession> sceneSession,const sptr<WindowSessionProperty> & property)1809 void SceneSessionManager::CacheSubSessionForRecovering(
1810 sptr<SceneSession> sceneSession, const sptr<WindowSessionProperty>& property)
1811 {
1812 if (recoveringFinished_) {
1813 WLOGFW("[WMSRecover] recovering is finished");
1814 return;
1815 }
1816
1817 if (sceneSession == nullptr || property == nullptr) {
1818 WLOGFE("[WMSRecover] sceneSession or property is nullptr");
1819 return;
1820 }
1821
1822 auto windowType = property->GetWindowType();
1823 if (!SessionHelper::IsSubWindow(windowType)) {
1824 return;
1825 }
1826
1827 auto persistentId = property->GetParentPersistentId();
1828 if (createSubSessionFuncMap_.find(persistentId) != createSubSessionFuncMap_.end()) {
1829 return;
1830 }
1831
1832 WLOGFI("[WMSRecover] Cache subsession persistentId = %{public}" PRId32 ", parent persistentId = %{public}" PRId32,
1833 sceneSession->GetPersistentId(), persistentId);
1834
1835 if (recoverSubSessionCacheMap_.find(persistentId) == recoverSubSessionCacheMap_.end()) {
1836 recoverSubSessionCacheMap_[persistentId] = std::vector{ sceneSession };
1837 } else {
1838 recoverSubSessionCacheMap_[persistentId].emplace_back(sceneSession);
1839 }
1840 }
1841
RecoverCachedSubSession(int32_t persistentId)1842 void SceneSessionManager::RecoverCachedSubSession(int32_t persistentId)
1843 {
1844 auto iter = recoverSubSessionCacheMap_.find(persistentId);
1845 if (iter == recoverSubSessionCacheMap_.end()) {
1846 return;
1847 }
1848
1849 WLOGFI("[WMSRecover] RecoverCachedSubSession persistentId = %{public}" PRId32, persistentId);
1850 for (auto& sceneSession : iter->second) {
1851 NotifyCreateSubSession(persistentId, sceneSession);
1852 }
1853 recoverSubSessionCacheMap_.erase(iter);
1854 }
1855
RecoverWindowSessionProperty(sptr<SceneSession> sceneSession,const sptr<WindowSessionProperty> & property)1856 void SceneSessionManager::RecoverWindowSessionProperty(
1857 sptr<SceneSession> sceneSession, const sptr<WindowSessionProperty>& property)
1858 {
1859 if (sceneSession == nullptr || property == nullptr) {
1860 WLOGFE("[WMSRecover] sceneSession or property is nullptr");
1861 return;
1862 }
1863
1864 auto windowType = property->GetWindowType();
1865 if (windowType == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
1866 RelayoutKeyBoard(sceneSession);
1867 callingWindowId_ = property->GetCallingWindow();
1868 const auto& callingSession = GetSceneSession(static_cast<int32_t>(callingWindowId_));
1869 if (callingSession != nullptr) {
1870 WLOGFI("[WMSRecover] NotifyOccupiedAreaChangeInfo after inputMethod session recovered,"
1871 "persistentId = %{public}" PRId32, callingSession->GetPersistentId());
1872 sptr<OccupiedAreaChangeInfo> info = new OccupiedAreaChangeInfo();
1873 callingSession->NotifyOccupiedAreaChangeInfo(info);
1874 }
1875 } else {
1876 auto persistentId = sceneSession->GetPersistentId();
1877 if (persistentId == static_cast<int32_t>(callingWindowId_)) {
1878 WLOGFI("[WMSRecover] NotifyOccupiedAreaChangeInfo after calling session recovered,"
1879 "persistentId = %{public}" PRId32, persistentId);
1880 sptr<OccupiedAreaChangeInfo> info = new OccupiedAreaChangeInfo();
1881 sceneSession->NotifyOccupiedAreaChangeInfo(info);
1882 }
1883 }
1884
1885 if (listenerController_ != nullptr) {
1886 WLOGFI("[WMSRecover] NotifySessionUnfocused");
1887 listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
1888 }
1889 }
1890
RecoverAndReconnectSceneSession(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<ISession> & session,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token)1891 WSError SceneSessionManager::RecoverAndReconnectSceneSession(const sptr<ISessionStage>& sessionStage,
1892 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
1893 sptr<ISession>& session, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token)
1894 {
1895 if (property == nullptr) {
1896 WLOGFE("[WMSRecover] property is nullptr!");
1897 return WSError::WS_ERROR_NULLPTR;
1898 }
1899 if (!isNeedRecover(property->GetPersistentId())) {
1900 return WSError::WS_ERROR_INVALID_PARAM;
1901 }
1902 SessionInfo sessionInfo = property->GetSessionInfo();
1903 sessionInfo.persistentId_ = property->GetPersistentId();
1904 sessionInfo.windowMode = static_cast<int32_t>(property->GetWindowMode());
1905 sessionInfo.windowType_ = static_cast<uint32_t>(property->GetWindowType());
1906 sessionInfo.requestOrientation_ = static_cast<uint32_t>(property->GetRequestedOrientation());
1907 WindowState windowState = property->GetWindowState();
1908 WLOGFI("[WMSRecover] Recover and reconnect sceneSession with: bundleName=%{public}s, moduleName=%{public}s, "
1909 "abilityName=%{public}s, windowMode=%{public}d, windowType=%{public}u, persistentId=%{public}d, "
1910 "windowState=%{public}u",
1911 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str(),
1912 sessionInfo.windowMode, sessionInfo.windowType_, sessionInfo.persistentId_, static_cast<uint32_t>(windowState));
1913 sptr<SceneSession> sceneSession = nullptr;
1914 if (SessionHelper::IsMainWindow(property->GetWindowType())) {
1915 sceneSession = RequestSceneSession(sessionInfo, nullptr);
1916 } else {
1917 sceneSession = RequestSceneSession(sessionInfo, property);
1918 }
1919 if (sceneSession == nullptr) {
1920 WLOGFE("[WMSRecover] Request sceneSession failed");
1921 return WSError::WS_ERROR_NULLPTR;
1922 }
1923 auto ret = sceneSession->Reconnect(sessionStage, eventChannel, surfaceNode, property, token,
1924 IPCSkeleton::GetCallingPid(), IPCSkeleton::GetCallingUid());
1925 if (ret != WSError::WS_OK) {
1926 WLOGFE("[WMSRecover] Reconnect failed");
1927 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1928 sceneSessionMap_.erase(sessionInfo.persistentId_);
1929 return ret;
1930 }
1931 sessionInfo.sessionState_ = sceneSession->GetSessionState();
1932 if (recoverSceneSessionFunc_) {
1933 recoverSceneSessionFunc_(sceneSession, sessionInfo);
1934 } else {
1935 WLOGFE("[WMSRecover] recoverSceneSessionFunc_ is null");
1936 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1937 sceneSessionMap_.erase(sessionInfo.persistentId_);
1938 return WSError::WS_ERROR_NULLPTR;
1939 }
1940 RecoverWindowSessionProperty(sceneSession, property);
1941 session = sceneSession;
1942 return WSError::WS_OK;
1943 }
1944
SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc & func)1945 void SceneSessionManager::SetRecoverSceneSessionListener(const NotifyRecoverSceneSessionFunc& func)
1946 {
1947 WLOGFI("[WMSRecover] SetRecoverSceneSessionListener");
1948 recoverSceneSessionFunc_ = func;
1949 }
1950
SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc & func)1951 void SceneSessionManager::SetCreateSystemSessionListener(const NotifyCreateSystemSessionFunc& func)
1952 {
1953 createSystemSessionFunc_ = func;
1954 }
1955
RegisterCreateSubSessionListener(int32_t persistentId,const NotifyCreateSubSessionFunc & func)1956 void SceneSessionManager::RegisterCreateSubSessionListener(int32_t persistentId,
1957 const NotifyCreateSubSessionFunc& func)
1958 {
1959 WLOGFI("[WMSSub] RegisterCreateSubSessionListener, id: %{public}d", persistentId);
1960 auto task = [this, persistentId, func]() {
1961 auto iter = createSubSessionFuncMap_.find(persistentId);
1962 if (iter == createSubSessionFuncMap_.end()) {
1963 createSubSessionFuncMap_.insert(std::make_pair(persistentId, func));
1964 RecoverCachedSubSession(persistentId);
1965 } else {
1966 WLOGFW("[WMSSub] CreateSubSessionListener is existed, id: %{public}d", persistentId);
1967 }
1968 return WMError::WM_OK;
1969 };
1970 taskScheduler_->PostSyncTask(task, "RegisterCreateSubSessionListener");
1971 }
1972
NotifyCreateSpecificSession(sptr<SceneSession> newSession,sptr<WindowSessionProperty> property,const WindowType & type)1973 void SceneSessionManager::NotifyCreateSpecificSession(sptr<SceneSession> newSession,
1974 sptr<WindowSessionProperty> property, const WindowType& type)
1975 {
1976 if (newSession == nullptr) {
1977 WLOGFE("newSession is nullptr");
1978 return;
1979 }
1980 if (property == nullptr) {
1981 WLOGFE("property is nullptr");
1982 return;
1983 }
1984 if (SessionHelper::IsSystemWindow(type)) {
1985 if ((type == WindowType::WINDOW_TYPE_TOAST) || (type == WindowType::WINDOW_TYPE_FLOAT)) {
1986 auto parentSession = GetSceneSession(property->GetParentPersistentId());
1987 if (parentSession != nullptr) {
1988 newSession->SetParentSession(parentSession);
1989 }
1990 }
1991 if (createSystemSessionFunc_ && type != WindowType::WINDOW_TYPE_DIALOG) {
1992 createSystemSessionFunc_(newSession);
1993 WLOGFD("[WMSLife] Create system session, id:%{public}d, type: %{public}d",
1994 newSession->GetPersistentId(), type);
1995 } else {
1996 WLOGFW("[WMSLife] Didn't create jsSceneSession for this system type, id:%{public}d, "
1997 "type: %{public}d", newSession->GetPersistentId(), type);
1998 return;
1999 }
2000 } else if (SessionHelper::IsSubWindow(type)) {
2001 NotifyCreateSubSession(property->GetParentPersistentId(), newSession);
2002 WLOGFD("[WMSLife] Notify sub jsSceneSession, id:%{public}d, parentId: %{public}d, type: %{public}d",
2003 newSession->GetPersistentId(), property->GetParentPersistentId(), type);
2004 } else {
2005 WLOGFW("[WMSLife] Invalid session type, id:%{public}d, type: %{public}d",
2006 newSession->GetPersistentId(), type);
2007 }
2008 }
2009
NotifyCreateSubSession(int32_t persistentId,sptr<SceneSession> session)2010 void SceneSessionManager::NotifyCreateSubSession(int32_t persistentId, sptr<SceneSession> session)
2011 {
2012 if (session == nullptr) {
2013 WLOGFE("[WMSLife] SubSession is nullptr");
2014 return;
2015 }
2016 auto iter = createSubSessionFuncMap_.find(persistentId);
2017 if (iter == createSubSessionFuncMap_.end()) {
2018 WLOGFW("[WMSLife] Can't find CreateSubSessionListener, parentId: %{public}d", persistentId);
2019 return;
2020 }
2021
2022 auto parentSession = GetSceneSession(persistentId);
2023 if (parentSession == nullptr) {
2024 WLOGFE("[WMSLife] Can't find CreateSubSessionListener, parentId: %{public}d, subId: %{public}d",
2025 persistentId, session->GetPersistentId());
2026 return;
2027 }
2028 parentSession->AddSubSession(session);
2029 session->SetParentSession(parentSession);
2030 if (iter->second) {
2031 iter->second(session);
2032 }
2033 WLOGFD("[WMSLife] NotifyCreateSubSession success, parentId: %{public}d, subId: %{public}d",
2034 persistentId, session->GetPersistentId());
2035 }
2036
UnregisterCreateSubSessionListener(int32_t persistentId)2037 void SceneSessionManager::UnregisterCreateSubSessionListener(int32_t persistentId)
2038 {
2039 WLOGFI("[WMSSub] UnregisterCreateSubSessionListener, id: %{public}d", persistentId);
2040 auto task = [this, persistentId]() {
2041 auto iter = createSubSessionFuncMap_.find(persistentId);
2042 if (iter != createSubSessionFuncMap_.end()) {
2043 createSubSessionFuncMap_.erase(persistentId);
2044 } else {
2045 WLOGFW("[WMSSub] Can't find CreateSubSessionListener, id: %{public}d", persistentId);
2046 }
2047 return WMError::WM_OK;
2048 };
2049 taskScheduler_->PostSyncTask(task);
2050 }
2051
NotifyStatusBarEnabledChange(bool enable)2052 void SceneSessionManager::NotifyStatusBarEnabledChange(bool enable)
2053 {
2054 WLOGFI("NotifyStatusBarEnabledChange enable %{public}d", enable);
2055 auto task = [this, enable]() {
2056 if (statusBarEnabledChangeFunc_) {
2057 statusBarEnabledChangeFunc_(enable);
2058 }
2059 return WMError::WM_OK;
2060 };
2061 taskScheduler_->PostSyncTask(task, "NotifyStatusBarEnabledChange");
2062 }
2063
SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc & func)2064 void SceneSessionManager::SetStatusBarEnabledChangeListener(const ProcessStatusBarEnabledChangeFunc& func)
2065 {
2066 WLOGFD("SetStatusBarEnabledChangeListener");
2067 if (!func) {
2068 WLOGFD("set func is null");
2069 }
2070 statusBarEnabledChangeFunc_ = func;
2071 NotifyStatusBarEnabledChange(gestureNavigationEnabled_);
2072 }
2073
SetGestureNavigationEnabledChangeListener(const ProcessGestureNavigationEnabledChangeFunc & func)2074 void SceneSessionManager::SetGestureNavigationEnabledChangeListener(
2075 const ProcessGestureNavigationEnabledChangeFunc& func)
2076 {
2077 WLOGFD("SetGestureNavigationEnabledChangeListener");
2078 if (!func) {
2079 WLOGFD("set func is null");
2080 }
2081 gestureNavigationEnabledChangeFunc_ = func;
2082 }
2083
OnOutsideDownEvent(int32_t x,int32_t y)2084 void SceneSessionManager::OnOutsideDownEvent(int32_t x, int32_t y)
2085 {
2086 WLOGFD("OnOutsideDownEvent x = %{public}d, y = %{public}d", x, y);
2087 if (outsideDownEventFunc_) {
2088 outsideDownEventFunc_(x, y);
2089 }
2090 }
2091
NotifySessionTouchOutside(int32_t persistentId)2092 void SceneSessionManager::NotifySessionTouchOutside(int32_t persistentId)
2093 {
2094 auto task = [this, persistentId]() {
2095 int32_t callingSessionId = persistentId;
2096 auto sceneSession = GetSceneSession(persistentId);
2097 if (callingSession_ != nullptr && sceneSession != nullptr &&
2098 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2099 callingSessionId = callingSession_->GetPersistentId();
2100 }
2101 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2102 for (const auto &item : sceneSessionMap_) {
2103 sceneSession = item.second;
2104 if (sceneSession == nullptr) {
2105 continue;
2106 }
2107 if (!(sceneSession->IsVisible() ||
2108 sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
2109 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE)) {
2110 continue;
2111 }
2112 auto sessionId = sceneSession->GetPersistentId();
2113 if ((!sceneSession->CheckOutTouchOutsideRegister()) &&
2114 (touchOutsideListenerSessionSet_.find(sessionId) == touchOutsideListenerSessionSet_.end())) {
2115 WLOGFD("id: %{public}d is not in touchOutsideListenerNodes, don't notify.", sessionId);
2116 continue;
2117 }
2118 if (sessionId == callingSessionId || sessionId == persistentId) {
2119 WLOGFD("No need to notify touch window, id: %{public}d", sessionId);
2120 continue;
2121 }
2122 sceneSession->NotifyTouchOutside();
2123 }
2124 };
2125
2126 taskScheduler_->PostAsyncTask(task, "NotifySessionTouchOutside:PID" + std::to_string(persistentId));
2127 return;
2128 }
2129
SetOutsideDownEventListener(const ProcessOutsideDownEventFunc & func)2130 void SceneSessionManager::SetOutsideDownEventListener(const ProcessOutsideDownEventFunc& func)
2131 {
2132 WLOGFD("SetOutsideDownEventListener");
2133 outsideDownEventFunc_ = func;
2134 }
2135
DestroyAndDisconnectSpecificSessionInner(sptr<SceneSession> sceneSession)2136 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionInner(sptr<SceneSession> sceneSession)
2137 {
2138 if (sceneSession == nullptr) {
2139 return WSError::WS_ERROR_NULLPTR;
2140 }
2141 const auto& persistentId = sceneSession->GetPersistentId();
2142 auto ret = sceneSession->UpdateActiveStatus(false);
2143 WindowDestroyNotifyVisibility(sceneSession);
2144 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
2145 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
2146 if (parentSession == nullptr) {
2147 WLOGFE("[WMSSystem][WMSDialog] Dialog not bind parent");
2148 } else {
2149 parentSession->RemoveDialogToParentSession(sceneSession);
2150 }
2151 sceneSession->NotifyDestroy();
2152 }
2153 ret = sceneSession->Disconnect();
2154 sceneSession->ClearSpecificSessionCbMap();
2155 if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
2156 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
2157 if (parentSession != nullptr) {
2158 WLOGFD("[WMSSub] Find parentSession, id: %{public}d", persistentId);
2159 parentSession->RemoveSubSession(persistentId);
2160 } else {
2161 WLOGFW("[WMSSub] ParentSession is nullptr, id: %{public}d", persistentId);
2162 }
2163 }
2164 {
2165 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2166 sceneSessionMap_.erase(persistentId);
2167 systemTopSceneSessionMap_.erase(persistentId);
2168 nonSystemFloatSceneSessionMap_.erase(persistentId);
2169 UnregisterCreateSubSessionListener(persistentId);
2170 }
2171 WLOGFI("[WMSLife] Destroy specific session end, id: %{public}d", persistentId);
2172 return ret;
2173 }
2174
DestroyAndDisconnectSpecificSession(const int32_t & persistentId)2175 WSError SceneSessionManager::DestroyAndDisconnectSpecificSession(const int32_t& persistentId)
2176 {
2177 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
2178 auto task = [this, persistentId, callingPid]() {
2179 WLOGFI("[WMSLife] Destroy specific session start, id: %{public}d", persistentId);
2180 auto sceneSession = GetSceneSession(persistentId);
2181 if (sceneSession == nullptr) {
2182 return WSError::WS_ERROR_NULLPTR;
2183 }
2184
2185 if (callingPid != sceneSession->GetCallingPid()) {
2186 WLOGFE("[WMSLife] Permission denied, not destroy by the same process");
2187 return WSError::WS_ERROR_INVALID_PERMISSION;
2188 }
2189 return DestroyAndDisconnectSpecificSessionInner(sceneSession);
2190 };
2191
2192 return taskScheduler_->PostSyncTask(task, "DestroyAndDisConnect:PID:" + std::to_string(persistentId));
2193 }
2194
GetWindowSceneConfig() const2195 const AppWindowSceneConfig& SceneSessionManager::GetWindowSceneConfig() const
2196 {
2197 return appWindowSceneConfig_;
2198 }
2199
ProcessBackEvent()2200 WSError SceneSessionManager::ProcessBackEvent()
2201 {
2202 auto task = [this]() {
2203 auto session = GetSceneSession(focusedSessionId_);
2204 if (!session) {
2205 WLOGFE("session is nullptr: %{public}d", focusedSessionId_);
2206 return WSError::WS_ERROR_INVALID_SESSION;
2207 }
2208 WLOGFI("ProcessBackEvent session persistentId: %{public}d", focusedSessionId_);
2209 if (needBlockNotifyFocusStatusUntilForeground_) {
2210 WLOGFD("RequestSessionBack when start session");
2211 session->RequestSessionBack(false);
2212 return WSError::WS_OK;
2213 }
2214 session->ProcessBackEvent();
2215 return WSError::WS_OK;
2216 };
2217
2218 taskScheduler_->PostAsyncTask(task, "ProcessBackEvent");
2219 return WSError::WS_OK;
2220 }
2221
CleanUserMap()2222 void SceneSessionManager::CleanUserMap()
2223 {
2224 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2225 WLOGFI("CleanUserMap in size = %{public}zu", sceneSessionMap_.size());
2226 auto iter = sceneSessionMap_.begin();
2227 while (iter != sceneSessionMap_.end()) {
2228 if (iter->second != nullptr && !iter->second->GetSessionInfo().isSystem_ &&
2229 iter->second->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2230 iter = sceneSessionMap_.erase(iter);
2231 } else {
2232 iter++;
2233 }
2234 }
2235 WLOGFI("CleanUserMap out size = %{public}zu", sceneSessionMap_.size());
2236
2237 WLOGFI("Clean systemTopSceneSessionMap in size = %{public}zu", systemTopSceneSessionMap_.size());
2238 iter = systemTopSceneSessionMap_.begin();
2239 while (iter != systemTopSceneSessionMap_.end()) {
2240 if (iter->second != nullptr && !iter->second->GetSessionInfo().isSystem_) {
2241 iter = systemTopSceneSessionMap_.erase(iter);
2242 } else {
2243 iter++;
2244 }
2245 }
2246 WLOGFI("Clean systemTopSceneSessionMap out size = %{public}zu", systemTopSceneSessionMap_.size());
2247 WLOGFI("Clean nonSystemFloatSceneSessionMap in size = %{public}zu", nonSystemFloatSceneSessionMap_.size());
2248 iter = nonSystemFloatSceneSessionMap_.begin();
2249 while (iter != nonSystemFloatSceneSessionMap_.end()) {
2250 if (iter->second != nullptr && !iter->second->GetSessionInfo().isSystem_) {
2251 iter = nonSystemFloatSceneSessionMap_.erase(iter);
2252 } else {
2253 iter++;
2254 }
2255 }
2256 WLOGFI("Clean nonSystemFloatSceneSessionMap out size = %{public}zu", nonSystemFloatSceneSessionMap_.size());
2257 }
2258
SwitchUser(int32_t oldUserId,int32_t newUserId,std::string & fileDir)2259 WSError SceneSessionManager::SwitchUser(int32_t oldUserId, int32_t newUserId, std::string &fileDir)
2260 {
2261 if (oldUserId != currentUserId_ || oldUserId == newUserId || fileDir.empty()) {
2262 WLOGFE("SwitchUser params invalid");
2263 return WSError::WS_DO_NOTHING;
2264 }
2265 WLOGFD("SwitchUser oldUserId : %{public}d newUserId : %{public}d path : %{public}s",
2266 oldUserId, newUserId, fileDir.c_str());
2267 auto task = [this, newUserId, &fileDir]() {
2268 ScenePersistence::CreateSnapshotDir(fileDir);
2269 ScenePersistence::CreateUpdatedIconDir(fileDir);
2270 currentUserId_ = newUserId;
2271 {
2272 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2273 for (const auto &item : sceneSessionMap_) {
2274 auto scnSession = item.second;
2275 auto persistentId = scnSession->GetPersistentId();
2276 scnSession->SetActive(false);
2277 scnSession->Background();
2278 if (persistentId == brightnessSessionId_) {
2279 UpdateBrightness(focusedSessionId_);
2280 }
2281 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
2282 if (!scnSessionInfo) {
2283 return WSError::WS_ERROR_NULLPTR;
2284 }
2285 WLOGFI("[WMSMain]begin MinimizeUIAbility newUserId : %{public}d persistentId: %{public}d",
2286 newUserId, persistentId);
2287 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo);
2288 }
2289 }
2290 CleanUserMap();
2291 return WSError::WS_OK;
2292 };
2293 taskScheduler_->PostSyncTask(task, "SwitchUser");
2294 return WSError::WS_OK;
2295 }
2296
GetBundleManager()2297 sptr<AppExecFwk::IBundleMgr> SceneSessionManager::GetBundleManager()
2298 {
2299 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
2300 if (systemAbilityMgr == nullptr) {
2301 WLOGFE("Failed to get SystemAbilityManager.");
2302 return nullptr;
2303 }
2304
2305 auto bmsObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
2306 if (bmsObj == nullptr) {
2307 WLOGFE("Failed to get BundleManagerService.");
2308 return nullptr;
2309 }
2310
2311 return iface_cast<AppExecFwk::IBundleMgr>(bmsObj);
2312 }
2313
GetResourceManager(const AppExecFwk::AbilityInfo & abilityInfo)2314 std::shared_ptr<Global::Resource::ResourceManager> SceneSessionManager::GetResourceManager(
2315 const AppExecFwk::AbilityInfo& abilityInfo)
2316 {
2317 auto context = rootSceneContextWeak_.lock();
2318 if (!context) {
2319 WLOGFE("context is nullptr.");
2320 return nullptr;
2321 }
2322 auto resourceMgr = context->GetResourceManager();
2323 if (!resourceMgr) {
2324 WLOGFE("resourceMgr is nullptr.");
2325 return nullptr;
2326 }
2327 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
2328 if (!resConfig) {
2329 WLOGFE("resConfig is nullptr.");
2330 return nullptr;
2331 }
2332 resourceMgr->GetResConfig(*resConfig);
2333 resourceMgr = Global::Resource::CreateResourceManager(
2334 abilityInfo.bundleName, abilityInfo.moduleName, "", {}, *resConfig);
2335 if (!resourceMgr) {
2336 WLOGFE("resourceMgr is nullptr.");
2337 return nullptr;
2338 }
2339 resourceMgr->UpdateResConfig(*resConfig);
2340
2341 std::string loadPath;
2342 if (!abilityInfo.hapPath.empty()) { // zipped hap
2343 loadPath = abilityInfo.hapPath;
2344 } else {
2345 loadPath = abilityInfo.resourcePath;
2346 }
2347
2348 if (!resourceMgr->AddResource(loadPath.c_str())) {
2349 WLOGFW("Add resource %{private}s failed.", loadPath.c_str());
2350 }
2351 return resourceMgr;
2352 }
2353
GetStartupPageFromResource(const AppExecFwk::AbilityInfo & abilityInfo,std::string & path,uint32_t & bgColor)2354 void SceneSessionManager::GetStartupPageFromResource(const AppExecFwk::AbilityInfo& abilityInfo,
2355 std::string& path, uint32_t& bgColor)
2356 {
2357 auto resourceMgr = GetResourceManager(abilityInfo);
2358 if (!resourceMgr) {
2359 WLOGFE("resourceMgr is nullptr.");
2360 return;
2361 }
2362
2363 if (resourceMgr->GetColorById(abilityInfo.startWindowBackgroundId, bgColor) != Global::Resource::RState::SUCCESS) {
2364 WLOGFW("Failed to get background color id %{public}d.", abilityInfo.startWindowBackgroundId);
2365 }
2366
2367 if (resourceMgr->GetMediaById(abilityInfo.startWindowIconId, path) != Global::Resource::RState::SUCCESS) {
2368 WLOGFE("Failed to get icon id %{public}d.", abilityInfo.startWindowIconId);
2369 return;
2370 }
2371
2372 if (!abilityInfo.hapPath.empty()) { // zipped hap
2373 auto pos = path.find_last_of('.');
2374 if (pos == std::string::npos) {
2375 WLOGFE("Format error, path %{private}s.", path.c_str());
2376 return;
2377 }
2378 path = "resource:///" + std::to_string(abilityInfo.startWindowIconId) + path.substr(pos);
2379 }
2380 }
2381
GetStartupPage(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)2382 void SceneSessionManager::GetStartupPage(const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
2383 {
2384 if (!bundleMgr_) {
2385 WLOGFE("bundleMgr_ is nullptr.");
2386 return;
2387 }
2388 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetStartupPage");
2389 AAFwk::Want want;
2390 want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
2391 AppExecFwk::AbilityInfo abilityInfo;
2392 if (!bundleMgr_->QueryAbilityInfo(
2393 want, AppExecFwk::GET_ABILITY_INFO_DEFAULT, AppExecFwk::Constants::ANY_USERID, abilityInfo)) {
2394 WLOGFE("Get ability info from BMS failed!");
2395 return;
2396 }
2397
2398 GetStartupPageFromResource(abilityInfo, path, bgColor);
2399 WLOGFI("%{public}d, %{public}d, %{public}s, %{public}x",
2400 abilityInfo.startWindowIconId, abilityInfo.startWindowBackgroundId, path.c_str(), bgColor);
2401 }
2402
FillSessionInfo(sptr<SceneSession> & sceneSession)2403 void SceneSessionManager::FillSessionInfo(sptr<SceneSession>& sceneSession)
2404 {
2405 auto sessionInfo = sceneSession->GetSessionInfo();
2406 if (sessionInfo.bundleName_.empty()) {
2407 WLOGFE("FillSessionInfo bundleName_ is null");
2408 return;
2409 }
2410 if (sessionInfo.isSystem_) {
2411 WLOGFD("FillSessionInfo systemScene!");
2412 return;
2413 }
2414 auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
2415 sessionInfo.moduleName_);
2416 if (abilityInfo == nullptr) {
2417 WLOGFE("FillSessionInfo abilityInfo is nullptr!");
2418 return;
2419 }
2420 sceneSession->SetSessionInfoAbilityInfo(abilityInfo);
2421 sceneSession->SetSessionInfoTime(GetCurrentTime());
2422 if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
2423 sceneSession->SetCollaboratorType(CollaboratorType::RESERVE_TYPE);
2424 } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
2425 sceneSession->SetCollaboratorType(CollaboratorType::OTHERS_TYPE);
2426 }
2427 WLOGFI("FillSessionInfo end, removeMissionAfterTerminate: %{public}d excludeFromMissions: %{public}d "
2428 " label:%{public}s iconPath:%{public}s collaboratorType:%{public}s",
2429 abilityInfo->removeMissionAfterTerminate, abilityInfo->excludeFromMissions,
2430 abilityInfo->label.c_str(), abilityInfo->iconPath.c_str(), abilityInfo->applicationInfo.codePath.c_str());
2431 }
2432
QueryAbilityInfoFromBMS(const int32_t uId,const std::string & bundleName,const std::string & abilityName,const std::string & moduleName)2433 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSessionManager::QueryAbilityInfoFromBMS(const int32_t uId,
2434 const std::string& bundleName, const std::string& abilityName, const std::string& moduleName)
2435 {
2436 AAFwk::Want want;
2437 want.SetElementName("", bundleName, abilityName, moduleName);
2438 std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo = std::make_shared<AppExecFwk::AbilityInfo>();
2439 if (abilityInfo == nullptr) {
2440 WLOGFE("QueryAbilityInfoFromBMS abilityInfo is nullptr!");
2441 return nullptr;
2442 }
2443 auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
2444 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
2445 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA);
2446 bool ret = bundleMgr_->QueryAbilityInfo(want, abilityInfoFlag, uId, *abilityInfo);
2447 if (!ret) {
2448 WLOGFE("Get ability info from BMS failed!");
2449 return nullptr;
2450 }
2451 return abilityInfo;
2452 }
2453
GetTopWindowId(uint32_t mainWinId,uint32_t & topWinId)2454 WMError SceneSessionManager::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId)
2455 {
2456 const auto& callingPid = IPCSkeleton::GetCallingRealPid();
2457 auto task = [this, mainWinId, &topWinId, callingPid]() {
2458 const auto& mainSession = GetSceneSession(mainWinId);
2459 if (mainSession == nullptr) {
2460 return WMError::WM_ERROR_INVALID_WINDOW;
2461 }
2462
2463 if (callingPid != mainSession->GetCallingPid()) {
2464 WLOGFE("Permission denied, not destroy by the same process");
2465 return WMError::WM_ERROR_INVALID_PERMISSION;
2466 }
2467 const auto& subVec = mainSession->GetSubSession();
2468 uint32_t zOrder = mainSession->GetZOrder();
2469 topWinId = mainWinId;
2470 for (const auto& subSession : subVec) {
2471 if (subSession != nullptr && (subSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
2472 subSession->GetSessionState() == SessionState::STATE_ACTIVE) && subSession->GetZOrder() > zOrder) {
2473 topWinId = subSession->GetPersistentId();
2474 zOrder = subSession->GetZOrder();
2475 WLOGFD("[GetTopWin] Current zorder is larger than mainWin, mainId: %{public}d, topWinId: %{public}d, "
2476 "zOrder: %{public}d", mainWinId, topWinId, zOrder);
2477 }
2478 }
2479 WLOGFD("[GetTopWin] Get top window, mainId: %{public}d, topWinId: %{public}d, zOrder: %{public}d",
2480 mainWinId, topWinId, zOrder);
2481 return WMError::WM_OK;
2482 };
2483 return taskScheduler_->PostSyncTask(task, "GetTopWindowId");
2484 }
2485
UpdateSessionProperty(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)2486 WMError SceneSessionManager::UpdateSessionProperty(const sptr<WindowSessionProperty>& property,
2487 WSPropertyChangeAction action)
2488 {
2489 if (property == nullptr) {
2490 WLOGFE("property is nullptr");
2491 return WMError::WM_ERROR_NULLPTR;
2492 }
2493 if (action == WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE) {
2494 if (!SessionPermission::VerifyCallingPermission("ohos.permission.PRIVACY_WINDOW")) {
2495 return WMError::WM_ERROR_INVALID_PERMISSION;
2496 }
2497 }
2498
2499 bool isSystemCalling = SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd();
2500 property->SetSystemCalling(isSystemCalling);
2501 wptr<SceneSessionManager> weak = this;
2502 auto task = [weak, property, action]() -> WMError {
2503 auto weakSession = weak.promote();
2504 if (weakSession == nullptr) {
2505 WLOGFE("the session is nullptr");
2506 return WMError::WM_DO_NOTHING;
2507 }
2508 if (property == nullptr) {
2509 WLOGFE("the property is nullptr");
2510 return WMError::WM_DO_NOTHING;
2511 }
2512 auto sceneSession = weakSession->GetSceneSession(property->GetPersistentId());
2513 if (sceneSession == nullptr) {
2514 WLOGFW("the scene session is nullptr, persistentId: %{public}d", property->GetPersistentId());
2515 return WMError::WM_DO_NOTHING;
2516 }
2517 WLOGD("Id: %{public}d, action: %{public}u", sceneSession->GetPersistentId(), action);
2518 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:UpdateProperty");
2519 return weakSession->HandleUpdateProperty(property, action, sceneSession);
2520 };
2521 return taskScheduler_->PostSyncTask(task, "UpdateProperty");
2522 }
2523
UpdatePropertyDragEnabled(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)2524 WMError SceneSessionManager::UpdatePropertyDragEnabled(const sptr<WindowSessionProperty>& property,
2525 const sptr<SceneSession>& sceneSession)
2526 {
2527 if (!property->GetSystemCalling()) {
2528 WLOGFE("Update property dragEnabled permission denied!");
2529 return WMError::WM_ERROR_NOT_SYSTEM_APP;
2530 }
2531
2532 if (sceneSession->GetSessionProperty() != nullptr) {
2533 sceneSession->GetSessionProperty()->SetDragEnabled(property->GetDragEnabled());
2534 }
2535 return WMError::WM_OK;
2536 }
2537
UpdatePropertyRaiseEnabled(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)2538 WMError SceneSessionManager::UpdatePropertyRaiseEnabled(const sptr<WindowSessionProperty>& property,
2539 const sptr<SceneSession>& sceneSession)
2540 {
2541 if (!property->GetSystemCalling()) {
2542 WLOGFE("Update property raiseEnabled permission denied!");
2543 return WMError::WM_ERROR_NOT_SYSTEM_APP;
2544 }
2545
2546 if (sceneSession->GetSessionProperty() != nullptr) {
2547 sceneSession->GetSessionProperty()->SetRaiseEnabled(property->GetRaiseEnabled());
2548 }
2549 return WMError::WM_OK;
2550 }
2551
HandleSpecificSystemBarProperty(WindowType type,const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)2552 void SceneSessionManager::HandleSpecificSystemBarProperty(WindowType type, const sptr<WindowSessionProperty>& property,
2553 const sptr<SceneSession>& sceneSession)
2554 {
2555 auto systemBarProperties = property->GetSystemBarProperty();
2556 for (auto iter : systemBarProperties) {
2557 if (iter.first == type) {
2558 sceneSession->SetSystemBarProperty(iter.first, iter.second);
2559 WLOGFD("SetSystemBarProperty: %{public}d, enable: %{public}d",
2560 static_cast<int32_t>(iter.first), iter.second.enable_);
2561 }
2562 }
2563 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
2564 }
2565
SetCallingSession(const sptr<SceneSession> & sceneSession,uint32_t newCallingWindowId)2566 void SceneSessionManager::SetCallingSession(const sptr<SceneSession>& sceneSession, uint32_t newCallingWindowId)
2567 {
2568 uint32_t oldCallingWindowId = INVALID_WINDOW_ID;
2569 if (sceneSession && sceneSession->GetSessionProperty()) {
2570 oldCallingWindowId = sceneSession->GetSessionProperty()->GetCallingWindow();
2571 }
2572 if (callingSession_ && oldCallingWindowId == newCallingWindowId) {
2573 WLOGFI("[WMSInput] CallingWindowId not changed, not need to reset callingSession");
2574 return;
2575 }
2576 WLOGFI("[WMSInput] Get callingSesstion by CallingWindowId: %{public}d", newCallingWindowId);
2577 callingSession_ = GetSceneSession(newCallingWindowId);
2578 return;
2579 }
2580
HandleUpdateProperty(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action,const sptr<SceneSession> & sceneSession)2581 WMError SceneSessionManager::HandleUpdateProperty(const sptr<WindowSessionProperty>& property,
2582 WSPropertyChangeAction action, const sptr<SceneSession>& sceneSession)
2583 {
2584 switch (action) {
2585 case WSPropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON: {
2586 sceneSession->SetTurnScreenOn(property->IsTurnScreenOn());
2587 HandleTurnScreenOn(sceneSession);
2588 break;
2589 }
2590 case WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON: {
2591 sceneSession->SetKeepScreenOn(property->IsKeepScreenOn());
2592 HandleKeepScreenOn(sceneSession, property->IsKeepScreenOn());
2593 break;
2594 }
2595 case WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE: {
2596 sceneSession->SetFocusable(property->GetFocusable());
2597 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
2598 break;
2599 }
2600 case WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE: {
2601 sceneSession->SetTouchable(property->GetTouchable());
2602 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
2603 break;
2604 }
2605 case WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS: {
2606 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2607 WLOGW("only app main window can set brightness");
2608 return WMError::WM_OK;
2609 }
2610 // @todo if sceneSession is inactive, return
2611 SetBrightness(sceneSession, property->GetBrightness());
2612 break;
2613 }
2614 case WSPropertyChangeAction::ACTION_UPDATE_ORIENTATION: {
2615 sceneSession->SetRequestedOrientation(property->GetRequestedOrientation());
2616 break;
2617 }
2618 case WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE: {
2619 bool isPrivacyMode = property->GetPrivacyMode() || property->GetSystemPrivacyMode();
2620 sceneSession->SetPrivacyMode(isPrivacyMode);
2621 UpdatePrivateStateAndNotify(sceneSession->GetPersistentId());
2622 break;
2623 }
2624 case WSPropertyChangeAction::ACTION_UPDATE_SYSTEM_PRIVACY_MODE: {
2625 bool isPrivacyMode = property->GetPrivacyMode() || property->GetSystemPrivacyMode();
2626 sceneSession->SetPrivacyMode(isPrivacyMode);
2627 UpdatePrivateStateAndNotify(sceneSession->GetPersistentId());
2628 break;
2629 }
2630 case WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE: {
2631 if (sceneSession->GetSessionProperty() != nullptr) {
2632 sceneSession->GetSessionProperty()->SetMaximizeMode(property->GetMaximizeMode());
2633 }
2634 break;
2635 }
2636 case WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS: {
2637 auto systemBarProperties = property->GetSystemBarProperty();
2638 for (auto iter : systemBarProperties) {
2639 sceneSession->SetSystemBarProperty(iter.first, iter.second);
2640 }
2641 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
2642 break;
2643 }
2644 case WSPropertyChangeAction::ACTION_UPDATE_STATUS_PROPS: {
2645 HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, property, sceneSession);
2646 break;
2647 }
2648 case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_PROPS: {
2649 HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_BAR, property, sceneSession);
2650 break;
2651 }
2652 case WSPropertyChangeAction::ACTION_UPDATE_NAVIGATION_INDICATOR_PROPS: {
2653 HandleSpecificSystemBarProperty(WindowType::WINDOW_TYPE_NAVIGATION_INDICATOR, property, sceneSession);
2654 break;
2655 }
2656 case WSPropertyChangeAction::ACTION_UPDATE_FLAGS: {
2657 SetWindowFlags(sceneSession, property);
2658 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
2659 break;
2660 }
2661 case WSPropertyChangeAction::ACTION_UPDATE_MODE: {
2662 if (sceneSession->GetSessionProperty() != nullptr) {
2663 sceneSession->GetSessionProperty()->SetWindowMode(property->GetWindowMode());
2664 }
2665 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
2666 break;
2667 }
2668 case WSPropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG: {
2669 if (sceneSession->GetSessionProperty() != nullptr) {
2670 sceneSession->GetSessionProperty()->SetAnimationFlag(property->GetAnimationFlag());
2671 }
2672 break;
2673 }
2674 case WSPropertyChangeAction::ACTION_UPDATE_TOUCH_HOT_AREA: {
2675 if (sceneSession->GetSessionProperty() != nullptr) {
2676 std::vector<Rect> touchHotAreas;
2677 property->GetTouchHotAreas(touchHotAreas);
2678 sceneSession->GetSessionProperty()->SetTouchHotAreas(touchHotAreas);
2679 }
2680 break;
2681 }
2682 case WSPropertyChangeAction::ACTION_UPDATE_CALLING_WINDOW: {
2683 if (sceneSession->GetSessionProperty() != nullptr) {
2684 SetCallingSession(sceneSession, property->GetCallingWindow());
2685 sceneSession->GetSessionProperty()->SetCallingWindow(property->GetCallingWindow());
2686 }
2687 if (callingWindowIdChangeFunc_ != nullptr) {
2688 callingWindowIdChangeFunc_(property->GetCallingWindow());
2689 }
2690 break;
2691 }
2692 case WSPropertyChangeAction::ACTION_UPDATE_DECOR_ENABLE: {
2693 if (property != nullptr && !property->GetSystemCalling()) {
2694 WLOGFE("update decor enable permission denied!");
2695 break;
2696 }
2697 if (sceneSession->GetSessionProperty() != nullptr) {
2698 sceneSession->GetSessionProperty()->SetDecorEnable(property->IsDecorEnable());
2699 }
2700 break;
2701 }
2702 case WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS: {
2703 if (sceneSession->GetSessionProperty() != nullptr) {
2704 sceneSession->GetSessionProperty()->SetWindowLimits(property->GetWindowLimits());
2705 }
2706 break;
2707 }
2708 case WSPropertyChangeAction::ACTION_UPDATE_DRAGENABLED: {
2709 return UpdatePropertyDragEnabled(property, sceneSession);
2710 }
2711 case WSPropertyChangeAction::ACTION_UPDATE_RAISEENABLED: {
2712 return UpdatePropertyRaiseEnabled(property, sceneSession);
2713 }
2714 case WSPropertyChangeAction::ACTION_UPDATE_HIDE_NON_SYSTEM_FLOATING_WINDOWS: {
2715 UpdateHideNonSystemFloatingWindows(property, sceneSession);
2716 break;
2717 }
2718 default:
2719 break;
2720 }
2721 return WMError::WM_OK;
2722 }
2723
UpdateHideNonSystemFloatingWindows(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)2724 void SceneSessionManager::UpdateHideNonSystemFloatingWindows(const sptr<WindowSessionProperty>& property,
2725 const sptr<SceneSession>& sceneSession)
2726 {
2727 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2728 WLOGFE("Update property hideNonSystemFloatingWindows permission denied!");
2729 return;
2730 }
2731
2732 auto propertyOld = sceneSession->GetSessionProperty();
2733 if (propertyOld == nullptr) {
2734 WLOGFI("UpdateHideNonSystemFloatingWindows, session property null");
2735 return;
2736 }
2737
2738 bool hideNonSystemFloatingWindowsOld = propertyOld->GetHideNonSystemFloatingWindows();
2739 bool hideNonSystemFloatingWindowsNew = property->GetHideNonSystemFloatingWindows();
2740 if (hideNonSystemFloatingWindowsOld == hideNonSystemFloatingWindowsNew) {
2741 WLOGFI("property hideNonSystemFloatingWindows not change");
2742 return;
2743 }
2744
2745 if (IsSessionVisible(sceneSession)) {
2746 if (hideNonSystemFloatingWindowsOld) {
2747 UpdateForceHideState(sceneSession, propertyOld, false);
2748 } else {
2749 UpdateForceHideState(sceneSession, property, true);
2750 }
2751 }
2752 propertyOld->SetHideNonSystemFloatingWindows(hideNonSystemFloatingWindowsNew);
2753 }
2754
UpdateForceHideState(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property,bool add)2755 void SceneSessionManager::UpdateForceHideState(const sptr<SceneSession>& sceneSession,
2756 const sptr<WindowSessionProperty>& property, bool add)
2757 {
2758 if (property == nullptr) {
2759 WLOGFD("property is nullptr");
2760 return;
2761 }
2762 auto persistentId = sceneSession->GetPersistentId();
2763 bool forceHideFloatOld = !systemTopSceneSessionMap_.empty();
2764 bool notifyAll = false;
2765 if (add) {
2766 if (property->GetHideNonSystemFloatingWindows()) {
2767 systemTopSceneSessionMap_.insert({ persistentId, sceneSession });
2768 notifyAll = !forceHideFloatOld;
2769 } else if (property->IsFloatingWindowAppType()) {
2770 nonSystemFloatSceneSessionMap_.insert({ persistentId, sceneSession });
2771 if (forceHideFloatOld) {
2772 sceneSession->NotifyForceHideChange(true);
2773 }
2774 }
2775 } else {
2776 if (property->GetHideNonSystemFloatingWindows()) {
2777 systemTopSceneSessionMap_.erase(persistentId);
2778 notifyAll = forceHideFloatOld && systemTopSceneSessionMap_.empty();
2779 } else if (property->IsFloatingWindowAppType()) {
2780 nonSystemFloatSceneSessionMap_.erase(persistentId);
2781 if (property->GetForceHide()) {
2782 sceneSession->NotifyForceHideChange(false);
2783 }
2784 }
2785 }
2786 if (notifyAll) {
2787 bool forceHideFloatNew = !systemTopSceneSessionMap_.empty();
2788 for (const auto &item : nonSystemFloatSceneSessionMap_) {
2789 auto forceHideSceneSession = item.second;
2790 auto forceHideProperty = forceHideSceneSession->GetSessionProperty();
2791 if (forceHideProperty && forceHideFloatNew != forceHideProperty->GetForceHide()) {
2792 forceHideSceneSession->NotifyForceHideChange(forceHideFloatNew);
2793 }
2794 }
2795 }
2796 }
2797
HandleTurnScreenOn(const sptr<SceneSession> & sceneSession)2798 void SceneSessionManager::HandleTurnScreenOn(const sptr<SceneSession>& sceneSession)
2799 {
2800 #ifdef POWER_MANAGER_ENABLE
2801 auto task = [this, sceneSession]() {
2802 if (sceneSession == nullptr) {
2803 WLOGFE("session is invalid");
2804 return;
2805 }
2806 WLOGFD("Win: %{public}s, is turn on%{public}d",
2807 sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
2808 std::string identity = IPCSkeleton::ResetCallingIdentity();
2809 if (sceneSession->IsTurnScreenOn() && !PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
2810 WLOGI("turn screen on");
2811 PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
2812 }
2813 // set ipc identity to raw
2814 IPCSkeleton::SetCallingIdentity(identity);
2815 };
2816 taskScheduler_->PostAsyncTask(task, "HandleTurnScreenOn");
2817
2818 #else
2819 WLOGFD("Can not found the sub system of PowerMgr");
2820 #endif
2821 }
2822
HandleKeepScreenOn(const sptr<SceneSession> & sceneSession,bool requireLock)2823 void SceneSessionManager::HandleKeepScreenOn(const sptr<SceneSession>& sceneSession, bool requireLock)
2824 {
2825 #ifdef POWER_MANAGER_ENABLE
2826 wptr<SceneSession> weakSceneSession(sceneSession);
2827 auto task = [this, weakSceneSession, requireLock]() {
2828 auto scnSession = weakSceneSession.promote();
2829 if (scnSession == nullptr) {
2830 WLOGFE("session is invalid");
2831 return;
2832 }
2833 if (requireLock && scnSession->keepScreenLock_ == nullptr) {
2834 // reset ipc identity
2835 std::string identity = IPCSkeleton::ResetCallingIdentity();
2836 scnSession->keepScreenLock_ =
2837 PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(scnSession->GetWindowName(),
2838 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
2839 // set ipc identity to raw
2840 IPCSkeleton::SetCallingIdentity(identity);
2841 }
2842 if (scnSession->keepScreenLock_ == nullptr) {
2843 return;
2844 }
2845 bool shouldLock = requireLock && IsSessionVisible(scnSession);
2846 WLOGI("keep screen on: [%{public}s, %{public}d]", scnSession->GetWindowName().c_str(), shouldLock);
2847 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:HandleKeepScreenOn");
2848 ErrCode res;
2849 std::string identity = IPCSkeleton::ResetCallingIdentity();
2850 if (shouldLock) {
2851 res = scnSession->keepScreenLock_->Lock();
2852 } else {
2853 res = scnSession->keepScreenLock_->UnLock();
2854 }
2855 // set ipc identity to raw
2856 IPCSkeleton::SetCallingIdentity(identity);
2857 if (res != ERR_OK) {
2858 WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]",
2859 requireLock, res);
2860 }
2861 };
2862 taskScheduler_->PostAsyncTask(task, "HandleKeepScreenOn");
2863 #else
2864 WLOGFD("Can not found the sub system of PowerMgr");
2865 #endif
2866 }
2867
SetBrightness(const sptr<SceneSession> & sceneSession,float brightness)2868 WSError SceneSessionManager::SetBrightness(const sptr<SceneSession>& sceneSession, float brightness)
2869 {
2870 if (!sceneSession->IsSessionValid()) {
2871 return WSError::WS_ERROR_INVALID_SESSION;
2872 }
2873 if (brightness == sceneSession->GetBrightness()) {
2874 WLOGFD("Session brightness do not change: [%{public}f]", brightness);
2875 return WSError::WS_DO_NOTHING;
2876 }
2877 sceneSession->SetBrightness(brightness);
2878 #ifdef POWERMGR_DISPLAY_MANAGER_ENABLE
2879 if (GetDisplayBrightness() != brightness) {
2880 if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
2881 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
2882 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
2883 } else {
2884 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
2885 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
2886 SetDisplayBrightness(brightness);
2887 }
2888 }
2889 #else
2890 WLOGFD("Can not found the sub system of DisplayPowerMgr");
2891 #endif
2892 brightnessSessionId_ = sceneSession->GetPersistentId();
2893 return WSError::WS_OK;
2894 }
2895
UpdateBrightness(int32_t persistentId)2896 WSError SceneSessionManager::UpdateBrightness(int32_t persistentId)
2897 {
2898 auto sceneSession = GetSceneSession(persistentId);
2899 if (sceneSession == nullptr) {
2900 WLOGFE("session is invalid");
2901 return WSError::WS_ERROR_NULLPTR;
2902 }
2903 if (!(sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
2904 sceneSession->GetSessionInfo().isSystem_)) {
2905 WLOGW("only app main window can set brightness");
2906 return WSError::WS_DO_NOTHING;
2907 }
2908 auto brightness = sceneSession->GetBrightness();
2909 WLOGI("Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), brightness);
2910 if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
2911 if (GetDisplayBrightness() != brightness) {
2912 WLOGI("adjust brightness with default value");
2913 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
2914 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
2915 }
2916 brightnessSessionId_ = INVALID_WINDOW_ID;
2917 } else {
2918 if (GetDisplayBrightness() != brightness) {
2919 WLOGI("adjust brightness with value");
2920 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
2921 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
2922 SetDisplayBrightness(brightness);
2923 }
2924 brightnessSessionId_ = sceneSession->GetPersistentId();
2925 }
2926 return WSError::WS_OK;
2927 }
2928
GetCurrentUserId() const2929 int32_t SceneSessionManager::GetCurrentUserId() const
2930 {
2931 return currentUserId_;
2932 }
2933
SetDisplayBrightness(float brightness)2934 void SceneSessionManager::SetDisplayBrightness(float brightness)
2935 {
2936 displayBrightness_ = brightness;
2937 }
2938
GetDisplayBrightness() const2939 float SceneSessionManager::GetDisplayBrightness() const
2940 {
2941 return displayBrightness_;
2942 }
2943
SetGestureNavigaionEnabled(bool enable)2944 WMError SceneSessionManager::SetGestureNavigaionEnabled(bool enable)
2945 {
2946 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
2947 WLOGFE("SetGestureNavigationEnabled permission denied!");
2948 return WMError::WM_ERROR_NOT_SYSTEM_APP;
2949 }
2950 WLOGFD("SetGestureNavigationEnabled, enable: %{public}d", enable);
2951 gestureNavigationEnabled_ = enable;
2952 auto task = [this, enable]() {
2953 if (!gestureNavigationEnabledChangeFunc_ && !statusBarEnabledChangeFunc_) {
2954 WLOGFE("callback func is null");
2955 return WMError::WM_DO_NOTHING;
2956 }
2957 if (gestureNavigationEnabledChangeFunc_) {
2958 gestureNavigationEnabledChangeFunc_(enable);
2959 }
2960 if (statusBarEnabledChangeFunc_) {
2961 statusBarEnabledChangeFunc_(enable);
2962 }
2963 return WMError::WM_OK;
2964 };
2965 return taskScheduler_->PostSyncTask(task, "SetGestureNavigaionEnabled");
2966 }
2967
SetFocusedSession(int32_t persistentId)2968 WSError SceneSessionManager::SetFocusedSession(int32_t persistentId)
2969 {
2970 if (focusedSessionId_ == persistentId) {
2971 WLOGI("Focus scene not change, id: %{public}d", focusedSessionId_);
2972 return WSError::WS_DO_NOTHING;
2973 }
2974 lastFocusedSessionId_ = focusedSessionId_;
2975 focusedSessionId_ = persistentId;
2976 return WSError::WS_OK;
2977 }
2978
GetFocusedSession() const2979 int32_t SceneSessionManager::GetFocusedSession() const
2980 {
2981 return focusedSessionId_;
2982 }
2983
GetFocusWindowInfo(FocusChangeInfo & focusInfo)2984 void SceneSessionManager::GetFocusWindowInfo(FocusChangeInfo& focusInfo)
2985 {
2986 auto sceneSession = GetSceneSession(focusedSessionId_);
2987 if (sceneSession) {
2988 WLOGFD("Get focus session info success");
2989 focusInfo.windowId_ = sceneSession->GetWindowId();
2990 focusInfo.displayId_ = static_cast<DisplayId>(0);
2991 focusInfo.pid_ = sceneSession->GetCallingPid();
2992 focusInfo.uid_ = sceneSession->GetCallingUid();
2993 focusInfo.windowType_ = sceneSession->GetWindowType();
2994 focusInfo.abilityToken_ = sceneSession->GetAbilityToken();
2995 }
2996 return;
2997 }
2998
IsValidDigitString(const std::string & windowIdStr)2999 static bool IsValidDigitString(const std::string& windowIdStr)
3000 {
3001 if (windowIdStr.empty()) {
3002 return false;
3003 }
3004 for (char ch : windowIdStr) {
3005 if ((ch >= '0' && ch <= '9')) {
3006 continue;
3007 }
3008 WLOGFE("invalid window id");
3009 return false;
3010 }
3011 return true;
3012 }
3013
RegisterSessionExceptionFunc(const sptr<SceneSession> & sceneSession)3014 void SceneSessionManager::RegisterSessionExceptionFunc(const sptr<SceneSession>& sceneSession)
3015 {
3016 if (sceneSession == nullptr) {
3017 WLOGFE("session is nullptr");
3018 return;
3019 }
3020 NotifySessionExceptionFunc sessionExceptionFunc = [this](const SessionInfo& info, bool needRemoveSession = false) {
3021 auto task = [this, info]() {
3022 auto scnSession = GetSceneSession(info.persistentId_);
3023 if (scnSession == nullptr) {
3024 WLOGFW("[WMSLife]NotifySessionExceptionFunc, Not found session, id: %{public}d", info.persistentId_);
3025 return;
3026 }
3027 if (listenerController_ == nullptr) {
3028 WLOGFW("[WMSLife]NotifySessionExceptionFunc, listenerController_ is nullptr");
3029 return;
3030 }
3031 if (scnSession->GetSessionInfo().isSystem_) {
3032 WLOGFW("[WMSLife]NotifySessionExceptionFunc, id: %{public}d is system", scnSession->GetPersistentId());
3033 return;
3034 }
3035 WLOGFI("[WMSLife]NotifySessionExceptionFunc, errorCode: %{public}d, id: %{public}d", info.errorCode,
3036 info.persistentId_);
3037 if (info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_LOAD_TIMEOUT) ||
3038 info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_FOREGROUND_TIMEOUT)) {
3039 WLOGFD("[WMSLife]NotifySessionClosed when ability load timeout or foreground timeout, id: %{public}d",
3040 info.persistentId_);
3041 listenerController_->NotifySessionClosed(info.persistentId_);
3042 }
3043 };
3044 taskScheduler_->PostVoidSyncTask(task, "sessionException");
3045 };
3046 sceneSession->SetSessionExceptionListener(sessionExceptionFunc, false);
3047 WLOGFD("[WMSLife]RegisterSessionExceptionFunc success, id: %{public}d", sceneSession->GetPersistentId());
3048 }
3049
RegisterSessionSnapshotFunc(const sptr<SceneSession> & sceneSession)3050 void SceneSessionManager::RegisterSessionSnapshotFunc(const sptr<SceneSession>& sceneSession)
3051 {
3052 if (sceneSession == nullptr) {
3053 WLOGFE("session is nullptr");
3054 return;
3055 }
3056 NotifySessionSnapshotFunc sessionSnapshotFunc = [this](int32_t persistentId) {
3057 auto task = [this, persistentId]() {
3058 auto scnSession = GetSceneSession(persistentId);
3059 if (scnSession == nullptr) {
3060 WLOGFW("NotifySessionSnapshotFunc, Not found session, id: %{public}d", persistentId);
3061 return;
3062 }
3063 if (scnSession->GetSessionInfo().isSystem_) {
3064 WLOGFW("NotifySessionSnapshotFunc, id: %{public}d is system", scnSession->GetPersistentId());
3065 return;
3066 }
3067 auto abilityInfoPtr = scnSession->GetSessionInfo().abilityInfo;
3068 if (abilityInfoPtr == nullptr) {
3069 WLOGFW("NotifySessionSnapshotFunc, abilityInfoPtr is nullptr");
3070 return;
3071 }
3072 if (listenerController_ == nullptr) {
3073 WLOGFW("NotifySessionSnapshotFunc, listenerController_ is nullptr");
3074 return;
3075 }
3076 if (!(abilityInfoPtr->excludeFromMissions)) {
3077 listenerController_->NotifySessionSnapshotChanged(persistentId);
3078 }
3079 };
3080 taskScheduler_->PostVoidSyncTask(task, "sessionSnapshot");
3081 };
3082 sceneSession->SetSessionSnapshotListener(sessionSnapshotFunc);
3083 WLOGFD("RegisterSessionSnapshotFunc success, id: %{public}d", sceneSession->GetPersistentId());
3084 }
3085
NotifySessionForCallback(const sptr<SceneSession> & scnSession,const bool needRemoveSession)3086 void SceneSessionManager::NotifySessionForCallback(const sptr<SceneSession>& scnSession, const bool needRemoveSession)
3087 {
3088 if (scnSession == nullptr) {
3089 WLOGFW("NotifySessionForCallback, scnSession is nullptr");
3090 return;
3091 }
3092 if (scnSession->GetSessionInfo().isSystem_) {
3093 WLOGFW("NotifySessionForCallback, id: %{public}d is system", scnSession->GetPersistentId());
3094 return;
3095 }
3096 WLOGFI("NotifySessionForCallback, id: %{public}d, needRemoveSession: %{public}u", scnSession->GetPersistentId(),
3097 static_cast<uint32_t>(needRemoveSession));
3098 if (scnSession->GetSessionInfo().appIndex_ != 0) {
3099 WLOGFI("NotifySessionDestroy, appIndex_: %{public}d, id: %{public}d",
3100 scnSession->GetSessionInfo().appIndex_, scnSession->GetPersistentId());
3101 listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
3102 return;
3103 }
3104 if (needRemoveSession) {
3105 WLOGFI("NotifySessionDestroy, needRemoveSession, id: %{public}d", scnSession->GetPersistentId());
3106 listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
3107 return;
3108 }
3109 if (scnSession->GetSessionInfo().abilityInfo == nullptr) {
3110 WLOGFW("abilityInfo is nullptr, id: %{public}d", scnSession->GetPersistentId());
3111 } else if ((scnSession->GetSessionInfo().abilityInfo)->removeMissionAfterTerminate ||
3112 (scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
3113 WLOGFI("NotifySessionDestroy, removeMissionAfterTerminate or excludeFromMissions, id: %{public}d",
3114 scnSession->GetPersistentId());
3115 listenerController_->NotifySessionDestroyed(scnSession->GetPersistentId());
3116 return;
3117 }
3118 WLOGFI("NotifySessionClosed, id: %{public}d", scnSession->GetPersistentId());
3119 listenerController_->NotifySessionClosed(scnSession->GetPersistentId());
3120 }
3121
3122
NotifyWindowInfoChangeFromSession(int32_t persistentId)3123 void SceneSessionManager::NotifyWindowInfoChangeFromSession(int32_t persistentId)
3124 {
3125 WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d", persistentId);
3126 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
3127 if (sceneSession == nullptr) {
3128 WLOGFE("sceneSession nullptr");
3129 return;
3130 }
3131
3132 SceneInputManager::GetInstance().NotifyWindowInfoChangeFromSession(sceneSession);
3133 }
3134
IsSessionVisible(const sptr<SceneSession> & session)3135 bool SceneSessionManager::IsSessionVisible(const sptr<SceneSession>& session)
3136 {
3137 if (session == nullptr) {
3138 return false;
3139 }
3140 const auto& state = session->GetSessionState();
3141 if (WindowHelper::IsSubWindow(session->GetWindowType())) {
3142 const auto& parentSceneSession = GetSceneSession(session->GetParentPersistentId());
3143 if (parentSceneSession == nullptr) {
3144 WLOGFW("Can not find parent for this sub window, id: %{public}d", session->GetPersistentId());
3145 return false;
3146 }
3147 const auto& parentState = parentSceneSession->GetSessionState();
3148 if (session->IsVisible() || (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND)) {
3149 if (parentState == SessionState::STATE_INACTIVE || parentState == SessionState::STATE_BACKGROUND) {
3150 WLOGFD("Parent of this sub window is at background, id: %{public}d", session->GetPersistentId());
3151 return false;
3152 }
3153 WLOGFD("Sub window is at foreground, id: %{public}d", session->GetPersistentId());
3154 return true;
3155 }
3156 WLOGFD("Sub window is at background, id: %{public}d", session->GetPersistentId());
3157 return false;
3158 }
3159
3160 if (session->IsVisible() || state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND) {
3161 WLOGFD("Window is at foreground, id: %{public}d", session->GetPersistentId());
3162 return true;
3163 }
3164 WLOGFD("Window is at background, id: %{public}d", session->GetPersistentId());
3165 return false;
3166 }
3167
DumpSessionInfo(const sptr<SceneSession> & session,std::ostringstream & oss)3168 void SceneSessionManager::DumpSessionInfo(const sptr<SceneSession>& session, std::ostringstream& oss)
3169 {
3170 if (session == nullptr) {
3171 return;
3172 }
3173 int32_t zOrder = IsSessionVisible(session) ? static_cast<int32_t>(session->GetZOrder()) : -1;
3174 WSRect rect = session->GetSessionRect();
3175 std::string sName;
3176 if (session->GetSessionInfo().isSystem_) {
3177 sName = session->GetSessionInfo().abilityName_;
3178 } else {
3179 sName = session->GetWindowName();
3180 }
3181 uint32_t flag = 0;
3182 uint64_t displayId = INVALID_SCREEN_ID;
3183 if (session->GetSessionProperty()) {
3184 flag = session->GetSessionProperty()->GetWindowFlags();
3185 displayId = session->GetSessionProperty()->GetDisplayId();
3186 }
3187 uint32_t orientation = 0;
3188 const std::string& windowName = sName.size() <= WINDOW_NAME_MAX_LENGTH ?
3189 sName : sName.substr(0, WINDOW_NAME_MAX_LENGTH);
3190 // std::setw is used to set the output width and different width values are set to keep the format aligned.
3191 oss << std::left << std::setw(WINDOW_NAME_MAX_WIDTH) << windowName
3192 << std::left << std::setw(DISPLAY_NAME_MAX_WIDTH) << displayId
3193 << std::left << std::setw(PID_MAX_WIDTH) << session->GetCallingPid()
3194 << std::left << std::setw(PARENT_ID_MAX_WIDTH) << session->GetPersistentId()
3195 << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowType())
3196 << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowMode())
3197 << std::left << std::setw(VALUE_MAX_WIDTH) << flag
3198 << std::left << std::setw(VALUE_MAX_WIDTH) << zOrder
3199 << std::left << std::setw(ORIEN_MAX_WIDTH) << orientation
3200 << "[ "
3201 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posX_
3202 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posY_
3203 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.width_
3204 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.height_
3205 << "]"
3206 << " [ "
3207 << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetX()
3208 << std::left << std::setw(OFFSET_MAX_WIDTH) << session->GetOffsetY()
3209 << "]"
3210 << " [ "
3211 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleX()
3212 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetScaleY()
3213 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotX()
3214 << std::left << std::setw(SCALE_MAX_WIDTH) << session->GetPivotY()
3215 << "]"
3216 << std::endl;
3217 }
3218
DumpAllAppSessionInfo(std::ostringstream & oss,const std::map<int32_t,sptr<SceneSession>> & sceneSessionMap)3219 void SceneSessionManager::DumpAllAppSessionInfo(std::ostringstream& oss,
3220 const std::map<int32_t, sptr<SceneSession>>& sceneSessionMap)
3221 {
3222 oss << std::endl << "Current mission lists:" << std::endl;
3223 oss << " MissionList Type #NORMAL" << std::endl;
3224 for (const auto& elem : sceneSessionMap) {
3225 auto curSession = elem.second;
3226 if (curSession == nullptr) {
3227 WLOGFW("curSession is nullptr");
3228 continue;
3229 }
3230 if (curSession->GetSessionInfo().isSystem_ ||
3231 curSession->GetWindowType() < WindowType::APP_MAIN_WINDOW_BASE ||
3232 curSession->GetWindowType() >= WindowType::APP_MAIN_WINDOW_END) {
3233 WLOGFW("No need to dump, id: %{public}d, isSystem: %{public}d, windowType: %{public}d",
3234 curSession->GetPersistentId(), curSession->GetSessionInfo().isSystem_, curSession->GetWindowType());
3235 continue;
3236 }
3237
3238 const auto& sessionInfo = curSession->GetSessionInfo();
3239 std::string isActive = curSession->IsActive() ? "FOREGROUND" : "BACKGROUND";
3240 oss << " Mission ID #" << curSession->GetPersistentId() << " mission name #" << "[#"
3241 << sessionInfo.bundleName_ << ":" << sessionInfo.moduleName_ << ":" << sessionInfo.abilityName_
3242 << "]" << " lockedState #0" << std::endl;
3243 oss << " app name [" << sessionInfo.bundleName_ << "]" << std::endl;
3244 oss << " main name [" << sessionInfo.abilityName_ << "]" << std::endl;
3245 oss << " bundle name [" << sessionInfo.bundleName_ << "]" << std::endl;
3246 oss << " ability type [PAGE]" << std::endl;
3247 oss << " state #" << isActive.c_str() << std::endl;
3248 oss << " app state #" << isActive.c_str() << std::endl;
3249 oss << " callee connections:" << std::endl;
3250 }
3251 }
3252
GetAllSessionDumpInfo(std::string & dumpInfo)3253 WSError SceneSessionManager::GetAllSessionDumpInfo(std::string& dumpInfo)
3254 {
3255 int32_t screenGroupId = 0;
3256 std::ostringstream oss;
3257 oss << "-------------------------------------ScreenGroup " << screenGroupId
3258 << "-------------------------------------" << std::endl;
3259 oss << "WindowName DisplayId Pid WinId Type Mode Flag ZOrd Orientation [ x y w h ]"
3260 << " [ OffsetX OffsetY ] [ ScaleX ScaleY PivotX PivotY ]"
3261 << std::endl;
3262
3263 std::vector<sptr<SceneSession>> allSession;
3264 std::vector<sptr<SceneSession>> backgroundSession;
3265 std::map<int32_t, sptr<SceneSession>> sceneSessionMapCopy;
3266 {
3267 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3268 sceneSessionMapCopy = sceneSessionMap_;
3269 }
3270 for (const auto& elem : sceneSessionMapCopy) {
3271 auto curSession = elem.second;
3272 if (curSession == nullptr) {
3273 continue;
3274 }
3275 if (IsSessionVisible(curSession)) {
3276 allSession.push_back(curSession);
3277 } else {
3278 backgroundSession.push_back(curSession);
3279 }
3280 }
3281 allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
3282 uint32_t count = 0;
3283 for (const auto& session : allSession) {
3284 if (session == nullptr) {
3285 continue;
3286 }
3287 if (count == static_cast<uint32_t>(allSession.size() - backgroundSession.size())) {
3288 oss << "---------------------------------------------------------------------------------------"
3289 << std::endl;
3290 }
3291 DumpSessionInfo(session, oss);
3292 count++;
3293 }
3294 oss << "Focus window: " << GetFocusedSession() << std::endl;
3295 oss << "Total window num: " << sceneSessionMapCopy.size() << std::endl;
3296 DumpAllAppSessionInfo(oss, sceneSessionMapCopy);
3297 dumpInfo.append(oss.str());
3298 return WSError::WS_OK;
3299 }
3300
SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc & func)3301 void SceneSessionManager::SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc& func)
3302 {
3303 dumpRootSceneFunc_ = func;
3304 }
3305
DumpSessionElementInfo(const sptr<SceneSession> & session,const std::vector<std::string> & params,std::string & dumpInfo)3306 void SceneSessionManager::DumpSessionElementInfo(const sptr<SceneSession>& session,
3307 const std::vector<std::string>& params, std::string& dumpInfo)
3308 {
3309 std::vector<std::string> resetParams;
3310 resetParams.assign(params.begin() + 2, params.end()); // 2: params num
3311 if (resetParams.empty()) {
3312 WLOGI("do not dump ui info");
3313 return;
3314 }
3315
3316 if (!session->GetSessionInfo().isSystem_) {
3317 WLOGFI("Dump normal session, not system");
3318 dumpInfoFuture_.ResetLock({});
3319 session->DumpSessionElementInfo(resetParams);
3320 std::vector<std::string> infos = dumpInfoFuture_.GetResult(2000); // 2000: wait for 2000ms
3321 for (auto& info: infos) {
3322 dumpInfo.append(info).append("\n");
3323 }
3324 } else {
3325 WLOGFI("Dump system session");
3326 std::vector<std::string> infos;
3327 dumpRootSceneFunc_(resetParams, infos);
3328 for (auto& info: infos) {
3329 dumpInfo.append(info).append("\n");
3330 }
3331 }
3332 }
3333
GetSpecifiedSessionDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params,const std::string & strId)3334 WSError SceneSessionManager::GetSpecifiedSessionDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params,
3335 const std::string& strId)
3336 {
3337 uint64_t persistentId = std::stoull(strId);
3338 auto session = GetSceneSession(persistentId);
3339 if (session == nullptr) {
3340 return WSError::WS_ERROR_INVALID_PARAM;
3341 }
3342
3343 WSRect rect = session->GetSessionRect();
3344 std::string isVisible = session->GetVisible() ? "true" : "false";
3345 std::string Focusable = session->GetFocusable() ? "true" : "false";
3346 std::string DecoStatus = session->GetSessionProperty()->IsDecorEnable() ? "true" : "false";
3347 bool PrivacyMode = session->GetSessionProperty()->GetSystemPrivacyMode() ||
3348 session->GetSessionProperty()->GetPrivacyMode();
3349 std::string isPrivacyMode = PrivacyMode ? "true" : "false";
3350 bool isFirstFrameAvailable = true;
3351 std::ostringstream oss;
3352 oss << "WindowName: " << session->GetWindowName() << std::endl;
3353 oss << "DisplayId: " << 0 << std::endl;
3354 oss << "WinId: " << session->GetPersistentId() << std::endl;
3355 oss << "Pid: " << session->GetCallingPid() << std::endl;
3356 oss << "Type: " << static_cast<uint32_t>(session->GetWindowType()) << std::endl;
3357 oss << "Mode: " << static_cast<uint32_t>(session->GetWindowMode()) << std::endl;
3358 oss << "Flag: " << session->GetSessionProperty()->GetWindowFlags() << std::endl;
3359 oss << "Orientation: " << static_cast<uint32_t>(session->GetRequestedOrientation()) << std::endl;
3360 oss << "FirstFrameCallbackCalled: " << isFirstFrameAvailable << std::endl;
3361 oss << "IsVisible: " << isVisible << std::endl;
3362 oss << "Focusable: " << Focusable << std::endl;
3363 oss << "DecoStatus: " << DecoStatus << std::endl;
3364 oss << "isPrivacyMode: " << isPrivacyMode << std::endl;
3365 oss << "WindowRect: " << "[ "
3366 << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_
3367 << " ]" << std::endl;
3368 oss << "Offset: " << "[ "
3369 << session->GetOffsetX() << ", " << session->GetOffsetY() << " ]" << std::endl;
3370 oss << "Scale: " << "[ "
3371 << session->GetScaleX() << ", " << session->GetScaleY() << ", "
3372 << session->GetPivotX() << ", " << session->GetPivotY()
3373 << " ]" << std::endl;
3374 dumpInfo.append(oss.str());
3375
3376 DumpSessionElementInfo(session, params, dumpInfo);
3377 return WSError::WS_OK;
3378 }
3379
NotifyDumpInfoResult(const std::vector<std::string> & info)3380 void SceneSessionManager::NotifyDumpInfoResult(const std::vector<std::string>& info)
3381 {
3382 dumpInfoFuture_.SetValue(info);
3383 WLOGFD("NotifyDumpInfoResult");
3384 }
3385
GetSessionDumpInfo(const std::vector<std::string> & params,std::string & dumpInfo)3386 WSError SceneSessionManager::GetSessionDumpInfo(const std::vector<std::string>& params, std::string& dumpInfo)
3387 {
3388 if (!(SessionPermission::IsSACalling() || SessionPermission::IsStartByHdcd())) {
3389 WLOGFE("GetSessionDumpInfo permission denied!");
3390 return WSError::WS_ERROR_INVALID_PERMISSION;
3391 }
3392 auto task = [this, params, &dumpInfo]() {
3393 if (params.size() == 1 && params[0] == ARG_DUMP_ALL) { // 1: params num
3394 return GetAllSessionDumpInfo(dumpInfo);
3395 }
3396 if (params.size() >= 2 && params[0] == ARG_DUMP_WINDOW && IsValidDigitString(params[1])) { // 2: params num
3397 return GetSpecifiedSessionDumpInfo(dumpInfo, params, params[1]);
3398 }
3399 return WSError::WS_ERROR_INVALID_OPERATION;
3400 };
3401 return taskScheduler_->PostSyncTask(task);
3402 }
3403
FocusIDChange(int32_t persistentId,sptr<SceneSession> & sceneSession)3404 void FocusIDChange(int32_t persistentId, sptr<SceneSession>& sceneSession)
3405 {
3406 // notify RS
3407 WLOGFD("current focus session: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
3408 " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", persistentId,
3409 sceneSession->GetSessionProperty()->GetWindowName().c_str(),
3410 sceneSession->GetSessionInfo().bundleName_.c_str(),
3411 sceneSession->GetSessionInfo().abilityName_.c_str(),
3412 sceneSession->GetCallingPid(), sceneSession->GetCallingUid());
3413 uint64_t focusNodeId = 0; // 0 means invalid
3414 if (sceneSession->GetSurfaceNode() == nullptr) {
3415 WLOGFW("focused window surfaceNode is null");
3416 } else {
3417 focusNodeId = sceneSession->GetSurfaceNode()->GetId();
3418 }
3419 FocusAppInfo appInfo = {
3420 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
3421 sceneSession->GetSessionInfo().bundleName_,
3422 sceneSession->GetSessionInfo().abilityName_, focusNodeId};
3423 RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
3424 }
3425
3426 // ordered vector by compare func
GetSceneSessionVector(CmpFunc cmp)3427 std::vector<std::pair<int32_t, sptr<SceneSession>>> SceneSessionManager::GetSceneSessionVector(CmpFunc cmp)
3428 {
3429 std::vector<std::pair<int32_t, sptr<SceneSession>>> ret;
3430 {
3431 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3432 for (auto& iter : sceneSessionMap_) {
3433 ret.push_back(iter);
3434 }
3435 }
3436 std::sort(ret.begin(), ret.end(), cmp);
3437 return ret;
3438 }
3439
TraverseSessionTree(TraverseFunc func,bool isFromTopToBottom)3440 void SceneSessionManager::TraverseSessionTree(TraverseFunc func, bool isFromTopToBottom)
3441 {
3442 if (isFromTopToBottom) {
3443 TraverseSessionTreeFromTopToBottom(func);
3444 } else {
3445 TraverseSessionTreeFromBottomToTop(func);
3446 }
3447 return;
3448 }
3449
TraverseSessionTreeFromTopToBottom(TraverseFunc func)3450 void SceneSessionManager::TraverseSessionTreeFromTopToBottom(TraverseFunc func)
3451 {
3452 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
3453 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
3454 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
3455 return lhsZOrder < rhsZOrder;
3456 };
3457 auto sceneSessionVector = GetSceneSessionVector(cmp);
3458
3459 for (auto iter = sceneSessionVector.rbegin(); iter != sceneSessionVector.rend(); ++iter) {
3460 auto session = iter->second;
3461 if (session == nullptr) {
3462 WLOGFE("session is nullptr");
3463 continue;
3464 }
3465 if (func(session)) {
3466 return;
3467 }
3468 }
3469 return;
3470 }
3471
TraverseSessionTreeFromBottomToTop(TraverseFunc func)3472 void SceneSessionManager::TraverseSessionTreeFromBottomToTop(TraverseFunc func)
3473 {
3474 // std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3475 CmpFunc cmp = [](std::pair<int32_t, sptr<SceneSession>>& lhs, std::pair<int32_t, sptr<SceneSession>>& rhs) {
3476 uint32_t lhsZOrder = lhs.second != nullptr ? lhs.second->GetZOrder() : 0;
3477 uint32_t rhsZOrder = rhs.second != nullptr ? rhs.second->GetZOrder() : 0;
3478 return lhsZOrder < rhsZOrder;
3479 };
3480 auto sceneSessionVector = GetSceneSessionVector(cmp);
3481 // std::map<int32_t, sptr<SceneSession>>::iterator iter;
3482 for (auto iter = sceneSessionVector.begin(); iter != sceneSessionVector.end(); ++iter) {
3483 auto session = iter->second;
3484 if (session == nullptr) {
3485 WLOGFE("session is nullptr");
3486 continue;
3487 }
3488 if (func(session)) {
3489 return;
3490 }
3491 }
3492 return;
3493 }
3494
RequestFocusStatus(int32_t persistentId,bool isFocused,bool byForeground)3495 WMError SceneSessionManager::RequestFocusStatus(int32_t persistentId, bool isFocused, bool byForeground)
3496 {
3497 auto task = [this, persistentId, isFocused, byForeground]() {
3498 if (isFocused) {
3499 RequestSessionFocus(persistentId, byForeground);
3500 } else {
3501 RequestSessionUnfocus(persistentId);
3502 }
3503 };
3504 taskScheduler_->PostAsyncTask(task, "RequestFocusStatus" + std::to_string(persistentId));
3505 return WMError::WM_OK;
3506 }
3507
RequestAllAppSessionUnfocus()3508 void SceneSessionManager::RequestAllAppSessionUnfocus()
3509 {
3510 auto task = [this]() {
3511 RequestAllAppSessionUnfocusInner();
3512 };
3513 taskScheduler_->PostAsyncTask(task, "RequestAllAppSessionUnfocus");
3514 return;
3515 }
3516
3517 /**
3518 * request focus and ignore its state
3519 * only used when app main window start before foreground
3520 */
RequestSessionFocusImmediately(int32_t persistentId)3521 WSError SceneSessionManager::RequestSessionFocusImmediately(int32_t persistentId)
3522 {
3523 WLOGFI("[WMSFocus]RequestSessionFocusImmediately, id: %{public}d", persistentId);
3524 // base block
3525 WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
3526 if (basicCheckRet != WSError::WS_OK) {
3527 return basicCheckRet;
3528 }
3529 auto sceneSession = GetSceneSession(persistentId);
3530 if (sceneSession == nullptr) {
3531 WLOGFE("[WMSComm]session is nullptr");
3532 return WSError::WS_ERROR_INVALID_SESSION;
3533 }
3534 if (!sceneSession->GetFocusable()) {
3535 WLOGFD("[WMSFocus]session is not focusable!");
3536 return WSError::WS_DO_NOTHING;
3537 }
3538 // specific block
3539 WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, true);
3540 if (specificCheckRet != WSError::WS_OK) {
3541 return specificCheckRet;
3542 }
3543
3544 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
3545 if (!IsSessionVisible(sceneSession)) {
3546 needBlockNotifyFocusStatusUntilForeground_ = true;
3547 }
3548 ShiftFocus(sceneSession);
3549 return WSError::WS_OK;
3550 }
3551
RequestSessionFocus(int32_t persistentId,bool byForeground)3552 WSError SceneSessionManager::RequestSessionFocus(int32_t persistentId, bool byForeground)
3553 {
3554 WLOGFI("[WMSFocus]RequestSessionFocus, id: %{public}d, by foreground: %{public}d", persistentId, byForeground);
3555 WSError basicCheckRet = RequestFocusBasicCheck(persistentId);
3556 if (basicCheckRet != WSError::WS_OK) {
3557 return basicCheckRet;
3558 }
3559 auto sceneSession = GetSceneSession(persistentId);
3560 if (sceneSession == nullptr) {
3561 WLOGFE("[WMSComm]session is nullptr");
3562 return WSError::WS_ERROR_INVALID_SESSION;
3563 }
3564 if (!sceneSession->GetFocusable() || !IsSessionVisible(sceneSession)) {
3565 WLOGFD("[WMSFocus]session is not focusable or not visible!");
3566 return WSError::WS_DO_NOTHING;
3567 }
3568 // subwindow/dialog state block
3569 if ((WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
3570 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
3571 GetSceneSession(sceneSession->GetParentPersistentId()) &&
3572 !IsSessionVisible(GetSceneSession(sceneSession->GetParentPersistentId()))) {
3573 WLOGFD("[WMSFocus]parent session id: %{public}d is not visible!", sceneSession->GetParentPersistentId());
3574 return WSError::WS_DO_NOTHING;
3575 }
3576 // specific block
3577 WSError specificCheckRet = RequestFocusSpecificCheck(sceneSession, byForeground);
3578 if (specificCheckRet != WSError::WS_OK) {
3579 return specificCheckRet;
3580 }
3581
3582 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
3583 needBlockNotifyFocusStatusUntilForeground_ = false;
3584 ShiftFocus(sceneSession);
3585 return WSError::WS_OK;
3586 }
3587
RequestSessionUnfocus(int32_t persistentId)3588 WSError SceneSessionManager::RequestSessionUnfocus(int32_t persistentId)
3589 {
3590 WLOGFI("[WMSFocus]RequestSessionUnfocus, id: %{public}d", persistentId);
3591 if (persistentId == INVALID_SESSION_ID) {
3592 WLOGFE("id is invalid");
3593 return WSError::WS_ERROR_INVALID_SESSION;
3594 }
3595 auto focusedSession = GetSceneSession(focusedSessionId_);
3596 if (persistentId != focusedSessionId_ &&
3597 !(focusedSession && focusedSession->GetParentPersistentId() == persistentId)) {
3598 WLOGFD("[WMSFocus]unfocused id cannot request unfocus!");
3599 return WSError::WS_DO_NOTHING;
3600 }
3601 // if pop menu created by desktop request unfocus, back to desktop
3602 auto lastSession = GetSceneSession(lastFocusedSessionId_);
3603 if (focusedSession && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_SYSTEM_FLOAT &&
3604 lastSession && lastSession->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP &&
3605 RequestSessionFocus(lastFocusedSessionId_, false) == WSError::WS_OK) {
3606 WLOGFD("[WMSFocus]focus is back to desktop");
3607 return WSError::WS_OK;
3608 }
3609 auto nextSession = GetNextFocusableSession(persistentId);
3610
3611 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
3612 needBlockNotifyFocusStatusUntilForeground_ = false;
3613 return ShiftFocus(nextSession);
3614 }
3615
RequestAllAppSessionUnfocusInner()3616 WSError SceneSessionManager::RequestAllAppSessionUnfocusInner()
3617 {
3618 WLOGFI("[WMSFocus]RequestAllAppSessionUnfocusInner");
3619 auto focusedSession = GetSceneSession(focusedSessionId_);
3620 if (!focusedSession) {
3621 WLOGFE("[WMSFocus]focused session is null");
3622 return WSError::WS_DO_NOTHING;
3623 }
3624 if (!focusedSession->IsAppSession()) {
3625 WLOGW("[WMFocus]Focused session is non app session: %{public}d", focusedSessionId_);
3626 return WSError::WS_DO_NOTHING;
3627 }
3628 auto nextSession = GetTopFocusableNonAppSession();
3629
3630 needBlockNotifyUnfocusStatus_ = needBlockNotifyFocusStatusUntilForeground_;
3631 needBlockNotifyFocusStatusUntilForeground_ = false;
3632 return ShiftFocus(nextSession);
3633 }
3634
RequestFocusBasicCheck(int32_t persistentId)3635 WSError SceneSessionManager::RequestFocusBasicCheck(int32_t persistentId)
3636 {
3637 // basic focus rule
3638 if (persistentId == INVALID_SESSION_ID) {
3639 WLOGFE("[WMSFocus]id is invalid!");
3640 return WSError::WS_ERROR_INVALID_SESSION;
3641 }
3642 if (persistentId == focusedSessionId_) {
3643 WLOGFD("[WMSFocus]request id has been focused!");
3644 return WSError::WS_DO_NOTHING;
3645 }
3646 return WSError::WS_OK;
3647 }
3648
RequestFocusSpecificCheck(sptr<SceneSession> & sceneSession,bool byForeground)3649 WSError SceneSessionManager::RequestFocusSpecificCheck(sptr<SceneSession>& sceneSession, bool byForeground)
3650 {
3651 int32_t persistentId = sceneSession->GetPersistentId();
3652 // dialog get focus
3653 if ((sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW ||
3654 SessionHelper::IsSubWindow(sceneSession->GetWindowType())) &&
3655 ProcessDialogRequestFocusImmdediately(sceneSession) == WSError::WS_OK) {
3656 WLOGFD("[WMSFocus]dialog is focused");
3657 return WSError::WS_DO_NOTHING;
3658 }
3659 // blocking-type session will block lower zOrder request focus
3660 auto focusedSession = GetSceneSession(focusedSessionId_);
3661 if (focusedSession) {
3662 bool isBlockingType = focusedSession->IsAppSession() ||
3663 (focusedSession->GetSessionInfo().isSystem_ && focusedSession->GetBlockingFocus());
3664 if (byForeground && isBlockingType && sceneSession->GetZOrder() < focusedSession->GetZOrder()) {
3665 WLOGFD("[WMSFocus]session %{public}d is lower than focused session %{public}d",
3666 persistentId, focusedSessionId_);
3667 return WSError::WS_DO_NOTHING;
3668 }
3669 // temp check
3670 if (isBlockingType && focusedSession->GetWindowType() == WindowType::WINDOW_TYPE_KEYGUARD &&
3671 sceneSession->GetZOrder() < focusedSession->GetZOrder()) {
3672 WLOGFD("[WMSFocus]Lower session %{public}d cannot request focus from keyguard!", persistentId);
3673 return WSError::WS_DO_NOTHING;
3674 }
3675 }
3676 return WSError::WS_OK;
3677 }
3678
GetNextFocusableSession(int32_t persistentId)3679 sptr<SceneSession> SceneSessionManager::GetNextFocusableSession(int32_t persistentId)
3680 {
3681 WLOGFD("[WMSFocus]GetNextFocusableSession, id: %{public}d", persistentId);
3682 bool previousFocusedSessionFound = false;
3683 sptr<SceneSession> ret = nullptr;
3684 auto func = [this, persistentId, &previousFocusedSessionFound, &ret](sptr<SceneSession> session) {
3685 if (session == nullptr) {
3686 return false;
3687 }
3688 bool parentVisible = true;
3689 if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
3690 session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) &&
3691 GetSceneSession(session->GetParentPersistentId()) &&
3692 !IsSessionVisible(GetSceneSession(session->GetParentPersistentId()))) {
3693 parentVisible = false;
3694 }
3695 if (previousFocusedSessionFound && session->GetFocusable() && IsSessionVisible(session) && parentVisible) {
3696 ret = session;
3697 return true;
3698 }
3699 if (session->GetPersistentId() == persistentId) {
3700 previousFocusedSessionFound = true;
3701 }
3702 return false;
3703 };
3704 TraverseSessionTree(func, true);
3705 return ret;
3706 }
3707
GetTopFocusableNonAppSession()3708 sptr<SceneSession> SceneSessionManager::GetTopFocusableNonAppSession()
3709 {
3710 WLOGFD("[WMSFocus]GetTopFocusableNonAppSession.");
3711 sptr<SceneSession> ret = nullptr;
3712 auto func = [this, &ret](sptr<SceneSession> session) {
3713 if (session == nullptr) {
3714 return false;
3715 }
3716 if (session->IsAppSession()) {
3717 return true;
3718 }
3719 if (session->GetFocusable() && IsSessionVisible(session)) {
3720 ret = session;
3721 }
3722 return false;
3723 };
3724 TraverseSessionTree(func, false);
3725 return ret;
3726 }
3727
SetShiftFocusListener(const ProcessShiftFocusFunc & func)3728 void SceneSessionManager::SetShiftFocusListener(const ProcessShiftFocusFunc& func)
3729 {
3730 WLOGFD("[WMSFocus]SetShiftFocusListener");
3731 shiftFocusFunc_ = func;
3732 }
3733
SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc & func)3734 void SceneSessionManager::SetSCBFocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
3735 {
3736 WLOGFD("[WMSFocus]SetSCBFocusedListener");
3737 notifySCBAfterFocusedFunc_ = func;
3738 }
3739
SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc & func)3740 void SceneSessionManager::SetSCBUnfocusedListener(const NotifySCBAfterUpdateFocusFunc& func)
3741 {
3742 WLOGFD("[WMSFocus]SetSCBUnfocusedListener");
3743 notifySCBAfterUnfocusedFunc_ = func;
3744 }
3745
SetShowPiPMainWindowListener(const ProcessShowPiPMainWindowFunc & func)3746 void SceneSessionManager::SetShowPiPMainWindowListener(const ProcessShowPiPMainWindowFunc& func)
3747 {
3748 WLOGFD("SetShowPiPMainWindowListener");
3749 showPiPMainWindowFunc_ = func;
3750 }
3751
SetCallingWindowIdChangeListenser(const ProcessCallingWindowIdChangeFunc & func)3752 void SceneSessionManager::SetCallingWindowIdChangeListenser(const ProcessCallingWindowIdChangeFunc& func)
3753 {
3754 WLOGFD("SetCallingWindowIdChangeListenser");
3755 callingWindowIdChangeFunc_ = func;
3756 }
3757
SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc & func)3758 void SceneSessionManager::SetStartUIAbilityErrorListener(const ProcessStartUIAbilityErrorFunc& func)
3759 {
3760 WLOGFD("SetStartUIAbilityErrorListener");
3761 startUIAbilityErrorFunc_ = func;
3762 }
3763
ShiftFocus(sptr<SceneSession> & nextSession)3764 WSError SceneSessionManager::ShiftFocus(sptr<SceneSession>& nextSession)
3765 {
3766 // unfocus
3767 int32_t focusedId = focusedSessionId_;
3768 auto focusedSession = GetSceneSession(focusedSessionId_);
3769 UpdateFocusStatus(focusedSession, false);
3770 // focus
3771 int32_t nextId = INVALID_SESSION_ID;
3772 if (nextSession == nullptr) {
3773 std::string sessionLog(GetAllSessionFocusInfo());
3774 WLOGFW("[WMSFocus]ShiftFocus to nullptr! id: %{public}d, info: %{public}s", focusedSessionId_, sessionLog.c_str());
3775 } else {
3776 nextId = nextSession->GetPersistentId();
3777 }
3778 UpdateFocusStatus(nextSession, true);
3779 bool scbPrevFocus = focusedSession && focusedSession->GetSessionInfo().isSystem_;
3780 bool scbCurrFocus = nextSession && nextSession->GetSessionInfo().isSystem_;
3781 if (!scbPrevFocus && scbCurrFocus) {
3782 if (notifySCBAfterFocusedFunc_ != nullptr) {
3783 notifySCBAfterFocusedFunc_();
3784 }
3785 } else if (scbPrevFocus && !scbCurrFocus) {
3786 if (notifySCBAfterUnfocusedFunc_ != nullptr) {
3787 notifySCBAfterUnfocusedFunc_();
3788 }
3789 }
3790 WLOGFI("[WMSFocus]ShiftFocus, focusedId: %{public}d, nextId: %{public}d", focusedId, nextId);
3791 return WSError::WS_OK;
3792 }
3793
UpdateFocusStatus(sptr<SceneSession> & sceneSession,bool isFocused)3794 void SceneSessionManager::UpdateFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
3795 {
3796 if (sceneSession == nullptr) {
3797 if (isFocused) {
3798 SetFocusedSession(INVALID_SESSION_ID);
3799 }
3800 return;
3801 }
3802 WLOGFI("[WMSFocus]UpdateFocusStatus, name: %{public}s, id: %{public}d, isFocused: %{public}d",
3803 sceneSession->GetWindowNameAllType().c_str(), sceneSession->GetPersistentId(), isFocused);
3804 // set focused
3805 if (isFocused) {
3806 SetFocusedSession(sceneSession->GetPersistentId());
3807 }
3808 sceneSession->UpdateFocus(isFocused);
3809 if ((isFocused && !needBlockNotifyFocusStatusUntilForeground_) || (!isFocused && !needBlockNotifyUnfocusStatus_)) {
3810 NotifyFocusStatus(sceneSession, isFocused);
3811 }
3812 }
3813
NotifyFocusStatus(sptr<SceneSession> & sceneSession,bool isFocused)3814 void SceneSessionManager::NotifyFocusStatus(sptr<SceneSession>& sceneSession, bool isFocused)
3815 {
3816 if (sceneSession == nullptr) {
3817 WLOGFE("[WMSComm]session is nullptr");
3818 return;
3819 }
3820 int32_t persistentId = sceneSession->GetPersistentId();
3821
3822 WLOGFI("[WMSFocus]NotifyFocusStatus, name: %{public}s/%{public}s/%{public}s, id: %{public}d, isFocused: %{public}d",
3823 sceneSession->GetSessionInfo().bundleName_.c_str(),
3824 sceneSession->GetSessionInfo().abilityName_.c_str(),
3825 sceneSession->GetWindowNameAllType().c_str(),
3826 sceneSession->GetPersistentId(), isFocused);
3827 if (isFocused) {
3828 if (IsSessionVisible(sceneSession)) {
3829 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_FOCUSED);
3830 }
3831 UpdateBrightness(focusedSessionId_);
3832 FocusIDChange(sceneSession->GetPersistentId(), sceneSession);
3833 if (shiftFocusFunc_ != nullptr) {
3834 shiftFocusFunc_(persistentId);
3835 }
3836 }
3837 // notify window manager
3838 sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(
3839 sceneSession->GetWindowId(),
3840 static_cast<DisplayId>(0),
3841 sceneSession->GetCallingPid(),
3842 sceneSession->GetCallingUid(),
3843 sceneSession->GetWindowType(),
3844 sceneSession->GetAbilityToken()
3845 );
3846 #ifdef EFFICIENCY_MANAGER_ENABLE
3847 SuspendManager::SuspendManagerClient::GetInstance().ThawOneApplication(focusChangeInfo->uid_,
3848 "", "THAW_BY_FOCUS_CHANGED");
3849 #endif // EFFICIENCY_MANAGER_ENABLE
3850 SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
3851 WSError res = WSError::WS_OK;
3852 res = sceneSession->NotifyFocusStatus(isFocused);
3853 std::string sName = "FoucusWindow:";
3854 if (sceneSession->GetSessionInfo().isSystem_) {
3855 sName += sceneSession->GetSessionInfo().abilityName_;
3856 } else {
3857 sName += sceneSession->GetWindowName();
3858 }
3859 if (isFocused) {
3860 StartAsyncTrace(HITRACE_TAG_WINDOW_MANAGER, sName, sceneSession->GetPersistentId());
3861 } else {
3862 FinishAsyncTrace(HITRACE_TAG_WINDOW_MANAGER, sName, sceneSession->GetPersistentId());
3863 }
3864 if (res != WSError::WS_OK) {
3865 return;
3866 }
3867 // notify listenerController
3868 if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
3869 if (isFocused) {
3870 WLOGFD("[WMSFocus]NotifySessionFocused, id: %{public}d", sceneSession->GetPersistentId());
3871 listenerController_->NotifySessionFocused(sceneSession->GetPersistentId());
3872 } else {
3873 WLOGFD("[WMSFocus]NotifySessionUnfocused, id: %{public}d", sceneSession->GetPersistentId());
3874 listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
3875 }
3876 }
3877 return;
3878 }
3879
GetAllSessionFocusInfo()3880 std::string SceneSessionManager::GetAllSessionFocusInfo()
3881 {
3882 std::ostringstream os;
3883 auto func = [&os](sptr<SceneSession> session) {
3884 if (session == nullptr) {
3885 WLOGE("sceneSession is nullptr");
3886 return false;
3887 }
3888 os << "WindowName: " << session->GetWindowName() << ", id: " << session->GetPersistentId() <<
3889 " ,focusable: "<< session->GetFocusable() << ";";
3890 return false;
3891 };
3892 TraverseSessionTree(func, true);
3893 return os.str();
3894 }
3895
UpdateFocus(int32_t persistentId,bool isFocused)3896 WSError SceneSessionManager::UpdateFocus(int32_t persistentId, bool isFocused)
3897 {
3898 auto task = [this, persistentId, isFocused]() {
3899 // notify session and client
3900 auto sceneSession = GetSceneSession(persistentId);
3901 if (sceneSession == nullptr) {
3902 WLOGFE("UpdateFocus could not find window, persistentId:%{public}d", persistentId);
3903 return WSError::WS_ERROR_INVALID_WINDOW;
3904 }
3905 WLOGFI("UpdateFocus, name: %{public}s, id: %{public}d, isFocused: %{public}u",
3906 sceneSession->GetWindowName().c_str(), persistentId, static_cast<uint32_t>(isFocused));
3907 // focusId change
3908 if (isFocused) {
3909 SetFocusedSession(persistentId);
3910 UpdateBrightness(focusedSessionId_);
3911 FocusIDChange(persistentId, sceneSession);
3912 } else if (persistentId == GetFocusedSession()) {
3913 SetFocusedSession(INVALID_SESSION_ID);
3914 }
3915 // notify window manager
3916 sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(
3917 sceneSession->GetWindowId(),
3918 static_cast<DisplayId>(0),
3919 sceneSession->GetCallingPid(),
3920 sceneSession->GetCallingUid(),
3921 sceneSession->GetWindowType(),
3922 sceneSession->GetAbilityToken()
3923 );
3924 SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
3925 WSError res = WSError::WS_OK;
3926 res = sceneSession->UpdateFocus(isFocused);
3927 if (res != WSError::WS_OK) {
3928 return res;
3929 }
3930 WLOGFI("UpdateFocus, id: %{public}d, isSystem: %{public}d", sceneSession->GetPersistentId(),
3931 sceneSession->GetSessionInfo().isSystem_);
3932 if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
3933 if (isFocused) {
3934 WLOGFD("NotifySessionFocused, id: %{public}d", sceneSession->GetPersistentId());
3935 listenerController_->NotifySessionFocused(sceneSession->GetPersistentId());
3936 } else {
3937 WLOGFD("NotifySessionUnfocused, id: %{public}d", sceneSession->GetPersistentId());
3938 listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
3939 }
3940 }
3941 return WSError::WS_OK;
3942 };
3943
3944 taskScheduler_->PostAsyncTask(task, "UpdateFocus" + std::to_string(persistentId));
3945 return WSError::WS_OK;
3946 }
3947
UpdateWindowMode(int32_t persistentId,int32_t windowMode)3948 WSError SceneSessionManager::UpdateWindowMode(int32_t persistentId, int32_t windowMode)
3949 {
3950 WLOGFD("update window mode, id: %{public}d, mode: %{public}d", persistentId, windowMode);
3951 auto sceneSession = GetSceneSession(persistentId);
3952 if (sceneSession == nullptr) {
3953 WLOGFE("could not find window, persistentId:%{public}d", persistentId);
3954 return WSError::WS_ERROR_INVALID_WINDOW;
3955 }
3956 WindowMode mode = static_cast<WindowMode>(windowMode);
3957 return sceneSession->UpdateWindowMode(mode);
3958 }
3959
3960 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,MMI::PointerEvent::PointerItem & pointerItem)3961 static void FillSecCompEnhanceData(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
3962 MMI::PointerEvent::PointerItem& pointerItem)
3963 {
3964 struct PointerEventData {
3965 double x;
3966 double y;
3967 uint64_t time;
3968 } pointerEventData = {
3969 .x = pointerItem.GetDisplayX(),
3970 .y = pointerItem.GetDisplayY(),
3971 .time = pointerEvent->GetActionTime()
3972 };
3973
3974 const uint32_t MAX_HMAC_SIZE = 64;
3975 uint8_t outBuf[MAX_HMAC_SIZE] = { 0 };
3976 uint8_t *enhanceData = reinterpret_cast<uint8_t *>(&outBuf[0]);
3977 uint32_t enhanceDataLen = MAX_HMAC_SIZE;
3978 if (Security::SecurityComponent::SecCompEnhanceKit::GetPointerEventEnhanceData(&pointerEventData,
3979 sizeof(pointerEventData), enhanceData, enhanceDataLen) == 0) {
3980 pointerEvent->SetEnhanceData(std::vector<uint8_t>(outBuf, outBuf + enhanceDataLen));
3981 }
3982 }
3983 #endif // SECURITY_COMPONENT_MANAGER_ENABLE
3984
SendTouchEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,uint32_t zIndex)3985 WSError SceneSessionManager::SendTouchEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent, uint32_t zIndex)
3986 {
3987 if (!pointerEvent) {
3988 WLOGFE("pointerEvent is null");
3989 return WSError::WS_ERROR_NULLPTR;
3990 }
3991 MMI::PointerEvent::PointerItem pointerItem;
3992 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
3993 WLOGFE("Failed to get pointerItem");
3994 return WSError::WS_ERROR_INVALID_PARAM;
3995 }
3996 #ifdef SECURITY_COMPONENT_MANAGER_ENABLE
3997 FillSecCompEnhanceData(pointerEvent, pointerItem);
3998 #endif
3999 MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent, static_cast<float>(zIndex));
4000 return WSError::WS_OK;
4001 }
4002
SetScreenLocked(const bool isScreenLocked)4003 void SceneSessionManager::SetScreenLocked(const bool isScreenLocked)
4004 {
4005 isScreenLocked_ = isScreenLocked;
4006 }
4007
IsScreenLocked() const4008 bool SceneSessionManager::IsScreenLocked() const
4009 {
4010 return isScreenLocked_;
4011 }
4012
RegisterWindowChanged(const WindowChangedFunc & func)4013 void SceneSessionManager::RegisterWindowChanged(const WindowChangedFunc& func)
4014 {
4015 WindowChangedFunc_ = func;
4016 }
4017
UpdatePrivateStateAndNotify(uint32_t persistentId)4018 void SceneSessionManager::UpdatePrivateStateAndNotify(uint32_t persistentId)
4019 {
4020 int counts = GetSceneSessionPrivacyModeCount();
4021 bool hasPrivateWindow = (counts != 0);
4022 ScreenSessionManagerClient::GetInstance().SetScreenPrivacyState(hasPrivateWindow);
4023 }
4024
GetSceneSessionPrivacyModeCount()4025 int SceneSessionManager::GetSceneSessionPrivacyModeCount()
4026 {
4027 auto countFunc = [](const std::pair<int32_t, sptr<SceneSession>>& sessionPair) -> bool {
4028 sptr<SceneSession> sceneSession = sessionPair.second;
4029 bool isForeground = sceneSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
4030 sceneSession->GetSessionState() == SessionState::STATE_ACTIVE;
4031 if (isForeground && sceneSession->GetParentSession() != nullptr) {
4032 isForeground &= sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_FOREGROUND ||
4033 sceneSession->GetParentSession()->GetSessionState() == SessionState::STATE_ACTIVE;
4034 }
4035 bool isPrivate = sceneSession->GetSessionProperty() != nullptr &&
4036 sceneSession->GetSessionProperty()->GetPrivacyMode();
4037 bool IsSystemWindowVisible = sceneSession->GetSessionInfo().isSystem_ && sceneSession->IsVisible();
4038 return (isForeground || IsSystemWindowVisible) && isPrivate;
4039 };
4040 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4041 return std::count_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), countFunc);
4042 }
4043
RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)4044 void SceneSessionManager::RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
4045 {
4046 NotifySessionStateChangeNotifyManagerFunc func = [this](int32_t persistentId, const SessionState& state) {
4047 this->OnSessionStateChange(persistentId, state);
4048 };
4049 if (sceneSession == nullptr) {
4050 WLOGFE("session is nullptr");
4051 return;
4052 }
4053 sceneSession->SetSessionStateChangeNotifyManagerListener(func);
4054 WLOGFD("RegisterSessionStateChangeFunc success");
4055 }
4056
RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)4057 void SceneSessionManager::RegisterSessionInfoChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
4058 {
4059 wptr<SceneSessionManager> weakSessionManager = this;
4060 NotifySessionInfoChangeNotifyManagerFunc func = [weakSessionManager](int32_t persistentId) {
4061 auto sceneSessionManager = weakSessionManager.promote();
4062 if (sceneSessionManager == nullptr) {
4063 return;
4064 }
4065 sceneSessionManager->NotifyWindowInfoChangeFromSession(persistentId);
4066 };
4067 if (sceneSession == nullptr) {
4068 WLOGFE("session is nullptr");
4069 return;
4070 }
4071 sceneSession->SetSessionInfoChangeNotifyManagerListener(func);
4072 }
4073
RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession> & sceneSession)4074 void SceneSessionManager::RegisterRequestFocusStatusNotifyManagerFunc(sptr<SceneSession>& sceneSession)
4075 {
4076 NotifyRequestFocusStatusNotifyManagerFunc func =
4077 [this](int32_t persistentId, const bool isFocused, const bool byForeground) {
4078 this->RequestFocusStatus(persistentId, isFocused, byForeground);
4079 };
4080 if (sceneSession == nullptr) {
4081 WLOGFE("session is nullptr");
4082 return;
4083 }
4084 sceneSession->SetRequestFocusStatusNotifyManagerListener(func);
4085 WLOGFD("RegisterSessionUpdateFocusStatusFunc success");
4086 }
4087
RegisterGetStateFromManagerFunc(sptr<SceneSession> & sceneSession)4088 void SceneSessionManager::RegisterGetStateFromManagerFunc(sptr<SceneSession>& sceneSession)
4089 {
4090 GetStateFromManagerFunc func = [this](const ManagerState key) {
4091 switch (key)
4092 {
4093 case ManagerState::MANAGER_STATE_SCREEN_LOCKED:
4094 return this->IsScreenLocked();
4095 break;
4096 default:
4097 return false;
4098 break;
4099 }
4100 };
4101 if (sceneSession == nullptr) {
4102 WLOGFE("session is nullptr");
4103 return;
4104 }
4105 sceneSession->SetGetStateFromManagerListener(func);
4106 WLOGFD("RegisterGetStateFromManagerFunc success");
4107 }
4108
OnSessionStateChange(int32_t persistentId,const SessionState & state)4109 __attribute__((no_sanitize("cfi"))) void SceneSessionManager::OnSessionStateChange(
4110 int32_t persistentId, const SessionState& state)
4111 {
4112 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:OnSessionStateChange%d", persistentId);
4113 WLOGFD("Session state change, id: %{public}d, state:%{public}u", persistentId, state);
4114 auto sceneSession = GetSceneSession(persistentId);
4115 if (sceneSession == nullptr) {
4116 WLOGFD("session is nullptr");
4117 return;
4118 }
4119 switch (state) {
4120 case SessionState::STATE_FOREGROUND:
4121 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
4122 persistentId == focusedSessionId_) {
4123 if (needBlockNotifyFocusStatusUntilForeground_) {
4124 needBlockNotifyUnfocusStatus_ = false;
4125 needBlockNotifyFocusStatusUntilForeground_ = false;
4126 NotifyFocusStatus(sceneSession, true);
4127 }
4128 } else {
4129 RequestSessionFocus(persistentId, true);
4130 }
4131 UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), true);
4132 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
4133 HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
4134 UpdatePrivateStateAndNotify(persistentId);
4135 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
4136 ProcessSubSessionForeground(sceneSession);
4137 }
4138 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
4139 ProcessPiPSessionForeground(sceneSession);
4140 }
4141 break;
4142 case SessionState::STATE_BACKGROUND:
4143 RequestSessionUnfocus(persistentId);
4144 UpdateForceHideState(sceneSession, sceneSession->GetSessionProperty(), false);
4145 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
4146 HandleKeepScreenOn(sceneSession, false);
4147 UpdatePrivateStateAndNotify(persistentId);
4148 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
4149 ProcessSubSessionBackground(sceneSession);
4150 }
4151 break;
4152 default:
4153 break;
4154 }
4155 }
4156
ProcessSubSessionForeground(sptr<SceneSession> & sceneSession)4157 void SceneSessionManager::ProcessSubSessionForeground(sptr<SceneSession>& sceneSession)
4158 {
4159 if (sceneSession == nullptr) {
4160 WLOGFD("session is nullptr");
4161 return;
4162 }
4163 for (const auto& subSession : sceneSession->GetSubSession()) {
4164 if (subSession == nullptr) {
4165 WLOGFD("sub session is nullptr");
4166 continue;
4167 }
4168 const auto& state = subSession->GetSessionState();
4169 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
4170 WLOGFD("sub session is not active");
4171 continue;
4172 }
4173 RequestSessionFocus(subSession->GetPersistentId(), true);
4174 NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
4175 HandleKeepScreenOn(subSession, subSession->IsKeepScreenOn());
4176 }
4177 std::vector<sptr<Session>> dialogVec = sceneSession->GetDialogVector();
4178 for (const auto& dialog : dialogVec) {
4179 if (dialog == nullptr) {
4180 WLOGFD("[WMSDialog] dialog is nullptr");
4181 continue;
4182 }
4183 const auto& state = dialog->GetSessionState();
4184 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
4185 WLOGFD("[WMSDialog] dialog is not active");
4186 continue;
4187 }
4188 auto dialogSession = GetSceneSession(dialog->GetPersistentId());
4189 NotifyWindowInfoChange(dialog->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
4190 if (dialog->GetPersistentId() == focusedSessionId_ && needBlockNotifyFocusStatusUntilForeground_) {
4191 needBlockNotifyUnfocusStatus_ = false;
4192 needBlockNotifyFocusStatusUntilForeground_ = false;
4193 NotifyFocusStatus(dialogSession, true);
4194 }
4195 HandleKeepScreenOn(dialogSession, dialogSession->IsKeepScreenOn());
4196 }
4197 }
4198
ProcessDialogRequestFocusImmdediately(sptr<SceneSession> & sceneSession)4199 WSError SceneSessionManager::ProcessDialogRequestFocusImmdediately(sptr<SceneSession>& sceneSession)
4200 {
4201 // focus must on dialog when APP_MAIN_WINDOW or sub winodw request focus
4202 sptr<SceneSession> mainSession = nullptr;
4203 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
4204 mainSession = sceneSession;
4205 } else if (SessionHelper::IsSubWindow(sceneSession->GetWindowType())) {
4206 mainSession = GetSceneSession(sceneSession->GetParentPersistentId());
4207 }
4208 if (mainSession == nullptr) {
4209 WLOGFD("[WMSFocus]main window is nullptr");
4210 return WSError::WS_DO_NOTHING;
4211 }
4212 std::vector<sptr<Session>> dialogVec = mainSession->GetDialogVector();
4213 if (std::find_if(dialogVec.begin(), dialogVec.end(),
4214 [this](sptr<Session>& iter) { return iter && iter->GetPersistentId() == focusedSessionId_; })
4215 != dialogVec.end()) {
4216 WLOGFD("[WMSDialog] dialog id: %{public}d has been focused!", focusedSessionId_);
4217 return WSError::WS_OK;
4218 }
4219 WSError ret = WSError::WS_DO_NOTHING;
4220 for (auto dialog : dialogVec) {
4221 if (dialog == nullptr) {
4222 continue;
4223 }
4224 // no need to consider order, since rule of zOrder
4225 if (RequestSessionFocusImmediately(dialog->GetPersistentId()) == WSError::WS_OK) {
4226 ret = WSError::WS_OK;
4227 }
4228 }
4229 return ret;
4230 }
4231
ProcessSubSessionBackground(sptr<SceneSession> & sceneSession)4232 void SceneSessionManager::ProcessSubSessionBackground(sptr<SceneSession>& sceneSession)
4233 {
4234 if (sceneSession == nullptr) {
4235 WLOGFD("session is nullptr");
4236 return;
4237 }
4238 for (const auto& subSession : sceneSession->GetSubSession()) {
4239 if (subSession == nullptr) {
4240 WLOGFD("sub session is nullptr");
4241 continue;
4242 }
4243 const auto& state = subSession->GetSessionState();
4244 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
4245 WLOGFD("sub session is not active");
4246 continue;
4247 }
4248 NotifyWindowInfoChange(subSession->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
4249 HandleKeepScreenOn(subSession, false);
4250 UpdatePrivateStateAndNotify(subSession->GetPersistentId());
4251 }
4252 std::vector<sptr<Session>> dialogVec = sceneSession->GetDialogVector();
4253 for (const auto& dialog : dialogVec) {
4254 if (dialog == nullptr) {
4255 WLOGFD("[WMSDialog] dialog is nullptr");
4256 continue;
4257 }
4258 auto dialogSession = GetSceneSession(dialog->GetPersistentId());
4259 NotifyWindowInfoChange(dialog->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
4260 HandleKeepScreenOn(dialogSession, false);
4261 UpdatePrivateStateAndNotify(dialog->GetPersistentId());
4262 }
4263 }
4264
SetWindowFlags(const sptr<SceneSession> & sceneSession,const sptr<WindowSessionProperty> & property)4265 WSError SceneSessionManager::SetWindowFlags(const sptr<SceneSession>& sceneSession,
4266 const sptr<WindowSessionProperty>& property)
4267 {
4268 if (sceneSession == nullptr) {
4269 WLOGFD("session is nullptr");
4270 return WSError::WS_ERROR_NULLPTR;
4271 }
4272 auto sessionProperty = sceneSession->GetSessionProperty();
4273 if (sessionProperty == nullptr) {
4274 return WSError::WS_ERROR_NULLPTR;
4275 }
4276 uint32_t flags = property->GetWindowFlags();
4277 uint32_t oldFlags = sessionProperty->GetWindowFlags();
4278 if (((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED) ||
4279 (oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) &&
4280 !property->GetSystemCalling()) {
4281 WLOGFE("Set window flags permission denied");
4282 return WSError::WS_ERROR_NOT_SYSTEM_APP;
4283 }
4284 sessionProperty->SetWindowFlags(flags);
4285 CheckAndNotifyWaterMarkChangedResult();
4286 if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
4287 sceneSession->OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
4288 }
4289 WLOGFI("SetWindowFlags end, flags: %{public}u", flags);
4290 return WSError::WS_OK;
4291 }
4292
CheckAndNotifyWaterMarkChangedResult()4293 void SceneSessionManager::CheckAndNotifyWaterMarkChangedResult()
4294 {
4295 bool currentWaterMarkShowState = false;
4296 {
4297 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4298 for (const auto& iter: sceneSessionMap_) {
4299 auto& session = iter.second;
4300 if (!session || !session->GetSessionProperty()) {
4301 continue;
4302 }
4303 bool hasWaterMark = session->GetSessionProperty()->GetWindowFlags()
4304 & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK);
4305 if (hasWaterMark && session->GetVisible()) {
4306 currentWaterMarkShowState = true;
4307 break;
4308 }
4309 }
4310 }
4311 if (lastWaterMarkShowState_ != currentWaterMarkShowState) {
4312 lastWaterMarkShowState_ = currentWaterMarkShowState;
4313 NotifyWaterMarkFlagChangedResult(currentWaterMarkShowState);
4314 }
4315 return;
4316 }
4317
NotifyWaterMarkFlagChangedResult(bool hasWaterMark)4318 WSError SceneSessionManager::NotifyWaterMarkFlagChangedResult(bool hasWaterMark)
4319 {
4320 WLOGFI("WaterMark status : %{public}u", static_cast<uint32_t>(hasWaterMark));
4321 SessionManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(hasWaterMark);
4322 return WSError::WS_OK;
4323 }
4324
ProcessPreload(const AppExecFwk::AbilityInfo & abilityInfo) const4325 void SceneSessionManager::ProcessPreload(const AppExecFwk::AbilityInfo &abilityInfo) const
4326 {
4327 if (!bundleMgr_) {
4328 WLOGFE("bundle manager is nullptr.");
4329 return;
4330 }
4331
4332 AAFwk::Want want;
4333 want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name, abilityInfo.moduleName);
4334 auto uid = abilityInfo.uid;
4335 want.SetParam("uid", uid);
4336 bundleMgr_->ProcessPreload(want);
4337 }
4338
NotifyCompleteFirstFrameDrawing(int32_t persistentId)4339 void SceneSessionManager::NotifyCompleteFirstFrameDrawing(int32_t persistentId)
4340 {
4341 auto scnSession = GetSceneSession(persistentId);
4342 if (scnSession == nullptr) {
4343 WLOGFE("[WMSMain] scnSession is nullptr.");
4344 return;
4345 }
4346
4347 const auto& sessionInfo = scnSession->GetSessionInfo();
4348 WLOGFI("[WMSMain] id: %{public}d, app info: [%{public}s %{public}s %{public}s]", scnSession->GetPersistentId(),
4349 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
4350 auto abilityInfoPtr = sessionInfo.abilityInfo;
4351 if (abilityInfoPtr == nullptr) {
4352 WLOGFE("[WMSMain] abilityInfoPtr is nullptr, persistentId: %{public}d", persistentId);
4353 return;
4354 }
4355 if ((listenerController_ != nullptr) && !scnSession->GetSessionInfo().isSystem_ &&
4356 !(abilityInfoPtr->excludeFromMissions)) {
4357 WLOGFD("NotifySessionCreated, id: %{public}d", persistentId);
4358 listenerController_->NotifySessionCreated(persistentId);
4359 }
4360
4361 if (taskScheduler_ == nullptr) {
4362 return;
4363 }
4364 auto task = [this, abilityInfoPtr]() {
4365 ProcessPreload(*abilityInfoPtr);
4366 };
4367 return taskScheduler_->PostAsyncTask(task, "NotifyCompleteFirstFrameDrawing" + std::to_string(persistentId));
4368 }
4369
NotifySessionMovedToFront(int32_t persistentId)4370 void SceneSessionManager::NotifySessionMovedToFront(int32_t persistentId)
4371 {
4372 WLOGFI("NotifySessionMovedToFront, persistentId: %{public}d", persistentId);
4373 auto scnSession = GetSceneSession(persistentId);
4374 if (scnSession == nullptr) {
4375 WLOGFE("session is invalid with %{public}d", persistentId);
4376 return;
4377 }
4378 WLOGFI("NotifySessionMovedToFront, id: %{public}d, isSystem: %{public}d", scnSession->GetPersistentId(),
4379 scnSession->GetSessionInfo().isSystem_);
4380 if (listenerController_ != nullptr &&
4381 !scnSession->GetSessionInfo().isSystem_ &&
4382 (scnSession->GetSessionInfo().abilityInfo) != nullptr &&
4383 !(scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
4384 listenerController_->NotifySessionMovedToFront(persistentId);
4385 }
4386 }
4387
SetSessionLabel(const sptr<IRemoteObject> & token,const std::string & label)4388 WSError SceneSessionManager::SetSessionLabel(const sptr<IRemoteObject> &token, const std::string &label)
4389 {
4390 WLOGFI("run SetSessionLabel");
4391
4392 auto task = [this, &token, &label]() {
4393 auto sceneSession = FindSessionByToken(token);
4394 if (sceneSession == nullptr) {
4395 WLOGFI("fail to find session by token");
4396 return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
4397 }
4398 sceneSession->SetSessionLabel(label);
4399 if (sessionListener_ != nullptr) {
4400 WLOGFI("try to run OnSessionLabelChange");
4401 sessionListener_->OnSessionLabelChange(sceneSession->GetPersistentId(), label);
4402 }
4403 WLOGFI("NotifySessionLabelUpdated, id: %{public}d, isSystem: %{public}d", sceneSession->GetPersistentId(),
4404 sceneSession->GetSessionInfo().isSystem_);
4405 if (listenerController_ != nullptr && !sceneSession->GetSessionInfo().isSystem_) {
4406 WLOGFD("NotifySessionLabelUpdated, id: %{public}d", sceneSession->GetPersistentId());
4407 listenerController_->NotifySessionLabelUpdated(sceneSession->GetPersistentId());
4408 }
4409 return WSError::WS_OK;
4410 };
4411 return taskScheduler_->PostSyncTask(task, "SetSessionLabel");
4412 }
4413
SetSessionIcon(const sptr<IRemoteObject> & token,const std::shared_ptr<Media::PixelMap> & icon)4414 WSError SceneSessionManager::SetSessionIcon(const sptr<IRemoteObject> &token,
4415 const std::shared_ptr<Media::PixelMap> &icon)
4416 {
4417 WLOGFI("run SetSessionIcon");
4418 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
4419 WLOGFE("The caller is not system-app, can not use system-api");
4420 return WSError::WS_ERROR_NOT_SYSTEM_APP;
4421 }
4422
4423 auto task = [this, &token, &icon]() {
4424 auto sceneSession = FindSessionByToken(token);
4425 if (sceneSession == nullptr) {
4426 WLOGFI("fail to find session by token");
4427 return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
4428 }
4429 sceneSession->SetSessionIcon(icon);
4430 if (sessionListener_ != nullptr) {
4431 WLOGFI("try to run OnSessionIconChange.");
4432 sessionListener_->OnSessionIconChange(sceneSession->GetPersistentId(), icon);
4433 }
4434 WLOGFI("NotifySessionIconChanged, id: %{public}d, isSystem: %{public}d", sceneSession->GetPersistentId(),
4435 sceneSession->GetSessionInfo().isSystem_);
4436 if (listenerController_ != nullptr &&
4437 !sceneSession->GetSessionInfo().isSystem_ &&
4438 (sceneSession->GetSessionInfo().abilityInfo) != nullptr &&
4439 !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
4440 WLOGFD("NotifySessionIconChanged, id: %{public}d", sceneSession->GetPersistentId());
4441 listenerController_->NotifySessionIconChanged(sceneSession->GetPersistentId(), icon);
4442 }
4443 return WSError::WS_OK;
4444 };
4445 return taskScheduler_->PostSyncTask(task, "SetSessionIcon");
4446 }
4447
IsValidSessionIds(const std::vector<int32_t> & sessionIds,std::vector<bool> & results)4448 WSError SceneSessionManager::IsValidSessionIds(
4449 const std::vector<int32_t> &sessionIds, std::vector<bool> &results)
4450 {
4451 WLOGFI("run IsValidSessionIds");
4452 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4453 for (auto i = 0; i < static_cast<int32_t>(sessionIds.size()); ++i) {
4454 auto search = sceneSessionMap_.find(sessionIds.at(i));
4455 if (search == sceneSessionMap_.end() || search->second == nullptr) {
4456 results.push_back(false);
4457 continue;
4458 }
4459 results.push_back(true);
4460 }
4461 return WSError::WS_OK;
4462 }
4463
RegisterSessionListener(const sptr<ISessionListener> & listener)4464 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionListener>& listener)
4465 {
4466 WLOGFI("run RegisterSessionListener");
4467 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
4468 WLOGFE("The caller is not system-app, can not use system-api");
4469 return WSError::WS_ERROR_NOT_SYSTEM_APP;
4470 }
4471 if (!SessionPermission::VerifySessionPermission()) {
4472 WLOGFE("The caller has not permission granted");
4473 return WSError::WS_ERROR_INVALID_PERMISSION;
4474 }
4475 auto task = [this, &listener]() {
4476 if (listenerController_ != nullptr) {
4477 return listenerController_->AddSessionListener(listener);
4478 } else {
4479 WLOGFE("The listenerController is nullptr");
4480 return WSError::WS_DO_NOTHING;
4481 }
4482 };
4483 return taskScheduler_->PostSyncTask(task, "AddSessionListener");
4484 }
4485
UnRegisterSessionListener(const sptr<ISessionListener> & listener)4486 WSError SceneSessionManager::UnRegisterSessionListener(const sptr<ISessionListener>& listener)
4487 {
4488 WLOGFI("run UnRegisterSessionListener");
4489 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
4490 WLOGFE("The caller is not system-app, can not use system-api");
4491 return WSError::WS_ERROR_NOT_SYSTEM_APP;
4492 }
4493 if (!SessionPermission::VerifySessionPermission()) {
4494 WLOGFE("The caller has not permission granted");
4495 return WSError::WS_ERROR_INVALID_PERMISSION;
4496 }
4497 auto task = [this, &listener]() {
4498 if (listenerController_ != nullptr) {
4499 listenerController_->DelSessionListener(listener);
4500 return WSError::WS_OK;
4501 } else {
4502 WLOGFE("The listenerController is nullptr");
4503 return WSError::WS_DO_NOTHING;
4504 }
4505 };
4506 return taskScheduler_->PostSyncTask(task, "DelSessionListener");
4507 }
4508
GetSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)4509 WSError SceneSessionManager::GetSessionInfos(const std::string& deviceId, int32_t numMax,
4510 std::vector<SessionInfoBean>& sessionInfos)
4511 {
4512 WLOGFI("run GetSessionInfos");
4513 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
4514 WLOGFE("The caller is not system-app, can not use system-api");
4515 return WSError::WS_ERROR_NOT_SYSTEM_APP;
4516 }
4517 if (!SessionPermission::VerifySessionPermission()) {
4518 WLOGFE("The caller has not permission granted");
4519 return WSError::WS_ERROR_INVALID_PERMISSION;
4520 }
4521 auto task = [this, &deviceId, numMax, &sessionInfos]() {
4522 if (CheckIsRemote(deviceId)) {
4523 int ret = GetRemoteSessionInfos(deviceId, numMax, sessionInfos);
4524 if (ret != ERR_OK) {
4525 return WSError::WS_ERROR_INVALID_PARAM;
4526 } else {
4527 return WSError::WS_OK;
4528 }
4529 }
4530 std::map<int32_t, sptr<SceneSession>>::iterator iter;
4531 std::vector<sptr<SceneSession>> sceneSessionInfos;
4532 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4533 for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
4534 auto sceneSession = iter->second;
4535 if (sceneSession == nullptr) {
4536 WLOGFE("session is nullptr");
4537 continue;
4538 }
4539 auto sessionInfo = sceneSession->GetSessionInfo();
4540 if (sessionInfo.isSystem_) {
4541 WLOGFD("sessionId: %{public}d isSystemScene", sceneSession->GetPersistentId());
4542 continue;
4543 }
4544 auto want = sessionInfo.want;
4545 if (want == nullptr || sessionInfo.bundleName_.empty() || want->GetElement().GetBundleName().empty()) {
4546 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
4547 sceneSession->GetPersistentId());
4548 continue;
4549 }
4550 if (static_cast<int>(sceneSessionInfos.size()) >= numMax) {
4551 break;
4552 }
4553 WLOGFD("GetSessionInfos session: %{public}d, bundleName:%{public}s", sceneSession->GetPersistentId(),
4554 sessionInfo.bundleName_.c_str());
4555 sceneSessionInfos.emplace_back(sceneSession);
4556 }
4557 return SceneSessionConverter::ConvertToMissionInfos(sceneSessionInfos, sessionInfos);
4558 };
4559 return taskScheduler_->PostSyncTask(task, "GetSessionInfos");
4560 }
4561
GetRemoteSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)4562 int SceneSessionManager::GetRemoteSessionInfos(const std::string& deviceId, int32_t numMax,
4563 std::vector<SessionInfoBean>& sessionInfos)
4564 {
4565 WLOGFI("GetRemoteSessionInfos From Dms begin");
4566 DistributedClient dmsClient;
4567 int result = dmsClient.GetMissionInfos(deviceId, numMax, sessionInfos);
4568 if (result != ERR_OK) {
4569 WLOGFE("GetRemoteMissionInfos failed, result = %{public}d", result);
4570 return result;
4571 }
4572 return ERR_OK;
4573 }
4574
GetSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)4575 WSError SceneSessionManager::GetSessionInfo(const std::string& deviceId,
4576 int32_t persistentId, SessionInfoBean& sessionInfo)
4577 {
4578 WLOGFI("run GetSessionInfo");
4579 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
4580 WLOGFE("The caller is not system-app, can not use system-api");
4581 return WSError::WS_ERROR_NOT_SYSTEM_APP;
4582 }
4583 if (!SessionPermission::VerifySessionPermission()) {
4584 WLOGFE("The caller has not permission granted");
4585 return WSError::WS_ERROR_INVALID_PERMISSION;
4586 }
4587 auto task = [this, &deviceId, persistentId, &sessionInfo]() {
4588 if (CheckIsRemote(deviceId)) {
4589 int ret = GetRemoteSessionInfo(deviceId, persistentId, sessionInfo);
4590 if (ret != ERR_OK) {
4591 return WSError::WS_ERROR_INVALID_PARAM;
4592 } else {
4593 return WSError::WS_OK;
4594 }
4595 }
4596 std::map<int32_t, sptr<SceneSession>>::iterator iter;
4597 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4598 iter = sceneSessionMap_.find(persistentId);
4599 if (iter != sceneSessionMap_.end()) {
4600 auto sceneSession = iter->second;
4601 if (sceneSession == nullptr) {
4602 WLOGFE("session: %{public}d is nullptr", persistentId);
4603 return WSError::WS_ERROR_INVALID_PARAM;
4604 }
4605 auto sceneSessionInfo = sceneSession->GetSessionInfo();
4606 if (sceneSessionInfo.isSystem_) {
4607 WLOGFD("sessionId: %{public}d isSystemScene", persistentId);
4608 return WSError::WS_ERROR_INVALID_PARAM;
4609 }
4610 auto want = sceneSessionInfo.want;
4611 if (want == nullptr || sceneSessionInfo.bundleName_.empty() ||
4612 want->GetElement().GetBundleName().empty()) {
4613 WLOGFE("session: %{public}d, want is null or bundleName is empty or want bundleName is empty",
4614 persistentId);
4615 return WSError::WS_ERROR_INTERNAL_ERROR;
4616 }
4617 WLOGFD("GetSessionInfo sessionId:%{public}d bundleName:%{public}s", persistentId,
4618 sceneSessionInfo.bundleName_.c_str());
4619 return SceneSessionConverter::ConvertToMissionInfo(iter->second, sessionInfo);
4620 } else {
4621 WLOGFW("sessionId: %{public}d not found", persistentId);
4622 return WSError::WS_ERROR_INVALID_PARAM;
4623 }
4624 };
4625 return taskScheduler_->PostSyncTask(task, "GetSessionInfo");
4626 }
4627
GetRemoteSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)4628 int SceneSessionManager::GetRemoteSessionInfo(const std::string& deviceId,
4629 int32_t persistentId, SessionInfoBean& sessionInfo)
4630 {
4631 WLOGFI("GetRemoteSessionInfoFromDms begin");
4632 std::vector<SessionInfoBean> sessionVector;
4633 int result = GetRemoteSessionInfos(deviceId, MAX_NUMBER_OF_DISTRIBUTED_SESSIONS, sessionVector);
4634 if (result != ERR_OK) {
4635 return result;
4636 }
4637 for (auto iter = sessionVector.begin(); iter != sessionVector.end(); iter++) {
4638 if (iter->id == persistentId) {
4639 sessionInfo = *iter;
4640 return ERR_OK;
4641 }
4642 }
4643 WLOGFW("missionId not found");
4644 return ERR_INVALID_VALUE;
4645 }
4646
CheckIsRemote(const std::string & deviceId)4647 bool SceneSessionManager::CheckIsRemote(const std::string& deviceId)
4648 {
4649 if (deviceId.empty()) {
4650 WLOGFI("CheckIsRemote: deviceId is empty.");
4651 return false;
4652 }
4653 std::string localDeviceId;
4654 if (!GetLocalDeviceId(localDeviceId)) {
4655 WLOGFE("CheckIsRemote: get local deviceId failed");
4656 return false;
4657 }
4658 if (localDeviceId == deviceId) {
4659 WLOGFI("CheckIsRemote: deviceId is local.");
4660 return false;
4661 }
4662 WLOGFD("CheckIsRemote, deviceId = %{public}s", AnonymizeDeviceId(deviceId).c_str());
4663 return true;
4664 }
4665
GetLocalDeviceId(std::string & localDeviceId)4666 bool SceneSessionManager::GetLocalDeviceId(std::string& localDeviceId)
4667 {
4668 auto localNode = std::make_unique<NodeBasicInfo>();
4669 int32_t errCode = GetLocalNodeDeviceInfo(DM_PKG_NAME.c_str(), localNode.get());
4670 if (errCode != ERR_OK) {
4671 WLOGFE("GetLocalNodeDeviceInfo errCode = %{public}d", errCode);
4672 return false;
4673 }
4674 if (localNode != nullptr) {
4675 localDeviceId = localNode->networkId;
4676 WLOGFD("get local deviceId, deviceId = %{public}s", AnonymizeDeviceId(localDeviceId).c_str());
4677 return true;
4678 }
4679 WLOGFE("localDeviceId null");
4680 return false;
4681 }
4682
AnonymizeDeviceId(const std::string & deviceId)4683 std::string SceneSessionManager::AnonymizeDeviceId(const std::string& deviceId)
4684 {
4685 if (deviceId.length() < NON_ANONYMIZE_LENGTH) {
4686 return EMPTY_DEVICE_ID;
4687 }
4688 std::string anonDeviceId = deviceId.substr(0, NON_ANONYMIZE_LENGTH);
4689 anonDeviceId.append("******");
4690 return anonDeviceId;
4691 }
4692
DumpSessionAll(std::vector<std::string> & infos)4693 WSError SceneSessionManager::DumpSessionAll(std::vector<std::string> &infos)
4694 {
4695 WLOGFI("Dump all session.");
4696 if (!SessionPermission::IsSystemCalling()) {
4697 WLOGFE("DumpSessionAll permission denied!");
4698 return WSError::WS_ERROR_NOT_SYSTEM_APP;
4699 }
4700
4701 auto task = [this, &infos]() {
4702 std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
4703 infos.push_back(dumpInfo);
4704 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4705 for (const auto &item : sceneSessionMap_) {
4706 auto& session = item.second;
4707 if (session) {
4708 session->DumpSessionInfo(infos);
4709 }
4710 }
4711 return WSError::WS_OK;
4712 };
4713
4714 return taskScheduler_->PostSyncTask(task, "DumpSessionAll");
4715 }
4716
DumpSessionWithId(int32_t persistentId,std::vector<std::string> & infos)4717 WSError SceneSessionManager::DumpSessionWithId(int32_t persistentId, std::vector<std::string> &infos)
4718 {
4719 WLOGFI("Dump session with id %{public}d", persistentId);
4720 if (!SessionPermission::IsSystemCalling()) {
4721 WLOGFE("DumpSessionWithId permission denied!");
4722 return WSError::WS_ERROR_NOT_SYSTEM_APP;
4723 }
4724
4725 auto task = [this, persistentId, &infos]() {
4726 std::string dumpInfo = "User ID #" + std::to_string(currentUserId_);
4727 infos.push_back(dumpInfo);
4728 auto session = GetSceneSession(persistentId);
4729 if (session) {
4730 session->DumpSessionInfo(infos);
4731 } else {
4732 infos.push_back("error: invalid mission number, please see 'aa dump --mission-list'.");
4733 }
4734 return WSError::WS_OK;
4735 };
4736
4737 return taskScheduler_->PostSyncTask(task, "DumpSessionWithId");
4738 }
4739
GetAllAbilityInfos(const AAFwk::Want & want,int32_t userId,std::vector<AppExecFwk::AbilityInfo> & abilityInfos)4740 WSError SceneSessionManager::GetAllAbilityInfos(const AAFwk::Want &want, int32_t userId,
4741 std::vector<AppExecFwk::AbilityInfo> &abilityInfos)
4742 {
4743 if (bundleMgr_ == nullptr) {
4744 WLOGFE("bundleMgr_ is nullptr");
4745 return WSError::WS_ERROR_NULLPTR;
4746 }
4747 auto elementName = want.GetElement();
4748 int32_t ret{0};
4749 auto flag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
4750 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
4751 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA |
4752 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_ABILITY) |
4753 static_cast<int32_t>(AppExecFwk::GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_HAP_MODULE));
4754 std::vector<AppExecFwk::BundleInfo> bundleInfos;
4755 if (elementName.GetBundleName().empty() && elementName.GetAbilityName().empty()) {
4756 WLOGFD("want is empty queryAllAbilityInfos");
4757 ret = static_cast<int32_t>(bundleMgr_->GetBundleInfosV9(flag, bundleInfos, userId));
4758 if (ret) {
4759 WLOGFE("Query all ability infos from BMS failed!");
4760 return WSError::WS_ERROR_INVALID_PARAM;
4761 }
4762 } else if (!elementName.GetBundleName().empty()) {
4763 AppExecFwk::BundleInfo bundleInfo;
4764 WLOGFD("bundleName is not empty, query abilityInfo of %{public}s", elementName.GetBundleName().c_str());
4765 ret = static_cast<int32_t>(bundleMgr_->GetBundleInfoV9(elementName.GetBundleName(), flag, bundleInfo, userId));
4766 if (ret) {
4767 WLOGFE("Query ability info from BMS failed!");
4768 return WSError::WS_ERROR_INVALID_PARAM;
4769 }
4770 bundleInfos.push_back(bundleInfo);
4771 } else {
4772 WLOGFE("invalid want:%{public}s", want.ToString().c_str());
4773 return WSError::WS_ERROR_INVALID_PARAM;
4774 }
4775 return GetAbilityInfosFromBundleInfo(bundleInfos, abilityInfos);
4776 }
4777
GetAbilityInfosFromBundleInfo(std::vector<AppExecFwk::BundleInfo> & bundleInfos,std::vector<AppExecFwk::AbilityInfo> & abilityInfos)4778 WSError SceneSessionManager::GetAbilityInfosFromBundleInfo(std::vector<AppExecFwk::BundleInfo> &bundleInfos,
4779 std::vector<AppExecFwk::AbilityInfo> &abilityInfos)
4780 {
4781 if (bundleInfos.empty()) {
4782 WLOGFE("bundleInfos is empty");
4783 return WSError::WS_ERROR_INVALID_PARAM;
4784 }
4785 for (auto bundleInfo: bundleInfos) {
4786 auto hapModulesList = bundleInfo.hapModuleInfos;
4787 if (hapModulesList.empty()) {
4788 WLOGFD("hapModulesList is empty");
4789 continue;
4790 }
4791 for (auto hapModule: hapModulesList) {
4792 auto abilityInfoList = hapModule.abilityInfos;
4793 abilityInfos.insert(abilityInfos.end(), abilityInfoList.begin(), abilityInfoList.end());
4794 }
4795 }
4796 return WSError::WS_OK;
4797 }
4798
TerminateSessionNew(const sptr<AAFwk::SessionInfo> info,bool needStartCaller)4799 WSError SceneSessionManager::TerminateSessionNew(const sptr<AAFwk::SessionInfo> info, bool needStartCaller)
4800 {
4801 if (info == nullptr) {
4802 WLOGFI("sessionInfo is nullptr.");
4803 return WSError::WS_ERROR_INVALID_PARAM;
4804 }
4805 WLOGFI("run TerminateSessionNew, bundleName=%{public}s, needStartCaller=%{public}d",
4806 info->want.GetElement().GetBundleName().c_str(), needStartCaller);
4807 auto task = [this, info, needStartCaller]() {
4808 sptr<SceneSession> sceneSession = FindSessionByToken(info->sessionToken);
4809 if (sceneSession == nullptr) {
4810 WLOGFE("fail to find session by token.");
4811 return WSError::WS_ERROR_INVALID_PARAM;
4812 }
4813 const WSError& errCode = sceneSession->TerminateSessionNew(info, needStartCaller);
4814 return errCode;
4815 };
4816 return taskScheduler_->PostSyncTask(task, "TerminateSessionNew");
4817 }
4818
GetSessionSnapshot(const std::string & deviceId,int32_t persistentId,SessionSnapshot & snapshot,bool isLowResolution)4819 WSError SceneSessionManager::GetSessionSnapshot(const std::string& deviceId, int32_t persistentId,
4820 SessionSnapshot& snapshot, bool isLowResolution)
4821 {
4822 WLOGFI("run GetSessionSnapshot");
4823 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
4824 WLOGFE("The caller is not system-app, can not use system-api");
4825 return WSError::WS_ERROR_NOT_SYSTEM_APP;
4826 }
4827 if (!SessionPermission::VerifySessionPermission()) {
4828 WLOGFE("The caller has not permission granted");
4829 return WSError::WS_ERROR_INVALID_PERMISSION;
4830 }
4831 auto task = [this, &deviceId, persistentId, &snapshot, isLowResolution]() {
4832 if (CheckIsRemote(deviceId)) {
4833 int ret = GetRemoteSessionSnapshotInfo(deviceId, persistentId, snapshot);
4834 if (ret != ERR_OK) {
4835 return WSError::WS_ERROR_INVALID_PARAM;
4836 } else {
4837 return WSError::WS_OK;
4838 }
4839 }
4840 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
4841 if (!sceneSession) {
4842 WLOGFE("fail to find session by persistentId: %{public}d", persistentId);
4843 return WSError::WS_ERROR_INVALID_PARAM;
4844 }
4845 auto sessionInfo = sceneSession->GetSessionInfo();
4846 if (sessionInfo.abilityName_.empty() || sessionInfo.moduleName_.empty() || sessionInfo.bundleName_.empty()) {
4847 WLOGFW("sessionInfo: %{public}d, abilityName or moduleName or bundleName is empty",
4848 sceneSession->GetPersistentId());
4849 }
4850 snapshot.topAbility.SetElementBundleName(&(snapshot.topAbility), sessionInfo.bundleName_.c_str());
4851 snapshot.topAbility.SetElementModuleName(&(snapshot.topAbility), sessionInfo.moduleName_.c_str());
4852 snapshot.topAbility.SetElementAbilityName(&(snapshot.topAbility), sessionInfo.abilityName_.c_str());
4853 auto oriSnapshot = sceneSession->Snapshot();
4854 if (oriSnapshot != nullptr) {
4855 if (isLowResolution) {
4856 OHOS::Media::InitializationOptions options;
4857 options.size.width = oriSnapshot->GetWidth() / 2; // low resolution ratio
4858 options.size.height = oriSnapshot->GetHeight() / 2; // low resolution ratio
4859 std::unique_ptr<OHOS::Media::PixelMap> reducedPixelMap = OHOS::Media::PixelMap::Create(*oriSnapshot, options);
4860 snapshot.snapshot = std::shared_ptr<OHOS::Media::PixelMap>(reducedPixelMap.release());
4861 } else {
4862 snapshot.snapshot = oriSnapshot;
4863 }
4864 }
4865 return WSError::WS_OK;
4866 };
4867 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshot");
4868 }
4869
GetRemoteSessionSnapshotInfo(const std::string & deviceId,int32_t sessionId,AAFwk::MissionSnapshot & sessionSnapshot)4870 int SceneSessionManager::GetRemoteSessionSnapshotInfo(const std::string& deviceId, int32_t sessionId,
4871 AAFwk::MissionSnapshot& sessionSnapshot)
4872 {
4873 WLOGFI("GetRemoteSessionSnapshotInfo begin");
4874 std::unique_ptr<AAFwk::MissionSnapshot> sessionSnapshotPtr = std::make_unique<AAFwk::MissionSnapshot>();
4875 DistributedClient dmsClient;
4876 int result = dmsClient.GetRemoteMissionSnapshotInfo(deviceId, sessionId, sessionSnapshotPtr);
4877 if (result != ERR_OK) {
4878 WLOGFE("GetRemoteMissionSnapshotInfo failed, result = %{public}d", result);
4879 return result;
4880 }
4881 sessionSnapshot = *sessionSnapshotPtr;
4882 return ERR_OK;
4883 }
4884
RegisterSessionListener(const sptr<ISessionChangeListener> sessionListener)4885 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionChangeListener> sessionListener)
4886 {
4887 WLOGFI("run RegisterSessionListener");
4888 if (sessionListener == nullptr) {
4889 return WSError::WS_ERROR_INVALID_SESSION_LISTENER;
4890 }
4891 if (!SessionPermission::VerifySessionPermission()) {
4892 WLOGFE("The caller has not permission granted");
4893 return WSError::WS_ERROR_INVALID_PERMISSION;
4894 }
4895 auto task = [this, sessionListener]() {
4896 sessionListener_ = sessionListener;
4897 return WSError::WS_OK;
4898 };
4899 return taskScheduler_->PostSyncTask(task, "RegisterSessionListener");
4900 }
4901
UnregisterSessionListener()4902 void SceneSessionManager::UnregisterSessionListener()
4903 {
4904 if (!SessionPermission::VerifySessionPermission()) {
4905 WLOGFE("The caller has not permission granted");
4906 return;
4907 }
4908 auto task = [this]() {
4909 sessionListener_ = nullptr;
4910 };
4911 taskScheduler_->PostAsyncTask(task, "UnregisterSessionListener");
4912 }
4913
RequestSceneSessionByCall(const sptr<SceneSession> & sceneSession)4914 WSError SceneSessionManager::RequestSceneSessionByCall(const sptr<SceneSession>& sceneSession)
4915 {
4916 wptr<SceneSession> weakSceneSession(sceneSession);
4917 auto task = [this, weakSceneSession]() {
4918 auto scnSession = weakSceneSession.promote();
4919 if (scnSession == nullptr) {
4920 WLOGFE("session is nullptr");
4921 return WSError::WS_ERROR_NULLPTR;
4922 }
4923 auto persistentId = scnSession->GetPersistentId();
4924 WLOGFI("[WMSMain]RequestSceneSessionByCall persistentId: %{public}d", persistentId);
4925 if (!GetSceneSession(persistentId)) {
4926 WLOGFE("session is invalid with %{public}d", persistentId);
4927 return WSError::WS_ERROR_INVALID_SESSION;
4928 }
4929 auto sessionInfo = scnSession->GetSessionInfo();
4930 auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
4931 if (!abilitySessionInfo) {
4932 return WSError::WS_ERROR_NULLPTR;
4933 }
4934 if (sessionInfo.callState_ == static_cast<uint32_t>(AAFwk::CallToState::BACKGROUND)) {
4935 scnSession->SetActive(false);
4936 } else if (sessionInfo.callState_ == static_cast<uint32_t>(AAFwk::CallToState::FOREGROUND)) {
4937 scnSession->SetActive(true);
4938 } else {
4939 WLOGFE("wrong callState_");
4940 }
4941 WLOGFI("[WMSMain]RequestSceneSessionByCall callState:%{public}d, persistentId: %{public}d",
4942 sessionInfo.callState_, persistentId);
4943 AAFwk::AbilityManagerClient::GetInstance()->CallUIAbilityBySCB(abilitySessionInfo);
4944 scnSession->RemoveLifeCycleTask(LifeCycleTaskType::START);
4945 return WSError::WS_OK;
4946 };
4947 std::string taskName = "RequestSceneSessionByCall:PID:" +
4948 (sceneSession != nullptr ? std::to_string(sceneSession->GetPersistentId()):"nullptr");
4949 taskScheduler_->PostAsyncTask(task, taskName);
4950 return WSError::WS_OK;
4951 }
4952
StartAbilityBySpecified(const SessionInfo & sessionInfo)4953 void SceneSessionManager::StartAbilityBySpecified(const SessionInfo& sessionInfo)
4954 {
4955 auto task = [this, sessionInfo]() {
4956 WLOGFI("StartAbilityBySpecified: bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s",
4957 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
4958 AAFwk::Want want;
4959 want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
4960 AAFwk::AbilityManagerClient::GetInstance()->StartSpecifiedAbilityBySCB(want);
4961 };
4962
4963 taskScheduler_->PostAsyncTask(task, "StartAbilityBySpecified:PID:" + sessionInfo.bundleName_);
4964 }
4965
FindMainWindowWithToken(sptr<IRemoteObject> targetToken)4966 sptr<SceneSession> SceneSessionManager::FindMainWindowWithToken(sptr<IRemoteObject> targetToken)
4967 {
4968 if (!targetToken) {
4969 WLOGFE("Token is null, cannot find main window");
4970 return nullptr;
4971 }
4972
4973 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
4974 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(),
4975 [targetToken](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
4976 if (pair.second->IsTerminated()) {
4977 return false;
4978 }
4979 if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
4980 return pair.second->GetAbilityToken() == targetToken;
4981 }
4982 return false;
4983 });
4984 if (iter == sceneSessionMap_.end()) {
4985 WLOGFE("Cannot find session");
4986 return nullptr;
4987 }
4988 return iter->second;
4989 }
4990
BindDialogSessionTarget(uint64_t persistentId,sptr<IRemoteObject> targetToken)4991 WSError SceneSessionManager::BindDialogSessionTarget(uint64_t persistentId, sptr<IRemoteObject> targetToken)
4992 {
4993 if (!SessionPermission::IsSystemCalling()) {
4994 WLOGFE("[WMSDialog] BindDialogSessionTarget permission denied!");
4995 return WSError::WS_ERROR_NOT_SYSTEM_APP;
4996 }
4997 if (targetToken == nullptr) {
4998 WLOGFE("[WMSDialog] Target token is null");
4999 return WSError::WS_ERROR_NULLPTR;
5000 }
5001
5002 auto task = [this, persistentId, targetToken]() {
5003 auto scnSession = GetSceneSession(static_cast<int32_t>(persistentId));
5004 if (scnSession == nullptr) {
5005 WLOGFE("[WMSDialog] Session is nullptr, persistentId:%{public}" PRIu64, persistentId);
5006 return WSError::WS_ERROR_NULLPTR;
5007 }
5008 if (scnSession->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) {
5009 WLOGFE("[WMSDialog] Session is not dialog window, window type:%{public}u", scnSession->GetWindowType());
5010 return WSError::WS_OK;
5011 }
5012 scnSession->dialogTargetToken_ = targetToken;
5013 sptr<SceneSession> parentSession = FindMainWindowWithToken(targetToken);
5014 if (parentSession == nullptr) {
5015 scnSession->NotifyDestroy();
5016 return WSError::WS_ERROR_INVALID_PARAM;
5017 }
5018 scnSession->SetParentSession(parentSession);
5019 scnSession->SetParentPersistentId(parentSession->GetPersistentId());
5020 UpdateParentSessionForDialog(scnSession, scnSession->GetSessionProperty());
5021 WLOGFI("[WMSDialog] Bind dialog success, dialog id %{public}" PRIu64 ", parentId %{public}d",
5022 persistentId, parentSession->GetPersistentId());
5023 return WSError::WS_OK;
5024 };
5025 return taskScheduler_->PostSyncTask(task, "BindDialogTarget:PID:" + std::to_string(persistentId));
5026 }
5027
OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds)5028 void DisplayChangeListener::OnGetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
5029 std::vector<uint64_t>& surfaceNodeIds)
5030 {
5031 SceneSessionManager::GetInstance().GetSurfaceNodeIdsFromMissionIds(missionIds, surfaceNodeIds);
5032 }
5033
GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t> & missionIds,std::vector<uint64_t> & surfaceNodeIds)5034 WMError SceneSessionManager::GetSurfaceNodeIdsFromMissionIds(std::vector<uint64_t>& missionIds,
5035 std::vector<uint64_t>& surfaceNodeIds)
5036 {
5037 auto isSaCall = SessionPermission::IsSACalling();
5038 if (!isSaCall) {
5039 WLOGFE("The interface only support for sa call");
5040 return WMError::WM_ERROR_INVALID_PERMISSION;
5041 }
5042 auto task = [this, &missionIds, &surfaceNodeIds]() {
5043 std::map<int32_t, sptr<SceneSession>>::iterator iter;
5044 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5045 for (auto missionId : missionIds) {
5046 iter = sceneSessionMap_.find(static_cast<int32_t>(missionId));
5047 if (iter == sceneSessionMap_.end()) {
5048 continue;
5049 }
5050 auto sceneSession = iter->second;
5051 if (sceneSession == nullptr) {
5052 continue;
5053 }
5054 if (sceneSession->GetSurfaceNode() == nullptr) {
5055 continue;
5056 }
5057 surfaceNodeIds.push_back(sceneSession->GetSurfaceNode()->GetId());
5058 if (sceneSession->GetLeashWinSurfaceNode()) {
5059 surfaceNodeIds.push_back(sceneSession->GetLeashWinSurfaceNode()->GetId());
5060 }
5061 }
5062 return WMError::WM_OK;
5063 };
5064 return taskScheduler_->PostSyncTask(task, "GetSurfaceNodeIdsFromMissionIds");
5065 }
5066
RegisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)5067 WMError SceneSessionManager::RegisterWindowManagerAgent(WindowManagerAgentType type,
5068 const sptr<IWindowManagerAgent>& windowManagerAgent)
5069 {
5070 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
5071 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
5072 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
5073 if (!SessionPermission::IsSystemCalling()) {
5074 WLOGFE("RegisterWindowManagerAgent permission denied!");
5075 return WMError::WM_ERROR_NOT_SYSTEM_APP;
5076 }
5077 }
5078 if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
5079 WLOGFE("windowManagerAgent is null");
5080 return WMError::WM_ERROR_NULLPTR;
5081 }
5082 auto task = [this, &windowManagerAgent, type]() {
5083 return SessionManagerAgentController::GetInstance().RegisterWindowManagerAgent(windowManagerAgent, type);
5084 };
5085 return taskScheduler_->PostSyncTask(task, "RegisterWindowManagerAgent");
5086 }
5087
UnregisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)5088 WMError SceneSessionManager::UnregisterWindowManagerAgent(WindowManagerAgentType type,
5089 const sptr<IWindowManagerAgent>& windowManagerAgent)
5090 {
5091 if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR ||
5092 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_GESTURE_NAVIGATION_ENABLED ||
5093 type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WATER_MARK_FLAG) {
5094 if (!SessionPermission::IsSystemCalling()) {
5095 WLOGFE("UnregisterWindowManagerAgent permission denied!");
5096 return WMError::WM_ERROR_NOT_SYSTEM_APP;
5097 }
5098 }
5099 if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
5100 WLOGFE("windowManagerAgent is null");
5101 return WMError::WM_ERROR_NULLPTR;
5102 }
5103 auto task = [this, &windowManagerAgent, type]() {
5104 return SessionManagerAgentController::GetInstance().UnregisterWindowManagerAgent(windowManagerAgent, type);
5105 };
5106 return taskScheduler_->PostSyncTask(task, "UnregisterWindowManagerAgent");
5107 }
5108
UpdateCameraFloatWindowStatus(uint32_t accessTokenId,bool isShowing)5109 void SceneSessionManager::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing)
5110 {
5111 SessionManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
5112 }
5113
StartWindowInfoReportLoop()5114 void SceneSessionManager::StartWindowInfoReportLoop()
5115 {
5116 WLOGFD("Report loop");
5117 if (eventHandler_ == nullptr) {
5118 WLOGFE("Report event null");
5119 return ;
5120 }
5121 if (isReportTaskStart_) {
5122 WLOGFE("Report is ReportTask Start");
5123 return;
5124 }
5125 auto task = [this]() {
5126 WindowInfoReporter::GetInstance().ReportRecordedInfos();
5127 isReportTaskStart_ = false;
5128 StartWindowInfoReportLoop();
5129 };
5130 int64_t delayTime = 1000 * 60 * 60; // an hour.
5131 bool ret = eventHandler_->PostTask(task, "wms:WindowInfoReport", delayTime);
5132 if (!ret) {
5133 WLOGFE("Report post listener callback task failed. the task name is WindowInfoReport");
5134 return;
5135 }
5136 isReportTaskStart_ = true;
5137 }
5138
GetStatusBarHeight()5139 int32_t SceneSessionManager::GetStatusBarHeight()
5140 {
5141 int32_t statusBarHeight = 0;
5142 int32_t height = 0;
5143 std::vector<sptr<SceneSession>> statusBarVector = GetSceneSessionVectorByType(WindowType::WINDOW_TYPE_STATUS_BAR);
5144 for (auto& statusBar : statusBarVector) {
5145 if (statusBar == nullptr || !IsSessionVisible(statusBar)) {
5146 continue;
5147 }
5148 height = statusBar->GetSessionRect().height_;
5149 statusBarHeight = (statusBarHeight > height) ? statusBarHeight : height;
5150 }
5151
5152 return statusBarHeight;
5153 }
5154
ResizeSoftInputCallingSessionIfNeed(const sptr<SceneSession> & sceneSession,bool isInputUpdated)5155 void SceneSessionManager::ResizeSoftInputCallingSessionIfNeed(
5156 const sptr<SceneSession>& sceneSession, bool isInputUpdated)
5157 {
5158 if (callingSession_ == nullptr) {
5159 WLOGFI("[WMSInput] calling session is nullptr");
5160 return;
5161 }
5162 SessionGravity gravity;
5163 uint32_t percent = 0;
5164 sceneSession->GetSessionProperty()->GetSessionGravity(gravity, percent);
5165 if (gravity != SessionGravity::SESSION_GRAVITY_BOTTOM && gravity != SessionGravity::SESSION_GRAVITY_DEFAULT) {
5166 WLOGFI("[WMSInput] Gravity is not bottom, no need to raise calling window, gravity: %{public}d", gravity);
5167 return;
5168 }
5169
5170 bool isCallingSessionFloating;
5171 if (callingSession_->GetSessionProperty() &&
5172 callingSession_->GetSessionProperty()->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING) {
5173 isCallingSessionFloating = true;
5174 } else {
5175 isCallingSessionFloating = false;
5176 }
5177
5178 const WSRect& softInputSessionRect = sceneSession->GetSessionRect();
5179 WSRect callingSessionRect;
5180 if (isInputUpdated && isCallingSessionFloating) {
5181 callingSessionRect = callingWindowRestoringRect_;
5182 } else {
5183 callingSessionRect = callingSession_->GetSessionRect();
5184 }
5185 WLOGFI("[WMSInput] softInputSessionRect: %{public}s, callingSessionRect: %{public}s",
5186 softInputSessionRect.ToString().c_str(), callingSessionRect.ToString().c_str());
5187 if (SessionHelper::IsEmptyRect(SessionHelper::GetOverlap(softInputSessionRect, callingSessionRect, 0, 0))) {
5188 WLOGFD("[WMSInput] There is no overlap area");
5189 return;
5190 }
5191
5192 WSRect newRect = callingSessionRect;
5193 int32_t statusHeight = GetStatusBarHeight();
5194 if (isCallingSessionFloating && callingSessionRect.posY_ > statusHeight) {
5195 // calculate new rect of calling window
5196 newRect.posY_ = softInputSessionRect.posY_ - static_cast<int32_t>(newRect.height_);
5197 newRect.posY_ = std::max(newRect.posY_, statusHeight);
5198 }
5199
5200 if (!isInputUpdated) {
5201 callingWindowRestoringRect_ = callingSessionRect;
5202 }
5203 NotifyOccupiedAreaChangeInfo(sceneSession, newRect, softInputSessionRect);
5204 if (isCallingSessionFloating && callingSessionRect.posY_ > statusHeight) {
5205 needUpdateSessionRect_ = true;
5206 callingSession_->UpdateSessionRect(newRect, SizeChangeReason::UNDEFINED);
5207 callingWindowNewRect_ = callingSession_->GetSessionRect();
5208 }
5209 }
5210
NotifyOccupiedAreaChangeInfo(const sptr<SceneSession> sceneSession,const WSRect & rect,const WSRect & occupiedArea)5211 void SceneSessionManager::NotifyOccupiedAreaChangeInfo(const sptr<SceneSession> sceneSession,
5212 const WSRect& rect, const WSRect& occupiedArea)
5213 {
5214 // if keyboard will occupy calling, notify calling window the occupied area and safe height
5215 const WSRect& safeRect = SessionHelper::GetOverlap(occupiedArea, rect, 0, 0);
5216 const WSRect& lastSafeRect = callingSession_->GetLastSafeRect();
5217 if (lastSafeRect == safeRect) {
5218 WLOGFI("[WMSInput] NotifyOccupiedAreaChangeInfo lastSafeRect is same to safeRect");
5219 return;
5220 }
5221 callingSession_->SetLastSafeRect(safeRect);
5222 sptr<OccupiedAreaChangeInfo> info = new OccupiedAreaChangeInfo(OccupiedAreaType::TYPE_INPUT,
5223 SessionHelper::TransferToRect(safeRect), safeRect.height_,
5224 sceneSession->textFieldPositionY_, sceneSession->textFieldHeight_);
5225 WLOGFD("[WMSInput] OccupiedAreaChangeInfo rect: %{public}u %{public}u %{public}u %{public}u",
5226 occupiedArea.posX_, occupiedArea.posY_, occupiedArea.width_, occupiedArea.height_);
5227 callingSession_->NotifyOccupiedAreaChangeInfo(info);
5228 }
5229
RestoreCallingSessionSizeIfNeed()5230 void SceneSessionManager::RestoreCallingSessionSizeIfNeed()
5231 {
5232 WLOGFD("[WMSInput] RestoreCallingSessionSizeIfNeed");
5233 if (callingSession_ == nullptr) {
5234 WLOGFI("[WMSInput] Calling session is nullptr");
5235 return;
5236 }
5237
5238 if (!SessionHelper::IsEmptyRect(callingWindowRestoringRect_)) {
5239 WSRect overlapRect = { 0, 0, 0, 0 };
5240 NotifyOccupiedAreaChangeInfo(callingSession_, callingWindowRestoringRect_, overlapRect);
5241 if (needUpdateSessionRect_ && callingSession_->GetSessionProperty() &&
5242 callingSession_->GetSessionProperty()->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING &&
5243 callingSession_->GetSessionRect() == callingWindowNewRect_) {
5244 callingSession_->UpdateSessionRect(callingWindowRestoringRect_, SizeChangeReason::UNDEFINED);
5245 }
5246 }
5247 needUpdateSessionRect_ = false;
5248 callingWindowRestoringRect_ = { 0, 0, 0, 0 };
5249 }
5250
SetSessionGravity(int32_t persistentId,SessionGravity gravity,uint32_t percent)5251 WSError SceneSessionManager::SetSessionGravity(int32_t persistentId, SessionGravity gravity, uint32_t percent)
5252 {
5253 auto task = [this, persistentId, gravity, percent]() -> WSError {
5254 auto sceneSession = GetSceneSession(persistentId);
5255 if (!sceneSession) {
5256 WLOGFE("scene session is nullptr");
5257 return WSError::WS_ERROR_NULLPTR;
5258 }
5259 WLOGFI("[WMSInput] SetSessionGravity persistentId: %{public}d, windowType: %{public}d, gravity: %{public}d",
5260 persistentId, sceneSession->GetWindowType(), gravity);
5261 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
5262 WLOGFE("[WMSInput] scene session is not input method");
5263 return WSError::WS_ERROR_INVALID_TYPE;
5264 }
5265 sceneSession->GetSessionProperty()->SetSessionGravity(gravity, percent);
5266 RelayoutKeyBoard(sceneSession);
5267 if (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
5268 sceneSession->GetSessionState() != SessionState::STATE_ACTIVE) {
5269 WLOGFI("[WMSInput] InputMethod is not foreground, not need to adjust or restore callingWindow");
5270 return WSError::WS_OK;
5271 }
5272 if (gravity == SessionGravity::SESSION_GRAVITY_FLOAT) {
5273 WLOGFD("[WMSInput] input method is float mode");
5274 sceneSession->SetWindowAnimationFlag(false);
5275 RestoreCallingSessionSizeIfNeed();
5276 } else {
5277 WLOGFD("[WMSInput] input method is bottom mode");
5278 sceneSession->SetWindowAnimationFlag(true);
5279 ResizeSoftInputCallingSessionIfNeed(sceneSession);
5280 }
5281 return WSError::WS_OK;
5282 };
5283 taskScheduler_->PostAsyncTask(task, "SetSessionGravity" + std::to_string(persistentId));
5284 return WSError::WS_OK;
5285 }
5286
RelayoutKeyBoard(sptr<SceneSession> sceneSession)5287 void SceneSessionManager::RelayoutKeyBoard(sptr<SceneSession> sceneSession)
5288 {
5289 if (sceneSession == nullptr) {
5290 WLOGFE("[WMSInput] sceneSession is nullptr");
5291 return;
5292 }
5293 SessionGravity gravity;
5294 uint32_t percent = 0;
5295 sceneSession->GetSessionProperty()->GetSessionGravity(gravity, percent);
5296 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
5297 gravity == SessionGravity::SESSION_GRAVITY_FLOAT) {
5298 return;
5299 }
5300
5301 auto defaultDisplayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
5302 if (defaultDisplayInfo == nullptr) {
5303 WLOGFE("[WMSInput] screenSession is null");
5304 return;
5305 }
5306
5307 auto requestRect = sceneSession->GetSessionProperty()->GetRequestRect();
5308 if (gravity == SessionGravity::SESSION_GRAVITY_BOTTOM) {
5309 requestRect.width_ = static_cast<uint32_t>(defaultDisplayInfo->GetWidth());
5310 requestRect.posX_ = 0;
5311 if (percent != 0) {
5312 requestRect.height_ =
5313 static_cast<uint32_t>(defaultDisplayInfo->GetHeight()) * percent / 100u; // 100: for calc percent.
5314 }
5315 }
5316 requestRect.posY_ = defaultDisplayInfo->GetHeight() -
5317 static_cast<int32_t>(requestRect.height_);
5318 sceneSession->GetSessionProperty()->SetRequestRect(requestRect);
5319 WLOGFD("[WMSInput] Id: %{public}d, rect: %{public}s", sceneSession->GetPersistentId(),
5320 SessionHelper::TransferToWSRect(requestRect).ToString().c_str());
5321 sceneSession->UpdateSessionRect(SessionHelper::TransferToWSRect(requestRect), SizeChangeReason::UNDEFINED);
5322 }
5323
InitPersistentStorage()5324 void SceneSessionManager::InitPersistentStorage()
5325 {
5326 if (ScenePersistentStorage::HasKey("maximize_state", ScenePersistentStorageType::MAXIMIZE_STATE)) {
5327 int32_t storageMode = -1;
5328 ScenePersistentStorage::Get("maximize_state", storageMode, ScenePersistentStorageType::MAXIMIZE_STATE);
5329 if (storageMode == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
5330 storageMode == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL)) {
5331 WLOGFI("init MaximizeMode as %{public}d from persistent storage", storageMode);
5332 SceneSession::maximizeMode_ = static_cast<MaximizeMode>(storageMode);
5333 }
5334 }
5335 }
5336
GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos)5337 WMError SceneSessionManager::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos)
5338 {
5339 WLOGFI("GetAccessibilityWindowInfo Called.");
5340 if (!SessionPermission::IsSystemServiceCalling()) {
5341 WLOGFE("The interface only support for system service.");
5342 return WMError::WM_ERROR_NOT_SYSTEM_APP;
5343 }
5344 auto task = [this, &infos]() {
5345 std::map<int32_t, sptr<SceneSession>>::iterator iter;
5346 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5347 for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
5348 sptr<SceneSession> sceneSession = iter->second;
5349 if (sceneSession == nullptr) {
5350 WLOGFW("null scene session");
5351 continue;
5352 }
5353 WLOGFD("name = %{public}s, isSystem = %{public}d, persistendId = %{public}d, winType = %{public}d, "
5354 "state = %{public}d, visible = %{public}d", sceneSession->GetWindowName().c_str(),
5355 sceneSession->GetSessionInfo().isSystem_, iter->first, sceneSession->GetWindowType(),
5356 sceneSession->GetSessionState(), sceneSession->IsVisibleForAccessibility());
5357 if (sceneSession->IsVisibleForAccessibility()) {
5358 FillWindowInfo(infos, iter->second);
5359 }
5360 }
5361 return WMError::WM_OK;
5362 };
5363 return taskScheduler_->PostSyncTask(task, "GetAccessibilityWindowInfo");
5364 }
5365
NotifyWindowInfoChange(int32_t persistentId,WindowUpdateType type)5366 void SceneSessionManager::NotifyWindowInfoChange(int32_t persistentId, WindowUpdateType type)
5367 {
5368 WLOGFD("NotifyWindowInfoChange, persistentId = %{public}d, updateType = %{public}d", persistentId, type);
5369 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
5370 if (sceneSession == nullptr) {
5371 WLOGFE("NotifyWindowInfoChange sceneSession nullptr!");
5372 return;
5373 }
5374 wptr<SceneSession> weakSceneSession(sceneSession);
5375 auto task = [this, weakSceneSession, type]() {
5376 std::vector<sptr<AccessibilityWindowInfo>> infos;
5377 auto scnSession = weakSceneSession.promote();
5378 if (FillWindowInfo(infos, scnSession)) {
5379 SessionManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(infos, type);
5380 }
5381 if (WindowChangedFunc_ != nullptr && scnSession != nullptr &&
5382 scnSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
5383 WindowChangedFunc_(scnSession->GetPersistentId(), type);
5384 }
5385 };
5386 taskScheduler_->PostAsyncTask(task, "NotifyWindowInfoChange:PID:" + std::to_string(persistentId));
5387
5388 auto notifySceneInputTask = [weakSceneSession, type]() {
5389 auto scnSession = weakSceneSession.promote();
5390 if (scnSession == nullptr) {
5391 return;
5392 }
5393 SceneInputManager::GetInstance().NotifyWindowInfoChange(scnSession, type);
5394 };
5395 taskScheduler_->PostAsyncTask(notifySceneInputTask);
5396 }
5397
FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos,const sptr<SceneSession> & sceneSession)5398 bool SceneSessionManager::FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos,
5399 const sptr<SceneSession>& sceneSession)
5400 {
5401 if (sceneSession == nullptr) {
5402 WLOGFW("null scene session.");
5403 return false;
5404 }
5405 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos
5406 || sceneSession->GetSessionInfo().bundleName_.find("SCBGestureNavBar") != std::string::npos) {
5407 WLOGFD("filter gesture window.");
5408 return false;
5409 }
5410 sptr<AccessibilityWindowInfo> info = new (std::nothrow) AccessibilityWindowInfo();
5411 if (info == nullptr) {
5412 WLOGFE("null info.");
5413 return false;
5414 }
5415 if (sceneSession->GetSessionInfo().isSystem_) {
5416 info->wid_ = 1;
5417 info->innerWid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
5418 } else {
5419 info->wid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
5420 }
5421 info->uiNodeId_ = sceneSession->GetUINodeId();
5422 WSRect wsrect = sceneSession->GetSessionRect();
5423 info->windowRect_ = {wsrect.posX_, wsrect.posY_, wsrect.width_, wsrect.height_ };
5424 info->focused_ = sceneSession->GetPersistentId() == focusedSessionId_;
5425 info->type_ = sceneSession->GetWindowType();
5426 info->mode_ = sceneSession->GetWindowMode();
5427 info->layer_ = sceneSession->GetZOrder();
5428 info->scaleVal_ = sceneSession->GetFloatingScale();
5429 info->scaleX_ = sceneSession->GetScaleX();
5430 info->scaleY_ = sceneSession->GetScaleY();
5431 auto property = sceneSession->GetSessionProperty();
5432 if (property != nullptr) {
5433 info->displayId_ = property->GetDisplayId();
5434 info->isDecorEnable_ = property->IsDecorEnable();
5435 }
5436 infos.emplace_back(info);
5437 WLOGFD("wid = %{public}d, inWid = %{public}d, uiNId = %{public}d", info->wid_, info->innerWid_, info->uiNodeId_);
5438 return true;
5439 }
5440
GetSessionSnapshotFilePath(int32_t persistentId)5441 std::string SceneSessionManager::GetSessionSnapshotFilePath(int32_t persistentId)
5442 {
5443 WLOGFI("GetSessionSnapshotFilePath persistentId %{public}d", persistentId);
5444 auto sceneSession = GetSceneSession(persistentId);
5445 if (sceneSession == nullptr) {
5446 WLOGFE("GetSessionSnapshotFilePath sceneSession nullptr!");
5447 return "";
5448 }
5449 wptr<SceneSession> weakSceneSession(sceneSession);
5450 auto task = [this, weakSceneSession]() {
5451 auto scnSession = weakSceneSession.promote();
5452 if (scnSession == nullptr) {
5453 WLOGFE("session is nullptr");
5454 return std::string("");
5455 }
5456 std::string filePath = scnSession->GetSessionSnapshotFilePath();
5457 return filePath;
5458 };
5459 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotFilePath" + std::to_string(persistentId));
5460 }
5461
SelectSesssionFromMap(const uint64_t & surfaceId)5462 sptr<SceneSession> SceneSessionManager::SelectSesssionFromMap(const uint64_t& surfaceId)
5463 {
5464 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5465 for (const auto &item : sceneSessionMap_) {
5466 auto sceneSession = item.second;
5467 if (sceneSession == nullptr) {
5468 continue;
5469 }
5470 if (sceneSession->GetSurfaceNode() == nullptr) {
5471 continue;
5472 }
5473 if (surfaceId == sceneSession->GetSurfaceNode()->GetId()) {
5474 return sceneSession;
5475 }
5476 }
5477 return nullptr;
5478 }
5479
WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)5480 void SceneSessionManager::WindowLayerInfoChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)
5481 {
5482 WLOGFD("WindowLayerInfoChangeCallback: entry");
5483 std::weak_ptr<RSOcclusionData> weak(occlusiontionData);
5484
5485 auto task = [this, weak]() {
5486 auto weakOcclusionData = weak.lock();
5487 if (weakOcclusionData == nullptr) {
5488 WLOGFE("weak occlusionData is nullptr");
5489 return;
5490 }
5491 std::vector<std::pair<uint64_t, WindowVisibilityState>> currVisibleData;
5492 std::vector<std::pair<uint64_t, bool>> currDrawingContentData;
5493 GetWindowLayerChangeInfo(weakOcclusionData, currVisibleData, currDrawingContentData);
5494 std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfos;
5495 if (currVisibleData.size() != 0) {
5496 visibilityChangeInfos = GetWindowVisibilityChangeInfo(currVisibleData);
5497 }
5498 if (visibilityChangeInfos.size() != 0) {
5499 DealwithVisibilityChange(visibilityChangeInfos);
5500 }
5501
5502 std::vector<std::pair<uint64_t, bool>> drawingContentChangeInfos;
5503 if (currDrawingContentData.size() != 0) {
5504 drawingContentChangeInfos = GetWindowDrawingContentChangeInfo(currDrawingContentData);
5505 }
5506 if (drawingContentChangeInfos.size() != 0) {
5507 DealwithDrawingContentChange(drawingContentChangeInfos);
5508 }
5509 };
5510 taskScheduler_->PostVoidSyncTask(task, "WindowLayerInfoChangeCallback");
5511 }
5512
GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData,std::vector<std::pair<uint64_t,bool>> & currDrawingContentData)5513 void SceneSessionManager::GetWindowLayerChangeInfo(std::shared_ptr<RSOcclusionData> occlusiontionData,
5514 std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData,
5515 std::vector<std::pair<uint64_t, bool>>& currDrawingContentData)
5516 {
5517 VisibleData& rsVisibleData = occlusiontionData->GetVisibleData();
5518 for (auto iter = rsVisibleData.begin(); iter != rsVisibleData.end(); iter++) {
5519 WindowLayerState windowLayerState = static_cast<WindowLayerState>(iter->second);
5520 switch (windowLayerState) {
5521 case WINDOW_ALL_VISIBLE:
5522 case WINDOW_SEMI_VISIBLE:
5523 case WINDOW_IN_VISIBLE:
5524 currVisibleData.emplace_back(iter->first, static_cast<WindowVisibilityState>(iter->second));
5525 break;
5526 case WINDOW_LAYER_DRAWING:
5527 currDrawingContentData.emplace_back(iter->first, true);
5528 break;
5529 case WINDOW_LAYER_NO_DRAWING:
5530 currDrawingContentData.emplace_back(iter->first, false);
5531 break;
5532 default:
5533 break;
5534 }
5535 }
5536 }
5537
GetWindowVisibilityChangeInfo(std::vector<std::pair<uint64_t,WindowVisibilityState>> & currVisibleData)5538 std::vector<std::pair<uint64_t, WindowVisibilityState>> SceneSessionManager::GetWindowVisibilityChangeInfo(
5539 std::vector<std::pair<uint64_t, WindowVisibilityState>>& currVisibleData)
5540 {
5541 std::vector<std::pair<uint64_t, WindowVisibilityState>> visibilityChangeInfo;
5542 std::sort(currVisibleData.begin(), currVisibleData.end(), Comp);
5543 uint32_t i, j;
5544 i = j = 0;
5545 for (; i < lastVisibleData_.size() && j < currVisibleData.size();) {
5546 if (lastVisibleData_[i].first < currVisibleData[j].first) {
5547 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
5548 i++;
5549 } else if (lastVisibleData_[i].first > currVisibleData[j].first) {
5550 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
5551 j++;
5552 } else {
5553 if (lastVisibleData_[i].second != currVisibleData[j].second) {
5554 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
5555 }
5556 i++;
5557 j++;
5558 }
5559 }
5560 for (; i < lastVisibleData_.size(); ++i) {
5561 visibilityChangeInfo.emplace_back(lastVisibleData_[i].first, WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
5562 }
5563 for (; j < currVisibleData.size(); ++j) {
5564 visibilityChangeInfo.emplace_back(currVisibleData[j].first, currVisibleData[j].second);
5565 }
5566 lastVisibleData_ = currVisibleData;
5567 return visibilityChangeInfo;
5568 }
5569
DealwithVisibilityChange(const std::vector<std::pair<uint64_t,WindowVisibilityState>> & visibilityChangeInfo)5570 void SceneSessionManager::DealwithVisibilityChange(const std::vector<std::pair<uint64_t, WindowVisibilityState>>&
5571 visibilityChangeInfo)
5572 {
5573 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
5574 #ifdef MEMMGR_WINDOW_ENABLE
5575 std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
5576 #endif
5577
5578 std::string visibilityInfo = "WindowVisibilityInfos [name, winId, visibleState]: ";
5579 for (const auto& elem : visibilityChangeInfo) {
5580 uint64_t surfaceId = elem.first;
5581 WindowVisibilityState visibleState = elem.second;
5582 bool isVisible = visibleState < WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION;
5583 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
5584 if (session == nullptr) {
5585 continue;
5586 }
5587 if ((WindowHelper::IsSubWindow(session->GetWindowType()) ||
5588 session->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) && isVisible == true) {
5589 if (session->GetParentSession() != nullptr &&
5590 !session->GetParentSession()->IsSessionForeground()) {
5591 continue;
5592 }
5593 }
5594 session->SetVisible(isVisible);
5595 session->SetVisibilityState(visibleState);
5596 int32_t windowId = session->GetWindowId();
5597 if (windowVisibilityListenerSessionSet_.find(windowId) != windowVisibilityListenerSessionSet_.end()) {
5598 session->NotifyWindowVisibility();
5599 }
5600 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(windowId, session->GetCallingPid(),
5601 session->GetCallingUid(), visibleState, session->GetWindowType()));
5602 #ifdef MEMMGR_WINDOW_ENABLE
5603 memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(session->GetWindowId(), session->GetCallingPid(),
5604 session->GetCallingUid(), isVisible));
5605 #endif
5606 visibilityInfo += "[" + session->GetWindowName() + ", " + std::to_string(windowId) + ", " +
5607 std::to_string(visibleState) + "], ";
5608 CheckAndNotifyWaterMarkChangedResult();
5609 }
5610 if (windowVisibilityInfos.size() != 0) {
5611 WLOGI("Notify windowvisibilityinfo changed start, size: %{public}zu, %{public}s", windowVisibilityInfos.size(),
5612 visibilityInfo.c_str());
5613 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
5614 }
5615 #ifdef MEMMGR_WINDOW_ENABLE
5616 if (memMgrWindowInfos.size() != 0) {
5617 WLOGD("Notify memMgrWindowInfos changed start");
5618 Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
5619 }
5620 #endif
5621 }
5622
DealwithDrawingContentChange(const std::vector<std::pair<uint64_t,bool>> & drawingContentChangeInfo)5623 void SceneSessionManager::DealwithDrawingContentChange(const std::vector<std::pair<uint64_t, bool>>&
5624 drawingContentChangeInfo)
5625 {
5626 std::vector<sptr<WindowDrawingContentInfo>> windowDrawingContenInfos;
5627 for (const auto& elem : drawingContentChangeInfo) {
5628 uint64_t surfaceId = elem.first;
5629 bool drawingState = elem.second;
5630 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
5631 if (session == nullptr) {
5632 continue;
5633 }
5634 windowDrawingContenInfos.emplace_back(new WindowDrawingContentInfo(session->GetWindowId(),
5635 session->GetCallingPid(), session->GetCallingUid(), drawingState, session->GetWindowType()));
5636 if (openDebugTrace) {
5637 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "Drawing status changed pid:(%d ) surfaceId:(%" PRIu64 ")"
5638 "drawingState:(%d )", session->GetCallingPid(), surfaceId, drawingState);
5639 }
5640 WLOGFD("NotifyWindowDrawingContenInfoChange: drawing status changed pid:%{public}d,"
5641 "surfaceId:%{public}" PRIu64", drawingState:%{public}d", session->GetCallingPid(), surfaceId, drawingState);
5642 }
5643 if (windowDrawingContenInfos.size() != 0) {
5644 WLOGFD("Notify WindowDrawingContenInfo changed start");
5645 SessionManagerAgentController::GetInstance().UpdateWindowDrawingContentInfo(windowDrawingContenInfos);
5646 }
5647 }
5648
GetWindowDrawingContentChangeInfo(std::vector<std::pair<uint64_t,bool>> currDrawingContentData)5649 std::vector<std::pair<uint64_t, bool>> SceneSessionManager::GetWindowDrawingContentChangeInfo(
5650 std::vector<std::pair<uint64_t, bool>> currDrawingContentData)
5651 {
5652 std::vector<std::pair<uint64_t, bool>> processDrawingContentChangeInfo;
5653 for (const auto& data : currDrawingContentData) {
5654 uint64_t windowId = data.first;
5655 bool currentDrawingContentState = data.second;
5656 int32_t pid = 0;
5657 bool isChange = false;
5658 if (GetPreWindowDrawingState(windowId, pid, currentDrawingContentState) == currentDrawingContentState) {
5659 continue;
5660 } else {
5661 isChange = GetProcessDrawingState(windowId, pid, currentDrawingContentState);
5662 }
5663
5664 if (isChange) {
5665 processDrawingContentChangeInfo.emplace_back(windowId, currentDrawingContentState);
5666 }
5667 }
5668 return processDrawingContentChangeInfo;
5669 }
5670
GetPreWindowDrawingState(uint64_t windowId,int32_t & pid,bool currentDrawingContentState)5671 bool SceneSessionManager::GetPreWindowDrawingState(uint64_t windowId, int32_t& pid, bool currentDrawingContentState)
5672 {
5673 bool preWindowDrawingState = true;
5674 sptr<SceneSession> session = SelectSesssionFromMap(windowId);
5675 if (session == nullptr) {
5676 return false;
5677 }
5678 pid = session->GetCallingPid();
5679 preWindowDrawingState = session->GetDrawingContentState();
5680 session->SetDrawingContentState(currentDrawingContentState);
5681 return preWindowDrawingState;
5682 }
5683
GetProcessDrawingState(uint64_t windowId,int32_t pid,bool currentDrawingContentState)5684 bool SceneSessionManager::GetProcessDrawingState(uint64_t windowId, int32_t pid, bool currentDrawingContentState)
5685 {
5686 bool isChange = true;
5687 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5688 for (const auto& item : sceneSessionMap_) {
5689 auto sceneSession = item.second;
5690 if (sceneSession == nullptr) {
5691 continue;
5692 }
5693 if (sceneSession->GetCallingPid() == pid && sceneSession->GetSurfaceNode() != nullptr &&
5694 windowId != sceneSession->GetSurfaceNode()->GetId()) {
5695 if (sceneSession->GetDrawingContentState()) {
5696 return false;
5697 }
5698 }
5699 }
5700 return isChange;
5701 }
5702
5703
InitWithRenderServiceAdded()5704 void SceneSessionManager::InitWithRenderServiceAdded()
5705 {
5706 auto windowVisibilityChangeCb = std::bind(&SceneSessionManager::WindowLayerInfoChangeCallback, this,
5707 std::placeholders::_1);
5708 WLOGI("RegisterWindowVisibilityChangeCallback");
5709 if (rsInterface_.RegisterOcclusionChangeCallback(windowVisibilityChangeCb) != WM_OK) {
5710 WLOGFE("RegisterWindowVisibilityChangeCallback failed");
5711 }
5712 }
5713
SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)5714 WMError SceneSessionManager::SetSystemAnimatedScenes(SystemAnimatedSceneType sceneType)
5715 {
5716 if (sceneType > SystemAnimatedSceneType::SCENE_OTHERS) {
5717 WLOGFE("The input scene type is valid, scene type is %{public}d", sceneType);
5718 return WMError::WM_ERROR_INVALID_PARAM;
5719 }
5720
5721 auto task = [this, sceneType]() {
5722 WLOGFD("Set system animated scene %{public}d.", sceneType);
5723 bool ret = rsInterface_.SetSystemAnimatedScenes(static_cast<SystemAnimatedScenes>(sceneType));
5724 if (!ret) {
5725 WLOGFE("Set system animated scene failed.");
5726 }
5727 };
5728 taskScheduler_->PostAsyncTask(task, "SetSystemAnimatedScenes");
5729 return WMError::WM_OK;
5730 }
5731
NotifyWindowExtensionVisibilityChange(int32_t pid,int32_t uid,bool visible)5732 WSError SceneSessionManager::NotifyWindowExtensionVisibilityChange(int32_t pid, int32_t uid, bool visible)
5733 {
5734 if (!SessionPermission::IsSystemCalling()) {
5735 WLOGFE("NotifyWindowExtensionVisibilityChange permission denied!");
5736 return WSError::WS_ERROR_NOT_SYSTEM_APP;
5737 }
5738 WLOGFI("Notify WindowExtension visibility change to %{public}s for pid: %{public}d, uid: %{public}d",
5739 visible ? "VISIBLE" : "INVISIBLE", pid, uid);
5740 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
5741 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(INVALID_WINDOW_ID, pid, uid,
5742 visible ? WINDOW_VISIBILITY_STATE_NO_OCCLUSION : WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION,
5743 WindowType::WINDOW_TYPE_APP_COMPONENT));
5744 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
5745 return WSError::WS_OK;
5746 }
5747
WindowDestroyNotifyVisibility(const sptr<SceneSession> & sceneSession)5748 void SceneSessionManager::WindowDestroyNotifyVisibility(const sptr<SceneSession>& sceneSession)
5749 {
5750 if (sceneSession == nullptr) {
5751 WLOGFE("sceneSession is nullptr!");
5752 return;
5753 }
5754 if (sceneSession->GetVisible()) {
5755 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
5756 #ifdef MEMMGR_WINDOW_ENABLE
5757 std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
5758 #endif
5759 sceneSession->SetVisible(false);
5760 sceneSession->SetVisibilityState(WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION);
5761 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(sceneSession->GetWindowId(),
5762 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
5763 WINDOW_VISIBILITY_STATE_TOTALLY_OCCUSION, sceneSession->GetWindowType()));
5764 #ifdef MEMMGR_WINDOW_ENABLE
5765 memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(sceneSession->GetWindowId(),
5766 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(), false));
5767 #endif
5768 WLOGFD("NotifyWindowVisibilityChange: covered status changed window:%{public}u, isVisible:%{public}d",
5769 sceneSession->GetWindowId(), sceneSession->GetVisible());
5770 CheckAndNotifyWaterMarkChangedResult();
5771 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
5772 #ifdef MEMMGR_WINDOW_ENABLE
5773 WLOGD("Notify memMgrWindowInfos changed start");
5774 Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
5775 #endif
5776 }
5777 }
5778
FindSessionByToken(const sptr<IRemoteObject> & token)5779 sptr<SceneSession> SceneSessionManager::FindSessionByToken(const sptr<IRemoteObject> &token)
5780 {
5781 sptr<SceneSession> session = nullptr;
5782 auto cmpFunc = [token](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
5783 if (pair.second == nullptr) {
5784 return false;
5785 }
5786 return pair.second->GetAbilityToken() == token || pair.second->GetSelfToken() == token;
5787 };
5788 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5789 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
5790 if (iter != sceneSessionMap_.end()) {
5791 session = iter->second;
5792 }
5793 return session;
5794 }
5795
FindSessionByAffinity(std::string affinity)5796 sptr<SceneSession> SceneSessionManager::FindSessionByAffinity(std::string affinity)
5797 {
5798 if (affinity.size() == 0) {
5799 WLOGFI("AbilityInfo affinity is empty");
5800 return nullptr;
5801 }
5802 sptr<SceneSession> session = nullptr;
5803 auto cmpFunc = [this, affinity](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
5804 if (pair.second == nullptr || !CheckCollaboratorType(pair.second->GetCollaboratorType())) {
5805 return false;
5806 }
5807 return pair.second->GetSessionInfo().sessionAffinity == affinity;
5808 };
5809 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
5810 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
5811 if (iter != sceneSessionMap_.end()) {
5812 session = iter->second;
5813 }
5814 return session;
5815 }
5816
PreloadInLakeApp(const std::string & bundleName)5817 void SceneSessionManager::PreloadInLakeApp(const std::string& bundleName)
5818 {
5819 WLOGFI("run PreloadInLakeApp");
5820 auto iter = collaboratorMap_.find(CollaboratorType::RESERVE_TYPE);
5821 if (iter == collaboratorMap_.end()) {
5822 WLOGFE("Fail to found collaborator with type: RESERVE_TYPE");
5823 return;
5824 }
5825 auto collaborator = iter->second;
5826 if (collaborator != nullptr) {
5827 collaborator->NotifyPreloadAbility(bundleName);
5828 }
5829 }
5830
PendingSessionToForeground(const sptr<IRemoteObject> & token)5831 WSError SceneSessionManager::PendingSessionToForeground(const sptr<IRemoteObject> &token)
5832 {
5833 WLOGFI("run PendingSessionToForeground");
5834 auto task = [this, &token]() {
5835 auto session = FindSessionByToken(token);
5836 if (session != nullptr) {
5837 return session->PendingSessionToForeground();
5838 }
5839 WLOGFE("fail to find token");
5840 return WSError::WS_ERROR_INVALID_PARAM;
5841 };
5842 return taskScheduler_->PostSyncTask(task, "PendingSessionToForeground");
5843 }
5844
PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject> & token)5845 WSError SceneSessionManager::PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject> &token)
5846 {
5847 auto task = [this, &token]() {
5848 auto session = FindSessionByToken(token);
5849 if (session != nullptr) {
5850 return session->PendingSessionToBackgroundForDelegator();
5851 }
5852 WLOGFE("fail to find token");
5853 return WSError::WS_ERROR_INVALID_PARAM;
5854 };
5855 return taskScheduler_->PostSyncTask(task, "PendingSessionToBackgroundForDelegator");
5856 }
5857
GetFocusSessionToken(sptr<IRemoteObject> & token)5858 WSError SceneSessionManager::GetFocusSessionToken(sptr<IRemoteObject> &token)
5859 {
5860 auto task = [this, &token]() {
5861 WLOGFD("run GetFocusSessionToken with focusedSessionId: %{public}d", focusedSessionId_);
5862 auto sceneSession = GetSceneSession(focusedSessionId_);
5863 if (sceneSession) {
5864 token = sceneSession->GetAbilityToken();
5865 if (token == nullptr) {
5866 WLOGFE("token is nullptr");
5867 return WSError::WS_ERROR_INVALID_PARAM;
5868 }
5869 return WSError::WS_OK;
5870 }
5871 return WSError::WS_ERROR_INVALID_PARAM;
5872 };
5873 return taskScheduler_->PostSyncTask(task, "GetFocusSessionToken");
5874 }
5875
UpdateSessionAvoidAreaListener(int32_t & persistentId,bool haveListener)5876 WSError SceneSessionManager::UpdateSessionAvoidAreaListener(int32_t& persistentId, bool haveListener)
5877 {
5878 auto task = [this, persistentId, haveListener]() {
5879 WLOGFI("UpdateSessionAvoidAreaListener persistentId: %{public}d haveListener:%{public}d",
5880 persistentId, haveListener);
5881 auto sceneSession = GetSceneSession(persistentId);
5882 if (sceneSession == nullptr) {
5883 WLOGFD("sceneSession is nullptr.");
5884 return WSError::WS_DO_NOTHING;
5885 }
5886 if (haveListener) {
5887 avoidAreaListenerSessionSet_.insert(persistentId);
5888 UpdateAvoidArea(persistentId);
5889 } else {
5890 lastUpdatedAvoidArea_.erase(persistentId);
5891 avoidAreaListenerSessionSet_.erase(persistentId);
5892 }
5893 return WSError::WS_OK;
5894 };
5895 return taskScheduler_->PostSyncTask(task, "UpdateSessionAvoidAreaListener:PID:" + std::to_string(persistentId));
5896 }
5897
UpdateSessionAvoidAreaIfNeed(const int32_t & persistentId,const sptr<SceneSession> & sceneSession,const AvoidArea & avoidArea,AvoidAreaType avoidAreaType)5898 bool SceneSessionManager::UpdateSessionAvoidAreaIfNeed(const int32_t& persistentId,
5899 const sptr<SceneSession>& sceneSession, const AvoidArea& avoidArea, AvoidAreaType avoidAreaType)
5900 {
5901 if (sceneSession == nullptr) {
5902 return false;
5903 }
5904 auto iter = lastUpdatedAvoidArea_.find(persistentId);
5905 bool needUpdate = true;
5906
5907 if (iter != lastUpdatedAvoidArea_.end()) {
5908 auto avoidAreaIter = iter->second.find(avoidAreaType);
5909 if (avoidAreaIter != iter->second.end()) {
5910 needUpdate = avoidAreaIter->second != avoidArea;
5911 } else {
5912 if (avoidArea.isEmptyAvoidArea()) {
5913 needUpdate = false;
5914 return needUpdate;
5915 }
5916 }
5917 } else {
5918 if (avoidArea.isEmptyAvoidArea()) {
5919 needUpdate = false;
5920 return needUpdate;
5921 }
5922 }
5923 if (needUpdate ||
5924 avoidAreaType == AvoidAreaType::TYPE_SYSTEM || avoidAreaType == AvoidAreaType::TYPE_NAVIGATION_INDICATOR) {
5925 lastUpdatedAvoidArea_[persistentId][avoidAreaType] = avoidArea;
5926 sceneSession->UpdateAvoidArea(new AvoidArea(avoidArea), avoidAreaType);
5927 }
5928
5929 return needUpdate;
5930 }
5931
UpdateAvoidSessionAvoidArea(WindowType type,bool & needUpdate)5932 void SceneSessionManager::UpdateAvoidSessionAvoidArea(WindowType type, bool& needUpdate)
5933 {
5934 bool ret = true;
5935 AvoidAreaType avoidType = (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) ?
5936 AvoidAreaType::TYPE_KEYBOARD : AvoidAreaType::TYPE_SYSTEM;
5937 for (auto& persistentId : avoidAreaListenerSessionSet_) {
5938 auto sceneSession = GetSceneSession(persistentId);
5939 if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
5940 continue;
5941 }
5942 AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
5943 ret = UpdateSessionAvoidAreaIfNeed(
5944 persistentId, sceneSession, avoidArea, static_cast<AvoidAreaType>(avoidType));
5945 needUpdate = needUpdate || ret;
5946 }
5947
5948 return;
5949 }
5950
CheckAvoidAreaForAINavigationBar(bool isVisible,const AvoidArea & avoidArea,int32_t sessionBottom)5951 static bool CheckAvoidAreaForAINavigationBar(bool isVisible, const AvoidArea& avoidArea, int32_t sessionBottom)
5952 {
5953 if (!avoidArea.topRect_.IsUninitializedRect() || !avoidArea.leftRect_.IsUninitializedRect() ||
5954 !avoidArea.rightRect_.IsUninitializedRect()) {
5955 return false;
5956 }
5957 if (isVisible) {
5958 if (avoidArea.bottomRect_.IsUninitializedRect() ||
5959 (avoidArea.bottomRect_.posY_ + static_cast<int32_t>(avoidArea.bottomRect_.height_) != sessionBottom)) {
5960 return false;
5961 }
5962 } else if (!avoidArea.bottomRect_.IsUninitializedRect()) {
5963 return false;
5964 }
5965 return true;
5966 }
5967
UpdateNormalSessionAvoidArea(const int32_t & persistentId,sptr<SceneSession> & sceneSession,bool & needUpdate)5968 void SceneSessionManager::UpdateNormalSessionAvoidArea(
5969 const int32_t& persistentId, sptr<SceneSession>& sceneSession, bool& needUpdate)
5970 {
5971 bool ret = true;
5972 if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
5973 needUpdate = false;
5974 return;
5975 }
5976 if (avoidAreaListenerSessionSet_.find(persistentId) == avoidAreaListenerSessionSet_.end()) {
5977 WLOGD("id:%{public}d is not in avoidAreaListenerNodes, don't update avoid area.", persistentId);
5978 needUpdate = false;
5979 return;
5980 }
5981 uint32_t start = static_cast<uint32_t>(AvoidAreaType::TYPE_SYSTEM);
5982 uint32_t end = static_cast<uint32_t>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
5983 for (uint32_t avoidType = start; avoidType <= end; avoidType++) {
5984 AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
5985 if (avoidType == static_cast<uint32_t>(AvoidAreaType::TYPE_NAVIGATION_INDICATOR) &&
5986 !CheckAvoidAreaForAINavigationBar(isAINavigationBarVisible_, avoidArea,
5987 sceneSession->GetSessionRect().posY_ + sceneSession->GetSessionRect().height_)) {
5988 continue;
5989 }
5990 ret = UpdateSessionAvoidAreaIfNeed(
5991 persistentId, sceneSession, avoidArea, static_cast<AvoidAreaType>(avoidType));
5992 needUpdate = needUpdate || ret;
5993 }
5994
5995 return;
5996 }
5997
NotifyMMIWindowPidChange(int32_t windowId,bool startMoving)5998 void SceneSessionManager::NotifyMMIWindowPidChange(int32_t windowId, bool startMoving)
5999 {
6000 int32_t pid = startMoving ? static_cast<int32_t>(getpid()) : -1;
6001 auto sceneSession = GetSceneSession(windowId);
6002 if (sceneSession == nullptr) {
6003 WLOGFW("window not exist: %{public}d", windowId);
6004 return;
6005 }
6006
6007 wptr<SceneSession> weakSceneSession(sceneSession);
6008 WLOGFI("SceneSessionManager NotifyMMIWindowPidChange to notify window: %{public}d, pid: %{public}d", windowId, pid);
6009 auto task = [weakSceneSession, startMoving]() -> WSError {
6010 auto scnSession = weakSceneSession.promote();
6011 if (scnSession == nullptr) {
6012 WLOGFW("session is null");
6013 return WSError::WS_ERROR_NULLPTR;
6014 }
6015 SceneInputManager::GetInstance().NotifyMMIWindowPidChange(scnSession, startMoving);
6016 return WSError::WS_OK;
6017 };
6018 return taskScheduler_->PostAsyncTask(task);
6019 }
6020
UpdateAvoidArea(const int32_t & persistentId)6021 void SceneSessionManager::UpdateAvoidArea(const int32_t& persistentId)
6022 {
6023 auto task = [this, persistentId]() {
6024 bool needUpdate = false;
6025 auto sceneSession = GetSceneSession(persistentId);
6026 if (sceneSession == nullptr) {
6027 WLOGFD("sceneSession is nullptr.");
6028 return;
6029 }
6030 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_BOUNDS);
6031
6032 WindowType type = sceneSession->GetWindowType();
6033 SessionGravity gravity = SessionGravity::SESSION_GRAVITY_DEFAULT;
6034 uint32_t percent = 0;
6035 if (sceneSession->GetSessionProperty() != nullptr) {
6036 sceneSession->GetSessionProperty()->GetSessionGravity(gravity, percent);
6037 }
6038 if (type == WindowType::WINDOW_TYPE_STATUS_BAR ||
6039 type == WindowType::WINDOW_TYPE_NAVIGATION_BAR ||
6040 (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
6041 (gravity == SessionGravity::SESSION_GRAVITY_BOTTOM ||
6042 gravity == SessionGravity::SESSION_GRAVITY_DEFAULT))) {
6043 UpdateAvoidSessionAvoidArea(type, needUpdate);
6044 } else {
6045 UpdateNormalSessionAvoidArea(persistentId, sceneSession, needUpdate);
6046 }
6047 return;
6048 };
6049 taskScheduler_->PostAsyncTask(task, "UpdateAvoidArea:PID:" + std::to_string(persistentId));
6050 return;
6051 }
6052
NotifyAINavigationBarShowStatus(bool isVisible,WSRect barArea)6053 WSError SceneSessionManager::NotifyAINavigationBarShowStatus(bool isVisible, WSRect barArea)
6054 {
6055 WLOGFI("NotifyAINavigationBarShowStatus: isVisible: %{public}u, area{%{public}d,%{public}d,%{public}d,%{public}d}",
6056 isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_);
6057 auto task = [this, isVisible, barArea]() {
6058 if (isAINavigationBarVisible_ != isVisible || currAINavigationBarArea_ != barArea) {
6059 isAINavigationBarVisible_ = isVisible;
6060 currAINavigationBarArea_ = barArea;
6061 if (!isVisible && !barArea.IsEmpty()) {
6062 WLOGFD("NotifyAINavigationBarShowStatus: barArea should be empty if invisible");
6063 currAINavigationBarArea_ = WSRect();
6064 }
6065 WLOGFI("NotifyAINavigationBarShowStatus: enter: %{public}u, {%{public}d,%{public}d,%{public}d,%{public}d}",
6066 isVisible, barArea.posX_, barArea.posY_, barArea.width_, barArea.height_);
6067 for (auto persistentId : avoidAreaListenerSessionSet_) {
6068 auto sceneSession = GetSceneSession(persistentId);
6069 if (sceneSession == nullptr || !IsSessionVisible(sceneSession)) {
6070 continue;
6071 }
6072 AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
6073 if (!avoidArea.topRect_.IsUninitializedRect() || !avoidArea.leftRect_.IsUninitializedRect() ||
6074 !avoidArea.rightRect_.IsUninitializedRect()) {
6075 continue;
6076 }
6077 if (isVisible && avoidArea.bottomRect_.IsUninitializedRect()) {
6078 continue;
6079 }
6080 WLOGFI("NotifyAINavigationBarShowStatus: persistentId: %{public}d, "
6081 "{%{public}d,%{public}d,%{public}d,%{public}d}", persistentId,
6082 avoidArea.bottomRect_.posX_, avoidArea.bottomRect_.posY_,
6083 avoidArea.bottomRect_.width_, avoidArea.bottomRect_.height_);
6084 UpdateSessionAvoidAreaIfNeed(persistentId, sceneSession, avoidArea,
6085 AvoidAreaType::TYPE_NAVIGATION_INDICATOR);
6086 }
6087 }
6088 };
6089 taskScheduler_->PostAsyncTask(task, "NotifyAINavigationBarShowStatus");
6090 return WSError::WS_OK;
6091 }
6092
GetAINavigationBarArea()6093 WSRect SceneSessionManager::GetAINavigationBarArea()
6094 {
6095 return currAINavigationBarArea_;
6096 }
6097
UpdateSessionTouchOutsideListener(int32_t & persistentId,bool haveListener)6098 WSError SceneSessionManager::UpdateSessionTouchOutsideListener(int32_t& persistentId, bool haveListener)
6099 {
6100 auto task = [this, persistentId, haveListener]() {
6101 WLOGFI("UpdateSessionTouchOutsideListener persistentId: %{public}d haveListener:%{public}d",
6102 persistentId, haveListener);
6103 auto sceneSession = GetSceneSession(persistentId);
6104 if (sceneSession == nullptr) {
6105 WLOGFD("sceneSession is nullptr.");
6106 return WSError::WS_DO_NOTHING;
6107 }
6108 if (haveListener) {
6109 touchOutsideListenerSessionSet_.insert(persistentId);
6110 } else {
6111 touchOutsideListenerSessionSet_.erase(persistentId);
6112 }
6113 return WSError::WS_OK;
6114 };
6115 return taskScheduler_->PostSyncTask(task, "UpdateSessionTouchOutsideListener" + std::to_string(persistentId));
6116 }
6117
UpdateSessionWindowVisibilityListener(int32_t persistentId,bool haveListener)6118 WSError SceneSessionManager::UpdateSessionWindowVisibilityListener(int32_t persistentId, bool haveListener)
6119 {
6120 auto task = [this, persistentId, haveListener]() -> WSError {
6121 WLOGFI("UpdateSessionWindowVisibilityListener persistentId: %{public}d haveListener:%{public}d",
6122 persistentId, haveListener);
6123 auto sceneSession = GetSceneSession(persistentId);
6124 if (sceneSession == nullptr) {
6125 WLOGFD("sceneSession is nullptr.");
6126 return WSError::WS_DO_NOTHING;
6127 }
6128 if (haveListener) {
6129 windowVisibilityListenerSessionSet_.insert(persistentId);
6130 sceneSession->NotifyWindowVisibility();
6131 } else {
6132 windowVisibilityListenerSessionSet_.erase(persistentId);
6133 }
6134 return WSError::WS_OK;
6135 };
6136 return taskScheduler_->PostSyncTask(task, "UpdateSessionWindowVisibilityListener");
6137 }
6138
SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc & func)6139 void SceneSessionManager::SetVirtualPixelRatioChangeListener(const ProcessVirtualPixelRatioChangeFunc& func)
6140 {
6141 processVirtualPixelRatioChangeFunc_ = func;
6142 WLOGFI("SetVirtualPixelRatioChangeListener");
6143 }
6144
ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)6145 void SceneSessionManager::ProcessVirtualPixelRatioChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
6146 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
6147 {
6148 if (displayInfo == nullptr) {
6149 WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange displayInfo is nullptr.");
6150 return;
6151 }
6152 auto task = [this, displayInfo]() {
6153 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6154 if (processVirtualPixelRatioChangeFunc_ != nullptr &&
6155 displayInfo->GetVirtualPixelRatio() == displayInfo->GetDensityInCurResolution()) {
6156 Rect rect = { displayInfo->GetOffsetX(), displayInfo->GetOffsetY(),
6157 displayInfo->GetWidth(), displayInfo->GetHeight()
6158 };
6159 processVirtualPixelRatioChangeFunc_(displayInfo->GetVirtualPixelRatio(), rect);
6160 }
6161 for (const auto &item : sceneSessionMap_) {
6162 auto scnSession = item.second;
6163 if (scnSession == nullptr) {
6164 WLOGFE("SceneSessionManager::ProcessVirtualPixelRatioChange null scene session");
6165 continue;
6166 }
6167 SessionInfo sessionInfo = scnSession->GetSessionInfo();
6168 if (sessionInfo.isSystem_) {
6169 continue;
6170 }
6171 if (scnSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
6172 scnSession->GetSessionState() == SessionState::STATE_ACTIVE) {
6173 scnSession->UpdateDensity();
6174 WLOGFD("UpdateDensity name=%{public}s, persistendId=%{public}d, winType=%{public}d, "
6175 "state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(), item.first,
6176 scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
6177 }
6178 }
6179 return WSError::WS_OK;
6180 };
6181 taskScheduler_->PostSyncTask(task, "ProcessVirtualPixelRatioChange:DID:" + std::to_string(defaultDisplayId));
6182 }
6183
ProcessUpdateRotationChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)6184 void SceneSessionManager::ProcessUpdateRotationChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
6185 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
6186 {
6187 if (displayInfo == nullptr) {
6188 WLOGFE("SceneSessionManager::ProcessUpdateRotationChange displayInfo is nullptr.");
6189 return;
6190 }
6191 auto task = [this, displayInfo]() {
6192 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6193 for (const auto &item : sceneSessionMap_) {
6194 auto scnSession = item.second;
6195 if (scnSession == nullptr) {
6196 WLOGFE("SceneSessionManager::ProcessUpdateRotationChange null scene session");
6197 continue;
6198 }
6199 if (scnSession->GetSessionState() == SessionState::STATE_FOREGROUND ||
6200 scnSession->GetSessionState() == SessionState::STATE_ACTIVE) {
6201 scnSession->UpdateRotationAvoidArea();
6202 WLOGFD("UpdateRotationAvoidArea name=%{public}s, persistendId=%{public}d, winType=%{public}d, "
6203 "state=%{public}d, visible-%{public}d", scnSession->GetWindowName().c_str(), item.first,
6204 scnSession->GetWindowType(), scnSession->GetSessionState(), scnSession->IsVisible());
6205 }
6206 }
6207 return WSError::WS_OK;
6208 };
6209 taskScheduler_->PostSyncTask(task, "ProcessUpdateRotationChange" + std::to_string(defaultDisplayId));
6210 }
6211
OnDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)6212 void DisplayChangeListener::OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
6213 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
6214 {
6215 WLOGFD("DisplayChangeListener::OnDisplayStateChange: %{public}u", type);
6216 switch (type) {
6217 case DisplayStateChangeType::VIRTUAL_PIXEL_RATIO_CHANGE: {
6218 SceneSessionManager::GetInstance().ProcessVirtualPixelRatioChange(defaultDisplayId,
6219 displayInfo, displayInfoMap, type);
6220 break;
6221 }
6222 case DisplayStateChangeType::UPDATE_ROTATION: {
6223 SceneSessionManager::GetInstance().ProcessUpdateRotationChange(defaultDisplayId,
6224 displayInfo, displayInfoMap, type);
6225 break;
6226 }
6227 default:
6228 return;
6229 }
6230 }
6231
OnScreenshot(DisplayId displayId)6232 void DisplayChangeListener::OnScreenshot(DisplayId displayId)
6233 {
6234 SceneSessionManager::GetInstance().OnScreenshot(displayId);
6235 }
6236
OnScreenshot(DisplayId displayId)6237 void SceneSessionManager::OnScreenshot(DisplayId displayId)
6238 {
6239 auto task = [this, displayId]() {
6240 auto sceneSession = GetSceneSession(focusedSessionId_);
6241 if (sceneSession) {
6242 sceneSession->NotifyScreenshot();
6243 }
6244 };
6245 taskScheduler_->PostAsyncTask(task, "OnScreenshot:PID:" + std::to_string(displayId));
6246 }
6247
ClearSession(int32_t persistentId)6248 WSError SceneSessionManager::ClearSession(int32_t persistentId)
6249 {
6250 WLOGFI("run ClearSession with persistentId: %{public}d", persistentId);
6251 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6252 WLOGFE("The caller is not system-app, can not use system-api");
6253 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6254 }
6255 if (!SessionPermission::VerifySessionPermission()) {
6256 WLOGFE("The caller has not permission granted");
6257 return WSError::WS_ERROR_INVALID_PERMISSION;
6258 }
6259 auto task = [this, persistentId]() {
6260 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
6261 return ClearSession(sceneSession);
6262 };
6263 taskScheduler_->PostAsyncTask(task, "ClearSession:PID:" + std::to_string(persistentId));
6264 return WSError::WS_OK;
6265 }
6266
ClearSession(sptr<SceneSession> sceneSession)6267 WSError SceneSessionManager::ClearSession(sptr<SceneSession> sceneSession)
6268 {
6269 WLOGFI("run ClearSession");
6270 if (sceneSession == nullptr) {
6271 WLOGFE("sceneSession is nullptr");
6272 return WSError::WS_ERROR_INVALID_SESSION;
6273 }
6274 if (!IsSessionClearable(sceneSession)) {
6275 WLOGFI("sceneSession cannot be clear, persistentId %{public}d.", sceneSession->GetPersistentId());
6276 return WSError::WS_ERROR_INVALID_SESSION;
6277 }
6278 const WSError& errCode = sceneSession->Clear();
6279 return errCode;
6280 }
6281
ClearAllSessions()6282 WSError SceneSessionManager::ClearAllSessions()
6283 {
6284 WLOGFI("run ClearAllSessions");
6285 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6286 WLOGFE("The caller is not system-app, can not use system-api");
6287 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6288 }
6289 if (!SessionPermission::VerifySessionPermission()) {
6290 WLOGFE("The caller has not permission granted");
6291 return WSError::WS_ERROR_INVALID_PERMISSION;
6292 }
6293 auto task = [this]() {
6294 std::vector<sptr<SceneSession>> sessionVector;
6295 GetAllClearableSessions(sessionVector);
6296 for (uint32_t i = 0; i < sessionVector.size(); i++) {
6297 ClearSession(sessionVector[i]);
6298 }
6299 return WSError::WS_OK;
6300 };
6301 taskScheduler_->PostAsyncTask(task, "ClearAllSessions");
6302 return WSError::WS_OK;
6303 }
6304
GetAllClearableSessions(std::vector<sptr<SceneSession>> & sessionVector)6305 void SceneSessionManager::GetAllClearableSessions(std::vector<sptr<SceneSession>>& sessionVector)
6306 {
6307 WLOGFI("run GetAllClearableSessions");
6308 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6309 for (const auto &item : sceneSessionMap_) {
6310 auto scnSession = item.second;
6311 if (IsSessionClearable(scnSession)) {
6312 sessionVector.push_back(scnSession);
6313 }
6314 }
6315 }
6316
LockSession(int32_t sessionId)6317 WSError SceneSessionManager::LockSession(int32_t sessionId)
6318 {
6319 WLOGFI("run LockSession with persistentId: %{public}d", sessionId);
6320 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6321 WLOGFE("The caller is not system-app, can not use system-api");
6322 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6323 }
6324 if (!SessionPermission::VerifySessionPermission()) {
6325 WLOGFE("The caller has not permission granted");
6326 return WSError::WS_ERROR_INVALID_PERMISSION;
6327 }
6328 auto task = [this, sessionId]() {
6329 auto sceneSession = GetSceneSession(sessionId);
6330 if (sceneSession == nullptr) {
6331 WLOGFE("can not find sceneSession, sessionId:%{public}d", sessionId);
6332 return WSError::WS_ERROR_INVALID_PARAM;
6333 }
6334 sceneSession->SetSessionInfoLockedState(true);
6335 return WSError::WS_OK;
6336 };
6337 return taskScheduler_->PostSyncTask(task, "LockSession:SID:" + std::to_string(sessionId));
6338 }
6339
UnlockSession(int32_t sessionId)6340 WSError SceneSessionManager::UnlockSession(int32_t sessionId)
6341 {
6342 WLOGFI("run UnlockSession with persistentId: %{public}d", sessionId);
6343 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6344 WLOGFE("The caller is not system-app, can not use system-api");
6345 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6346 }
6347 if (!SessionPermission::VerifySessionPermission()) {
6348 WLOGFE("The caller has not permission granted");
6349 return WSError::WS_ERROR_INVALID_PERMISSION;
6350 }
6351 auto task = [this, sessionId]() {
6352 auto sceneSession = GetSceneSession(sessionId);
6353 if (sceneSession == nullptr) {
6354 WLOGFE("can not find sceneSession, sessionId:%{public}d", sessionId);
6355 return WSError::WS_ERROR_INVALID_PARAM;
6356 }
6357 sceneSession->SetSessionInfoLockedState(false);
6358 return WSError::WS_OK;
6359 };
6360 return taskScheduler_->PostSyncTask(task, "UnlockSession" + std::to_string(sessionId));
6361 }
6362
MoveSessionsToForeground(const std::vector<int32_t> & sessionIds,int32_t topSessionId)6363 WSError SceneSessionManager::MoveSessionsToForeground(const std::vector<int32_t>& sessionIds, int32_t topSessionId)
6364 {
6365 WLOGFI("run MoveSessionsToForeground");
6366 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6367 WLOGFE("The caller is not system-app, can not use system-api");
6368 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6369 }
6370 if (!SessionPermission::VerifySessionPermission()) {
6371 WLOGFE("The caller has not permission granted");
6372 return WSError::WS_ERROR_INVALID_PERMISSION;
6373 }
6374
6375 return WSError::WS_OK;
6376 }
6377
MoveSessionsToBackground(const std::vector<int32_t> & sessionIds,std::vector<int32_t> & result)6378 WSError SceneSessionManager::MoveSessionsToBackground(const std::vector<int32_t>& sessionIds,
6379 std::vector<int32_t>& result)
6380 {
6381 WLOGFI("run MoveSessionsToBackground");
6382 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
6383 WLOGFE("The caller is not system-app, can not use system-api");
6384 return WSError::WS_ERROR_NOT_SYSTEM_APP;
6385 }
6386 if (!SessionPermission::VerifySessionPermission()) {
6387 WLOGFE("The caller has not permission granted");
6388 return WSError::WS_ERROR_INVALID_PERMISSION;
6389 }
6390
6391 result.insert(result.end(), sessionIds.begin(), sessionIds.end());
6392 return WSError::WS_OK;
6393 }
6394
IsSessionClearable(sptr<SceneSession> scnSession)6395 bool SceneSessionManager::IsSessionClearable(sptr<SceneSession> scnSession)
6396 {
6397 if (scnSession == nullptr) {
6398 WLOGFI("scnSession is nullptr");
6399 return false;
6400 }
6401 SessionInfo sessionInfo = scnSession->GetSessionInfo();
6402 if (sessionInfo.abilityInfo == nullptr) {
6403 WLOGFI("scnSession abilityInfo is nullptr");
6404 return false;
6405 }
6406 if (sessionInfo.abilityInfo->excludeFromMissions) {
6407 WLOGFI("persistentId %{public}d is excludeFromMissions", scnSession->GetPersistentId());
6408 return false;
6409 }
6410 if (sessionInfo.abilityInfo->unclearableMission) {
6411 WLOGFI("persistentId %{public}d is unclearable", scnSession->GetPersistentId());
6412 return false;
6413 }
6414 if (sessionInfo.isSystem_) {
6415 WLOGFI("persistentId %{public}d is system app", scnSession->GetPersistentId());
6416 return false;
6417 }
6418 if (sessionInfo.lockedState) {
6419 WLOGFI("persistentId %{public}d is in lockedState", scnSession->GetPersistentId());
6420 return false;
6421 }
6422
6423 return true;
6424 }
6425
RegisterIAbilityManagerCollaborator(int32_t type,const sptr<AAFwk::IAbilityManagerCollaborator> & impl)6426 WSError SceneSessionManager::RegisterIAbilityManagerCollaborator(int32_t type,
6427 const sptr<AAFwk::IAbilityManagerCollaborator> &impl)
6428 {
6429 WLOGFI("RegisterIAbilityManagerCollaborator with type : %{public}d", type);
6430 auto isSaCall = SessionPermission::IsSACalling();
6431 auto callingUid = IPCSkeleton::GetCallingUid();
6432 if (!isSaCall || (callingUid != BROKER_UID && callingUid != BROKER_RESERVE_UID)) {
6433 WLOGFE("The interface only support for broker");
6434 return WSError::WS_ERROR_INVALID_PERMISSION;
6435 }
6436 if (!CheckCollaboratorType(type)) {
6437 WLOGFW("collaborator register failed, invalid type.");
6438 return WSError::WS_ERROR_INVALID_TYPE;
6439 }
6440 {
6441 std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
6442 collaboratorMap_[type] = impl;
6443 }
6444 return WSError::WS_OK;
6445 }
6446
UnregisterIAbilityManagerCollaborator(int32_t type)6447 WSError SceneSessionManager::UnregisterIAbilityManagerCollaborator(int32_t type)
6448 {
6449 WLOGFI("UnregisterIAbilityManagerCollaborator with type : %{public}d", type);
6450 auto isSaCall = SessionPermission::IsSACalling();
6451 auto callingUid = IPCSkeleton::GetCallingUid();
6452 if (!isSaCall || (callingUid != BROKER_UID && callingUid != BROKER_RESERVE_UID)) {
6453 WLOGFE("The interface only support for broker");
6454 return WSError::WS_ERROR_INVALID_PERMISSION;
6455 }
6456 if (!CheckCollaboratorType(type)) {
6457 WLOGFE("collaborator unregister failed, invalid type.");
6458 return WSError::WS_ERROR_INVALID_TYPE;
6459 }
6460 {
6461 std::unique_lock<std::shared_mutex> lock(collaboratorMapLock_);
6462 collaboratorMap_.erase(type);
6463 }
6464 return WSError::WS_OK;
6465 }
6466
ProcessPiPSessionForeground(const sptr<SceneSession> sceneSession)6467 void SceneSessionManager::ProcessPiPSessionForeground(const sptr<SceneSession> sceneSession)
6468 {
6469 if (sceneSession == nullptr) {
6470 WLOGFE("pip window not found");
6471 return;
6472 }
6473 WLOGFD("start pip rect");
6474 sceneSession->UpdatePiPRect(0, 0, PiPRectUpdateReason::REASON_PIP_START_WINDOW);
6475 }
6476
RecoveryPullPiPMainWindow(const int32_t & persistentId,const Rect & rect)6477 WSError SceneSessionManager::RecoveryPullPiPMainWindow(const int32_t& persistentId, const Rect& rect)
6478 {
6479 auto scnSession = GetSceneSession(persistentId);
6480 if (scnSession == nullptr) {
6481 WLOGFE("scnSession is nullptr, persistentId: %{public}d", persistentId);
6482 return WSError::WS_ERROR_NULLPTR;
6483 }
6484 if (!WindowHelper::IsPipWindow(scnSession->GetWindowType())) {
6485 WLOGFE("not pip window");
6486 return WSError::WS_DO_NOTHING;
6487 }
6488 if (!showPiPMainWindowFunc_) {
6489 WLOGFE("showPiPMainWindowFunc_ init error, persistentId: %{public}d", persistentId);
6490 return WSError::WS_DO_NOTHING;
6491 }
6492 auto task = [this, scnSession, rect]() {
6493 showPiPMainWindowFunc_(scnSession->GetParentPersistentId());
6494 WSRect rectPos = SessionHelper::TransferToWSRect(rect);
6495 scnSession->UpdateSessionRect(rectPos, SizeChangeReason::RECOVER);
6496 return WSError::WS_OK;
6497 };
6498 taskScheduler_->PostAsyncTask(task, "RecoveryPullPiPMainWindow");
6499 return WSError::WS_OK;
6500 }
6501
CheckCollaboratorType(int32_t type)6502 bool SceneSessionManager::CheckCollaboratorType(int32_t type)
6503 {
6504 if (type != CollaboratorType::RESERVE_TYPE && type != CollaboratorType::OTHERS_TYPE) {
6505 WLOGFD("type is invalid");
6506 return false;
6507 }
6508 return true;
6509 }
6510
CheckIfReuseSession(SessionInfo & sessionInfo)6511 BrokerStates SceneSessionManager::CheckIfReuseSession(SessionInfo& sessionInfo)
6512 {
6513 auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
6514 sessionInfo.moduleName_);
6515 if (abilityInfo == nullptr) {
6516 WLOGFE("CheckIfReuseSession abilityInfo is nullptr!");
6517 return BrokerStates::BROKER_UNKOWN;
6518 }
6519 sessionInfo.abilityInfo = abilityInfo;
6520 int32_t collaboratorType = CollaboratorType::DEFAULT_TYPE;
6521 if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
6522 collaboratorType = CollaboratorType::RESERVE_TYPE;
6523 } else if (abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
6524 collaboratorType = CollaboratorType::OTHERS_TYPE;
6525 }
6526 if (!CheckCollaboratorType(collaboratorType)) {
6527 WLOGFW("CheckIfReuseSession not collaborator!");
6528 return BrokerStates::BROKER_UNKOWN;
6529 }
6530 BrokerStates resultValue = NotifyStartAbility(collaboratorType, sessionInfo);
6531 sessionInfo.collaboratorType_ = collaboratorType;
6532 sessionInfo.sessionAffinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
6533 if (FindSessionByAffinity(sessionInfo.sessionAffinity) != nullptr) {
6534 WLOGFI("FindSessionByAffinity: %{public}s, try to reuse", sessionInfo.sessionAffinity.c_str());
6535 sessionInfo.reuse = true;
6536 } else {
6537 sessionInfo.reuse = false;
6538 }
6539 WLOGFI("CheckIfReuseSession end, affinity %{public}s type %{public}d reuse %{public}d",
6540 sessionInfo.sessionAffinity.c_str(), collaboratorType, sessionInfo.reuse);
6541 return resultValue;
6542 }
6543
NotifyStartAbility(int32_t collaboratorType,const SessionInfo & sessionInfo,int32_t persistentId)6544 BrokerStates SceneSessionManager::NotifyStartAbility(
6545 int32_t collaboratorType, const SessionInfo& sessionInfo, int32_t persistentId)
6546 {
6547 WLOGFI("run NotifyStartAbility type %{public}d param id %{public}d", collaboratorType, persistentId);
6548 auto iter = collaboratorMap_.find(collaboratorType);
6549 if (iter == collaboratorMap_.end()) {
6550 WLOGFI("Fail to found collaborator with type: %{public}d", collaboratorType);
6551 return BrokerStates::BROKER_UNKOWN;
6552 }
6553 if (sessionInfo.want == nullptr) {
6554 WLOGFI("sessionInfo.want is nullptr, init");
6555 sessionInfo.want = std::make_shared<AAFwk::Want>();
6556 sessionInfo.want->SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
6557 sessionInfo.moduleName_);
6558 }
6559 auto collaborator = iter->second;
6560 auto accessTokenIDEx = sessionInfo.callingTokenId_;
6561 if (collaborator != nullptr) {
6562 containerStartAbilityTime = std::chrono::duration_cast<std::chrono::milliseconds>(
6563 std::chrono::system_clock::now().time_since_epoch()).count();
6564
6565 std::string affinity = sessionInfo.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
6566 if (!affinity.empty() && FindSessionByAffinity(affinity) != nullptr) {
6567 WLOGFI("NotifyStartAbility affinity exit %{public}s.", affinity.c_str());
6568 return BrokerStates::BROKER_UNKOWN;
6569 }
6570 sessionInfo.want->SetParam("oh_persistentId", persistentId);
6571 int32_t ret = collaborator->NotifyStartAbility(*(sessionInfo.abilityInfo),
6572 currentUserId_, *(sessionInfo.want), static_cast<uint64_t>(accessTokenIDEx));
6573 WLOGFI("NotifyStartAbility ret: %{public}d", ret);
6574 if (ret == 0) {
6575 return BrokerStates::BROKER_STARTED;
6576 } else {
6577 return BrokerStates::BROKER_NOT_START;
6578 }
6579 }
6580 return BrokerStates::BROKER_UNKOWN;
6581 }
6582
NotifySessionCreate(sptr<SceneSession> sceneSession,const SessionInfo & sessionInfo)6583 void SceneSessionManager::NotifySessionCreate(sptr<SceneSession> sceneSession, const SessionInfo& sessionInfo)
6584 {
6585 WLOGFI("run NotifySessionCreate");
6586 if (sceneSession == nullptr) {
6587 WLOGFE("sceneSession is nullptr");
6588 return;
6589 }
6590 if (sessionInfo.want == nullptr) {
6591 WLOGFI("sessionInfo.want is nullptr");
6592 return;
6593 }
6594 auto iter = collaboratorMap_.find(sceneSession->GetCollaboratorType());
6595 if (iter == collaboratorMap_.end()) {
6596 WLOGFI("Fail to found collaborator with type: %{public}d", sceneSession->GetCollaboratorType());
6597 return;
6598 }
6599 auto collaborator = iter->second;
6600 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
6601 sceneSession->SetSelfToken(abilitySessionInfo->sessionToken);
6602 abilitySessionInfo->want = *(sessionInfo.want);
6603 if (collaborator != nullptr) {
6604 int32_t missionId = abilitySessionInfo->persistentId;
6605 std::string bundleName = sessionInfo.bundleName_;
6606 int64_t timestamp = containerStartAbilityTime;
6607 WindowInfoReporter::GetInstance().ReportContainerStartBegin(missionId, bundleName, timestamp);
6608
6609 collaborator->NotifyMissionCreated(abilitySessionInfo);
6610 }
6611 }
6612
NotifyLoadAbility(int32_t collaboratorType,sptr<AAFwk::SessionInfo> abilitySessionInfo,std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)6613 void SceneSessionManager::NotifyLoadAbility(int32_t collaboratorType,
6614 sptr<AAFwk::SessionInfo> abilitySessionInfo, std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
6615 {
6616 WLOGFI("run NotifyLoadAbility");
6617 auto iter = collaboratorMap_.find(collaboratorType);
6618 if (iter == collaboratorMap_.end()) {
6619 WLOGFE("Fail to found collaborator with type: %{public}d", collaboratorType);
6620 return;
6621 }
6622 auto collaborator = iter->second;
6623 if (collaborator != nullptr) {
6624 collaborator->NotifyLoadAbility(*abilityInfo, abilitySessionInfo);
6625 }
6626 }
6627
6628
NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)6629 void SceneSessionManager::NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)
6630 {
6631 WLOGFI("run NotifyUpdateSessionInfo");
6632 if (sceneSession == nullptr) {
6633 WLOGFE("sceneSession is nullptr");
6634 return;
6635 }
6636 auto iter = collaboratorMap_.find(sceneSession->GetCollaboratorType());
6637 if (iter == collaboratorMap_.end()) {
6638 WLOGFE("Fail to found collaborator with type: %{public}d", sceneSession->GetCollaboratorType());
6639 return;
6640 }
6641 auto collaborator = iter->second;
6642 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
6643 if (collaborator != nullptr) {
6644 collaborator->UpdateMissionInfo(abilitySessionInfo);
6645 }
6646 }
6647
NotifyMoveSessionToForeground(int32_t collaboratorType,int32_t persistentId)6648 void SceneSessionManager::NotifyMoveSessionToForeground(int32_t collaboratorType, int32_t persistentId)
6649 {
6650 WLOGFI("run NotifyMoveSessionToForeground");
6651 auto iter = collaboratorMap_.find(collaboratorType);
6652 if (iter == collaboratorMap_.end()) {
6653 WLOGFE("Fail to found collaborator with type: %{public}d", collaboratorType);
6654 return;
6655 }
6656 auto collaborator = iter->second;
6657 if (collaborator != nullptr) {
6658 collaborator->NotifyMoveMissionToForeground(persistentId);
6659 }
6660 }
6661
NotifyClearSession(int32_t collaboratorType,int32_t persistentId)6662 void SceneSessionManager::NotifyClearSession(int32_t collaboratorType, int32_t persistentId)
6663 {
6664 WLOGFI("run NotifyClearSession with persistentId %{public}d", persistentId);
6665 auto iter = collaboratorMap_.find(collaboratorType);
6666 if (iter == collaboratorMap_.end()) {
6667 WLOGFE("Fail to found collaborator with type: %{public}d", collaboratorType);
6668 return;
6669 }
6670 auto collaborator = iter->second;
6671 if (collaborator != nullptr) {
6672 collaborator->NotifyClearMission(persistentId);
6673 }
6674 }
6675
PreHandleCollaborator(sptr<SceneSession> & sceneSession,int32_t persistentId)6676 void SceneSessionManager::PreHandleCollaborator(sptr<SceneSession>& sceneSession, int32_t persistentId)
6677 {
6678 WLOGFI("run PreHandleCollaborator");
6679 if (sceneSession == nullptr) {
6680 return;
6681 }
6682 std::string sessionAffinity;
6683 WLOGFI("try to run NotifyStartAbility and NotifySessionCreate");
6684 if (sceneSession->GetSessionInfo().want != nullptr) {
6685 sessionAffinity = sceneSession->GetSessionInfo().want
6686 ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
6687 }
6688 if (sessionAffinity.empty()) {
6689 WLOGFI("PreHandleCollaborator sessionAffinity: %{public}s", sessionAffinity.c_str());
6690 BrokerStates notifyReturn = NotifyStartAbility(
6691 sceneSession->GetCollaboratorType(), sceneSession->GetSessionInfo(), persistentId);
6692 if (notifyReturn != BrokerStates::BROKER_STARTED) {
6693 WLOGFI("PreHandleCollaborator cant notify");
6694 return;
6695 }
6696
6697 }
6698 if (sceneSession->GetSessionInfo().want != nullptr) {
6699 WLOGFI("broker persistentId: %{public}d",
6700 sceneSession->GetSessionInfo().want->GetIntParam(AncoConsts::ANCO_SESSION_ID, 0));
6701 sceneSession->SetSessionInfoAffinity(sceneSession->GetSessionInfo().want
6702 ->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY));
6703 WLOGFI("affinity: %{public}s", sceneSession->GetSessionInfo().sessionAffinity.c_str());
6704 } else {
6705 WLOGFI("sceneSession->GetSessionInfo().want is nullptr");
6706 }
6707 NotifySessionCreate(sceneSession, sceneSession->GetSessionInfo());
6708 sceneSession->SetSessionInfoAncoSceneState(AncoSceneState::NOTIFY_CREATE);
6709 }
6710
AddWindowDragHotArea(int32_t type,WSRect & area)6711 void SceneSessionManager::AddWindowDragHotArea(int32_t type, WSRect& area)
6712 {
6713 WLOGFI("run AddWindowDragHotArea, type: %{public}d,posX: %{public}d,posY: %{public}d,width: %{public}d,"
6714 "height: %{public}d", type, area.posX_, area.posY_, area.width_, area.height_);
6715 SceneSession::windowDragHotAreaMap_.insert({type, area});
6716 }
6717
UpdateMaximizeMode(int32_t persistentId,bool isMaximize)6718 WSError SceneSessionManager::UpdateMaximizeMode(int32_t persistentId, bool isMaximize)
6719 {
6720 auto task = [this, persistentId, isMaximize]() -> WSError {
6721 WLOGFD("update maximize mode, id: %{public}d, isMaximize: %{public}d", persistentId, isMaximize);
6722 auto sceneSession = GetSceneSession(persistentId);
6723 if (sceneSession == nullptr) {
6724 WLOGFE("could not find window, persistentId:%{public}d", persistentId);
6725 return WSError::WS_ERROR_INVALID_WINDOW;
6726 }
6727 sceneSession->UpdateMaximizeMode(isMaximize);
6728 return WSError::WS_OK;
6729 };
6730 taskScheduler_->PostAsyncTask(task, "UpdateMaximizeMode:PID:" + std::to_string(persistentId));
6731 return WSError::WS_OK;
6732 }
6733
UpdateSessionDisplayId(int32_t persistentId,uint64_t screenId)6734 WSError SceneSessionManager::UpdateSessionDisplayId(int32_t persistentId, uint64_t screenId)
6735 {
6736 auto scnSession = GetSceneSession(persistentId);
6737 if (!scnSession) {
6738 WLOGFE("session is nullptr");
6739 return WSError::WS_ERROR_INVALID_WINDOW;
6740 }
6741 auto fromScreenId = scnSession->GetSessionInfo().screenId_;
6742 scnSession->SetScreenId(screenId);
6743 if (!scnSession->GetSessionProperty()) {
6744 WLOGFE("Property is null, synchronous screenId failed");
6745 return WSError::WS_ERROR_NULLPTR;
6746 }
6747 scnSession->GetSessionProperty()->SetDisplayId(screenId);
6748 WLOGFD("Session move display %{public}" PRIu64" from %{public}" PRIu64"", screenId, fromScreenId);
6749 NotifySessionUpdate(scnSession->GetSessionInfo(), ActionType::MOVE_DISPLAY, fromScreenId);
6750 return WSError::WS_OK;
6751 }
6752
OnImmersiveStateChange(bool & immersive)6753 void DisplayChangeListener::OnImmersiveStateChange(bool& immersive)
6754 {
6755 immersive = SceneSessionManager::GetInstance().UpdateImmersiveState();
6756 }
6757
UpdateImmersiveState()6758 bool SceneSessionManager::UpdateImmersiveState()
6759 {
6760 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6761 for (auto item = sceneSessionMap_.begin(); item != sceneSessionMap_.end(); ++item) {
6762 auto sceneSession = item->second;
6763 if (sceneSession == nullptr) {
6764 WLOGFE("Session is nullptr");
6765 continue;
6766 }
6767 if (!WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
6768 continue;
6769 }
6770 auto state = sceneSession->GetSessionState();
6771 if (state != SessionState::STATE_FOREGROUND && state != SessionState::STATE_ACTIVE) {
6772 continue;
6773 }
6774 if (sceneSession->GetWindowMode() != WindowMode::WINDOW_MODE_FULLSCREEN) {
6775 continue;
6776 }
6777 auto property = sceneSession->GetSessionProperty();
6778 if (property == nullptr) {
6779 WLOGFE("Property is nullptr");
6780 continue;
6781 }
6782 auto sysBarProperty = property->GetSystemBarProperty();
6783 if (sysBarProperty[WindowType::WINDOW_TYPE_STATUS_BAR].enable_ == false) {
6784 WLOGFD("Current window is immersive");
6785 return true;
6786 } else {
6787 WLOGFD("Current window is not immersive");
6788 break;
6789 }
6790 }
6791 return false;
6792 }
6793
NotifySessionForeground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation)6794 void SceneSessionManager::NotifySessionForeground(const sptr<SceneSession>& session, uint32_t reason,
6795 bool withAnimation)
6796 {
6797 session->NotifySessionForeground(reason, withAnimation);
6798 }
6799
NotifySessionBackground(const sptr<SceneSession> & session,uint32_t reason,bool withAnimation,bool isFromInnerkits)6800 void SceneSessionManager::NotifySessionBackground(const sptr<SceneSession>& session, uint32_t reason,
6801 bool withAnimation, bool isFromInnerkits)
6802 {
6803 session->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
6804 }
6805
UpdateTitleInTargetPos(int32_t persistentId,bool isShow,int32_t height)6806 WSError SceneSessionManager::UpdateTitleInTargetPos(int32_t persistentId, bool isShow, int32_t height)
6807 {
6808 auto sceneSession = GetSceneSession(persistentId);
6809 if (sceneSession == nullptr) {
6810 WLOGFE("could not find window, persistentId:%{public}d", persistentId);
6811 return WSError::WS_ERROR_INVALID_WINDOW;
6812 }
6813 return sceneSession->UpdateTitleInTargetPos(isShow, height);
6814 }
6815
GetSceneSessionMap()6816 const std::map<int32_t, sptr<SceneSession>> SceneSessionManager::GetSceneSessionMap()
6817 {
6818 std::map<int32_t, sptr<SceneSession>> retSceneSessionMap;
6819 {
6820 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6821 retSceneSessionMap = sceneSessionMap_;
6822 }
6823 EraseIf(retSceneSessionMap, [this](const auto& pair) {
6824 if (pair.second == nullptr) {
6825 return true;
6826 }
6827
6828 if (pair.second->IsSystemInput()) {
6829 return false;
6830 } else if (pair.second->IsSystemSession() && pair.second->IsVisible() && pair.second->IsSystemActive()) {
6831 return false;
6832 }
6833 if (!Rosen::SceneSessionManager::GetInstance().IsSessionVisible(pair.second)) {
6834 return true;
6835 }
6836 return false;
6837 });
6838 return retSceneSessionMap;
6839 }
6840
NotifyUpdateRectAfterLayout()6841 void SceneSessionManager::NotifyUpdateRectAfterLayout()
6842 {
6843 auto transactionController = Rosen::RSSyncTransactionController::GetInstance();
6844 std::shared_ptr<RSTransaction> rsTransaction = nullptr;
6845 if (transactionController) {
6846 rsTransaction = transactionController->GetRSTransaction();
6847 }
6848 auto task = [this, rsTransaction]() {
6849 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
6850 for (const auto& iter: sceneSessionMap_) {
6851 auto sceneSession = iter.second;
6852 if (sceneSession && sceneSession->IsDirtyWindow()) {
6853 sceneSession->NotifyClientToUpdateRect(rsTransaction);
6854 }
6855 }
6856 };
6857 // need sync task since animation transcation need
6858 return taskScheduler_->PostAsyncTask(task, "NotifyUpdateRectAfterLayout");
6859 }
6860
RaiseWindowToTop(int32_t persistentId)6861 WSError SceneSessionManager::RaiseWindowToTop(int32_t persistentId)
6862 {
6863 WLOGFI("RaiseWindowToTop, id %{public}d", persistentId);
6864 auto isSaCall = SessionPermission::IsSACalling();
6865 if (!isSaCall) {
6866 WLOGFE("The interface only support for sa call");
6867 return WSError::WS_ERROR_INVALID_PERMISSION;
6868 }
6869 auto task = [this, persistentId]() {
6870 auto sceneSession = GetSceneSession(persistentId);
6871 if (sceneSession == nullptr) {
6872 WLOGFE("session is nullptr");
6873 return WSError::WS_ERROR_INVALID_SESSION;
6874 }
6875 if (!IsSessionVisible(sceneSession)) {
6876 WLOGFD("session is not visible!");
6877 return WSError::WS_DO_NOTHING;
6878 }
6879 RequestSessionFocus(persistentId, true);
6880 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType())) {
6881 sceneSession->RaiseToAppTop();
6882 }
6883 if (WindowHelper::IsSubWindow(sceneSession->GetWindowType()) ||
6884 sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
6885 WLOGFD("parent session id: %{public}d", sceneSession->GetParentPersistentId());
6886 sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
6887 }
6888 if (sceneSession == nullptr) {
6889 WLOGFE("parent session is nullptr");
6890 return WSError::WS_ERROR_INVALID_SESSION;
6891 }
6892 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6893 sceneSession->NotifyClick();
6894 return WSError::WS_OK;
6895 } else {
6896 WLOGFE("session is not app main window!");
6897 return WSError::WS_ERROR_INVALID_SESSION;
6898 }
6899 };
6900 taskScheduler_->PostAsyncTask(task, "RaiseWindowToTop");
6901 return WSError::WS_OK;
6902 }
6903
ShiftAppWindowFocus(int32_t sourcePersistentId,int32_t targetPersistentId)6904 WSError SceneSessionManager::ShiftAppWindowFocus(int32_t sourcePersistentId, int32_t targetPersistentId)
6905 {
6906 WLOGI("run ShiftAppWindowFocus, form id: %{public}d to id: %{public}d", sourcePersistentId, targetPersistentId);
6907 if (sourcePersistentId != focusedSessionId_) {
6908 WLOGE("source session need be focused");
6909 return WSError::WS_ERROR_INVALID_OPERATION;
6910 }
6911 if (targetPersistentId == focusedSessionId_) {
6912 WLOGE("target session has been focused");
6913 return WSError::WS_DO_NOTHING;
6914 }
6915 sptr<SceneSession> sourceSession = nullptr;
6916 WSError ret = GetAppMainSceneSession(sourceSession, sourcePersistentId);
6917 if (ret != WSError::WS_OK) {
6918 return ret;
6919 }
6920 sptr<SceneSession> targetSession = nullptr;
6921 ret = GetAppMainSceneSession(targetSession, targetPersistentId);
6922 if (ret != WSError::WS_OK) {
6923 return ret;
6924 }
6925 if (sourceSession->GetSessionInfo().bundleName_ != targetSession->GetSessionInfo().bundleName_) {
6926 WLOGE("verify bundle name failed, source bundle name is %{public}s but target bundle name is %{public}s)",
6927 sourceSession->GetSessionInfo().bundleName_.c_str(), targetSession->GetSessionInfo().bundleName_.c_str());
6928 return WSError::WS_ERROR_INVALID_CALLING;
6929 }
6930 if (!SessionPermission::IsSameBundleNameAsCalling(targetSession->GetSessionInfo().bundleName_)) {
6931 return WSError::WS_ERROR_INVALID_CALLING;
6932 }
6933 targetSession->NotifyClick();
6934 return RequestSessionFocus(targetPersistentId, false);
6935 }
6936
GetAppMainSceneSession(sptr<SceneSession> & sceneSession,int32_t persistentId)6937 WSError SceneSessionManager::GetAppMainSceneSession(sptr<SceneSession>& sceneSession, int32_t persistentId)
6938 {
6939 sceneSession = GetSceneSession(persistentId);
6940 if (sceneSession == nullptr) {
6941 WLOGE("session(id: %{public}d) is nullptr", persistentId);
6942 return WSError::WS_ERROR_INVALID_SESSION;
6943 }
6944 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
6945 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
6946 WLOGE("session(id: %{public}d) is not main window or sub window", persistentId);
6947 return WSError::WS_ERROR_INVALID_CALLING;
6948 }
6949 sceneSession = GetSceneSession(sceneSession->GetParentPersistentId());
6950 if (sceneSession == nullptr) {
6951 WLOGE("session(id: %{public}d) parent is nullptr", persistentId);
6952 return WSError::WS_ERROR_INVALID_SESSION;
6953 }
6954 }
6955 return WSError::WS_OK;
6956 }
6957
GetSessionSnapshotPixelMap(const int32_t persistentId,const float scaleParam)6958 std::shared_ptr<Media::PixelMap> SceneSessionManager::GetSessionSnapshotPixelMap(const int32_t persistentId,
6959 const float scaleParam)
6960 {
6961 auto sceneSession = GetSceneSession(persistentId);
6962 if (!sceneSession) {
6963 WLOGFE("get scene session is nullptr");
6964 return nullptr;
6965 }
6966
6967 wptr<SceneSession> weakSceneSession(sceneSession);
6968 auto task = [this, persistentId, scaleParam, weakSceneSession]() {
6969 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:GetSessionSnapshotPixelMap(%d )", persistentId);
6970 auto scnSession = weakSceneSession.promote();
6971 std::shared_ptr<Media::PixelMap> pixelMap = nullptr;
6972 if (scnSession == nullptr) {
6973 WLOGFE("session is nullptr");
6974 return pixelMap;
6975 }
6976
6977 if (scnSession->GetSessionState() == SessionState::STATE_ACTIVE ||
6978 scnSession->GetSessionState() == SessionState::STATE_FOREGROUND) {
6979 pixelMap = scnSession->Snapshot(scaleParam);
6980 }
6981 if (!pixelMap) {
6982 WLOGFI("get local snapshot pixelmap start");
6983 pixelMap = scnSession->GetSnapshotPixelMap (snapshotScale_, scaleParam);
6984 }
6985 return pixelMap;
6986 };
6987 return taskScheduler_->PostSyncTask(task, "GetSessionSnapshotPixelMap" + std::to_string(persistentId));
6988 }
6989
OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)6990 void AppAnrListener::OnAppDebugStarted(const std::vector<AppExecFwk::AppDebugInfo> &debugInfos)
6991 {
6992 WLOGFI("AppAnrListener OnAppDebugStarted");
6993 if (debugInfos.empty()) {
6994 WLOGFE("AppAnrListener OnAppDebugStarted debugInfos is empty");
6995 return;
6996 }
6997 DelayedSingleton<ANRManager>::GetInstance()->SwitchAnr(false);
6998 }
6999
OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo> & debugInfos)7000 void AppAnrListener::OnAppDebugStoped(const std::vector<AppExecFwk::AppDebugInfo> &debugInfos)
7001 {
7002 WLOGFI("AppAnrListener OnAppDebugStoped");
7003 if (debugInfos.empty()) {
7004 WLOGFE("AppAnrListener OnAppDebugStoped debugInfos is empty");
7005 return;
7006 }
7007 DelayedSingleton<ANRManager>::GetInstance()->SwitchAnr(true);
7008 }
7009
FlushWindowInfoToMMI()7010 void SceneSessionManager::FlushWindowInfoToMMI()
7011 {
7012 auto task = []()-> WSError {
7013 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSessionManager::FlushWindowInfoToMMI");
7014 SceneInputManager::GetInstance().FlushDisplayInfoToMMI();
7015 return WSError::WS_OK;
7016 };
7017 return taskScheduler_->PostAsyncTask(task);
7018 }
7019
GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>> & infos)7020 WMError SceneSessionManager::GetVisibilityWindowInfo(std::vector<sptr<WindowVisibilityInfo>>& infos)
7021 {
7022 if (!SessionPermission::IsSystemCalling()) {
7023 WLOGFE("GetVisibilityWindowInfo permission denied!");
7024 return WMError::WM_ERROR_NOT_SYSTEM_APP;
7025 }
7026 auto task = [this, &infos]() {
7027 for (auto [surfaceId, _] : lastVisibleData_) {
7028 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
7029 if (session == nullptr) {
7030 continue;
7031 }
7032 infos.emplace_back(new WindowVisibilityInfo(session->GetWindowId(), session->GetCallingPid(),
7033 session->GetCallingUid(), session->GetVisibilityState(), session->GetWindowType()));
7034 }
7035 return WMError::WM_OK;
7036 };
7037 return taskScheduler_->PostSyncTask(task, "GetVisibilityWindowInfo");
7038 }
7039
PostFlushWindowInfoTask(FlushWindowInfoTask && task,const std::string taskName,const int delayTime)7040 void SceneSessionManager::PostFlushWindowInfoTask(FlushWindowInfoTask &&task,
7041 const std::string taskName, const int delayTime)
7042 {
7043 taskScheduler_->PostAsyncTask(std::move(task), taskName, delayTime);
7044 }
7045
HideNonSecureWindows(bool shouldHide)7046 WSError SceneSessionManager::HideNonSecureWindows(bool shouldHide)
7047 {
7048 WLOGFI("HideNonSecureWindows, shouldHide %{public}u", shouldHide);
7049 if (!SessionPermission::IsSystemCalling()) {
7050 WLOGFE("HideNonSecureWindows permission denied!");
7051 return WSError::WS_ERROR_NOT_SYSTEM_APP;
7052 }
7053 auto task = [this, shouldHide]() {
7054 for (const auto& item: nonSystemFloatSceneSessionMap_) {
7055 auto session = item.second;
7056 if (session && session->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT) {
7057 session->NotifyForceHideChange(shouldHide);
7058 WLOGFI("HideNonSecureWindows name=%{public}s, persistendId=%{public}d",
7059 session->GetWindowName().c_str(), item.first);
7060 }
7061 }
7062 return WSError::WS_OK;
7063 };
7064 return taskScheduler_->PostSyncTask(task);
7065 }
7066 } // namespace OHOS::Rosen
7067