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 <iomanip>
21 #include <map>
22 #include <sstream>
23 #include <unistd.h>
24
25 #include <ability_context.h>
26 #include <ability_info.h>
27 #include <ability_manager_client.h>
28 #include <bundle_mgr_interface.h>
29 #include <display_power_mgr_client.h>
30 #include <ipc_skeleton.h>
31 #include <iservice_registry.h>
32 #include <parameters.h>
33 #include "parameter.h"
34 #include <power_mgr_client.h>
35 #include <resource_manager.h>
36 #include <running_lock.h>
37 #include <session_info.h>
38 #include <start_options.h>
39 #include <system_ability_definition.h>
40 #include <want.h>
41 #include <hitrace_meter.h>
42 #include <transaction/rs_transaction.h>
43 #include <transaction/rs_interfaces.h>
44
45 #ifdef RES_SCHED_ENABLE
46 #include "res_type.h"
47 #include "res_sched_client.h"
48 #endif
49
50 #include "ability_start_setting.h"
51 #include "color_parser.h"
52 #include "common/include/session_permission.h"
53 #include "interfaces/include/ws_common.h"
54 #include "interfaces/include/ws_common_inner.h"
55 #include "session/host/include/scene_persistent_storage.h"
56 #include "session/host/include/scene_session.h"
57 #include "session_helper.h"
58 #include "window_helper.h"
59 #include "session/screen/include/screen_session.h"
60 #include "session_manager/include/screen_session_manager.h"
61 #include "singleton_container.h"
62 #include "window_manager_hilog.h"
63 #include "wm_common.h"
64 #include "wm_math.h"
65 #include "xcollie/watchdog.h"
66 #include "zidl/window_manager_agent_interface.h"
67 #include "session_manager_agent_controller.h"
68 #include "distributed_client.h"
69 #include "softbus_bus_center.h"
70 #include "window_manager.h"
71 #include "perform_reporter.h"
72 #include "focus_change_info.h"
73 #include "session_manager/include/screen_session_manager.h"
74
75 #include "window_visibility_info.h"
76 #ifdef MEMMGR_WINDOW_ENABLE
77 #include "mem_mgr_client.h"
78 #include "mem_mgr_window_info.h"
79 #endif
80
81 namespace OHOS::Rosen {
82 namespace {
83 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSessionManager" };
84 #ifdef RES_SCHED_ENABLE
85 const std::string SCENE_BOARD_BUNDLE_NAME = "com.ohos.sceneboard";
86 #endif
87 const std::string SCENE_SESSION_MANAGER_THREAD = "SceneSessionManager";
88 const std::string WINDOW_INFO_REPORT_THREAD = "WindowInfoReportThread";
89 constexpr const char* PREPARE_TERMINATE_ENABLE_PARAMETER = "persist.sys.prepare_terminate";
90 std::recursive_mutex g_instanceMutex;
91 constexpr uint32_t MAX_BRIGHTNESS = 255;
92 constexpr int32_t PREPARE_TERMINATE_ENABLE_SIZE = 6;
93 constexpr int32_t DEFAULT_USERID = -1;
94 constexpr int32_t SCALE_DIMENSION = 2;
95 constexpr int32_t TRANSLATE_DIMENSION = 2;
96 constexpr int32_t ROTAION_DIMENSION = 4;
97 constexpr int32_t CUBIC_CURVE_DIMENSION = 4;
98 const std::string DM_PKG_NAME = "ohos.distributedhardware.devicemanager";
99 constexpr int32_t NON_ANONYMIZE_LENGTH = 6;
100 const std::string EMPTY_DEVICE_ID = "";
101 const int32_t MAX_NUMBER_OF_DISTRIBUTED_SESSIONS = 20;
102
103 constexpr int WINDOW_NAME_MAX_WIDTH = 21;
104 constexpr int DISPLAY_NAME_MAX_WIDTH = 10;
105 constexpr int VALUE_MAX_WIDTH = 5;
106 constexpr int ORIEN_MAX_WIDTH = 12;
107 constexpr int PID_MAX_WIDTH = 8;
108 constexpr int PARENT_ID_MAX_WIDTH = 6;
109 constexpr int WINDOW_NAME_MAX_LENGTH = 20;
110 constexpr int32_t STATUS_BAR_AVOID_AREA = 0;
111 const std::string ARG_DUMP_ALL = "-a";
112 const std::string ARG_DUMP_WINDOW = "-w";
113 const std::string ARG_DUMP_SCREEN = "-s";
114 const std::string ARG_DUMP_DISPLAY = "-d";
115 constexpr uint64_t NANO_SECOND_PER_SEC = 1000000000; // ns
GetCurrentTime()116 std::string GetCurrentTime()
117 {
118 struct timespec tn;
119 clock_gettime(CLOCK_REALTIME, &tn);
120 uint64_t uTime = static_cast<uint64_t>(tn.tv_sec) * NANO_SECOND_PER_SEC +
121 static_cast<uint64_t>(tn.tv_nsec);
122 return std::to_string(uTime);
123 }
124 } // namespace
125
GetInstance()126 SceneSessionManager& SceneSessionManager::GetInstance()
127 {
128 std::lock_guard<std::recursive_mutex> lock(g_instanceMutex);
129 static SceneSessionManager* instance = nullptr;
130 if (instance == nullptr) {
131 instance = new SceneSessionManager();
132 instance->Init();
133 }
134 return *instance;
135 }
136
SceneSessionManager()137 SceneSessionManager::SceneSessionManager() : rsInterface_(RSInterfaces::GetInstance())
138 {
139 taskScheduler_ = std::make_shared<TaskScheduler>(SCENE_SESSION_MANAGER_THREAD);
140 currentUserId_ = DEFAULT_USERID;
141 }
142
Init()143 void SceneSessionManager::Init()
144 {
145 constexpr uint64_t interval = 5 * 1000; // 5 second
146 auto mainEventRunner = AppExecFwk::EventRunner::GetMainEventRunner();
147 auto mainEventHandler = std::make_shared<AppExecFwk::EventHandler>(mainEventRunner);
148 if (HiviewDFX::Watchdog::GetInstance().AddThread("MainThread", mainEventHandler, interval)) {
149 WLOGFW("Add thread MainThread to watchdog failed.");
150 }
151 if (HiviewDFX::Watchdog::GetInstance().AddThread(
152 SCENE_SESSION_MANAGER_THREAD, taskScheduler_->GetEventHandler(), interval)) {
153 WLOGFW("Add thread %{public}s to watchdog failed.", SCENE_SESSION_MANAGER_THREAD.c_str());
154 }
155
156 #ifdef RES_SCHED_ENABLE
157 std::unordered_map<std::string, std::string> payload {
158 { "pid", std::to_string(getpid()) },
159 { "tid", std::to_string(gettid()) },
160 { "uid", std::to_string(getuid()) },
161 { "bundleName", SCENE_BOARD_BUNDLE_NAME },
162 };
163 uint32_t type = OHOS::ResourceSchedule::ResType::RES_TYPE_REPORT_SCENE_BOARD;
164 int64_t value = 0;
165 OHOS::ResourceSchedule::ResSchedClient::GetInstance().ReportData(type, value, payload);
166 #endif
167
168 bundleMgr_ = GetBundleManager();
169 LoadWindowSceneXml();
170 ScreenSessionManager::GetInstance().SetSensorSubscriptionEnabled();
171 sptr<IDisplayChangeListener> listener = new DisplayChangeListener();
172 ScreenSessionManager::GetInstance().RegisterDisplayChangeListener(listener);
173 InitPrepareTerminateConfig();
174
175 // create handler for inner command at server
176 eventLoop_ = AppExecFwk::EventRunner::Create(WINDOW_INFO_REPORT_THREAD);
177 eventHandler_ = std::make_shared<AppExecFwk::EventHandler>(eventLoop_);
178 if (eventHandler_ == nullptr) {
179 WLOGFE("Invalid eventHander");
180 return ;
181 }
182 int ret = HiviewDFX::Watchdog::GetInstance().AddThread(WINDOW_INFO_REPORT_THREAD, eventHandler_);
183 if (ret != 0) {
184 WLOGFW("Add thread %{public}s to watchdog failed.", WINDOW_INFO_REPORT_THREAD.c_str());
185 }
186
187 listenerController_ = std::make_shared<SessionListenerController>();
188 listenerController_->Init();
189 scbSessionHandler_ = new ScbSessionHandler();
190 AAFwk::AbilityManagerClient::GetInstance()->RegisterSessionHandler(scbSessionHandler_);
191
192 StartWindowInfoReportLoop();
193 WLOGI("SceneSessionManager init success.");
194 }
195
LoadWindowSceneXml()196 void SceneSessionManager::LoadWindowSceneXml()
197 {
198 if (WindowSceneConfig::LoadConfigXml()) {
199 if (WindowSceneConfig::GetConfig().IsMap()) {
200 WindowSceneConfig::DumpConfig(*WindowSceneConfig::GetConfig().mapValue_);
201 }
202 ConfigWindowSceneXml();
203 } else {
204 WLOGFE("Load window scene xml failed");
205 }
206 }
207
InitPrepareTerminateConfig()208 void SceneSessionManager::InitPrepareTerminateConfig()
209 {
210 char value[PREPARE_TERMINATE_ENABLE_SIZE] = "false";
211 int32_t retSysParam = GetParameter(PREPARE_TERMINATE_ENABLE_PARAMETER, "false", value,
212 PREPARE_TERMINATE_ENABLE_SIZE);
213 WLOGFI("InitPrepareTerminateConfig, %{public}s value is %{public}s.", PREPARE_TERMINATE_ENABLE_PARAMETER, value);
214 if (retSysParam > 0 && !std::strcmp(value, "true")) {
215 isPrepareTerminateEnable_ = true;
216 }
217 }
218
ConfigWindowSceneXml()219 void SceneSessionManager::ConfigWindowSceneXml()
220 {
221 const auto& config = WindowSceneConfig::GetConfig();
222 WindowSceneConfig::ConfigItem item = config["windowEffect"];
223 if (item.IsMap()) {
224 ConfigWindowEffect(item);
225 }
226
227 item = config["decor"];
228 if (item.IsMap()) {
229 ConfigDecor(item);
230 }
231
232 item = config["defaultWindowMode"];
233 if (item.IsInts()) {
234 auto numbers = *item.intsValue_;
235 if (numbers.size() == 1 &&
236 (numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FULLSCREEN) ||
237 numbers[0] == static_cast<int32_t>(WindowMode::WINDOW_MODE_FLOATING))) {
238 systemConfig_.defaultWindowMode_ = static_cast<WindowMode>(static_cast<uint32_t>(numbers[0]));
239 }
240 }
241
242 item = config["defaultMaximizeMode"];
243 if (item.IsInts()) {
244 auto numbers = *item.intsValue_;
245 if (numbers.size() == 1 &&
246 (numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
247 numbers[0] == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL))) {
248 SceneSession::maximizeMode_ = static_cast<MaximizeMode>(numbers[0]);
249 }
250 }
251
252 item = config["keyboardAnimation"];
253 if (item.IsMap()) {
254 ConfigKeyboardAnimation(item);
255 }
256
257 item = config["maxFloatingWindowSize"];
258 if (item.IsInts()) {
259 auto numbers = *item.intsValue_;
260 if (numbers.size() == 1) {
261 systemConfig_.maxFloatingWindowSize_ = static_cast<uint32_t>(numbers[0]);
262 }
263 }
264
265 item = config["windowAnimation"];
266 if (item.IsMap()) {
267 ConfigWindowAnimation(item);
268 }
269
270 item = config["startWindowTransitionAnimation"];
271 if (item.IsMap()) {
272 ConfigStartingWindowAnimation(item);
273 }
274
275 ConfigWindowSizeLimits();
276 }
SetSessionContinueState(const sptr<IRemoteObject> & token,const ContinueState & continueState)277 WSError SceneSessionManager::SetSessionContinueState(const sptr<IRemoteObject> &token,
278 const ContinueState& continueState)
279 {
280 sptr<SceneSession> sceneSession = FindSessionByToken(token);
281 if (sceneSession == nullptr) {
282 WLOGFI("fail to find session by token.");
283 return WSError::WS_ERROR_INVALID_PARAM;
284 }
285 sceneSession->SetSessionContinueState(continueState);
286 DistributedClient dmsClient;
287 dmsClient.SetMissionContinueState(sceneSession->GetPersistentId(),
288 static_cast<AAFwk::ContinueState>(continueState));
289 return WSError::WS_OK;
290 }
291
ConfigDecor(const WindowSceneConfig::ConfigItem & decorConfig)292 void SceneSessionManager::ConfigDecor(const WindowSceneConfig::ConfigItem& decorConfig)
293 {
294 WindowSceneConfig::ConfigItem item = decorConfig.GetProp("enable");
295 if (item.IsBool()) {
296 systemConfig_.isSystemDecorEnable_ = item.boolValue_;
297 std::vector<std::string> supportedModes;
298 item = decorConfig["supportedMode"];
299 if (item.IsStrings()) {
300 systemConfig_.decorModeSupportInfo_ = 0;
301 supportedModes = *item.stringsValue_;
302 }
303 for (auto mode : supportedModes) {
304 if (mode == "fullscreen") {
305 systemConfig_.decorModeSupportInfo_ |= WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN;
306 } else if (mode == "floating") {
307 systemConfig_.decorModeSupportInfo_ |= WindowModeSupport::WINDOW_MODE_SUPPORT_FLOATING;
308 } else if (mode == "pip") {
309 systemConfig_.decorModeSupportInfo_ |= WindowModeSupport::WINDOW_MODE_SUPPORT_PIP;
310 } else if (mode == "split") {
311 systemConfig_.decorModeSupportInfo_ |= WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_PRIMARY |
312 WindowModeSupport::WINDOW_MODE_SUPPORT_SPLIT_SECONDARY;
313 } else {
314 WLOGFW("Invalid supporedMode");
315 systemConfig_.decorModeSupportInfo_ = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
316 break;
317 }
318 }
319 }
320 }
321
AddAlphaToColor(float alpha,std::string & color)322 static void AddAlphaToColor(float alpha, std::string& color)
323 {
324 if (color.size() == 9 || alpha > 1.0f) { // size 9: color is ARGB
325 return;
326 }
327
328 uint32_t alphaValue = 0xFF * alpha;
329 std::stringstream ss;
330 ss << std::hex << alphaValue;
331 std::string strAlpha = ss.str();
332 if (strAlpha.size() == 1) {
333 strAlpha.append(1, '0');
334 }
335
336 color.insert(1, strAlpha);
337 }
338
ConfigWindowEffect(const WindowSceneConfig::ConfigItem & effectConfig)339 void SceneSessionManager::ConfigWindowEffect(const WindowSceneConfig::ConfigItem& effectConfig)
340 {
341 AppWindowSceneConfig config;
342 // config corner radius
343 WindowSceneConfig::ConfigItem item = effectConfig["appWindows"]["cornerRadius"];
344 if (item.IsMap()) {
345 if (ConfigAppWindowCornerRadius(item["float"], config.floatCornerRadius_)) {
346 appWindowSceneConfig_ = config;
347 }
348 }
349
350 // config shadow
351 item = effectConfig["appWindows"]["shadow"]["focused"];
352 if (item.IsMap()) {
353 if (ConfigAppWindowShadow(item, config.focusedShadow_)) {
354 appWindowSceneConfig_.focusedShadow_ = config.focusedShadow_;
355 }
356 }
357
358 item = effectConfig["appWindows"]["shadow"]["unfocused"];
359 if (item.IsMap()) {
360 if (ConfigAppWindowShadow(item, config.unfocusedShadow_)) {
361 appWindowSceneConfig_.unfocusedShadow_ = config.unfocusedShadow_;
362 }
363 }
364
365 AddAlphaToColor(appWindowSceneConfig_.focusedShadow_.alpha_, appWindowSceneConfig_.focusedShadow_.color_);
366 AddAlphaToColor(appWindowSceneConfig_.unfocusedShadow_.alpha_, appWindowSceneConfig_.unfocusedShadow_.color_);
367
368 WLOGFI("Config window effect successfully");
369 }
370
ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem & item,float & out)371 bool SceneSessionManager::ConfigAppWindowCornerRadius(const WindowSceneConfig::ConfigItem& item, float& out)
372 {
373 std::map<std::string, float> stringToCornerRadius = {
374 {"off", 0.0f}, {"defaultCornerRadiusXS", 4.0f}, {"defaultCornerRadiusS", 8.0f},
375 {"defaultCornerRadiusM", 12.0f}, {"defaultCornerRadiusL", 16.0f}, {"defaultCornerRadiusXL", 24.0f}
376 };
377
378 if (item.IsString()) {
379 auto value = item.stringValue_;
380 if (stringToCornerRadius.find(value) != stringToCornerRadius.end()) {
381 out = stringToCornerRadius[value];
382 return true;
383 }
384 }
385 return false;
386 }
387
ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem & shadowConfig,WindowShadowConfig & outShadow)388 bool SceneSessionManager::ConfigAppWindowShadow(const WindowSceneConfig::ConfigItem& shadowConfig,
389 WindowShadowConfig& outShadow)
390 {
391 WindowSceneConfig::ConfigItem item = shadowConfig["color"];
392 if (item.IsString()) {
393 auto color = item.stringValue_;
394 uint32_t colorValue;
395 if (!ColorParser::Parse(color, colorValue)) {
396 return false;
397 }
398 outShadow.color_ = color;
399 }
400
401 item = shadowConfig["offsetX"];
402 if (item.IsFloats()) {
403 auto offsetX = *item.floatsValue_;
404 if (offsetX.size() != 1) {
405 return false;
406 }
407 outShadow.offsetX_ = offsetX[0];
408 }
409
410 item = shadowConfig["offsetY"];
411 if (item.IsFloats()) {
412 auto offsetY = *item.floatsValue_;
413 if (offsetY.size() != 1) {
414 return false;
415 }
416 outShadow.offsetY_ = offsetY[0];
417 }
418
419 item = shadowConfig["alpha"];
420 if (item.IsFloats()) {
421 auto alpha = *item.floatsValue_;
422 if (alpha.size() != 1 ||
423 (MathHelper::LessNotEqual(alpha[0], 0.0) && MathHelper::GreatNotEqual(alpha[0], 1.0))) {
424 return false;
425 }
426 outShadow.alpha_ = alpha[0];
427 }
428
429 item = shadowConfig["radius"];
430 if (item.IsFloats()) {
431 auto radius = *item.floatsValue_;
432 if (radius.size() != 1 || MathHelper::LessNotEqual(radius[0], 0.0)) {
433 return false;
434 }
435 outShadow.radius_ = radius[0];
436 }
437
438 return true;
439 }
440
ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem & animationConfig)441 void SceneSessionManager::ConfigKeyboardAnimation(const WindowSceneConfig::ConfigItem& animationConfig)
442 {
443 WindowSceneConfig::ConfigItem item = animationConfig["timing"];
444 if (item.IsMap() && item.mapValue_->count("curve")) {
445 appWindowSceneConfig_.keyboardAnimation_.curveType_ = CreateCurve(item["curve"]);
446 }
447 item = animationConfig["timing"]["durationIn"];
448 if (item.IsInts()) {
449 auto numbers = *item.intsValue_;
450 if (numbers.size() == 1) { // durationIn
451 appWindowSceneConfig_.keyboardAnimation_.durationIn_ = static_cast<uint32_t>(numbers[0]);
452 }
453 }
454 item = animationConfig["timing"]["durationOut"];
455 if (item.IsInts()) {
456 auto numbers = *item.intsValue_;
457 if (numbers.size() == 1) { // durationOut
458 appWindowSceneConfig_.keyboardAnimation_.durationOut_ = static_cast<uint32_t>(numbers[0]);
459 }
460 }
461 }
462
ConfigWindowAnimation(const WindowSceneConfig::ConfigItem & windowAnimationConfig)463 void SceneSessionManager::ConfigWindowAnimation(const WindowSceneConfig::ConfigItem& windowAnimationConfig)
464 {
465 WindowSceneConfig::ConfigItem item = windowAnimationConfig["timing"];
466 if (item.IsMap() && item.mapValue_->count("curve")) {
467 appWindowSceneConfig_.windowAnimation_.curveType_ = CreateCurve(item["curve"], "windowAnimation");
468 }
469 item = windowAnimationConfig["timing"]["duration"];
470 if (item.IsInts() && item.intsValue_->size() == 1) {
471 auto duration = *item.intsValue_;
472 appWindowSceneConfig_.windowAnimation_.duration_ = duration[0];
473 }
474 item = windowAnimationConfig["scale"];
475 if (item.IsFloats() && item.floatsValue_->size() == SCALE_DIMENSION) {
476 auto scales = *item.floatsValue_;
477 appWindowSceneConfig_.windowAnimation_.scaleX_ = scales[0];
478 appWindowSceneConfig_.windowAnimation_.scaleY_ = scales[1];
479 }
480 item = windowAnimationConfig["rotation"];
481 if (item.IsFloats() && item.floatsValue_->size() == ROTAION_DIMENSION) {
482 auto rotations = *item.floatsValue_;
483 appWindowSceneConfig_.windowAnimation_.rotationX_ = rotations[0]; // 0 ctrlX1
484 appWindowSceneConfig_.windowAnimation_.rotationY_ = rotations[1]; // 1 ctrlY1
485 appWindowSceneConfig_.windowAnimation_.rotationZ_ = rotations[2]; // 2 ctrlX2
486 appWindowSceneConfig_.windowAnimation_.angle_ = rotations[3]; // 3 ctrlY2
487 }
488 item = windowAnimationConfig["translate"];
489 if (item.IsFloats() && item.floatsValue_->size() == TRANSLATE_DIMENSION) {
490 auto translates = *item.floatsValue_;
491 appWindowSceneConfig_.windowAnimation_.translateX_ = translates[0];
492 appWindowSceneConfig_.windowAnimation_.translateY_ = translates[1];
493 }
494 item = windowAnimationConfig["opacity"];
495 if (item.IsFloats() && item.floatsValue_->size() == 1) {
496 auto opacity = *item.floatsValue_;
497 appWindowSceneConfig_.windowAnimation_.opacity_ = opacity[0];
498 }
499 }
500
ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem & configItem)501 void SceneSessionManager::ConfigStartingWindowAnimation(const WindowSceneConfig::ConfigItem& configItem)
502 {
503 auto& config = appWindowSceneConfig_.startingWindowAnimationConfig_;
504 auto item = configItem.GetProp("enable");
505 if (item.IsBool()) {
506 config.enabled_ = item.boolValue_;
507 }
508 item = configItem["timing"];
509 if (item.IsMap() && item.mapValue_->count("curve")) {
510 config.curve_ = CreateCurve(item["curve"]);
511 }
512 item = configItem["timing"]["duration"];
513 if (item.IsInts() && item.intsValue_->size() == 1) {
514 config.duration_ = (*item.intsValue_)[0];
515 }
516 item = configItem["opacityStart"];
517 if (item.IsFloats() && item.floatsValue_->size() == 1) {
518 config.opacityStart_ = (*item.floatsValue_)[0];
519 }
520 item = configItem["opacityEnd"];
521 if (item.IsFloats() && item.floatsValue_->size() == 1) {
522 config.opacityEnd_ = (*item.floatsValue_)[0];
523 }
524 }
525
CreateCurve(const WindowSceneConfig::ConfigItem & curveConfig,const std::string & nodeName)526 std::string SceneSessionManager::CreateCurve(const WindowSceneConfig::ConfigItem& curveConfig,
527 const std::string& nodeName)
528 {
529 static std::unordered_set<std::string> curveSet = { "easeOut", "ease", "easeIn", "easeInOut", "default",
530 "linear", "spring", "interactiveSpring", "interpolatingSpring" };
531
532 std::string curveName = "easeOut";
533 const auto& nameItem = curveConfig.GetProp("name");
534 if (!nameItem.IsString()) {
535 return curveName;
536 }
537 std::string name = nameItem.stringValue_;
538 if (name == "cubic" && curveConfig.IsFloats() && curveConfig.floatsValue_->size() == CUBIC_CURVE_DIMENSION) {
539 const auto& numbers = *curveConfig.floatsValue_;
540 curveName = name;
541 if (nodeName == "windowAnimation") {
542 appWindowSceneConfig_.windowAnimation_.ctrlX1_ = numbers[0]; // 0 ctrlX1
543 appWindowSceneConfig_.windowAnimation_.ctrlY1_ = numbers[1]; // 1 ctrlY1
544 appWindowSceneConfig_.windowAnimation_.ctrlX2_ = numbers[2]; // 2 ctrlX2
545 appWindowSceneConfig_.windowAnimation_.ctrlY2_ = numbers[3]; // 3 ctrlY2
546 } else {
547 appWindowSceneConfig_.keyboardAnimation_.ctrlX1_ = numbers[0]; // 0 ctrlX1
548 appWindowSceneConfig_.keyboardAnimation_.ctrlY1_ = numbers[1]; // 1 ctrlY1
549 appWindowSceneConfig_.keyboardAnimation_.ctrlX2_ = numbers[2]; // 2 ctrlX2
550 appWindowSceneConfig_.keyboardAnimation_.ctrlY2_ = numbers[3]; // 3 ctrlY2
551 }
552 } else {
553 auto iter = curveSet.find(name);
554 if (iter != curveSet.end()) {
555 curveName = name;
556 }
557 }
558 return curveName;
559 }
560
ConfigWindowSizeLimits()561 void SceneSessionManager::ConfigWindowSizeLimits()
562 {
563 const auto& config = WindowSceneConfig::GetConfig();
564 WindowSceneConfig::ConfigItem item = config["mainWindowSizeLimits"];
565 if (item.IsMap()) {
566 ConfigMainWindowSizeLimits(item);
567 }
568
569 item = config["subWindowSizeLimits"];
570 if (item.IsMap()) {
571 ConfigSubWindowSizeLimits(item);
572 }
573 }
574
ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem & mainWindowSizeConifg)575 void SceneSessionManager::ConfigMainWindowSizeLimits(const WindowSceneConfig::ConfigItem& mainWindowSizeConifg)
576 {
577 auto item = mainWindowSizeConifg["miniWidth"];
578 if (item.IsInts()) {
579 auto numbers = *item.intsValue_;
580 if (numbers.size() == 1) {
581 systemConfig_.miniWidthOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
582 }
583 }
584
585 item = mainWindowSizeConifg["miniHeight"];
586 if (item.IsInts()) {
587 auto numbers = *item.intsValue_;
588 if (numbers.size() == 1) {
589 systemConfig_.miniHeightOfMainWindow_ = static_cast<uint32_t>(numbers[0]);
590 }
591 }
592 }
593
ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem & subWindowSizeConifg)594 void SceneSessionManager::ConfigSubWindowSizeLimits(const WindowSceneConfig::ConfigItem& subWindowSizeConifg)
595 {
596 auto item = subWindowSizeConifg["miniWidth"];
597 if (item.IsInts()) {
598 auto numbers = *item.intsValue_;
599 if (numbers.size() == 1) {
600 systemConfig_.miniWidthOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
601 }
602 }
603
604 item = subWindowSizeConifg["miniHeight"];
605 if (item.IsInts()) {
606 auto numbers = *item.intsValue_;
607 if (numbers.size() == 1) {
608 systemConfig_.miniHeightOfSubWindow_ = static_cast<uint32_t>(numbers[0]);
609 }
610 }
611 }
612
SetRootSceneContext(AbilityRuntime::Context * context)613 void SceneSessionManager::SetRootSceneContext(AbilityRuntime::Context* context)
614 {
615 rootSceneContext_ = std::shared_ptr<AbilityRuntime::Context>(context);
616 }
617
GetRootSceneSession()618 sptr<RootSceneSession> SceneSessionManager::GetRootSceneSession()
619 {
620 auto task = [this]() -> sptr<RootSceneSession> {
621 if (rootSceneSession_ != nullptr) {
622 return rootSceneSession_;
623 }
624 system::SetParameter("bootevent.wms.fullscreen.ready", "true");
625 SessionInfo info;
626 rootSceneSession_ = new (std::nothrow) RootSceneSession(info);
627 if (!rootSceneSession_) {
628 WLOGFE("rootSceneSession is nullptr");
629 return nullptr;
630 }
631 sptr<ISession> iSession(rootSceneSession_);
632 AAFwk::AbilityManagerClient::GetInstance()->SetRootSceneSession(iSession->AsObject());
633 return rootSceneSession_;
634 };
635
636 return taskScheduler_->PostSyncTask(task);
637 }
638
GetSceneSession(int32_t persistentId)639 sptr<SceneSession> SceneSessionManager::GetSceneSession(int32_t persistentId)
640 {
641 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
642 auto iter = sceneSessionMap_.find(persistentId);
643 if (iter == sceneSessionMap_.end()) {
644 WLOGFE("Error found scene session with id: %{public}d", persistentId);
645 return nullptr;
646 }
647 return iter->second;
648 }
649
GetSceneSessionByName(const std::string & bundleName,const std::string & moduleName,const std::string & abilityName)650 sptr<SceneSession> SceneSessionManager::GetSceneSessionByName(const std::string& bundleName,
651 const std::string& moduleName, const std::string& abilityName)
652 {
653 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
654 for (const auto &item : sceneSessionMap_) {
655 auto sceneSession = item.second;
656 if (sceneSession->GetSessionInfo().bundleName_ == bundleName &&
657 sceneSession->GetSessionInfo().moduleName_ == moduleName &&
658 sceneSession->GetSessionInfo().abilityName_ == abilityName) {
659 return sceneSession;
660 }
661 }
662 return nullptr;
663 }
664
GetSceneSessionVectorByType(WindowType type)665 std::vector<sptr<SceneSession>> SceneSessionManager::GetSceneSessionVectorByType(WindowType type)
666 {
667 auto task = [this, type]() {
668 std::vector<sptr<SceneSession>> sceneSessionVector;
669 for (const auto &item : sceneSessionMap_) {
670 auto sceneSession = item.second;
671 if (sceneSession->GetWindowType() == type) {
672 sceneSessionVector.emplace_back(sceneSession);
673 }
674 }
675
676 return sceneSessionVector;
677 };
678
679 return taskScheduler_->PostSyncTask(task);
680 }
681
UpdateParentSession(const sptr<SceneSession> & sceneSession,sptr<WindowSessionProperty> property)682 WSError SceneSessionManager::UpdateParentSession(const sptr<SceneSession>& sceneSession,
683 sptr<WindowSessionProperty> property)
684 {
685 if (property == nullptr) {
686 WLOGFW("Property is null, no need to update parent info");
687 return WSError::WS_ERROR_NULLPTR;
688 }
689 if (sceneSession == nullptr) {
690 WLOGFE("Session is nullptr");
691 return WSError::WS_ERROR_NULLPTR;
692 }
693 auto parentPersistentId = property->GetParentPersistentId();
694 if (property->GetWindowType() == WindowType::WINDOW_TYPE_APP_SUB_WINDOW) {
695 auto parentSceneSession = GetSceneSession(parentPersistentId);
696 if (!parentSceneSession) {
697 WLOGFD("Session is invalid");
698 return WSError::WS_ERROR_INVALID_SESSION;
699 }
700 sceneSession->SetParentSession(parentSceneSession);
701 WLOGFD("Update parent of subWindow success, id %{public}d, parentId %{public}d",
702 sceneSession->GetPersistentId(), parentPersistentId);
703 } else if (property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG &&
704 parentPersistentId != INVALID_SESSION_ID) {
705 auto parentSession = GetSceneSession(parentPersistentId);
706 if (parentSession == nullptr) {
707 WLOGFE("Parent session is nullptr");
708 return WSError::WS_ERROR_NULLPTR;
709 }
710 parentSession->BindDialogToParentSession(sceneSession);
711 sceneSession->SetParentSession(parentSession);
712 WLOGFD("Update parent of dialog success, id %{public}d, parentId %{public}d",
713 sceneSession->GetPersistentId(), parentPersistentId);
714 }
715 return WSError::WS_OK;
716 }
717
CreateSpecificSessionCallback()718 sptr<SceneSession::SpecificSessionCallback> SceneSessionManager::CreateSpecificSessionCallback()
719 {
720 sptr<SceneSession::SpecificSessionCallback> specificCb = new (std::nothrow)SceneSession::SpecificSessionCallback();
721 if (specificCb == nullptr) {
722 WLOGFE("SpecificSessionCallback is nullptr");
723 return nullptr;
724 }
725 specificCb->onCreate_ = std::bind(&SceneSessionManager::RequestSceneSession,
726 this, std::placeholders::_1, std::placeholders::_2);
727 specificCb->onDestroy_ = std::bind(&SceneSessionManager::DestroyAndDisconnectSpecificSession,
728 this, std::placeholders::_1);
729 specificCb->onCameraFloatSessionChange_ = std::bind(&SceneSessionManager::UpdateCameraFloatWindowStatus,
730 this, std::placeholders::_1, std::placeholders::_2);
731 specificCb->onGetSceneSessionVectorByType_ = std::bind(&SceneSessionManager::GetSceneSessionVectorByType,
732 this, std::placeholders::_1);
733 specificCb->onUpdateAvoidArea_ = std::bind(&SceneSessionManager::UpdateAvoidArea, this, std::placeholders::_1);
734 specificCb->onWindowInfoUpdate_ = std::bind(&SceneSessionManager::NotifyWindowInfoChange,
735 this, std::placeholders::_1, std::placeholders::_2);
736 return specificCb;
737 }
738
RequestSceneSession(const SessionInfo & sessionInfo,sptr<WindowSessionProperty> property)739 sptr<SceneSession> SceneSessionManager::RequestSceneSession(const SessionInfo& sessionInfo,
740 sptr<WindowSessionProperty> property)
741 {
742 if (sessionInfo.persistentId_ != 0) {
743 auto session = GetSceneSession(sessionInfo.persistentId_);
744 if (session != nullptr) {
745 WLOGFI("get exist session persistentId: %{public}d", sessionInfo.persistentId_);
746 if (sessionInfo.want != nullptr) {
747 session->GetSessionInfo().want = sessionInfo.want;
748 WLOGFI("RequestSceneSession update want");
749 }
750 return session;
751 }
752 }
753
754 sptr<SceneSession::SpecificSessionCallback> specificCb = CreateSpecificSessionCallback();
755 auto task = [this, sessionInfo, specificCb, property]() {
756 WLOGFI("sessionInfo: bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s, type %{public}u",
757 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(),
758 sessionInfo.abilityName_.c_str(), sessionInfo.windowType_);
759 sptr<SceneSession> sceneSession = new (std::nothrow) SceneSession(sessionInfo, specificCb);
760 if (sceneSession == nullptr) {
761 WLOGFE("sceneSession is nullptr!");
762 return sceneSession;
763 }
764 if (sessionInfo.isSystem_) {
765 sceneSession->SetCallingPid(IPCSkeleton::GetCallingPid());
766 sceneSession->SetCallingUid(IPCSkeleton::GetCallingUid());
767 sceneSession->SetAbilityToken(rootSceneContext_ != nullptr ? rootSceneContext_->GetToken() : nullptr);
768 }
769 FillSessionInfo(sceneSession->GetSessionInfo());
770 auto persistentId = sceneSession->GetPersistentId();
771 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSession(%d )", persistentId);
772 sceneSession->SetSystemConfig(systemConfig_);
773 UpdateParentSession(sceneSession, property);
774 PreHandleCollaborator(sceneSession);
775 {
776 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
777 sceneSessionMap_.insert({ persistentId, sceneSession });
778 }
779 RegisterSessionStateChangeNotifyManagerFunc(sceneSession);
780 RegisterInputMethodShownFunc(sceneSession);
781 RegisterInputMethodHideFunc(sceneSession);
782
783 WLOGFI("create session persistentId: %{public}d", persistentId);
784 return sceneSession;
785 };
786
787 return taskScheduler_->PostSyncTask(task);
788 }
789
RegisterInputMethodShownFunc(const sptr<SceneSession> & sceneSession)790 void SceneSessionManager::RegisterInputMethodShownFunc(const sptr<SceneSession>& sceneSession)
791 {
792 if (sceneSession == nullptr) {
793 WLOGFE("session is nullptr");
794 return;
795 }
796 NotifyCallingSessionForegroundFunc onInputMethodShown = [this](int32_t persistentId) {
797 this->OnInputMethodShown(persistentId);
798 };
799 sceneSession->SetNotifyCallingSessionForegroundFunc(onInputMethodShown);
800 WLOGFD("RegisterInputMethodShownFunc success");
801 }
802
OnInputMethodShown(const int32_t & persistentId)803 void SceneSessionManager::OnInputMethodShown(const int32_t& persistentId)
804 {
805 WLOGFD("Resize input method calling window");
806 auto scnSession = GetSceneSession(persistentId);
807 if (scnSession == nullptr) {
808 WLOGFE("Input method is null");
809 return;
810 }
811 callingSession_ = GetSceneSession(focusedSessionId_);
812 ResizeSoftInputCallingSessionIfNeed(scnSession);
813 }
814
RegisterInputMethodHideFunc(const sptr<SceneSession> & sceneSession)815 void SceneSessionManager::RegisterInputMethodHideFunc(const sptr<SceneSession>& sceneSession)
816 {
817 if (sceneSession == nullptr) {
818 WLOGFE("session is nullptr");
819 return;
820 }
821 NotifyCallingSessionBackgroundFunc onInputMethodHide = [this]() {
822 this->RestoreCallingSessionSizeIfNeed();
823 };
824 sceneSession->SetNotifyCallingSessionBackgroundFunc(onInputMethodHide);
825 WLOGFD("RegisterInputMethodHideFunc success");
826 }
827
SetAbilitySessionInfo(const sptr<SceneSession> & scnSession)828 sptr<AAFwk::SessionInfo> SceneSessionManager::SetAbilitySessionInfo(const sptr<SceneSession>& scnSession)
829 {
830 sptr<AAFwk::SessionInfo> abilitySessionInfo = new (std::nothrow) AAFwk::SessionInfo();
831 if (!abilitySessionInfo) {
832 WLOGFE("abilitySessionInfo is nullptr");
833 return nullptr;
834 }
835 auto sessionInfo = scnSession->GetSessionInfo();
836 sptr<ISession> iSession(scnSession);
837 abilitySessionInfo->sessionToken = iSession->AsObject();
838 abilitySessionInfo->callerToken = sessionInfo.callerToken_;
839 abilitySessionInfo->persistentId = scnSession->GetPersistentId();
840 abilitySessionInfo->requestCode = sessionInfo.requestCode;
841 abilitySessionInfo->resultCode = sessionInfo.resultCode;
842 abilitySessionInfo->uiAbilityId = sessionInfo.uiAbilityId_;
843 abilitySessionInfo->startSetting = sessionInfo.startSetting;
844 abilitySessionInfo->callingTokenId = sessionInfo.callingTokenId_;
845 abilitySessionInfo->userId = currentUserId_;
846 if (sessionInfo.want != nullptr) {
847 abilitySessionInfo->want = *sessionInfo.want;
848 } else {
849 abilitySessionInfo->want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_,
850 sessionInfo.moduleName_);
851 }
852 return abilitySessionInfo;
853 }
854
PrepareTerminate(int32_t persistentId,bool & isPrepareTerminate)855 WSError SceneSessionManager::PrepareTerminate(int32_t persistentId, bool& isPrepareTerminate)
856 {
857 auto task = [this, persistentId, &isPrepareTerminate]() {
858 if (!isPrepareTerminateEnable_) { // not support prepareTerminate
859 isPrepareTerminate = false;
860 WLOGE("not support prepareTerminate");
861 return WSError::WS_OK;
862 }
863 auto scnSession = GetSceneSession(persistentId);
864 if (scnSession == nullptr) {
865 WLOGFE("scnSession is nullptr persistentId:%{public}d", persistentId);
866 isPrepareTerminate = false;
867 return WSError::WS_ERROR_NULLPTR;
868 }
869 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
870 if (scnSessionInfo == nullptr) {
871 WLOGFE("scnSessionInfo is nullptr");
872 isPrepareTerminate = false;
873 return WSError::WS_ERROR_NULLPTR;
874 }
875 auto errorCode = AAFwk::AbilityManagerClient::GetInstance()->
876 PrepareTerminateAbilityBySCB(scnSessionInfo, isPrepareTerminate);
877 WLOGI("PrepareTerminateAbilityBySCB isPrepareTerminate:%{public}d errorCode:%{public}d",
878 isPrepareTerminate, errorCode);
879 return WSError::WS_OK;
880 };
881
882 taskScheduler_->PostSyncTask(task);
883 return WSError::WS_OK;
884 }
885
RequestSceneSessionActivation(const sptr<SceneSession> & sceneSession,bool isNewActive)886 std::future<int32_t> SceneSessionManager::RequestSceneSessionActivation(
887 const sptr<SceneSession>& sceneSession, bool isNewActive)
888 {
889 wptr<SceneSession> weakSceneSession(sceneSession);
890 auto promise = std::make_shared<std::promise<int32_t>>();
891 auto future = promise->get_future();
892 auto task = [this, weakSceneSession, isNewActive, promise]() {
893 auto scnSession = weakSceneSession.promote();
894 if (scnSession == nullptr) {
895 WLOGFE("session is nullptr");
896 promise->set_value(static_cast<int32_t>(WSError::WS_ERROR_NULLPTR));
897 return WSError::WS_ERROR_INVALID_WINDOW;
898 }
899
900 auto persistentId = scnSession->GetPersistentId();
901 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionActivation(%d )", persistentId);
902 WLOGFI("active persistentId: %{public}d", persistentId);
903 if (!GetSceneSession(persistentId)) {
904 WLOGFE("session is invalid with %{public}d", persistentId);
905 promise->set_value(static_cast<int32_t>(WSError::WS_ERROR_INVALID_SESSION));
906 return WSError::WS_ERROR_INVALID_WINDOW;
907 }
908
909 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
910 if (!scnSessionInfo) {
911 promise->set_value(static_cast<int32_t>(WSError::WS_ERROR_NULLPTR));
912 return WSError::WS_ERROR_INVALID_WINDOW;
913 }
914 scnSessionInfo->isNewWant = isNewActive;
915 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
916 WLOGFI("set anco persistentId: %{public}d for type: %{public}d",
917 scnSession->GetBrokerPersistentId(), scnSession->GetCollaboratorType());
918 scnSessionInfo->want.SetParam(AncoConsts::ANCO_MISSION_ID, scnSession->GetBrokerPersistentId());
919 scnSessionInfo->collaboratorType = scnSession->GetCollaboratorType();
920 }
921 auto errCode = AAFwk::AbilityManagerClient::GetInstance()->StartUIAbilityBySCB(scnSessionInfo);
922
923 auto sessionInfo = scnSession->GetSessionInfo();
924 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
925 WindowInfoReporter::GetInstance().InsertShowReportInfo(sessionInfo.bundleName_);
926 }
927 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
928 scnSessionInfo->persistentId = scnSession->GetBrokerPersistentId();
929 NotifyLoadAbility(scnSession->GetCollaboratorType(), scnSessionInfo, sessionInfo.abilityInfo);
930 NotifyUpdateSessionInfo(scnSession);
931 NotifyMoveSessionToForeground(scnSession->GetCollaboratorType(), scnSession->GetBrokerPersistentId());
932 }
933 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
934 promise->set_value(static_cast<int32_t>(errCode));
935 return WSError::WS_OK;
936 };
937
938 taskScheduler_->PostAsyncTask(task);
939 return future;
940 }
941
RequestSceneSessionBackground(const sptr<SceneSession> & sceneSession,const bool isDelegator)942 WSError SceneSessionManager::RequestSceneSessionBackground(const sptr<SceneSession>& sceneSession,
943 const bool isDelegator)
944 {
945 wptr<SceneSession> weakSceneSession(sceneSession);
946 auto task = [this, weakSceneSession, isDelegator]() {
947 auto scnSession = weakSceneSession.promote();
948 if (scnSession == nullptr) {
949 WLOGFE("session is nullptr");
950 return WSError::WS_ERROR_NULLPTR;
951 }
952 auto persistentId = scnSession->GetPersistentId();
953 WLOGFI("background session persistentId: %{public}d", persistentId);
954 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionBackground (%d )", persistentId);
955 scnSession->SetActive(false);
956 scnSession->Background();
957 if (!GetSceneSession(persistentId)) {
958 WLOGFE("session is invalid with %{public}d", persistentId);
959 return WSError::WS_ERROR_INVALID_SESSION;
960 }
961 if (persistentId == brightnessSessionId_) {
962 UpdateBrightness(focusedSessionId_);
963 }
964 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
965 if (!scnSessionInfo) {
966 return WSError::WS_ERROR_NULLPTR;
967 }
968
969 if (!isDelegator) {
970 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo);
971 } else {
972 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo, true);
973 }
974 if (WindowHelper::IsMainWindow(scnSession->GetWindowType())) {
975 auto sessionInfo = scnSession->GetSessionInfo();
976 WindowInfoReporter::GetInstance().InsertHideReportInfo(sessionInfo.bundleName_);
977 }
978 return WSError::WS_OK;
979 };
980
981 taskScheduler_->PostAsyncTask(task);
982 return WSError::WS_OK;
983 }
984
DestroyDialogWithMainWindow(const sptr<SceneSession> & scnSession)985 WSError SceneSessionManager::DestroyDialogWithMainWindow(const sptr<SceneSession>& scnSession)
986 {
987 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:DestroyDialogWithMainWindow");
988 if (scnSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
989 WLOGFD("Begin to destroy its dialog");
990 auto dialogVec = scnSession->GetDialogVector();
991 for (auto dialog : dialogVec) {
992 if (dialog == nullptr) {
993 WLOGFE("dialog is nullptr");
994 return WSError::WS_ERROR_NULLPTR;
995 }
996 if (!GetSceneSession(dialog->GetPersistentId())) {
997 WLOGFE("session is invalid with %{public}d", dialog->GetPersistentId());
998 return WSError::WS_ERROR_INVALID_SESSION;
999 }
1000 auto sceneSession = GetSceneSession(dialog->GetPersistentId());
1001 WindowDestroyNotifyVisibility(sceneSession);
1002 dialog->NotifyDestroy();
1003 dialog->Disconnect();
1004 NotifyWindowInfoChange(dialog->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
1005 {
1006 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1007 sceneSessionMap_.erase(dialog->GetPersistentId());
1008 }
1009 }
1010 return WSError::WS_OK;
1011 }
1012 return WSError::WS_ERROR_INVALID_SESSION;
1013 }
1014
RequestSceneSessionDestruction(const sptr<SceneSession> & sceneSession,const bool needRemoveSession)1015 WSError SceneSessionManager::RequestSceneSessionDestruction(
1016 const sptr<SceneSession>& sceneSession, const bool needRemoveSession)
1017 {
1018 wptr<SceneSession> weakSceneSession(sceneSession);
1019 auto task = [this, weakSceneSession, needRemoveSession]() {
1020 auto scnSession = weakSceneSession.promote();
1021 if (scnSession == nullptr) {
1022 WLOGFE("session is nullptr");
1023 return WSError::WS_ERROR_NULLPTR;
1024 }
1025 auto persistentId = scnSession->GetPersistentId();
1026 DestroyDialogWithMainWindow(scnSession);
1027 WLOGFI("destroy session persistentId: %{public}d", persistentId);
1028 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "ssm:RequestSceneSessionDestruction (%" PRIu32" )", persistentId);
1029 WindowDestroyNotifyVisibility(scnSession);
1030 scnSession->Disconnect();
1031 if (!GetSceneSession(persistentId)) {
1032 WLOGFE("session is invalid with %{public}d", persistentId);
1033 return WSError::WS_ERROR_INVALID_SESSION;
1034 }
1035 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1036 if (!scnSessionInfo) {
1037 return WSError::WS_ERROR_NULLPTR;
1038 }
1039 if (CheckCollaboratorType(scnSession->GetCollaboratorType())) {
1040 NotifyClearSession(scnSession->GetCollaboratorType(), scnSession->GetBrokerPersistentId());
1041 }
1042 AAFwk::AbilityManagerClient::GetInstance()->CloseUIAbilityBySCB(scnSessionInfo);
1043 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
1044 if (needRemoveSession) {
1045 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1046 sceneSessionMap_.erase(persistentId);
1047 if (listenerController_ != nullptr &&
1048 (scnSession->GetSessionInfo().abilityInfo) != nullptr &&
1049 !(scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
1050 WLOGFD("NotifySessionDestroyed, id: %{public}d", persistentId);
1051 listenerController_->NotifySessionDestroyed(persistentId);
1052 }
1053 }
1054 return WSError::WS_OK;
1055 };
1056
1057 taskScheduler_->PostAsyncTask(task);
1058 return WSError::WS_OK;
1059 }
1060
AddClientDeathRecipient(const sptr<ISessionStage> & sessionStage,const sptr<SceneSession> & sceneSession)1061 void SceneSessionManager::AddClientDeathRecipient(const sptr<ISessionStage>& sessionStage,
1062 const sptr<SceneSession>& sceneSession)
1063 {
1064 if (sceneSession == nullptr || sessionStage == nullptr) {
1065 WLOGFE("sessionStage or sceneSession is nullptr");
1066 return;
1067 }
1068
1069 auto remoteObject = sessionStage->AsObject();
1070 remoteObjectMap_.insert(std::make_pair(remoteObject, sceneSession->GetPersistentId()));
1071 if (windowDeath_ == nullptr) {
1072 WLOGFE("failed to create death recipient");
1073 return;
1074 }
1075 if (!remoteObject->AddDeathRecipient(windowDeath_)) {
1076 WLOGFE("failed to add death recipient");
1077 return;
1078 }
1079 WLOGFD("Id: %{public}d", sceneSession->GetPersistentId());
1080 }
1081
DestroySpecificSession(const sptr<IRemoteObject> & remoteObject)1082 void SceneSessionManager::DestroySpecificSession(const sptr<IRemoteObject>& remoteObject)
1083 {
1084 auto task = [this, remoteObject] {
1085 auto iter = remoteObjectMap_.find(remoteObject);
1086 if (iter == remoteObjectMap_.end()) {
1087 WLOGFE("Invalid remoteObject");
1088 return;
1089 }
1090 WLOGFD("Remote died, id: %{public}d", iter->second);
1091 auto sceneSession = GetSceneSession(iter->second);
1092 if (sceneSession == nullptr) {
1093 WLOGFW("Remote died, session is nullptr, id: %{public}d", iter->second);
1094 return;
1095 }
1096 DestroyAndDisconnectSpecificSessionInner(sceneSession);
1097 remoteObjectMap_.erase(iter);
1098 };
1099 taskScheduler_->PostAsyncTask(task);
1100 }
1101
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)1102 WSError SceneSessionManager::CreateAndConnectSpecificSession(const sptr<ISessionStage>& sessionStage,
1103 const sptr<IWindowEventChannel>& eventChannel, const std::shared_ptr<RSSurfaceNode>& surfaceNode,
1104 sptr<WindowSessionProperty> property, int32_t& persistentId, sptr<ISession>& session, sptr<IRemoteObject> token)
1105 {
1106 if (property == nullptr) {
1107 WLOGFE("property is nullptr");
1108 return WSError::WS_ERROR_NULLPTR;
1109 }
1110 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartedByInputMethod()) {
1111 WLOGFE("check input method permission failed");
1112 }
1113 // get pid/uid before post sync task
1114 int32_t pid = IPCSkeleton::GetCallingPid();
1115 int32_t uid = IPCSkeleton::GetCallingUid();
1116 auto task = [this, sessionStage, eventChannel, surfaceNode, property, &persistentId, &session, token, pid, uid]() {
1117 // create specific session
1118 SessionInfo info;
1119 sptr<SceneSession> sceneSession = RequestSceneSession(info, property);
1120 if (sceneSession == nullptr) {
1121 return WSError::WS_ERROR_NULLPTR;
1122 }
1123 sceneSession->SetCallingPid(pid);
1124 sceneSession->SetCallingUid(uid);
1125 // connect specific session and sessionStage
1126 WSError errCode = sceneSession->ConnectImpl(
1127 sessionStage, eventChannel, surfaceNode, systemConfig_, property, token);
1128 if (property) {
1129 persistentId = property->GetPersistentId();
1130 }
1131 if (createSpecificSessionFunc_) {
1132 createSpecificSessionFunc_(sceneSession);
1133 }
1134 session = sceneSession;
1135 AddClientDeathRecipient(sessionStage, sceneSession);
1136 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
1137 auto sessionInfo = sceneSession->GetSessionInfo();
1138 WindowInfoReporter::GetInstance().InsertCreateReportInfo(sessionInfo.bundleName_);
1139 }
1140 return errCode;
1141 };
1142
1143 return taskScheduler_->PostSyncTask(task);
1144 }
1145
SetCreateSpecificSessionListener(const NotifyCreateSpecificSessionFunc & func)1146 void SceneSessionManager::SetCreateSpecificSessionListener(const NotifyCreateSpecificSessionFunc& func)
1147 {
1148 createSpecificSessionFunc_ = func;
1149 }
1150
SetGestureNavigationEnabledChangeListener(const ProcessGestureNavigationEnabledChangeFunc & func)1151 void SceneSessionManager::SetGestureNavigationEnabledChangeListener(
1152 const ProcessGestureNavigationEnabledChangeFunc& func)
1153 {
1154 WLOGFD("SetGestureNavigationEnabledChangeListener");
1155 if (!func) {
1156 WLOGFD("set func is null");
1157 }
1158 gestureNavigationEnabledChangeFunc_ = func;
1159 }
1160
OnOutsideDownEvent(int32_t x,int32_t y)1161 void SceneSessionManager::OnOutsideDownEvent(int32_t x, int32_t y)
1162 {
1163 WLOGFI("OnOutsideDownEvent x = %{public}d, y = %{public}d", x, y);
1164 if (outsideDownEventFunc_) {
1165 outsideDownEventFunc_(x, y);
1166 }
1167 }
1168
NotifySessionTouchOutside(int32_t action,int32_t x,int32_t y)1169 void SceneSessionManager::NotifySessionTouchOutside(int32_t action, int32_t x, int32_t y)
1170 {
1171 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1172 for (const auto &item : sceneSessionMap_) {
1173 auto sceneSession = item.second;
1174 if (sceneSession == nullptr) {
1175 continue;
1176 }
1177 if (sceneSession->GetSessionInfo().isSystem_ ||
1178 (sceneSession->GetSessionState() != SessionState::STATE_FOREGROUND &&
1179 sceneSession->GetSessionState() != SessionState::STATE_ACTIVE)) {
1180 continue;
1181 }
1182 auto persistentId = sceneSession->GetPersistentId();
1183 auto touchHotAreaRects = sceneSession->GetTouchHotAreas();
1184 if (!touchHotAreaRects.empty()) {
1185 bool touchInsideFlag = false;
1186 for (auto touchHotAreaRect : touchHotAreaRects) {
1187 if (!SessionHelper::IsPointInRect(x, y, touchHotAreaRect)) {
1188 continue;
1189 } else {
1190 WLOGFD("TouchInside %{public}d", persistentId);
1191 touchInsideFlag = true;
1192 break;
1193 }
1194 }
1195 if (!touchInsideFlag) {
1196 sceneSession->NotifyTouchOutside();
1197 }
1198 } else {
1199 auto hotAreaRect = sceneSession->GetHotAreaRect(action);
1200 if (!SessionHelper::IsPointInRect(x, y, hotAreaRect)) {
1201 sceneSession->NotifyTouchOutside();
1202 } else {
1203 WLOGFD("TouchInside %{public}d", persistentId);
1204 }
1205 }
1206 }
1207 }
1208
SetOutsideDownEventListener(const ProcessOutsideDownEventFunc & func)1209 void SceneSessionManager::SetOutsideDownEventListener(const ProcessOutsideDownEventFunc& func)
1210 {
1211 WLOGFD("SetOutsideDownEventListener");
1212 outsideDownEventFunc_ = func;
1213 }
1214
DestroyAndDisconnectSpecificSessionInner(sptr<SceneSession> sceneSession)1215 WSError SceneSessionManager::DestroyAndDisconnectSpecificSessionInner(sptr<SceneSession> sceneSession)
1216 {
1217 if (sceneSession == nullptr) {
1218 return WSError::WS_ERROR_NULLPTR;
1219 }
1220 const auto& persistentId = sceneSession->GetPersistentId();
1221 auto ret = sceneSession->UpdateActiveStatus(false);
1222 WindowDestroyNotifyVisibility(sceneSession);
1223 if (sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
1224 auto parentSession = GetSceneSession(sceneSession->GetParentPersistentId());
1225 if (parentSession == nullptr) {
1226 WLOGFE("Dialog not bind parent");
1227 } else {
1228 parentSession->RemoveDialogToParentSession(sceneSession);
1229 }
1230 sceneSession->NotifyDestroy();
1231 }
1232 ret = sceneSession->Disconnect();
1233 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
1234 {
1235 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1236 sceneSessionMap_.erase(persistentId);
1237 }
1238 if (WindowHelper::IsMainWindow(sceneSession->GetWindowType())) {
1239 auto sessionInfo = sceneSession->GetSessionInfo();
1240 WindowInfoReporter::GetInstance().InsertDestroyReportInfo(sessionInfo.bundleName_);
1241 }
1242 return ret;
1243 }
1244
DestroyAndDisconnectSpecificSession(const int32_t & persistentId)1245 WSError SceneSessionManager::DestroyAndDisconnectSpecificSession(const int32_t& persistentId)
1246 {
1247 const auto& callingPid = IPCSkeleton::GetCallingPid();
1248 auto task = [this, persistentId, callingPid]() {
1249 WLOGFI("Destroy specific session persistentId: %{public}d", persistentId);
1250 auto sceneSession = GetSceneSession(persistentId);
1251 if (sceneSession == nullptr) {
1252 return WSError::WS_ERROR_NULLPTR;
1253 }
1254
1255 if (callingPid != sceneSession->GetCallingPid()) {
1256 WLOGFE("[WMSSystem][WMSSub] Permission denied, not destroy by the same process");
1257 return WSError::WS_ERROR_INVALID_PERMISSION;
1258 }
1259 return DestroyAndDisconnectSpecificSessionInner(sceneSession);
1260 };
1261
1262 return taskScheduler_->PostSyncTask(task);
1263 }
1264
GetWindowSceneConfig() const1265 const AppWindowSceneConfig& SceneSessionManager::GetWindowSceneConfig() const
1266 {
1267 return appWindowSceneConfig_;
1268 }
1269
ProcessBackEvent()1270 WSError SceneSessionManager::ProcessBackEvent()
1271 {
1272 auto task = [this]() {
1273 auto session = GetSceneSession(focusedSessionId_);
1274 if (!session) {
1275 return WSError::WS_ERROR_INVALID_SESSION;
1276 }
1277 WLOGFD("ProcessBackEvent session persistentId: %{public}d", focusedSessionId_);
1278 session->ProcessBackEvent();
1279 return WSError::WS_OK;
1280 };
1281
1282 taskScheduler_->PostAsyncTask(task);
1283 return WSError::WS_OK;
1284 }
1285
CleanUserMap()1286 void SceneSessionManager::CleanUserMap()
1287 {
1288 WLOGFI("CleanUserMap in size = %{public}zu", sceneSessionMap_.size());
1289 auto iter = sceneSessionMap_.begin();
1290 while (iter != sceneSessionMap_.end()) {
1291 if (iter->second != nullptr && !iter->second->GetSessionInfo().isSystem_) {
1292 iter = sceneSessionMap_.erase(iter);
1293 } else {
1294 iter++;
1295 }
1296 }
1297 WLOGFI("CleanUserMap out size = %{public}zu", sceneSessionMap_.size());
1298 }
1299
SwitchUser(int32_t oldUserId,int32_t newUserId,std::string & fileDir)1300 WSError SceneSessionManager::SwitchUser(int32_t oldUserId, int32_t newUserId, std::string &fileDir)
1301 {
1302 if (oldUserId != currentUserId_ || oldUserId == newUserId || fileDir.empty()) {
1303 WLOGFE("SwitchUser params invalid");
1304 return WSError::WS_DO_NOTHING;
1305 }
1306 WLOGFD("SwitchUser oldUserId : %{public}d newUserId : %{public}d path : %{public}s",
1307 oldUserId, newUserId, fileDir.c_str());
1308 auto task = [this, newUserId, &fileDir]() {
1309 if (!ScenePersistence::CreateSnapshotDir(fileDir)) {
1310 WLOGFD("snapshot dir existed");
1311 }
1312 currentUserId_ = newUserId;
1313 std::unique_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1314 for (const auto &item : sceneSessionMap_) {
1315 auto scnSession = item.second;
1316 auto persistentId = scnSession->GetPersistentId();
1317 scnSession->SetActive(false);
1318 scnSession->Background();
1319 if (persistentId == brightnessSessionId_) {
1320 UpdateBrightness(focusedSessionId_);
1321 }
1322 auto scnSessionInfo = SetAbilitySessionInfo(scnSession);
1323 if (!scnSessionInfo) {
1324 return WSError::WS_ERROR_NULLPTR;
1325 }
1326 AAFwk::AbilityManagerClient::GetInstance()->MinimizeUIAbilityBySCB(scnSessionInfo);
1327 }
1328 CleanUserMap();
1329 return WSError::WS_OK;
1330 };
1331 taskScheduler_->PostSyncTask(task);
1332 return WSError::WS_OK;
1333 }
1334
GetBundleManager()1335 sptr<AppExecFwk::IBundleMgr> SceneSessionManager::GetBundleManager()
1336 {
1337 auto systemAbilityMgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
1338 if (systemAbilityMgr == nullptr) {
1339 WLOGFE("Failed to get SystemAbilityManager.");
1340 return nullptr;
1341 }
1342
1343 auto bmsObj = systemAbilityMgr->GetSystemAbility(BUNDLE_MGR_SERVICE_SYS_ABILITY_ID);
1344 if (bmsObj == nullptr) {
1345 WLOGFE("Failed to get BundleManagerService.");
1346 return nullptr;
1347 }
1348
1349 return iface_cast<AppExecFwk::IBundleMgr>(bmsObj);
1350 }
1351
CreateResourceManager(const AppExecFwk::AbilityInfo & abilityInfo)1352 std::shared_ptr<Global::Resource::ResourceManager> SceneSessionManager::CreateResourceManager(
1353 const AppExecFwk::AbilityInfo& abilityInfo)
1354 {
1355 std::unique_ptr<Global::Resource::ResConfig> resConfig(Global::Resource::CreateResConfig());
1356 std::shared_ptr<Global::Resource::ResourceManager> resourceMgr(Global::Resource::CreateResourceManager());
1357 resourceMgr->UpdateResConfig(*resConfig);
1358
1359 std::string loadPath;
1360 if (!abilityInfo.hapPath.empty()) { // zipped hap
1361 loadPath = abilityInfo.hapPath;
1362 } else {
1363 loadPath = abilityInfo.resourcePath;
1364 }
1365
1366 if (!resourceMgr->AddResource(loadPath.c_str())) {
1367 WLOGFE("Add resource %{private}s failed.", loadPath.c_str());
1368 return nullptr;
1369 }
1370 return resourceMgr;
1371 }
1372
GetStartPageFromResource(const AppExecFwk::AbilityInfo & abilityInfo,std::string & path,uint32_t & bgColor)1373 void SceneSessionManager::GetStartPageFromResource(const AppExecFwk::AbilityInfo& abilityInfo,
1374 std::string& path, uint32_t& bgColor)
1375 {
1376 auto resourceMgr = CreateResourceManager(abilityInfo);
1377 if (resourceMgr == nullptr) {
1378 WLOGFE("resource manager is nullptr.");
1379 return;
1380 }
1381
1382 if (resourceMgr->GetColorById(abilityInfo.startWindowBackgroundId, bgColor) != Global::Resource::RState::SUCCESS) {
1383 WLOGFW("Failed to get background color id %{private}d.", abilityInfo.startWindowBackgroundId);
1384 }
1385
1386 if (resourceMgr->GetMediaById(abilityInfo.startWindowIconId, path) != Global::Resource::RState::SUCCESS) {
1387 WLOGFE("Failed to get icon id %{private}d.", abilityInfo.startWindowIconId);
1388 return;
1389 }
1390
1391 if (!abilityInfo.hapPath.empty()) { // zipped hap
1392 auto pos = path.find_last_of('.');
1393 if (pos == std::string::npos) {
1394 WLOGFE("Format error, path %{private}s.", path.c_str());
1395 return;
1396 }
1397 path = "resource:///" + std::to_string(abilityInfo.startWindowIconId) + path.substr(pos);
1398 }
1399 }
1400
GetStartPage(const SessionInfo & sessionInfo,std::string & path,uint32_t & bgColor)1401 void SceneSessionManager::GetStartPage(const SessionInfo& sessionInfo, std::string& path, uint32_t& bgColor)
1402 {
1403 if (!bundleMgr_) {
1404 WLOGFE("bundle manager is nullptr.");
1405 return;
1406 }
1407
1408 AAFwk::Want want;
1409 want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
1410 AppExecFwk::AbilityInfo abilityInfo;
1411 bool ret = bundleMgr_->QueryAbilityInfo(
1412 want, AppExecFwk::GET_ABILITY_INFO_DEFAULT, AppExecFwk::Constants::ANY_USERID, abilityInfo);
1413 if (!ret) {
1414 WLOGFE("Get ability info from BMS failed!");
1415 return;
1416 }
1417
1418 GetStartPageFromResource(abilityInfo, path, bgColor);
1419 }
1420
FillSessionInfo(SessionInfo & sessionInfo)1421 void SceneSessionManager::FillSessionInfo(SessionInfo& sessionInfo)
1422 {
1423 auto abilityInfo = QueryAbilityInfoFromBMS(currentUserId_, sessionInfo.bundleName_, sessionInfo.abilityName_,
1424 sessionInfo.moduleName_);
1425 if (abilityInfo == nullptr) {
1426 WLOGFE("FillSessionInfo abilityInfo is nullptr!");
1427 return;
1428 }
1429 sessionInfo.abilityInfo = abilityInfo;
1430 sessionInfo.time = GetCurrentTime();
1431 WLOGFI("FillSessionInfo end, removeMissionAfterTerminate: %{public}d excludeFromMissions: %{public}d "
1432 " label:%{public}s iconPath:%{public}s",
1433 abilityInfo->removeMissionAfterTerminate, abilityInfo->excludeFromMissions,
1434 abilityInfo->label.c_str(), abilityInfo->iconPath.c_str());
1435 }
1436
QueryAbilityInfoFromBMS(const int32_t uId,const std::string & bundleName,const std::string & abilityName,const std::string & moduleName)1437 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSessionManager::QueryAbilityInfoFromBMS(const int32_t uId,
1438 const std::string& bundleName, const std::string& abilityName, const std::string& moduleName)
1439 {
1440 AAFwk::Want want;
1441 want.SetElementName("", bundleName, abilityName, moduleName);
1442 std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo = std::make_shared<AppExecFwk::AbilityInfo>();
1443 if (abilityInfo == nullptr) {
1444 WLOGFE("QueryAbilityInfoFromBMS abilityInfo is nullptr!");
1445 return nullptr;
1446 }
1447 auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
1448 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
1449 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA);
1450 bool ret = bundleMgr_->QueryAbilityInfo(want, abilityInfoFlag, uId, *abilityInfo);
1451 if (!ret) {
1452 WLOGFE("Get ability info from BMS failed!");
1453 return nullptr;
1454 }
1455 return abilityInfo;
1456 }
1457
UpdateProperty(sptr<WindowSessionProperty> & property,WSPropertyChangeAction action)1458 WMError SceneSessionManager::UpdateProperty(sptr<WindowSessionProperty>& property, WSPropertyChangeAction action)
1459 {
1460 if (property == nullptr) {
1461 WLOGFE("property is nullptr");
1462 return WMError::WM_ERROR_NULLPTR;
1463 }
1464 bool isSystemCalling = SessionPermission::IsSystemCalling() || SessionPermission::IsStartByHdcd();
1465 property->SetSystemCalling(isSystemCalling);
1466 wptr<SceneSessionManager> weak = this;
1467 auto task = [weak, property, action]() -> WMError {
1468 auto weakSession = weak.promote();
1469 if (weakSession == nullptr) {
1470 WLOGFE("the session is nullptr");
1471 WMError::WM_DO_NOTHING;
1472 }
1473 if (property == nullptr) {
1474 WLOGFE("the property is nullptr");
1475 WMError::WM_DO_NOTHING;
1476 }
1477 auto sceneSession = weakSession->GetSceneSession(property->GetPersistentId());
1478 if (sceneSession == nullptr) {
1479 WLOGFE("the scene session is nullptr");
1480 WMError::WM_DO_NOTHING;
1481 }
1482 WLOGI("Id: %{public}d, action: %{public}u", sceneSession->GetPersistentId(), action);
1483 return weakSession->HandleUpdateProperty(property, action, sceneSession);
1484 };
1485 return taskScheduler_->PostSyncTask(task);
1486 }
1487
UpdatePropertyDragEnabled(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)1488 WMError SceneSessionManager::UpdatePropertyDragEnabled(const sptr<WindowSessionProperty>& property,
1489 const sptr<SceneSession>& sceneSession)
1490 {
1491 if (!property->GetSystemCalling()) {
1492 WLOGFE("Update property dragEnabled permission denied!");
1493 return WMError::WM_ERROR_NOT_SYSTEM_APP;
1494 }
1495
1496 if (sceneSession->GetSessionProperty() != nullptr) {
1497 sceneSession->GetSessionProperty()->SetDragEnabled(property->GetDragEnabled());
1498 }
1499 return WMError::WM_OK;
1500 }
1501
UpdatePropertyRaiseEnabled(const sptr<WindowSessionProperty> & property,const sptr<SceneSession> & sceneSession)1502 WMError SceneSessionManager::UpdatePropertyRaiseEnabled(const sptr<WindowSessionProperty>& property,
1503 const sptr<SceneSession>& sceneSession)
1504 {
1505 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1506 WLOGFE("Update property raiseEnabled permission denied!");
1507 return WMError::WM_ERROR_NOT_SYSTEM_APP;
1508 }
1509
1510 if (sceneSession->GetSessionProperty() != nullptr) {
1511 sceneSession->GetSessionProperty()->SetRaiseEnabled(property->GetRaiseEnabled());
1512 }
1513 return WMError::WM_OK;
1514 }
1515
HandleUpdateProperty(const sptr<WindowSessionProperty> & property,WSPropertyChangeAction action,const sptr<SceneSession> & sceneSession)1516 WMError SceneSessionManager::HandleUpdateProperty(const sptr<WindowSessionProperty>& property,
1517 WSPropertyChangeAction action, const sptr<SceneSession>& sceneSession)
1518 {
1519 switch (action) {
1520 case WSPropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON: {
1521 sceneSession->SetTurnScreenOn(property->IsTurnScreenOn());
1522 HandleTurnScreenOn(sceneSession);
1523 break;
1524 }
1525 case WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON: {
1526 sceneSession->SetKeepScreenOn(property->IsKeepScreenOn());
1527 HandleKeepScreenOn(sceneSession, property->IsKeepScreenOn());
1528 break;
1529 }
1530 case WSPropertyChangeAction::ACTION_UPDATE_FOCUSABLE: {
1531 sceneSession->SetFocusable(property->GetFocusable());
1532 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1533 break;
1534 }
1535 case WSPropertyChangeAction::ACTION_UPDATE_TOUCHABLE: {
1536 sceneSession->SetTouchable(property->GetTouchable());
1537 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1538 break;
1539 }
1540 case WSPropertyChangeAction::ACTION_UPDATE_SET_BRIGHTNESS: {
1541 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1542 WLOGW("only app main window can set brightness");
1543 return WMError::WM_OK;
1544 }
1545 // @todo if sceneSession is inactive, return
1546 SetBrightness(sceneSession, property->GetBrightness());
1547 break;
1548 }
1549 case WSPropertyChangeAction::ACTION_UPDATE_ORIENTATION: {
1550 ScreenSessionManager::GetInstance().
1551 SetOrientationFromWindow(property->GetDisplayId(), property->GetRequestedOrientation());
1552 sceneSession->SetRequestedOrientation(property->GetRequestedOrientation());
1553 break;
1554 }
1555 case WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE: {
1556 bool isPrivacyMode = property->GetPrivacyMode() || property->GetSystemPrivacyMode();
1557 sceneSession->SetPrivacyMode(isPrivacyMode);
1558 break;
1559 }
1560 case WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE: {
1561 if (sceneSession->GetSessionProperty() != nullptr) {
1562 sceneSession->GetSessionProperty()->SetMaximizeMode(property->GetMaximizeMode());
1563 }
1564 break;
1565 }
1566 case WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS: {
1567 auto systemBarProperties = property->GetSystemBarProperty();
1568 for (auto iter : systemBarProperties) {
1569 sceneSession->SetSystemBarProperty(iter.first, iter.second);
1570 }
1571 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1572 break;
1573 }
1574 case WSPropertyChangeAction::ACTION_UPDATE_FLAGS: {
1575 SetWindowFlags(sceneSession, property->GetWindowFlags());
1576 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1577 break;
1578 }
1579 case WSPropertyChangeAction::ACTION_UPDATE_MODE: {
1580 if (sceneSession->GetSessionProperty() != nullptr) {
1581 sceneSession->GetSessionProperty()->SetWindowMode(property->GetWindowMode());
1582 }
1583 NotifyWindowInfoChange(property->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1584 break;
1585 }
1586 case WSPropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG: {
1587 if (sceneSession->GetSessionProperty() != nullptr) {
1588 sceneSession->GetSessionProperty()->SetAnimationFlag(property->GetAnimationFlag());
1589 }
1590 break;
1591 }
1592 case WSPropertyChangeAction::ACTION_UPDATE_TOUCH_HOT_AREA: {
1593 if (sceneSession->GetSessionProperty() != nullptr) {
1594 std::vector<Rect> touchHotAreas;
1595 property->GetTouchHotAreas(touchHotAreas);
1596 sceneSession->GetSessionProperty()->SetTouchHotAreas(touchHotAreas);
1597 }
1598 break;
1599 }
1600 case WSPropertyChangeAction::ACTION_UPDATE_DECOR_ENABLE: {
1601 if (sceneSession->GetSessionProperty() != nullptr) {
1602 sceneSession->GetSessionProperty()->SetDecorEnable(property->IsDecorEnable());
1603 }
1604 break;
1605 }
1606 case WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS: {
1607 if (sceneSession->GetSessionProperty() != nullptr) {
1608 sceneSession->GetSessionProperty()->SetWindowLimits(property->GetWindowLimits());
1609 }
1610 break;
1611 }
1612 case WSPropertyChangeAction::ACTION_UPDATE_DRAGENABLED: {
1613 return UpdatePropertyDragEnabled(property, sceneSession);
1614 }
1615 case WSPropertyChangeAction::ACTION_UPDATE_RAISEENABLED: {
1616 return UpdatePropertyRaiseEnabled(property, sceneSession);
1617 }
1618 default:
1619 break;
1620 }
1621 return WMError::WM_OK;
1622 }
1623
HandleTurnScreenOn(const sptr<SceneSession> & sceneSession)1624 void SceneSessionManager::HandleTurnScreenOn(const sptr<SceneSession>& sceneSession)
1625 {
1626 auto task = [this, sceneSession]() {
1627 if (sceneSession == nullptr) {
1628 WLOGFE("session is invalid");
1629 return;
1630 }
1631 WLOGFD("Win: %{public}s, is turn on%{public}d",
1632 sceneSession->GetWindowName().c_str(), sceneSession->IsTurnScreenOn());
1633 std::string identity = IPCSkeleton::ResetCallingIdentity();
1634 if (sceneSession->IsTurnScreenOn() && !PowerMgr::PowerMgrClient::GetInstance().IsScreenOn()) {
1635 WLOGI("turn screen on");
1636 PowerMgr::PowerMgrClient::GetInstance().WakeupDevice();
1637 }
1638 // set ipc identity to raw
1639 IPCSkeleton::SetCallingIdentity(identity);
1640 };
1641 taskScheduler_->PostAsyncTask(task);
1642 }
1643
HandleKeepScreenOn(const sptr<SceneSession> & sceneSession,bool requireLock)1644 void SceneSessionManager::HandleKeepScreenOn(const sptr<SceneSession>& sceneSession, bool requireLock)
1645 {
1646 auto task = [this, sceneSession, requireLock]() {
1647 if (sceneSession == nullptr) {
1648 WLOGFE("session is invalid");
1649 return;
1650 }
1651 if (requireLock && sceneSession->keepScreenLock_ == nullptr) {
1652 // reset ipc identity
1653 std::string identity = IPCSkeleton::ResetCallingIdentity();
1654 sceneSession->keepScreenLock_ =
1655 PowerMgr::PowerMgrClient::GetInstance().CreateRunningLock(sceneSession->GetWindowName(),
1656 PowerMgr::RunningLockType::RUNNINGLOCK_SCREEN);
1657 // set ipc identity to raw
1658 IPCSkeleton::SetCallingIdentity(identity);
1659 }
1660 if (sceneSession->keepScreenLock_ == nullptr) {
1661 return;
1662 }
1663 WLOGI("keep screen on: [%{public}s, %{public}d]", sceneSession->GetWindowName().c_str(), requireLock);
1664 ErrCode res;
1665 std::string identity = IPCSkeleton::ResetCallingIdentity();
1666 if (requireLock) {
1667 res = sceneSession->keepScreenLock_->Lock();
1668 } else {
1669 res = sceneSession->keepScreenLock_->UnLock();
1670 }
1671 // set ipc identity to raw
1672 IPCSkeleton::SetCallingIdentity(identity);
1673 if (res != ERR_OK) {
1674 WLOGFE("handle keep screen running lock failed: [operation: %{public}d, err: %{public}d]",
1675 requireLock, res);
1676 }
1677 };
1678 taskScheduler_->PostAsyncTask(task);
1679 }
1680
SetBrightness(const sptr<SceneSession> & sceneSession,float brightness)1681 WSError SceneSessionManager::SetBrightness(const sptr<SceneSession>& sceneSession, float brightness)
1682 {
1683 if (!sceneSession->IsSessionValid()) {
1684 return WSError::WS_ERROR_INVALID_SESSION;
1685 }
1686 if (brightness == sceneSession->GetBrightness()) {
1687 WLOGFD("Session brightness do not change: [%{public}f]", brightness);
1688 return WSError::WS_DO_NOTHING;
1689 }
1690 sceneSession->SetBrightness(brightness);
1691 if (GetDisplayBrightness() != brightness) {
1692 if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
1693 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
1694 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
1695 } else {
1696 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
1697 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
1698 SetDisplayBrightness(brightness);
1699 }
1700 }
1701 brightnessSessionId_ = sceneSession->GetPersistentId();
1702 return WSError::WS_OK;
1703 }
1704
UpdateBrightness(int32_t persistentId)1705 WSError SceneSessionManager::UpdateBrightness(int32_t persistentId)
1706 {
1707 auto sceneSession = GetSceneSession(persistentId);
1708 if (sceneSession == nullptr) {
1709 WLOGFE("session is invalid");
1710 return WSError::WS_ERROR_NULLPTR;
1711 }
1712 if (!(sceneSession->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW || sceneSession->GetSessionInfo().isSystem_)) {
1713 WLOGW("only app main window can set brightness");
1714 return WSError::WS_DO_NOTHING;
1715 }
1716 auto brightness = sceneSession->GetBrightness();
1717 WLOGI("Brightness: [%{public}f, %{public}f]", GetDisplayBrightness(), brightness);
1718 if (std::fabs(brightness - UNDEFINED_BRIGHTNESS) < std::numeric_limits<float>::min()) {
1719 if (GetDisplayBrightness() != brightness) {
1720 WLOGI("adjust brightness with default value");
1721 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().RestoreBrightness();
1722 SetDisplayBrightness(UNDEFINED_BRIGHTNESS); // UNDEFINED_BRIGHTNESS means system default brightness
1723 }
1724 brightnessSessionId_ = INVALID_WINDOW_ID;
1725 } else {
1726 if (GetDisplayBrightness() != brightness) {
1727 WLOGI("adjust brightness with value");
1728 DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().OverrideBrightness(
1729 static_cast<uint32_t>(brightness * MAX_BRIGHTNESS));
1730 SetDisplayBrightness(brightness);
1731 }
1732 brightnessSessionId_ = sceneSession->GetPersistentId();
1733 }
1734 return WSError::WS_OK;
1735 }
1736
GetCurrentUserId() const1737 int32_t SceneSessionManager::GetCurrentUserId() const
1738 {
1739 return currentUserId_;
1740 }
1741
SetDisplayBrightness(float brightness)1742 void SceneSessionManager::SetDisplayBrightness(float brightness)
1743 {
1744 displayBrightness_ = brightness;
1745 }
1746
GetDisplayBrightness() const1747 float SceneSessionManager::GetDisplayBrightness() const
1748 {
1749 return displayBrightness_;
1750 }
1751
SetGestureNavigaionEnabled(bool enable)1752 WMError SceneSessionManager::SetGestureNavigaionEnabled(bool enable)
1753 {
1754 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1755 WLOGFE("SetGestureNavigationEnabled permission denied!");
1756 return WMError::WM_ERROR_NOT_SYSTEM_APP;
1757 }
1758 WLOGFD("SetGestureNavigationEnabled, enable: %{public}d", enable);
1759 auto task = [this, enable]() {
1760 if (!gestureNavigationEnabledChangeFunc_) {
1761 WLOGFE("callback func is null");
1762 return WMError::WM_DO_NOTHING;
1763 } else {
1764 gestureNavigationEnabledChangeFunc_(enable);
1765 }
1766 return WMError::WM_OK;
1767 };
1768 return taskScheduler_->PostSyncTask(task);
1769 }
1770
SetFocusedSession(int32_t persistentId)1771 WSError SceneSessionManager::SetFocusedSession(int32_t persistentId)
1772 {
1773 if (focusedSessionId_ == persistentId) {
1774 WLOGI("Focus scene not change, id: %{public}d", focusedSessionId_);
1775 return WSError::WS_DO_NOTHING;
1776 }
1777 focusedSessionId_ = persistentId;
1778 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_FOCUSED);
1779 return WSError::WS_OK;
1780 }
1781
GetFocusedSession() const1782 int32_t SceneSessionManager::GetFocusedSession() const
1783 {
1784 return focusedSessionId_;
1785 }
1786
GetFocusWindowInfo(FocusChangeInfo & focusInfo)1787 void SceneSessionManager::GetFocusWindowInfo(FocusChangeInfo& focusInfo)
1788 {
1789 auto sceneSession = GetSceneSession(focusedSessionId_);
1790 if (sceneSession) {
1791 WLOGFD("Get focus session info success");
1792 focusInfo.windowId_ = sceneSession->GetWindowId();
1793 focusInfo.displayId_ = static_cast<DisplayId>(0);
1794 focusInfo.pid_ = sceneSession->GetCallingPid();
1795 focusInfo.uid_ = sceneSession->GetCallingUid();
1796 focusInfo.windowType_ = sceneSession->GetWindowType();
1797 focusInfo.abilityToken_ = sceneSession->GetAbilityToken();
1798 }
1799 return;
1800 }
1801
IsValidDigitString(const std::string & windowIdStr)1802 static bool IsValidDigitString(const std::string& windowIdStr)
1803 {
1804 if (windowIdStr.empty()) {
1805 return false;
1806 }
1807 for (char ch : windowIdStr) {
1808 if ((ch >= '0' && ch <= '9')) {
1809 continue;
1810 }
1811 WLOGFE("invalid window id");
1812 return false;
1813 }
1814 return true;
1815 }
1816
RegisterSessionExceptionFunc(const sptr<SceneSession> & sceneSession)1817 void SceneSessionManager::RegisterSessionExceptionFunc(const sptr<SceneSession>& sceneSession)
1818 {
1819 if (sceneSession == nullptr) {
1820 WLOGFE("session is nullptr");
1821 return;
1822 }
1823 NotifySessionExceptionFunc sessionExceptionFunc = [this](const SessionInfo& info) {
1824 if (info.errorCode == static_cast<int32_t>(AAFwk::ErrorLifecycleState::ABILITY_STATE_LOAD_TIMEOUT)) {
1825 auto scnSession = GetSceneSession(info.persistentId_);
1826 if (!scnSession && listenerController_ != nullptr) {
1827 WLOGFD("NotifySessionClosed when ability load timeout, id: %{public}d", info.persistentId_);
1828 listenerController_->NotifySessionClosed(info.persistentId_);
1829 }
1830 }
1831 };
1832 sceneSession->SetSessionExceptionListener(sessionExceptionFunc);
1833 WLOGFD("RegisterSessionExceptionFunc success");
1834 }
1835
IsSessionVisible(const sptr<SceneSession> & session)1836 bool SceneSessionManager::IsSessionVisible(const sptr<SceneSession>& session)
1837 {
1838 if (session->IsVisible() || session->GetSessionState() == SessionState::STATE_ACTIVE ||
1839 session->GetSessionState() == SessionState::STATE_FOREGROUND) {
1840 return true;
1841 }
1842 return false;
1843 }
1844
DumpSessionInfo(const sptr<SceneSession> & session,std::ostringstream & oss)1845 void SceneSessionManager::DumpSessionInfo(const sptr<SceneSession>& session, std::ostringstream& oss)
1846 {
1847 if (session == nullptr) {
1848 return;
1849 }
1850 int32_t zOrder = IsSessionVisible(session) ? static_cast<int32_t>(session->GetZOrder()) : -1;
1851 WSRect rect = session->GetSessionRect();
1852 std::string sName;
1853 if (session->GetSessionInfo().isSystem_) {
1854 sName = session->GetSessionInfo().abilityName_;
1855 } else {
1856 sName = session->GetWindowName();
1857 }
1858 uint32_t displayId = 0;
1859 uint32_t flag = session->GetWindowSessionProperty()->GetWindowFlags();
1860 uint32_t orientation = 0;
1861 const std::string& windowName = sName.size() <= WINDOW_NAME_MAX_LENGTH ?
1862 sName : sName.substr(0, WINDOW_NAME_MAX_LENGTH);
1863 // std::setw is used to set the output width and different width values are set to keep the format aligned.
1864 oss << std::left << std::setw(WINDOW_NAME_MAX_WIDTH) << windowName
1865 << std::left << std::setw(DISPLAY_NAME_MAX_WIDTH) << displayId
1866 << std::left << std::setw(PID_MAX_WIDTH) << session->GetCallingPid()
1867 << std::left << std::setw(PARENT_ID_MAX_WIDTH) << session->GetPersistentId()
1868 << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowType())
1869 << std::left << std::setw(VALUE_MAX_WIDTH) << static_cast<uint32_t>(session->GetWindowMode())
1870 << std::left << std::setw(VALUE_MAX_WIDTH) << flag
1871 << std::left << std::setw(VALUE_MAX_WIDTH) << zOrder
1872 << std::left << std::setw(ORIEN_MAX_WIDTH) << orientation
1873 << "[ "
1874 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posX_
1875 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.posY_
1876 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.width_
1877 << std::left << std::setw(VALUE_MAX_WIDTH) << rect.height_
1878 << "]"
1879 << std::endl;
1880 }
1881
DumpAllAppSessionInfo(std::ostringstream & oss)1882 void SceneSessionManager::DumpAllAppSessionInfo(std::ostringstream& oss)
1883 {
1884 oss << std::endl << "Current mission lists:" << std::endl;
1885 oss << " MissionList Type #NORMAL" << std::endl;
1886 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1887 for (const auto& elem : sceneSessionMap_) {
1888 auto curSession = elem.second;
1889 if (curSession == nullptr) {
1890 WLOGFW("curSession is nullptr");
1891 continue;
1892 }
1893 if (curSession->GetSessionInfo().isSystem_ ||
1894 curSession->GetWindowType() < WindowType::APP_MAIN_WINDOW_BASE ||
1895 curSession->GetWindowType() >= WindowType::APP_MAIN_WINDOW_END) {
1896 WLOGFW("No need to dump, id: %{public}d, isSystem: %{public}d, windowType: %{public}d",
1897 curSession->GetPersistentId(), curSession->GetSessionInfo().isSystem_, curSession->GetWindowType());
1898 continue;
1899 }
1900
1901 const auto& sessionInfo = curSession->GetSessionInfo();
1902 std::string isActive = curSession->IsActive() ? "FOREGROUND" : "BACKGROUND";
1903 oss << " Mission ID #" << curSession->GetPersistentId() << " mission name #" << "[#"
1904 << sessionInfo.bundleName_ << ":" << sessionInfo.moduleName_ << ":" << sessionInfo.abilityName_
1905 << "]" << " lockedState #0" << std::endl;
1906 oss << " app name [" << sessionInfo.bundleName_ << "]" << std::endl;
1907 oss << " main name [" << sessionInfo.abilityName_ << "]" << std::endl;
1908 oss << " bundle name [" << sessionInfo.bundleName_ << "]" << std::endl;
1909 oss << " ability type [PAGE]" << std::endl;
1910 oss << " state #" << isActive.c_str() << std::endl;
1911 oss << " app state #" << isActive.c_str() << std::endl;
1912 oss << " callee connections:" << std::endl;
1913 }
1914 }
1915
GetAllSessionDumpInfo(std::string & dumpInfo)1916 WSError SceneSessionManager::GetAllSessionDumpInfo(std::string& dumpInfo)
1917 {
1918 int32_t screenGroupId = 0;
1919 std::ostringstream oss;
1920 oss << "-------------------------------------ScreenGroup " << screenGroupId
1921 << "-------------------------------------" << std::endl;
1922 oss << "WindowName DisplayId Pid WinId Type Mode Flag ZOrd Orientation [ x y w h ]"
1923 << std::endl;
1924
1925 std::vector<sptr<SceneSession>> allSession;
1926 std::vector<sptr<SceneSession>> backgroundSession;
1927 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
1928 for (const auto& elem : sceneSessionMap_) {
1929 auto curSession = elem.second;
1930 if (curSession == nullptr) {
1931 continue;
1932 }
1933 if (IsSessionVisible(curSession)) {
1934 allSession.push_back(curSession);
1935 } else {
1936 backgroundSession.push_back(curSession);
1937 }
1938 }
1939 lock.unlock();
1940 allSession.insert(allSession.end(), backgroundSession.begin(), backgroundSession.end());
1941 uint32_t count = 0;
1942 for (const auto& session : allSession) {
1943 if (session == nullptr) {
1944 continue;
1945 }
1946 if (count == static_cast<uint32_t>(allSession.size() - backgroundSession.size())) {
1947 oss << "---------------------------------------------------------------------------------------"
1948 << std::endl;
1949 }
1950 DumpSessionInfo(session, oss);
1951 count++;
1952 }
1953 oss << "Focus window: " << GetFocusedSession() << std::endl;
1954 oss << "Total window num: " << sceneSessionMap_.size() << std::endl;
1955 DumpAllAppSessionInfo(oss);
1956 dumpInfo.append(oss.str());
1957 return WSError::WS_OK;
1958 }
1959
SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc & func)1960 void SceneSessionManager::SetDumpRootSceneElementInfoListener(const DumpRootSceneElementInfoFunc& func)
1961 {
1962 dumpRootSceneFunc_ = func;
1963 }
1964
DumpSessionElementInfo(const sptr<SceneSession> & session,const std::vector<std::string> & params,std::string & dumpInfo)1965 void SceneSessionManager::DumpSessionElementInfo(const sptr<SceneSession>& session,
1966 const std::vector<std::string>& params, std::string& dumpInfo)
1967 {
1968 std::vector<std::string> resetParams;
1969 resetParams.assign(params.begin() + 2, params.end()); // 2: params num
1970 if (resetParams.empty()) {
1971 WLOGI("do not dump ui info");
1972 return;
1973 }
1974
1975 if (!session->GetSessionInfo().isSystem_) {
1976 WLOGFI("Dump normal session, not system");
1977 dumpInfoFuture_.ResetLock({});
1978 session->DumpSessionElementInfo(resetParams);
1979 std::vector<std::string> infos = dumpInfoFuture_.GetResult(2000); // 2000: wait for 2000ms
1980 for (auto& info: infos) {
1981 dumpInfo.append(info).append("\n");
1982 }
1983 } else {
1984 WLOGFI("Dump system session");
1985 std::vector<std::string> infos;
1986 dumpRootSceneFunc_(resetParams, infos);
1987 for (auto& info: infos) {
1988 dumpInfo.append(info).append("\n");
1989 }
1990 }
1991 }
1992
GetSpecifiedSessionDumpInfo(std::string & dumpInfo,const std::vector<std::string> & params,const std::string & strId)1993 WSError SceneSessionManager::GetSpecifiedSessionDumpInfo(std::string& dumpInfo, const std::vector<std::string>& params,
1994 const std::string& strId)
1995 {
1996 uint64_t persistentId = std::stoull(strId);
1997 auto session = GetSceneSession(persistentId);
1998 if (session == nullptr) {
1999 return WSError::WS_ERROR_INVALID_PARAM;
2000 }
2001
2002 WSRect rect = session->GetSessionRect();
2003 std::string isShown_ = "-";
2004 std::string isVisible = session->GetVisible() ? "true" : "false";
2005 std::string Focusable = session->GetFocusable() ? "true" : "false";
2006 std::string DecoStatus = session->GetSessionProperty()->IsDecorEnable() ? "true" : "false";
2007 bool PrivacyMode = session->GetSessionProperty()->GetSystemPrivacyMode() ||
2008 session->GetSessionProperty()->GetPrivacyMode();
2009 std::string isPrivacyMode = PrivacyMode ? "true" : "false";
2010 bool isFirstFrameAvailable = true;
2011 std::ostringstream oss;
2012 oss << "WindowName: " << session->GetWindowName() << std::endl;
2013 oss << "DisplayId: " << 0 << std::endl;
2014 oss << "WinId: " << session->GetPersistentId() << std::endl;
2015 oss << "Pid: " << session->GetCallingPid() << std::endl;
2016 oss << "Type: " << static_cast<uint32_t>(session->GetWindowType()) << std::endl;
2017 oss << "Mode: " << static_cast<uint32_t>(session->GetWindowMode()) << std::endl;
2018 oss << "Flag: " << session->GetSessionProperty()->GetWindowFlags() << std::endl;
2019 oss << "Orientation: " << static_cast<uint32_t>(session->GetRequestedOrientation()) << std::endl;
2020 oss << "IsStartingWindow: " << isShown_ << std::endl;
2021 oss << "FirstFrameCallbackCalled: " << isFirstFrameAvailable << std::endl;
2022 oss << "IsVisible: " << isVisible << std::endl;
2023 oss << "Focusable: " << Focusable << std::endl;
2024 oss << "DecoStatus: " << DecoStatus << std::endl;
2025 oss << "isPrivacyMode: " << isPrivacyMode << std::endl;
2026 oss << "WindowRect: " << "[ "
2027 << rect.posX_ << ", " << rect.posY_ << ", " << rect.width_ << ", " << rect.height_
2028 << " ]" << std::endl;
2029 oss << "TouchHotAreas: ";
2030 std::vector<Rect> touchHotAreas;
2031 oss << std::endl;
2032 dumpInfo.append(oss.str());
2033
2034 DumpSessionElementInfo(session, params, dumpInfo);
2035 return WSError::WS_OK;
2036 }
2037
NotifyDumpInfoResult(const std::vector<std::string> & info)2038 void SceneSessionManager::NotifyDumpInfoResult(const std::vector<std::string>& info)
2039 {
2040 dumpInfoFuture_.SetValue(info);
2041 WLOGFD("NotifyDumpInfoResult");
2042 }
2043
GetSessionDumpInfo(const std::vector<std::string> & params,std::string & dumpInfo)2044 WSError SceneSessionManager::GetSessionDumpInfo(const std::vector<std::string>& params, std::string& dumpInfo)
2045 {
2046 if (params.size() == 1 && params[0] == ARG_DUMP_ALL) { // 1: params num
2047 return GetAllSessionDumpInfo(dumpInfo);
2048 }
2049 if (params.size() >= 2 && params[0] == ARG_DUMP_WINDOW && IsValidDigitString(params[1])) { // 2: params num
2050 return GetSpecifiedSessionDumpInfo(dumpInfo, params, params[1]);
2051 }
2052 return WSError::WS_ERROR_INVALID_OPERATION;
2053 }
2054
UpdateFocus(int32_t persistentId,bool isFocused)2055 WSError SceneSessionManager::UpdateFocus(int32_t persistentId, bool isFocused)
2056 {
2057 auto task = [this, persistentId, isFocused]() {
2058 WLOGFD("Update focus, id: %{public}d, isFocused: %{public}u", persistentId, static_cast<uint32_t>(isFocused));
2059 // notify session and client
2060 auto sceneSession = GetSceneSession(persistentId);
2061 if (sceneSession == nullptr) {
2062 WLOGFE("could not find window");
2063 return WSError::WS_ERROR_INVALID_WINDOW;
2064 }
2065 // focusId change
2066 if (isFocused) {
2067 SetFocusedSession(persistentId);
2068 UpdateBrightness(focusedSessionId_);
2069 // notify RS
2070 WLOGFD("current focus session: windowId: %{public}d, windowName: %{public}s, bundleName: %{public}s,"
2071 " abilityName: %{public}s, pid: %{public}d, uid: %{public}d", persistentId,
2072 sceneSession->GetWindowSessionProperty()->GetWindowName().c_str(),
2073 sceneSession->GetSessionInfo().bundleName_.c_str(),
2074 sceneSession->GetSessionInfo().abilityName_.c_str(),
2075 sceneSession->GetCallingPid(), sceneSession->GetCallingUid());
2076 uint64_t focusNodeId = 0; // 0 means invalid
2077 if (sceneSession->GetSurfaceNode() == nullptr) {
2078 WLOGFW("focused window surfaceNode is null");
2079 } else {
2080 focusNodeId = sceneSession->GetSurfaceNode()->GetId();
2081 }
2082 FocusAppInfo appInfo = {
2083 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(),
2084 sceneSession->GetSessionInfo().bundleName_, sceneSession->GetSessionInfo().abilityName_,
2085 focusNodeId
2086 };
2087 RSInterfaces::GetInstance().SetFocusAppInfo(appInfo);
2088 } else if (persistentId == GetFocusedSession()) {
2089 SetFocusedSession(INVALID_SESSION_ID);
2090 }
2091 // notify window manager
2092 sptr<FocusChangeInfo> focusChangeInfo = new FocusChangeInfo(
2093 sceneSession->GetWindowId(),
2094 static_cast<DisplayId>(0),
2095 sceneSession->GetCallingPid(),
2096 sceneSession->GetCallingUid(),
2097 sceneSession->GetWindowType(),
2098 sceneSession->GetAbilityToken()
2099 );
2100 SessionManagerAgentController::GetInstance().UpdateFocusChangeInfo(focusChangeInfo, isFocused);
2101 WSError res = WSError::WS_OK;
2102 res = sceneSession->UpdateFocus(isFocused);
2103 if (res != WSError::WS_OK) {
2104 return res;
2105 }
2106 if (listenerController_ != nullptr) {
2107 if (isFocused) {
2108 WLOGFD("NotifySessionFocused, id: %{public}d", sceneSession->GetPersistentId());
2109 listenerController_->NotifySessionFocused(sceneSession->GetPersistentId());
2110 } else {
2111 WLOGFD("NotifySessionUnfocused, id: %{public}d", sceneSession->GetPersistentId());
2112 listenerController_->NotifySessionUnfocused(sceneSession->GetPersistentId());
2113 }
2114 }
2115 if (windowFocusChangedFunc_ != nullptr) {
2116 windowFocusChangedFunc_(persistentId, isFocused);
2117 }
2118 return WSError::WS_OK;
2119 };
2120
2121 taskScheduler_->PostAsyncTask(task);
2122 return WSError::WS_OK;
2123 }
2124
UpdateWindowMode(int32_t persistentId,int32_t windowMode)2125 WSError SceneSessionManager::UpdateWindowMode(int32_t persistentId, int32_t windowMode)
2126 {
2127 WLOGFD("update window mode, id: %{public}d, mode: %{public}d", persistentId, windowMode);
2128 auto sceneSession = GetSceneSession(persistentId);
2129 if (sceneSession == nullptr) {
2130 WLOGFE("could not find window");
2131 return WSError::WS_ERROR_INVALID_WINDOW;
2132 }
2133 WindowMode mode = static_cast<WindowMode>(windowMode);
2134 return sceneSession->UpdateWindowMode(mode);
2135 }
2136
RegisterWindowFocusChanged(const WindowFocusChangedFunc & func)2137 void SceneSessionManager::RegisterWindowFocusChanged(const WindowFocusChangedFunc& func)
2138 {
2139 WLOGFE("RegisterWindowFocusChanged in");
2140 windowFocusChangedFunc_ = func;
2141 }
2142
UpdatePrivateStateAndNotify(bool isAddingPrivateSession)2143 void SceneSessionManager::UpdatePrivateStateAndNotify(bool isAddingPrivateSession)
2144 {
2145 auto screenSession = ScreenSessionManager::GetInstance().GetScreenSession(0);
2146 if (screenSession == nullptr) {
2147 WLOGFE("screen session is null");
2148 return;
2149 }
2150 ScreenSessionManager::GetInstance().UpdatePrivateStateAndNotify(screenSession, isAddingPrivateSession);
2151 }
2152
RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession> & sceneSession)2153 void SceneSessionManager::RegisterSessionStateChangeNotifyManagerFunc(sptr<SceneSession>& sceneSession)
2154 {
2155 NotifySessionStateChangeNotifyManagerFunc func = [this](int32_t persistentId, const SessionState& state) {
2156 this->OnSessionStateChange(persistentId, state);
2157 };
2158 if (sceneSession == nullptr) {
2159 WLOGFE("session is nullptr");
2160 return;
2161 }
2162 sceneSession->SetSessionStateChangeNotifyManagerListener(func);
2163 WLOGFD("RegisterSessionStateChangeFunc success");
2164 }
2165
OnSessionStateChange(int32_t persistentId,const SessionState & state)2166 void SceneSessionManager::OnSessionStateChange(int32_t persistentId, const SessionState& state)
2167 {
2168 WLOGFD("Session state change, id: %{public}d", persistentId);
2169 auto sceneSession = GetSceneSession(persistentId);
2170 if (sceneSession == nullptr) {
2171 WLOGFD("session is nullptr");
2172 return;
2173 }
2174 switch (state) {
2175 case SessionState::STATE_FOREGROUND:
2176 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_ADDED);
2177 HandleKeepScreenOn(sceneSession, sceneSession->IsKeepScreenOn());
2178 if (sceneSession->GetWindowSessionProperty()->GetPrivacyMode()) {
2179 UpdatePrivateStateAndNotify(true);
2180 }
2181 break;
2182 case SessionState::STATE_BACKGROUND:
2183 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_REMOVED);
2184 HandleKeepScreenOn(sceneSession, false);
2185 if (sceneSession->GetWindowSessionProperty()->GetPrivacyMode()) {
2186 UpdatePrivateStateAndNotify(false);
2187 }
2188 break;
2189 default:
2190 break;
2191 }
2192 }
2193
SetWaterMarkSessionCount(int32_t count)2194 void SceneSessionManager::SetWaterMarkSessionCount(int32_t count)
2195 {
2196 waterMarkSessionCount_ = count;
2197 }
2198
GetWaterMarkSessionCount() const2199 int32_t SceneSessionManager::GetWaterMarkSessionCount() const
2200 {
2201 return waterMarkSessionCount_;
2202 }
2203
SetWindowFlags(const sptr<SceneSession> & sceneSession,uint32_t flags)2204 WSError SceneSessionManager::SetWindowFlags(const sptr<SceneSession>& sceneSession, uint32_t flags)
2205 {
2206 if (sceneSession == nullptr) {
2207 WLOGFD("session is nullptr");
2208 return WSError::WS_ERROR_NULLPTR;
2209 }
2210 auto property = sceneSession->GetWindowSessionProperty();
2211 if (property == nullptr) {
2212 return WSError::WS_ERROR_NULLPTR;
2213 }
2214 uint32_t oldFlags = property->GetWindowFlags();
2215 property->SetWindowFlags(flags);
2216 // notify when visibility change
2217 if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) {
2218 CheckAndNotifyWaterMarkChangedResult(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK));
2219 }
2220 if ((oldFlags ^ flags) == static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED)) {
2221 sceneSession->OnShowWhenLocked(flags & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED));
2222 }
2223 WLOGFI("SetWindowFlags end, flags: %{public}u", flags);
2224 return WSError::WS_OK;
2225 }
2226
CheckAndNotifyWaterMarkChangedResult(bool isAddingWaterMark)2227 void SceneSessionManager::CheckAndNotifyWaterMarkChangedResult(bool isAddingWaterMark)
2228 {
2229 int32_t preWaterMarkSessionCount = GetWaterMarkSessionCount();
2230 WLOGFD("before update : water mark count: %{public}u", preWaterMarkSessionCount);
2231 SetWaterMarkSessionCount(preWaterMarkSessionCount + (isAddingWaterMark ? 1 : -1));
2232 if (preWaterMarkSessionCount == 0 && isAddingWaterMark) {
2233 NotifyWaterMarkFlagChangedResult(true);
2234 return;
2235 }
2236 if (preWaterMarkSessionCount == 1 && !isAddingWaterMark) {
2237 NotifyWaterMarkFlagChangedResult(false);
2238 return;
2239 }
2240 }
2241
NotifyWaterMarkFlagChangedResult(bool hasWaterMark)2242 WSError SceneSessionManager::NotifyWaterMarkFlagChangedResult(bool hasWaterMark)
2243 {
2244 WLOGFI("WaterMark status : %{public}u", static_cast<uint32_t>(hasWaterMark));
2245 SessionManagerAgentController::GetInstance().NotifyWaterMarkFlagChangedResult(hasWaterMark);
2246 return WSError::WS_OK;
2247 }
2248
ProcessPreload(const AppExecFwk::AbilityInfo & abilityInfo) const2249 void SceneSessionManager::ProcessPreload(const AppExecFwk::AbilityInfo &abilityInfo) const
2250 {
2251 if (!bundleMgr_) {
2252 WLOGFE("bundle manager is nullptr.");
2253 return;
2254 }
2255
2256 AAFwk::Want want;
2257 want.SetElementName(abilityInfo.deviceId, abilityInfo.bundleName, abilityInfo.name, abilityInfo.moduleName);
2258 auto uid = abilityInfo.uid;
2259 want.SetParam("uid", uid);
2260 bundleMgr_->ProcessPreload(want);
2261 }
2262
NotifyCompleteFirstFrameDrawing(int32_t persistentId)2263 void SceneSessionManager::NotifyCompleteFirstFrameDrawing(int32_t persistentId)
2264 {
2265 WLOGFI("NotifyCompleteFirstFrameDrawing, persistentId: %{public}d", persistentId);
2266 auto scnSession = GetSceneSession(persistentId);
2267 if (scnSession == nullptr) {
2268 return;
2269 }
2270 auto abilityInfoPtr = scnSession->GetSessionInfo().abilityInfo;
2271 if (abilityInfoPtr == nullptr) {
2272 return;
2273 }
2274 if ((listenerController_ != nullptr) && !(abilityInfoPtr->excludeFromMissions)) {
2275 WLOGFD("NotifySessionCreated, id: %{public}d", persistentId);
2276 listenerController_->NotifySessionCreated(persistentId);
2277 }
2278
2279 if (taskScheduler_ == nullptr) {
2280 return;
2281 }
2282 auto task = [this, abilityInfoPtr]() {
2283 ProcessPreload(*abilityInfoPtr);
2284 };
2285 return taskScheduler_->PostAsyncTask(task);
2286 }
2287
NotifySessionMovedToFront(int32_t persistentId)2288 void SceneSessionManager::NotifySessionMovedToFront(int32_t persistentId)
2289 {
2290 WLOGFI("NotifySessionMovedToFront, persistentId: %{public}d", persistentId);
2291 auto scnSession = GetSceneSession(persistentId);
2292 if (!scnSession && listenerController_ != nullptr &&
2293 (scnSession->GetSessionInfo().abilityInfo) != nullptr &&
2294 !(scnSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
2295 listenerController_->NotifySessionMovedToFront(persistentId);
2296 }
2297 }
2298
SetSessionLabel(const sptr<IRemoteObject> & token,const std::string & label)2299 WSError SceneSessionManager::SetSessionLabel(const sptr<IRemoteObject> &token, const std::string &label)
2300 {
2301 WLOGFI("run SetSessionLabel");
2302 if (sessionListener_ == nullptr) {
2303 WLOGFI("sessionListener not register, skip.");
2304 return WSError::WS_OK;
2305 }
2306 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2307 for (auto iter : sceneSessionMap_) {
2308 auto& sceneSession = iter.second;
2309 if (sceneSession->GetAbilityToken() == token) {
2310 WLOGFI("try to update session label.");
2311 sessionListener_->OnSessionLabelChange(iter.first, label);
2312 if (listenerController_ != nullptr) {
2313 WLOGFD("NotifySessionLabelUpdated, id: %{public}d", iter.first);
2314 listenerController_->NotifySessionLabelUpdated(iter.first);
2315 }
2316 return WSError::WS_OK;
2317 }
2318 }
2319 return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
2320 }
2321
SetSessionIcon(const sptr<IRemoteObject> & token,const std::shared_ptr<Media::PixelMap> & icon)2322 WSError SceneSessionManager::SetSessionIcon(const sptr<IRemoteObject> &token,
2323 const std::shared_ptr<Media::PixelMap> &icon)
2324 {
2325 WLOGFI("run SetSessionIcon");
2326 if (sessionListener_ == nullptr) {
2327 WLOGFI("sessionListener not register, skip.");
2328 return WSError::WS_OK;
2329 }
2330 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2331 for (auto iter : sceneSessionMap_) {
2332 auto& sceneSession = iter.second;
2333 if (sceneSession->GetAbilityToken() == token) {
2334 WLOGFI("try to update session icon.");
2335 sessionListener_->OnSessionIconChange(iter.first, icon);
2336 if (listenerController_ != nullptr &&
2337 (sceneSession->GetSessionInfo().abilityInfo) != nullptr &&
2338 !(sceneSession->GetSessionInfo().abilityInfo)->excludeFromMissions) {
2339 WLOGFD("NotifySessionIconChanged, id: %{public}d", iter.first);
2340 listenerController_->NotifySessionIconChanged(iter.first, icon);
2341 }
2342 return WSError::WS_OK;
2343 }
2344 }
2345 return WSError::WS_ERROR_SET_SESSION_ICON_FAILED;
2346 }
2347
IsValidSessionIds(const std::vector<int32_t> & sessionIds,std::vector<bool> & results)2348 WSError SceneSessionManager::IsValidSessionIds(
2349 const std::vector<int32_t> &sessionIds, std::vector<bool> &results)
2350 {
2351 WLOGFI("run IsValidSessionIds");
2352 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2353 for (auto i = 0; i < static_cast<int32_t>(sessionIds.size()); ++i) {
2354 auto search = sceneSessionMap_.find(sessionIds.at(i));
2355 if (search == sceneSessionMap_.end() || search->second == nullptr) {
2356 results.push_back(false);
2357 continue;
2358 }
2359 results.push_back(true);
2360 }
2361 return WSError::WS_OK;
2362 }
2363
RegisterSessionListener(const sptr<ISessionListener> & listener)2364 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionListener>& listener)
2365 {
2366 WLOGFI("run RegisterSessionListener");
2367 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
2368 WLOGFE("The caller is not system-app, can not use system-api");
2369 return WSError::WS_ERROR_NOT_SYSTEM_APP;
2370 }
2371 if (!SessionPermission::VerifySessionPermission()) {
2372 WLOGFE("The caller has not permission granted");
2373 return WSError::WS_ERROR_INVALID_PERMISSION;
2374 }
2375 auto task = [this, &listener]() {
2376 return listenerController_->AddSessionListener(listener);
2377 };
2378 return taskScheduler_->PostSyncTask(task);
2379 }
2380
UnRegisterSessionListener(const sptr<ISessionListener> & listener)2381 WSError SceneSessionManager::UnRegisterSessionListener(const sptr<ISessionListener>& listener)
2382 {
2383 WLOGFI("run UnRegisterSessionListener");
2384 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
2385 WLOGFE("The caller is not system-app, can not use system-api");
2386 return WSError::WS_ERROR_NOT_SYSTEM_APP;
2387 }
2388 if (!SessionPermission::VerifySessionPermission()) {
2389 WLOGFE("The caller has not permission granted");
2390 return WSError::WS_ERROR_INVALID_PERMISSION;
2391 }
2392 auto task = [this, &listener]() {
2393 listenerController_->DelSessionListener(listener);
2394 return WSError::WS_OK;
2395 };
2396 return taskScheduler_->PostSyncTask(task);
2397 }
2398
GetSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)2399 WSError SceneSessionManager::GetSessionInfos(const std::string& deviceId, int32_t numMax,
2400 std::vector<SessionInfoBean>& sessionInfos)
2401 {
2402 WLOGFI("run GetSessionInfos");
2403 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
2404 WLOGFE("The caller is not system-app, can not use system-api");
2405 return WSError::WS_ERROR_NOT_SYSTEM_APP;
2406 }
2407 if (!SessionPermission::VerifySessionPermission()) {
2408 WLOGFE("The caller has not permission granted");
2409 return WSError::WS_ERROR_INVALID_PERMISSION;
2410 }
2411 auto task = [this, &deviceId, numMax, &sessionInfos]() {
2412 if (CheckIsRemote(deviceId)) {
2413 int ret = GetRemoteSessionInfos(deviceId, numMax, sessionInfos);
2414 if (ret != ERR_OK) {
2415 return WSError::WS_ERROR_INVALID_PARAM;
2416 } else {
2417 return WSError::WS_OK;
2418 }
2419 }
2420 std::map<int32_t, sptr<SceneSession>>::iterator iter;
2421 std::vector<sptr<SceneSession>> sceneSessionInfos;
2422 for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
2423 if (static_cast<int>(sceneSessionInfos.size()) >= numMax) {
2424 break;
2425 }
2426 sceneSessionInfos.emplace_back(iter->second);
2427 }
2428 return SceneSessionConverter::ConvertToMissionInfos(sceneSessionInfos, sessionInfos);
2429 };
2430 return taskScheduler_->PostSyncTask(task);
2431 }
2432
GetRemoteSessionInfos(const std::string & deviceId,int32_t numMax,std::vector<SessionInfoBean> & sessionInfos)2433 int SceneSessionManager::GetRemoteSessionInfos(const std::string& deviceId, int32_t numMax,
2434 std::vector<SessionInfoBean>& sessionInfos)
2435 {
2436 WLOGFI("GetRemoteSessionInfos From Dms begin");
2437 DistributedClient dmsClient;
2438 int result = dmsClient.GetMissionInfos(deviceId, numMax, sessionInfos);
2439 if (result != ERR_OK) {
2440 WLOGFE("GetRemoteMissionInfos failed, result = %{public}d", result);
2441 return result;
2442 }
2443 return ERR_OK;
2444 }
2445
GetSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)2446 WSError SceneSessionManager::GetSessionInfo(const std::string& deviceId,
2447 int32_t persistentId, SessionInfoBean& sessionInfo)
2448 {
2449 WLOGFI("run GetSessionInfo");
2450 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
2451 WLOGFE("The caller is not system-app, can not use system-api");
2452 return WSError::WS_ERROR_NOT_SYSTEM_APP;
2453 }
2454 if (!SessionPermission::VerifySessionPermission()) {
2455 WLOGFE("The caller has not permission granted");
2456 return WSError::WS_ERROR_INVALID_PERMISSION;
2457 }
2458 auto task = [this, &deviceId, persistentId, &sessionInfo]() {
2459 if (CheckIsRemote(deviceId)) {
2460 int ret = GetRemoteSessionInfo(deviceId, persistentId, sessionInfo);
2461 if (ret != ERR_OK) {
2462 return WSError::WS_ERROR_INVALID_PARAM;
2463 } else {
2464 return WSError::WS_OK;
2465 }
2466 }
2467 std::map<int32_t, sptr<SceneSession>>::iterator iter;
2468 iter = sceneSessionMap_.find(persistentId);
2469 if (iter != sceneSessionMap_.end()) {
2470 return SceneSessionConverter::ConvertToMissionInfo(iter->second, sessionInfo);
2471 }
2472 return WSError::WS_OK;
2473 };
2474 return taskScheduler_->PostSyncTask(task);
2475 }
2476
GetRemoteSessionInfo(const std::string & deviceId,int32_t persistentId,SessionInfoBean & sessionInfo)2477 int SceneSessionManager::GetRemoteSessionInfo(const std::string& deviceId,
2478 int32_t persistentId, SessionInfoBean& sessionInfo)
2479 {
2480 WLOGFI("GetRemoteSessionInfoFromDms begin");
2481 std::vector<SessionInfoBean> sessionVector;
2482 int result = GetRemoteSessionInfos(deviceId, MAX_NUMBER_OF_DISTRIBUTED_SESSIONS, sessionVector);
2483 if (result != ERR_OK) {
2484 return result;
2485 }
2486 for (auto iter = sessionVector.begin(); iter != sessionVector.end(); iter++) {
2487 if (iter->id == persistentId) {
2488 sessionInfo = *iter;
2489 return ERR_OK;
2490 }
2491 }
2492 WLOGFW("missionId not found");
2493 return ERR_INVALID_VALUE;
2494 }
2495
CheckIsRemote(const std::string & deviceId)2496 bool SceneSessionManager::CheckIsRemote(const std::string& deviceId)
2497 {
2498 if (deviceId.empty()) {
2499 WLOGFI("CheckIsRemote: deviceId is empty.");
2500 return false;
2501 }
2502 std::string localDeviceId;
2503 if (!GetLocalDeviceId(localDeviceId)) {
2504 WLOGFE("CheckIsRemote: get local deviceId failed");
2505 return false;
2506 }
2507 if (localDeviceId == deviceId) {
2508 WLOGFI("CheckIsRemote: deviceId is local.");
2509 return false;
2510 }
2511 WLOGFD("CheckIsRemote, deviceId = %{public}s", AnonymizeDeviceId(deviceId).c_str());
2512 return true;
2513 }
2514
GetLocalDeviceId(std::string & localDeviceId)2515 bool SceneSessionManager::GetLocalDeviceId(std::string& localDeviceId)
2516 {
2517 auto localNode = std::make_unique<NodeBasicInfo>();
2518 int32_t errCode = GetLocalNodeDeviceInfo(DM_PKG_NAME.c_str(), localNode.get());
2519 if (errCode != ERR_OK) {
2520 WLOGFE("GetLocalNodeDeviceInfo errCode = %{public}d", errCode);
2521 return false;
2522 }
2523 if (localNode != nullptr) {
2524 localDeviceId = localNode->networkId;
2525 WLOGFD("get local deviceId, deviceId = %{public}s", AnonymizeDeviceId(localDeviceId).c_str());
2526 return true;
2527 }
2528 WLOGFE("localDeviceId null");
2529 return false;
2530 }
2531
AnonymizeDeviceId(const std::string & deviceId)2532 std::string SceneSessionManager::AnonymizeDeviceId(const std::string& deviceId)
2533 {
2534 if (deviceId.length() < NON_ANONYMIZE_LENGTH) {
2535 return EMPTY_DEVICE_ID;
2536 }
2537 std::string anonDeviceId = deviceId.substr(0, NON_ANONYMIZE_LENGTH);
2538 anonDeviceId.append("******");
2539 return anonDeviceId;
2540 }
2541
GetAllAbilityInfos(const AAFwk::Want & want,int32_t userId,std::vector<AppExecFwk::AbilityInfo> & abilityInfos)2542 WSError SceneSessionManager::GetAllAbilityInfos(const AAFwk::Want &want, int32_t userId,
2543 std::vector<AppExecFwk::AbilityInfo> &abilityInfos)
2544 {
2545 if (bundleMgr_ == nullptr) {
2546 WLOGFE("bundleMgr_ is nullptr");
2547 return WSError::WS_ERROR_NULLPTR;
2548 }
2549 auto ret = bundleMgr_->QueryAllAbilityInfos(want, userId, abilityInfos);
2550 if (!ret) {
2551 WLOGFE("Query all ability infos from BMS failed!");
2552 return WSError::WS_ERROR_INVALID_PARAM;
2553 }
2554 return WSError::WS_OK;
2555 }
2556
TerminateSessionNew(const sptr<AAFwk::SessionInfo> info,bool needStartCaller)2557 WSError SceneSessionManager::TerminateSessionNew(const sptr<AAFwk::SessionInfo> info, bool needStartCaller)
2558 {
2559 WLOGFI("run SetSessionIcon");
2560 if (info == nullptr) {
2561 WLOGFI("sessionInfo is nullptr.");
2562 return WSError::WS_ERROR_INVALID_PARAM;
2563 }
2564 sptr<SceneSession> sceneSession = FindSessionByToken(info->sessionToken);
2565 if (sceneSession == nullptr) {
2566 WLOGFI("fail to find session by token.");
2567 return WSError::WS_ERROR_INVALID_PARAM;
2568 }
2569 const WSError& errCode = sceneSession->TerminateSessionNew(info, needStartCaller);
2570 return errCode;
2571 }
2572
GetSessionSnapshot(const std::string & deviceId,int32_t persistentId,std::shared_ptr<Media::PixelMap> & snapshot,bool isLowResolution)2573 WSError SceneSessionManager::GetSessionSnapshot(const std::string& deviceId, int32_t persistentId,
2574 std::shared_ptr<Media::PixelMap>& snapshot, bool isLowResolution)
2575 {
2576 WLOGFI("run GetSessionSnapshot");
2577 if (!SessionPermission::JudgeCallerIsAllowedToUseSystemAPI()) {
2578 WLOGFE("The caller is not system-app, can not use system-api");
2579 return WSError::WS_ERROR_NOT_SYSTEM_APP;
2580 }
2581 if (!SessionPermission::VerifySessionPermission()) {
2582 WLOGFE("The caller has not permission granted");
2583 return WSError::WS_ERROR_INVALID_PERMISSION;
2584 }
2585 auto task = [this, &deviceId, persistentId, &snapshot, isLowResolution]() {
2586 if (CheckIsRemote(deviceId)) {
2587 WLOGFI("get remote session snapshot.");
2588 std::unique_ptr<AAFwk::MissionSnapshot> missionSnapshotPtr = std::make_unique<AAFwk::MissionSnapshot>();
2589 int ret = GetRemoteSessionSnapshotInfo(deviceId, persistentId, *missionSnapshotPtr);
2590 if (ret != ERR_OK) {
2591 return WSError::WS_ERROR_INVALID_PARAM;
2592 } else {
2593 snapshot = missionSnapshotPtr->snapshot;
2594 return WSError::WS_OK;
2595 }
2596 }
2597 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
2598 if (!sceneSession) {
2599 WLOGFE("fail to find session by persistentId: %{public}d", persistentId);
2600 return WSError::WS_ERROR_INVALID_PARAM;
2601 }
2602 auto oriSnapshot = sceneSession->Snapshot();
2603 if (oriSnapshot != nullptr) {
2604 if (isLowResolution) {
2605 OHOS::Media::InitializationOptions options;
2606 options.size.width = oriSnapshot->GetWidth() / 2; // low resolution ratio
2607 options.size.height = oriSnapshot->GetHeight() / 2; // low resolution ratio
2608 std::unique_ptr<OHOS::Media::PixelMap> reducedPixelMap = OHOS::Media::PixelMap::Create(*oriSnapshot, options);
2609 snapshot = std::shared_ptr<OHOS::Media::PixelMap>(reducedPixelMap.release());
2610 } else {
2611 snapshot = oriSnapshot;
2612 }
2613 }
2614 return WSError::WS_OK;
2615 };
2616 return taskScheduler_->PostSyncTask(task);
2617 }
2618
GetRemoteSessionSnapshotInfo(const std::string & deviceId,int32_t sessionId,AAFwk::MissionSnapshot & sessionSnapshot)2619 int SceneSessionManager::GetRemoteSessionSnapshotInfo(const std::string& deviceId, int32_t sessionId,
2620 AAFwk::MissionSnapshot& sessionSnapshot)
2621 {
2622 WLOGFI("GetRemoteSessionSnapshotInfo begin");
2623 std::unique_ptr<AAFwk::MissionSnapshot> sessionSnapshotPtr = std::make_unique<AAFwk::MissionSnapshot>();
2624 DistributedClient dmsClient;
2625 int result = dmsClient.GetRemoteMissionSnapshotInfo(deviceId, sessionId, sessionSnapshotPtr);
2626 if (result != ERR_OK) {
2627 WLOGFE("GetRemoteMissionSnapshotInfo failed, result = %{public}d", result);
2628 return result;
2629 }
2630 sessionSnapshot = *sessionSnapshotPtr;
2631 return ERR_OK;
2632 }
2633
RegisterSessionListener(const sptr<ISessionChangeListener> sessionListener)2634 WSError SceneSessionManager::RegisterSessionListener(const sptr<ISessionChangeListener> sessionListener)
2635 {
2636 WLOGFI("run RegisterSessionListener");
2637 if (sessionListener == nullptr) {
2638 return WSError::WS_ERROR_INVALID_SESSION_LISTENER;
2639 }
2640 sessionListener_ = sessionListener;
2641 return WSError::WS_OK;
2642 }
2643
UnregisterSessionListener()2644 void SceneSessionManager::UnregisterSessionListener()
2645 {
2646 WLOGFI("run UnregisterSessionListener");
2647 sessionListener_ = nullptr;
2648 }
2649
RequestSceneSessionByCall(const sptr<SceneSession> & sceneSession)2650 WSError SceneSessionManager::RequestSceneSessionByCall(const sptr<SceneSession>& sceneSession)
2651 {
2652 wptr<SceneSession> weakSceneSession(sceneSession);
2653 auto task = [this, weakSceneSession]() {
2654 auto scnSession = weakSceneSession.promote();
2655 if (scnSession == nullptr) {
2656 WLOGFE("session is nullptr");
2657 return WSError::WS_ERROR_NULLPTR;
2658 }
2659 auto persistentId = scnSession->GetPersistentId();
2660 WLOGFI("RequestSceneSessionByCall persistentId: %{public}d", persistentId);
2661 if (!GetSceneSession(persistentId)) {
2662 WLOGFE("session is invalid with %{public}d", persistentId);
2663 return WSError::WS_ERROR_INVALID_SESSION;
2664 }
2665 auto sessionInfo = scnSession->GetSessionInfo();
2666 WLOGFI("RequestSceneSessionByCall callState:%{public}d, persistentId: %{public}d",
2667 sessionInfo.callState_, persistentId);
2668 auto abilitySessionInfo = SetAbilitySessionInfo(scnSession);
2669 if (!abilitySessionInfo) {
2670 return WSError::WS_ERROR_NULLPTR;
2671 }
2672 if (sessionInfo.callState_ == static_cast<uint32_t>(AAFwk::CallToState::BACKGROUND)) {
2673 scnSession->SetActive(false);
2674 } else if (sessionInfo.callState_ == static_cast<uint32_t>(AAFwk::CallToState::FOREGROUND)) {
2675 scnSession->SetActive(true);
2676 } else {
2677 WLOGFE("wrong callState_");
2678 }
2679
2680 AAFwk::AbilityManagerClient::GetInstance()->CallUIAbilityBySCB(abilitySessionInfo);
2681 return WSError::WS_OK;
2682 };
2683
2684 taskScheduler_->PostAsyncTask(task);
2685 return WSError::WS_OK;
2686 }
2687
StartAbilityBySpecified(const SessionInfo & sessionInfo)2688 void SceneSessionManager::StartAbilityBySpecified(const SessionInfo& sessionInfo)
2689 {
2690 auto task = [this, sessionInfo]() {
2691 WLOGFI("StartAbilityBySpecified: bundleName: %{public}s, moduleName: %{public}s, abilityName: %{public}s",
2692 sessionInfo.bundleName_.c_str(), sessionInfo.moduleName_.c_str(), sessionInfo.abilityName_.c_str());
2693 AAFwk::Want want;
2694 want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
2695 AAFwk::AbilityManagerClient::GetInstance()->StartSpecifiedAbilityBySCB(want);
2696 };
2697
2698 taskScheduler_->PostAsyncTask(task);
2699 }
2700
FindMainWindowWithToken(sptr<IRemoteObject> targetToken)2701 sptr<SceneSession> SceneSessionManager::FindMainWindowWithToken(sptr<IRemoteObject> targetToken)
2702 {
2703 if (!targetToken) {
2704 WLOGFE("Token is null, cannot find main window");
2705 return nullptr;
2706 }
2707
2708 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2709 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(),
2710 [targetToken](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
2711 if (pair.second->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
2712 return pair.second->GetAbilityToken() == targetToken;
2713 }
2714 return false;
2715 });
2716 if (iter == sceneSessionMap_.end()) {
2717 WLOGFE("Cannot find session");
2718 return nullptr;
2719 }
2720 return iter->second;
2721 }
2722
BindDialogTarget(uint64_t persistentId,sptr<IRemoteObject> targetToken)2723 WSError SceneSessionManager::BindDialogTarget(uint64_t persistentId, sptr<IRemoteObject> targetToken)
2724 {
2725 if (targetToken == nullptr) {
2726 WLOGFE("Target token is null");
2727 return WSError::WS_ERROR_NULLPTR;
2728 }
2729 auto scnSession = GetSceneSession(static_cast<int32_t>(persistentId));
2730 if (scnSession == nullptr) {
2731 WLOGFE("Session is nullptr");
2732 return WSError::WS_ERROR_NULLPTR;
2733 }
2734 if (scnSession->GetWindowType() != WindowType::WINDOW_TYPE_DIALOG) {
2735 WLOGFE("Session is not dialog window");
2736 return WSError::WS_OK;
2737 }
2738 scnSession->dialogTargetToken_ = targetToken;
2739 sptr<SceneSession> parentSession = FindMainWindowWithToken(targetToken);
2740 if (parentSession == nullptr) {
2741 scnSession->NotifyDestroy();
2742 return WSError::WS_ERROR_INVALID_PARAM;
2743 }
2744 scnSession->SetParentSession(parentSession);
2745 parentSession->BindDialogTarget(scnSession);
2746 scnSession->SetParentPersistentId(parentSession->GetPersistentId());
2747 UpdateParentSession(scnSession, scnSession->GetSessionProperty());
2748 WLOGFD("Bind dialog success, dialog id %{public}" PRIu64 ", parent id %{public}d",
2749 persistentId, parentSession->GetPersistentId());
2750 return WSError::WS_OK;
2751 }
2752
RegisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)2753 WMError SceneSessionManager::RegisterWindowManagerAgent(WindowManagerAgentType type,
2754 const sptr<IWindowManagerAgent>& windowManagerAgent)
2755 {
2756 if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
2757 WLOGFE("windowManagerAgent is null");
2758 return WMError::WM_ERROR_NULLPTR;
2759 }
2760 auto task = [this, &windowManagerAgent, type]() {
2761 return SessionManagerAgentController::GetInstance().RegisterWindowManagerAgent(windowManagerAgent, type);
2762 };
2763 return taskScheduler_->PostSyncTask(task);
2764 }
2765
UnregisterWindowManagerAgent(WindowManagerAgentType type,const sptr<IWindowManagerAgent> & windowManagerAgent)2766 WMError SceneSessionManager::UnregisterWindowManagerAgent(WindowManagerAgentType type,
2767 const sptr<IWindowManagerAgent>& windowManagerAgent)
2768 {
2769 if ((windowManagerAgent == nullptr) || (windowManagerAgent->AsObject() == nullptr)) {
2770 WLOGFE("windowManagerAgent is null");
2771 return WMError::WM_ERROR_NULLPTR;
2772 }
2773 auto task = [this, &windowManagerAgent, type]() {
2774 return SessionManagerAgentController::GetInstance().UnregisterWindowManagerAgent(windowManagerAgent, type);
2775 };
2776 return taskScheduler_->PostSyncTask(task);
2777 }
2778
UpdateCameraFloatWindowStatus(uint32_t accessTokenId,bool isShowing)2779 void SceneSessionManager::UpdateCameraFloatWindowStatus(uint32_t accessTokenId, bool isShowing)
2780 {
2781 SessionManagerAgentController::GetInstance().UpdateCameraFloatWindowStatus(accessTokenId, isShowing);
2782 }
2783
StartWindowInfoReportLoop()2784 void SceneSessionManager::StartWindowInfoReportLoop()
2785 {
2786 WLOGFI("Report loop");
2787 if (eventHandler_ == nullptr) {
2788 WLOGFE("Report event null");
2789 return ;
2790 }
2791 if (isReportTaskStart_) {
2792 WLOGFE("Report is ReportTask Start");
2793 return;
2794 }
2795 auto task = [this]() {
2796 WindowInfoReporter::GetInstance().ReportRecordedInfos();
2797 isReportTaskStart_ = false;
2798 StartWindowInfoReportLoop();
2799 };
2800 int64_t delayTime = 1000 * 60 * 60; // an hour. 1000 * 60 * 60
2801 bool ret = eventHandler_->PostTask(task, "WindowInfoReport", delayTime);
2802 if (!ret) {
2803 WLOGFE("Report post listener callback task failed. the task name is WindowInfoReport");
2804 return;
2805 }
2806 isReportTaskStart_ = true;
2807 }
2808
ResizeSoftInputCallingSessionIfNeed(const sptr<SceneSession> & sceneSession)2809 void SceneSessionManager::ResizeSoftInputCallingSessionIfNeed(const sptr<SceneSession>& sceneSession)
2810 {
2811 if (callingSession_ == nullptr) {
2812 WLOGFE("calling session is nullptr");
2813 return;
2814 }
2815 SessionGravity gravity;
2816 uint32_t percent = 0;
2817 sceneSession->GetSessionProperty()->GetSessionGravity(gravity, percent);
2818 if (gravity != SessionGravity::SESSION_GRAVITY_BOTTOM) {
2819 WLOGFI("input method window gravity is not bottom, no need to raise calling window");
2820 return;
2821 }
2822
2823 const WSRect& softInputSessionRect = sceneSession->GetSessionRect();
2824 const WSRect& callingSessionRect = callingSession_->GetSessionRect();
2825 if (SessionHelper::IsEmptyRect(SessionHelper::GetOverlap(softInputSessionRect, callingSessionRect, 0, 0))) {
2826 WLOGFD("There is no overlap area");
2827 return;
2828 }
2829
2830 // calculate new rect of calling window
2831 WSRect newRect = callingSessionRect;
2832 newRect.posY_ = softInputSessionRect.posY_ - static_cast<int32_t>(newRect.height_);
2833 newRect.posY_ = std::max(newRect.posY_, STATUS_BAR_AVOID_AREA);
2834
2835 callingWindowRestoringRect_ = callingSessionRect;
2836 NotifyOccupiedAreaChangeInfo(callingSession_, newRect, softInputSessionRect);
2837 callingSession_->UpdateSessionRect(newRect, SizeChangeReason::UNDEFINED);
2838 }
2839
NotifyOccupiedAreaChangeInfo(const sptr<SceneSession> callingSession,const WSRect & rect,const WSRect & occupiedArea)2840 void SceneSessionManager::NotifyOccupiedAreaChangeInfo(const sptr<SceneSession> callingSession,
2841 const WSRect& rect, const WSRect& occupiedArea)
2842 {
2843 // if keyboard will occupy calling, notify calling window the occupied area and safe height
2844 const WSRect& safeRect = SessionHelper::GetOverlap(occupiedArea, rect, 0, 0);
2845 sptr<OccupiedAreaChangeInfo> info = new OccupiedAreaChangeInfo(OccupiedAreaType::TYPE_INPUT,
2846 SessionHelper::TransferToRect(safeRect), safeRect.height_);
2847 WLOGFD("OccupiedAreaChangeInfo rect: %{public}u %{public}u %{public}u %{public}u",
2848 occupiedArea.posX_, occupiedArea.posY_, occupiedArea.width_, occupiedArea.height_);
2849 callingSession->NotifyOccupiedAreaChangeInfo(info);
2850 }
2851
RestoreCallingSessionSizeIfNeed()2852 void SceneSessionManager::RestoreCallingSessionSizeIfNeed()
2853 {
2854 WLOGFD("RestoreCallingSessionSizeIfNeed");
2855 if (callingSession_ == nullptr) {
2856 WLOGFE("Calling session is nullptr");
2857 return;
2858 }
2859 if (!SessionHelper::IsEmptyRect(callingWindowRestoringRect_)) {
2860 WSRect overlapRect = { 0, 0, 0, 0 };
2861 NotifyOccupiedAreaChangeInfo(callingSession_, callingWindowRestoringRect_, overlapRect);
2862 callingSession_->UpdateSessionRect(callingWindowRestoringRect_, SizeChangeReason::UNDEFINED);
2863 }
2864 callingWindowRestoringRect_ = { 0, 0, 0, 0 };
2865 callingSession_ = nullptr;
2866 }
2867
SetSessionGravity(int32_t persistentId,SessionGravity gravity,uint32_t percent)2868 WSError SceneSessionManager::SetSessionGravity(int32_t persistentId, SessionGravity gravity, uint32_t percent)
2869 {
2870 auto sceneSession = GetSceneSession(persistentId);
2871 if (!sceneSession) {
2872 WLOGFE("scene session is nullptr");
2873 return WSError::WS_ERROR_NULLPTR;
2874 }
2875 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
2876 WLOGFE("scene session is not input method");
2877 return WSError::WS_ERROR_INVALID_TYPE;
2878 }
2879 sceneSession->GetSessionProperty()->SetSessionGravity(gravity, percent);
2880 RelayoutKeyBoard(sceneSession);
2881 if (gravity == SessionGravity::SESSION_GRAVITY_FLOAT) {
2882 WLOGFD("input method is float mode");
2883 RestoreCallingSessionSizeIfNeed();
2884 } else {
2885 WLOGFD("input method is bottom mode");
2886 ResizeSoftInputCallingSessionIfNeed(sceneSession);
2887 }
2888 return WSError::WS_OK;
2889 }
2890
RelayoutKeyBoard(sptr<SceneSession> sceneSession)2891 void SceneSessionManager::RelayoutKeyBoard(sptr<SceneSession> sceneSession)
2892 {
2893 if (sceneSession == nullptr) {
2894 WLOGFE("sceneSession is nullptr");
2895 return;
2896 }
2897 SessionGravity gravity;
2898 uint32_t percent = 0;
2899 sceneSession->GetSessionProperty()->GetSessionGravity(gravity, percent);
2900 if (sceneSession->GetWindowType() != WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
2901 gravity == SessionGravity::SESSION_GRAVITY_FLOAT) {
2902 return;
2903 }
2904
2905 auto defaultDisplayInfo = ScreenSessionManager::GetInstance().GetDefaultDisplayInfo();
2906 if (defaultDisplayInfo == nullptr) {
2907 WLOGFE("screenSession is null");
2908 return;
2909 }
2910
2911 auto requestRect = sceneSession->GetSessionProperty()->GetRequestRect();
2912 if (gravity == SessionGravity::SESSION_GRAVITY_BOTTOM) {
2913 if (percent != 0) {
2914 requestRect.width_ = static_cast<uint32_t>(defaultDisplayInfo->GetWidth());
2915 requestRect.height_ =
2916 static_cast<uint32_t>(defaultDisplayInfo->GetHeight()) * percent / 100u; // 100: for calc percent.
2917 requestRect.posX_ = 0;
2918 }
2919 }
2920 requestRect.posY_ = defaultDisplayInfo->GetHeight() -
2921 static_cast<int32_t>(requestRect.height_);
2922 sceneSession->GetSessionProperty()->SetRequestRect(requestRect);
2923 sceneSession->UpdateSessionRect(SessionHelper::TransferToWSRect(requestRect), SizeChangeReason::UNDEFINED);
2924 }
2925
InitPersistentStorage()2926 void SceneSessionManager::InitPersistentStorage()
2927 {
2928 if (ScenePersistentStorage::HasKey("maximize_state", ScenePersistentStorageType::MAXIMIZE_STATE)) {
2929 int32_t storageMode = -1;
2930 ScenePersistentStorage::Get("maximize_state", storageMode, ScenePersistentStorageType::MAXIMIZE_STATE);
2931 if (storageMode == static_cast<int32_t>(MaximizeMode::MODE_AVOID_SYSTEM_BAR) ||
2932 storageMode == static_cast<int32_t>(MaximizeMode::MODE_FULL_FILL)) {
2933 WLOGFI("init MaximizeMode as %{public}d from persistent storage", storageMode);
2934 SceneSession::maximizeMode_ = static_cast<MaximizeMode>(storageMode);
2935 }
2936 }
2937 }
2938
GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos)2939 WMError SceneSessionManager::GetAccessibilityWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos)
2940 {
2941 WLOGFI("GetAccessibilityWindowInfo Called.");
2942 auto task = [this, &infos]() {
2943 std::map<int32_t, sptr<SceneSession>>::iterator iter;
2944 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
2945 for (iter = sceneSessionMap_.begin(); iter != sceneSessionMap_.end(); iter++) {
2946 sptr<SceneSession> sceneSession = iter->second;
2947 if (sceneSession == nullptr) {
2948 WLOGFW("null scene session");
2949 continue;
2950 }
2951 WLOGFD("name = %{public}s, isSystem = %{public}d, persistendId = %{public}d, winType = %{public}d, "
2952 "state = %{public}d, visible = %{public}d", sceneSession->GetWindowName().c_str(),
2953 sceneSession->GetSessionInfo().isSystem_, iter->first, sceneSession->GetWindowType(),
2954 sceneSession->GetSessionState(), sceneSession->IsVisible());
2955 if (IsSessionVisible(sceneSession)) {
2956 FillWindowInfo(infos, iter->second);
2957 }
2958 }
2959 return WMError::WM_OK;
2960 };
2961 return taskScheduler_->PostSyncTask(task);
2962 }
2963
NotifyWindowInfoChange(int32_t persistentId,WindowUpdateType type)2964 void SceneSessionManager::NotifyWindowInfoChange(int32_t persistentId, WindowUpdateType type)
2965 {
2966 WLOGFI("NotifyWindowInfoChange, persistentId = %{public}d, updateType = %{public}d", persistentId, type);
2967 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
2968 if (sceneSession == nullptr) {
2969 WLOGFE("GetSessionSnapshot sceneSession nullptr!");
2970 return;
2971 }
2972 wptr<SceneSession> weakSceneSession(sceneSession);
2973 auto task = [this, weakSceneSession, type]() {
2974 std::vector<sptr<AccessibilityWindowInfo>> infos;
2975 auto scnSession = weakSceneSession.promote();
2976 if (FillWindowInfo(infos, scnSession)) {
2977 SessionManagerAgentController::GetInstance().NotifyAccessibilityWindowInfo(infos, type);
2978 }
2979 };
2980 taskScheduler_->PostAsyncTask(task);
2981 }
2982
FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>> & infos,const sptr<SceneSession> & sceneSession)2983 bool SceneSessionManager::FillWindowInfo(std::vector<sptr<AccessibilityWindowInfo>>& infos,
2984 const sptr<SceneSession>& sceneSession)
2985 {
2986 if (sceneSession == nullptr) {
2987 WLOGFW("null scene session.");
2988 return false;
2989 }
2990 if (sceneSession->GetSessionInfo().bundleName_.find("SCBGestureBack") != std::string::npos) {
2991 WLOGFW("filter gesture window.");
2992 return false;
2993 }
2994 sptr<AccessibilityWindowInfo> info = new (std::nothrow) AccessibilityWindowInfo();
2995 if (info == nullptr) {
2996 WLOGFE("null info.");
2997 return false;
2998 }
2999 if (sceneSession->GetSessionInfo().isSystem_) {
3000 info->wid_ = 1;
3001 info->innerWid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
3002 } else {
3003 info->wid_ = static_cast<int32_t>(sceneSession->GetPersistentId());
3004 }
3005 info->uiNodeId_ = sceneSession->GetUINodeId();
3006 WSRect wsrect = sceneSession->GetSessionRect();
3007 info->windowRect_ = {wsrect.posX_, wsrect.posY_, wsrect.width_, wsrect.height_ };
3008 info->focused_ = sceneSession->GetPersistentId() == focusedSessionId_;
3009 info->type_ = sceneSession->GetWindowType();
3010 info->mode_ = sceneSession->GetWindowMode();
3011 info->layer_ = sceneSession->GetZOrder();
3012 auto property = sceneSession->GetSessionProperty();
3013 if (property != nullptr) {
3014 info->displayId_ = property->GetDisplayId();
3015 info->isDecorEnable_ = property->IsDecorEnable();
3016 }
3017 infos.emplace_back(info);
3018 WLOGFD("wid = %{public}d, inWid = %{public}d, uiNId = %{public}d", info->wid_, info->innerWid_, info->uiNodeId_);
3019 return true;
3020 }
3021
GetSessionSnapshotFilePath(int32_t persistentId)3022 std::string SceneSessionManager::GetSessionSnapshotFilePath(int32_t persistentId)
3023 {
3024 WLOGFI("GetSessionSnapshot persistentId %{public}d", persistentId);
3025 auto sceneSession = GetSceneSession(persistentId);
3026 if (sceneSession == nullptr) {
3027 WLOGFE("GetSessionSnapshot sceneSession nullptr!");
3028 return "";
3029 }
3030 wptr<SceneSession> weakSceneSession(sceneSession);
3031 auto task = [this, weakSceneSession]() {
3032 auto scnSession = weakSceneSession.promote();
3033 if (scnSession == nullptr) {
3034 WLOGFE("session is nullptr");
3035 return std::string("");
3036 }
3037 std::string filePath = scnSession->GetSessionSnapshotFilePath();
3038 if (listenerController_ != nullptr && !filePath.empty()) {
3039 WLOGFD("NotifySessionSnapshotChanged, id: %{public}d", scnSession->GetPersistentId());
3040 listenerController_->NotifySessionSnapshotChanged(scnSession->GetPersistentId());
3041 }
3042 return filePath;
3043 };
3044 return taskScheduler_->PostSyncTask(task);
3045 }
3046
GetWindowVisibilityChangeInfo(std::shared_ptr<RSOcclusionData> occlusionData)3047 std::vector<std::pair<uint64_t, bool>> SceneSessionManager::GetWindowVisibilityChangeInfo(
3048 std::shared_ptr<RSOcclusionData> occlusionData)
3049 {
3050 std::vector<std::pair<uint64_t, bool>> visibilityChangeInfo;
3051 VisibleData& currentVisibleWindow = occlusionData->GetVisibleData();
3052 std::sort(currentVisibleWindow.begin(), currentVisibleWindow.end());
3053 VisibleData& lastVisibleWindow = lastOcclusionData_->GetVisibleData();
3054 uint32_t i, j;
3055 i = j = 0;
3056 for (; i < lastVisibleWindow.size() && j < currentVisibleWindow.size();) {
3057 if (lastVisibleWindow[i] < currentVisibleWindow[j]) {
3058 visibilityChangeInfo.emplace_back(lastVisibleWindow[i], false);
3059 i++;
3060 } else if (lastVisibleWindow[i] > currentVisibleWindow[j]) {
3061 visibilityChangeInfo.emplace_back(currentVisibleWindow[j], true);
3062 j++;
3063 } else {
3064 i++;
3065 j++;
3066 }
3067 }
3068 for (; i < lastVisibleWindow.size(); ++i) {
3069 visibilityChangeInfo.emplace_back(lastVisibleWindow[i], false);
3070 }
3071 for (; j < currentVisibleWindow.size(); ++j) {
3072 visibilityChangeInfo.emplace_back(currentVisibleWindow[j], true);
3073 }
3074 lastOcclusionData_ = occlusionData;
3075 return visibilityChangeInfo;
3076 }
3077
SelectSesssionFromMap(const uint64_t & surfaceId)3078 sptr<SceneSession> SceneSessionManager::SelectSesssionFromMap(const uint64_t& surfaceId)
3079 {
3080 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3081 for (const auto &item : sceneSessionMap_) {
3082 auto sceneSession = item.second;
3083 if (sceneSession == nullptr) {
3084 continue;
3085 }
3086 if (sceneSession->GetSurfaceNode() == nullptr) {
3087 continue;
3088 }
3089 if (surfaceId == sceneSession->GetSurfaceNode()->GetId()) {
3090 return sceneSession;
3091 }
3092 }
3093 return nullptr;
3094 }
3095
WindowVisibilityChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)3096 void SceneSessionManager::WindowVisibilityChangeCallback(std::shared_ptr<RSOcclusionData> occlusiontionData)
3097 {
3098 WLOGFI("WindowVisibilityChangeCallback: entry");
3099 std::weak_ptr<RSOcclusionData> weak(occlusiontionData);
3100
3101 taskScheduler_->PostVoidSyncTask([this, weak]() {
3102 auto weakOcclusionData = weak.lock();
3103 if (weakOcclusionData == nullptr) {
3104 WLOGFE("weak occlusionData is nullptr");
3105 return;
3106 }
3107
3108 std::vector<std::pair<uint64_t, bool>> visibilityChangeInfo = GetWindowVisibilityChangeInfo(weakOcclusionData);
3109 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
3110 #ifdef MEMMGR_WINDOW_ENABLE
3111 std::vector<sptr<Memory::MemMgrWindowInfo>> memMgrWindowInfos;
3112 #endif
3113 for (const auto& elem : visibilityChangeInfo) {
3114 uint64_t surfaceId = elem.first;
3115 bool isVisible = elem.second;
3116 sptr<SceneSession> session = SelectSesssionFromMap(surfaceId);
3117 if (session == nullptr) {
3118 continue;
3119 }
3120 session->SetVisible(isVisible);
3121 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(session->GetWindowId(), session->GetCallingPid(),
3122 session->GetCallingUid(), isVisible, session->GetWindowType()));
3123 #ifdef MEMMGR_WINDOW_ENABLE
3124 memMgrWindowInfos.emplace_back(new Memory::MemMgrWindowInfo(session->GetWindowId(), session->GetCallingPid(),
3125 session->GetCallingUid(), isVisible));
3126 #endif
3127 WLOGFD("NotifyWindowVisibilityChange: covered status changed window:%{public}u, isVisible:%{public}d",
3128 session->GetWindowId(), isVisible);
3129 if (session->GetWindowSessionProperty()->GetWindowFlags() &
3130 static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) {
3131 CheckAndNotifyWaterMarkChangedResult(isVisible);
3132 }
3133 }
3134 if (windowVisibilityInfos.size() != 0) {
3135 WLOGI("Notify windowvisibilityinfo changed start");
3136 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
3137 }
3138 #ifdef MEMMGR_WINDOW_ENABLE
3139 if (memMgrWindowInfos.size() != 0) {
3140 WLOGI("Notify memMgrWindowInfos changed start");
3141 Memory::MemMgrClient::GetInstance().OnWindowVisibilityChanged(memMgrWindowInfos);
3142 }
3143 #endif
3144 });
3145 }
3146
InitWithRenderServiceAdded()3147 void SceneSessionManager::InitWithRenderServiceAdded()
3148 {
3149 auto windowVisibilityChangeCb = std::bind(&SceneSessionManager::WindowVisibilityChangeCallback, this,
3150 std::placeholders::_1);
3151 WLOGI("RegisterWindowVisibilityChangeCallback");
3152 if (rsInterface_.RegisterOcclusionChangeCallback(windowVisibilityChangeCb) != WM_OK) {
3153 WLOGFE("RegisterWindowVisibilityChangeCallback failed");
3154 }
3155 }
3156
WindowDestroyNotifyVisibility(const sptr<SceneSession> & sceneSession)3157 void SceneSessionManager::WindowDestroyNotifyVisibility(const sptr<SceneSession>& sceneSession)
3158 {
3159 if (sceneSession == nullptr) {
3160 WLOGFE("sceneSession is nullptr!");
3161 return;
3162 }
3163 if (sceneSession->GetVisible()) {
3164 std::vector<sptr<WindowVisibilityInfo>> windowVisibilityInfos;
3165 sceneSession->SetVisible(false);
3166 windowVisibilityInfos.emplace_back(new WindowVisibilityInfo(sceneSession->GetWindowId(),
3167 sceneSession->GetCallingPid(), sceneSession->GetCallingUid(), false, sceneSession->GetWindowType()));
3168 WLOGFD("NotifyWindowVisibilityChange: covered status changed window:%{public}u, isVisible:%{public}d",
3169 sceneSession->GetWindowId(), sceneSession->GetVisible());
3170 if (sceneSession->GetWindowSessionProperty()->GetWindowFlags() &
3171 static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_WATER_MARK)) {
3172 CheckAndNotifyWaterMarkChangedResult(false);
3173 }
3174 SessionManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(windowVisibilityInfos);
3175 }
3176 }
3177
FindSessionByToken(const sptr<IRemoteObject> & token)3178 sptr<SceneSession> SceneSessionManager::FindSessionByToken(const sptr<IRemoteObject> &token)
3179 {
3180 sptr<SceneSession> session = nullptr;
3181 auto cmpFunc = [token](const std::map<uint64_t, sptr<SceneSession>>::value_type& pair) {
3182 if (pair.second == nullptr) {
3183 return false;
3184 }
3185 if (pair.second -> GetAbilityToken() == token) {
3186 return true;
3187 }
3188 return false;
3189 };
3190 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3191 auto iter = std::find_if(sceneSessionMap_.begin(), sceneSessionMap_.end(), cmpFunc);
3192 if (iter != sceneSessionMap_.end()) {
3193 session = iter->second;
3194 }
3195 return session;
3196 }
3197
PendingSessionToForeground(const sptr<IRemoteObject> & token)3198 WSError SceneSessionManager::PendingSessionToForeground(const sptr<IRemoteObject> &token)
3199 {
3200 WLOGFI("run PendingSessionToForeground");
3201 auto session = FindSessionByToken(token);
3202 if (session != nullptr) {
3203 return session->PendingSessionToForeground();
3204 }
3205 WLOGFE("fail to find token");
3206 return WSError::WS_ERROR_INVALID_PARAM;
3207 }
3208
PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject> & token)3209 WSError SceneSessionManager::PendingSessionToBackgroundForDelegator(const sptr<IRemoteObject> &token)
3210 {
3211 WLOGFI("run PendingSessionToBackgroundForDelegator");
3212 auto session = FindSessionByToken(token);
3213 if (session != nullptr) {
3214 return session->PendingSessionToBackgroundForDelegator();
3215 }
3216 WLOGFE("fail to find token");
3217 return WSError::WS_ERROR_INVALID_PARAM;
3218 }
3219
GetFocusSessionToken(sptr<IRemoteObject> & token)3220 WSError SceneSessionManager::GetFocusSessionToken(sptr<IRemoteObject> &token)
3221 {
3222 WLOGFI("run GetFocusSessionToken with focusedSessionId: %{public}d", focusedSessionId_);
3223 auto sceneSession = GetSceneSession(focusedSessionId_);
3224 if (sceneSession) {
3225 token = sceneSession->GetAbilityToken();
3226 if (token == nullptr) {
3227 WLOGFE("token is nullptr");
3228 return WSError::WS_ERROR_INVALID_PARAM;
3229 }
3230 return WSError::WS_OK;
3231 }
3232 return WSError::WS_ERROR_INVALID_PARAM;
3233 }
3234
UpdateSessionAvoidAreaListener(int32_t & persistentId,bool haveListener)3235 WSError SceneSessionManager::UpdateSessionAvoidAreaListener(int32_t& persistentId, bool haveListener)
3236 {
3237 WLOGFI("UpdateSessionAvoidAreaListener persistentId: %{public}d haveListener:%{public}d",
3238 persistentId, haveListener);
3239 auto sceneSession = GetSceneSession(persistentId);
3240 if (sceneSession == nullptr) {
3241 WLOGFE("sceneSession is nullptr.");
3242 return WSError::WS_DO_NOTHING;
3243 }
3244 if (haveListener) {
3245 avoidAreaListenerSessionSet_.insert(sceneSession);
3246 } else {
3247 lastUpdatedAvoidArea_.erase(persistentId);
3248 avoidAreaListenerSessionSet_.erase(sceneSession);
3249 }
3250 return WSError::WS_OK;
3251 }
3252
UpdateSessionAvoidAreaIfNeed(const int32_t & persistentId,const AvoidArea & avoidArea,AvoidAreaType avoidAreaType)3253 bool SceneSessionManager::UpdateSessionAvoidAreaIfNeed(const int32_t& persistentId,
3254 const AvoidArea& avoidArea, AvoidAreaType avoidAreaType)
3255 {
3256 auto iter = lastUpdatedAvoidArea_.find(persistentId);
3257 bool needUpdate = true;
3258
3259 if (iter != lastUpdatedAvoidArea_.end()) {
3260 auto avoidAreaIter = iter->second.find(avoidAreaType);
3261 if (avoidAreaIter != iter->second.end()) {
3262 needUpdate = avoidAreaIter->second != avoidArea;
3263 } else {
3264 if (avoidArea.isEmptyAvoidArea()) {
3265 needUpdate = false;
3266 }
3267 }
3268 } else {
3269 if (avoidArea.isEmptyAvoidArea()) {
3270 needUpdate = false;
3271 }
3272 }
3273 if (needUpdate) {
3274 auto sceneSession = GetSceneSession(persistentId);
3275 if (sceneSession == nullptr) {
3276 WLOGFE("sceneSession is nullptr.");
3277 return false;
3278 }
3279 lastUpdatedAvoidArea_[persistentId][avoidAreaType] = avoidArea;
3280 sceneSession->UpdateAvoidArea(new AvoidArea(avoidArea), avoidAreaType);
3281 }
3282
3283 return needUpdate;
3284 }
3285
UpdateAvoidArea(const int32_t & persistentId)3286 bool SceneSessionManager::UpdateAvoidArea(const int32_t& persistentId)
3287 {
3288 auto task = [this, persistentId]() {
3289 bool ret = true;
3290 bool needUpdate = false;
3291 auto sceneSession = GetSceneSession(persistentId);
3292 if (sceneSession == nullptr) {
3293 WLOGFE("sceneSession is nullptr.");
3294 return false;
3295 }
3296 NotifyWindowInfoChange(persistentId, WindowUpdateType::WINDOW_UPDATE_BOUNDS);
3297
3298 WindowType type = sceneSession->GetWindowType();
3299 SessionGravity gravity = SessionGravity::SESSION_GRAVITY_BOTTOM;
3300 uint32_t percent = 0;
3301 if (sceneSession->GetSessionProperty() != nullptr) {
3302 sceneSession->GetSessionProperty()->GetSessionGravity(gravity, percent);
3303 }
3304 if (type == WindowType::WINDOW_TYPE_STATUS_BAR ||
3305 type == WindowType::WINDOW_TYPE_NAVIGATION_BAR ||
3306 (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
3307 gravity == SessionGravity::SESSION_GRAVITY_BOTTOM)) {
3308 AvoidAreaType avoidType = (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) ?
3309 AvoidAreaType::TYPE_KEYBOARD : AvoidAreaType::TYPE_SYSTEM;
3310 for (auto& session : avoidAreaListenerSessionSet_) {
3311 AvoidArea avoidArea = session->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
3312 ret = UpdateSessionAvoidAreaIfNeed(
3313 session->GetPersistentId(), avoidArea, static_cast<AvoidAreaType>(avoidType));
3314 needUpdate = needUpdate || ret;
3315 }
3316 } else {
3317 if (avoidAreaListenerSessionSet_.find(sceneSession) == avoidAreaListenerSessionSet_.end()) {
3318 WLOGD("id:%{public}d is not in avoidAreaListenerNodes, don't update avoid area.", persistentId);
3319 return false;
3320 }
3321 uint32_t start = static_cast<uint32_t>(AvoidAreaType::TYPE_SYSTEM);
3322 uint32_t end = static_cast<uint32_t>(AvoidAreaType::TYPE_KEYBOARD);
3323 for (uint32_t avoidType = start; avoidType <= end; avoidType++) {
3324 AvoidArea avoidArea = sceneSession->GetAvoidAreaByType(static_cast<AvoidAreaType>(avoidType));
3325 ret = UpdateSessionAvoidAreaIfNeed(persistentId, avoidArea, static_cast<AvoidAreaType>(avoidType));
3326 needUpdate = needUpdate || ret;
3327 }
3328 }
3329
3330 return needUpdate;
3331 };
3332
3333 return taskScheduler_->PostSyncTask(task);
3334 }
3335
OnDisplayStateChange(DisplayId defaultDisplayId,sptr<DisplayInfo> displayInfo,const std::map<DisplayId,sptr<DisplayInfo>> & displayInfoMap,DisplayStateChangeType type)3336 void DisplayChangeListener::OnDisplayStateChange(DisplayId defaultDisplayId, sptr<DisplayInfo> displayInfo,
3337 const std::map<DisplayId, sptr<DisplayInfo>>& displayInfoMap, DisplayStateChangeType type)
3338 {
3339 return;
3340 }
3341
OnScreenshot(DisplayId displayId)3342 void DisplayChangeListener::OnScreenshot(DisplayId displayId)
3343 {
3344 SceneSessionManager::GetInstance().OnScreenshot(displayId);
3345 }
3346
OnScreenshot(DisplayId displayId)3347 void SceneSessionManager::OnScreenshot(DisplayId displayId)
3348 {
3349 auto task = [this, displayId]() {
3350 auto sceneSession = GetSceneSession(focusedSessionId_);
3351 if (sceneSession) {
3352 sceneSession->NotifyScreenshot();
3353 }
3354 };
3355 taskScheduler_->PostAsyncTask(task);
3356 }
3357
ClearSession(int32_t persistentId)3358 WSError SceneSessionManager::ClearSession(int32_t persistentId)
3359 {
3360 WLOGFI("run ClearSession with persistentId: %{public}d", persistentId);
3361 if (!SessionPermission::IsSACalling()) {
3362 WLOGFI("invalid permission");
3363 return WSError::WS_ERROR_INVALID_PERMISSION;
3364 }
3365
3366 auto task = [this, persistentId]() {
3367 sptr<SceneSession> sceneSession = GetSceneSession(persistentId);
3368 return ClearSession(sceneSession);
3369 };
3370 taskScheduler_->PostAsyncTask(task);
3371 return WSError::WS_OK;
3372 }
3373
ClearSession(sptr<SceneSession> sceneSession)3374 WSError SceneSessionManager::ClearSession(sptr<SceneSession> sceneSession)
3375 {
3376 WLOGFI("run ClearSession");
3377 if (sceneSession == nullptr) {
3378 WLOGFE("sceneSession is nullptr");
3379 return WSError::WS_ERROR_INVALID_SESSION;
3380 }
3381 if (!IsSessionClearable(sceneSession)) {
3382 WLOGFI("sceneSession cannot be clear, persistentId %{public}d.", sceneSession->GetPersistentId());
3383 return WSError::WS_ERROR_INVALID_SESSION;
3384 }
3385 const WSError& errCode = sceneSession->Clear();
3386 return errCode;
3387 }
3388
ClearAllSessions()3389 WSError SceneSessionManager::ClearAllSessions()
3390 {
3391 WLOGFI("run ClearAllSessions");
3392 auto task = [this]() {
3393 std::vector<sptr<SceneSession>> sessionVector;
3394 GetAllClearableSessions(sessionVector);
3395 for (uint32_t i = 0; i < sessionVector.size(); i++) {
3396 ClearSession(sessionVector[i]);
3397 }
3398 return WSError::WS_OK;
3399 };
3400 taskScheduler_->PostAsyncTask(task);
3401 return WSError::WS_OK;
3402 }
3403
GetAllClearableSessions(std::vector<sptr<SceneSession>> & sessionVector)3404 void SceneSessionManager::GetAllClearableSessions(std::vector<sptr<SceneSession>>& sessionVector)
3405 {
3406 WLOGFI("run GetAllClearableSessions");
3407 std::shared_lock<std::shared_mutex> lock(sceneSessionMapMutex_);
3408 for (const auto &item : sceneSessionMap_) {
3409 auto scnSession = item.second;
3410 if (IsSessionClearable(scnSession)) {
3411 sessionVector.push_back(scnSession);
3412 }
3413 }
3414 }
3415
IsSessionClearable(sptr<SceneSession> scnSession)3416 bool SceneSessionManager::IsSessionClearable(sptr<SceneSession> scnSession)
3417 {
3418 if (scnSession == nullptr) {
3419 WLOGFI("scnSession is nullptr");
3420 return false;
3421 }
3422 SessionInfo sessionInfo = scnSession->GetSessionInfo();
3423 if (sessionInfo.abilityInfo == nullptr) {
3424 WLOGFI("scnSession abilityInfo is nullptr");
3425 return false;
3426 }
3427 if (sessionInfo.abilityInfo->excludeFromMissions) {
3428 WLOGFI("persistentId %{public}d is excludeFromMissions", scnSession->GetPersistentId());
3429 return false;
3430 }
3431 if (sessionInfo.abilityInfo->unclearableMission) {
3432 WLOGFI("persistentId %{public}d is unclearable", scnSession->GetPersistentId());
3433 return false;
3434 }
3435 if (sessionInfo.isSystem_) {
3436 WLOGFI("persistentId %{public}d is system app", scnSession->GetPersistentId());
3437 return false;
3438 }
3439
3440 return true;
3441 }
3442
RegisterIAbilityManagerCollaborator(int32_t type,const sptr<AAFwk::IAbilityManagerCollaborator> & impl)3443 WSError SceneSessionManager::RegisterIAbilityManagerCollaborator(int32_t type, const sptr<AAFwk::IAbilityManagerCollaborator> &impl)
3444 {
3445 WLOGFI("RegisterIAbilityManagerCollaborator with type : %{public}d", type);
3446 auto isSaCall = SessionPermission::IsSACalling();
3447 auto callingUid = IPCSkeleton::GetCallingUid();
3448 if (!isSaCall || (callingUid != BROKER_UID && callingUid != BROKER_RESERVE_UID)) {
3449 WLOGFE("The interface only support for broker");
3450 return WSError::WS_ERROR_INVALID_PERMISSION;
3451 }
3452 if (!CheckCollaboratorType(type)) {
3453 WLOGFE("collaborator register failed, invalid type.");
3454 return WSError::WS_ERROR_INVALID_TYPE;
3455 }
3456 {
3457 std::shared_lock<std::shared_mutex> lock(collaboratorMapLock_);
3458 collaboratorMap_[type] = impl;
3459 }
3460 return WSError::WS_OK;
3461 }
3462
UnregisterIAbilityManagerCollaborator(int32_t type)3463 WSError SceneSessionManager::UnregisterIAbilityManagerCollaborator(int32_t type)
3464 {
3465 WLOGFI("UnregisterIAbilityManagerCollaborator with type : %{public}d", type);
3466 auto isSaCall = SessionPermission::IsSACalling();
3467 auto callingUid = IPCSkeleton::GetCallingUid();
3468 if (!isSaCall || (callingUid != BROKER_UID && callingUid != BROKER_RESERVE_UID)) {
3469 WLOGFE("The interface only support for broker");
3470 return WSError::WS_ERROR_INVALID_PERMISSION;
3471 }
3472 if (!CheckCollaboratorType(type)) {
3473 WLOGFE("collaborator unregister failed, invalid type.");
3474 return WSError::WS_ERROR_INVALID_TYPE;
3475 }
3476 {
3477 std::shared_lock<std::shared_mutex> lock(collaboratorMapLock_);
3478 collaboratorMap_.erase(type);
3479 }
3480 return WSError::WS_OK;
3481 }
3482
CheckCollaboratorType(int32_t type)3483 bool SceneSessionManager::CheckCollaboratorType(int32_t type)
3484 {
3485 if (type != CollaboratorType::RESERVE_TYPE && type != CollaboratorType::OTHERS_TYPE) {
3486 WLOGFE("type is invalid");
3487 return false;
3488 }
3489 return true;
3490 }
3491
QueryAbilityInfoFromBMS(const int32_t uId,const SessionInfo & sessionInfo,AppExecFwk::AbilityInfo & abilityInfo)3492 void SceneSessionManager::QueryAbilityInfoFromBMS(const int32_t uId,
3493 const SessionInfo& sessionInfo, AppExecFwk::AbilityInfo& abilityInfo)
3494 {
3495 WLOGFI("run QueryAbilityInfoFromBMS");
3496 if (bundleMgr_ == nullptr) {
3497 WLOGFE("bundleMgr_ is nullptr!");
3498 return;
3499 }
3500
3501 AAFwk::Want want;
3502 want.SetElementName("", sessionInfo.bundleName_, sessionInfo.abilityName_, sessionInfo.moduleName_);
3503 auto abilityInfoFlag = (AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_APPLICATION |
3504 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_PERMISSION |
3505 AppExecFwk::AbilityInfoFlag::GET_ABILITY_INFO_WITH_METADATA);
3506 bool ret = bundleMgr_->QueryAbilityInfo(want, abilityInfoFlag, uId, abilityInfo);
3507 if (!ret) {
3508 WLOGFE("Get ability info from BMS failed!");
3509 }
3510 }
3511
NotifyStartAbility(int32_t collaboratorType,const SessionInfo & sessionInfo)3512 void SceneSessionManager::NotifyStartAbility(int32_t collaboratorType, const SessionInfo& sessionInfo)
3513 {
3514 WLOGFI("run NotifyStartAbility");
3515 auto iter = collaboratorMap_.find(collaboratorType);
3516 if (iter == collaboratorMap_.end()) {
3517 WLOGFE("Fail to found collaborator with type: %{public}d", collaboratorType);
3518 return;
3519 }
3520 auto collaborator = iter->second;
3521 uint64_t accessTokenIDEx = IPCSkeleton::GetCallingFullTokenID();
3522 if (collaborator != nullptr) {
3523 collaborator->NotifyStartAbility(*(sessionInfo.abilityInfo), currentUserId_, *(sessionInfo.want), accessTokenIDEx);
3524 }
3525 }
3526
NotifySessionCreate(sptr<SceneSession> sceneSession,SessionInfo & sessionInfo)3527 void SceneSessionManager::NotifySessionCreate(sptr<SceneSession> sceneSession, SessionInfo& sessionInfo)
3528 {
3529 WLOGFI("run NotifySessionCreate");
3530 auto iter = collaboratorMap_.find(sceneSession->GetCollaboratorType());
3531 if (iter == collaboratorMap_.end()) {
3532 WLOGFE("Fail to found collaborator with type: %{public}d", sceneSession->GetCollaboratorType());
3533 return;
3534 }
3535 auto collaborator = iter->second;
3536 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
3537 abilitySessionInfo->persistentId = sceneSession->GetBrokerPersistentId();
3538 abilitySessionInfo->want = *(sessionInfo.want);
3539 if (collaborator != nullptr) {
3540 collaborator->NotifyMissionCreated(abilitySessionInfo);
3541 }
3542 }
3543
NotifyLoadAbility(int32_t collaboratorType,sptr<AAFwk::SessionInfo> abilitySessionInfo,std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)3544 void SceneSessionManager::NotifyLoadAbility(int32_t collaboratorType,
3545 sptr<AAFwk::SessionInfo> abilitySessionInfo, std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
3546 {
3547 WLOGFI("run NotifyLoadAbility");
3548 auto iter = collaboratorMap_.find(collaboratorType);
3549 if (iter == collaboratorMap_.end()) {
3550 WLOGFE("Fail to found collaborator with type: %{public}d", collaboratorType);
3551 return;
3552 }
3553 auto collaborator = iter->second;
3554 if (collaborator != nullptr) {
3555 collaborator->NotifyLoadAbility(*abilityInfo, abilitySessionInfo);
3556 }
3557 }
3558
3559
NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)3560 void SceneSessionManager::NotifyUpdateSessionInfo(sptr<SceneSession> sceneSession)
3561 {
3562 WLOGFI("run NotifyUpdateSessionInfo");
3563 if (sceneSession == nullptr) {
3564 WLOGFE("sceneSession is nullptr");
3565 return;
3566 }
3567 auto iter = collaboratorMap_.find(sceneSession->GetCollaboratorType());
3568 if (iter == collaboratorMap_.end()) {
3569 WLOGFE("Fail to found collaborator with type: %{public}d", sceneSession->GetCollaboratorType());
3570 return;
3571 }
3572 auto collaborator = iter->second;
3573 auto abilitySessionInfo = SetAbilitySessionInfo(sceneSession);
3574 abilitySessionInfo->persistentId = sceneSession->GetBrokerPersistentId();
3575 if (collaborator != nullptr) {
3576 collaborator->UpdateMissionInfo(abilitySessionInfo);
3577 }
3578 }
3579
NotifyMoveSessionToForeground(int32_t collaboratorType,int32_t persistentId)3580 void SceneSessionManager::NotifyMoveSessionToForeground(int32_t collaboratorType, int32_t persistentId)
3581 {
3582 WLOGFI("run NotifyMoveSessionToForeground");
3583 auto iter = collaboratorMap_.find(collaboratorType);
3584 if (iter == collaboratorMap_.end()) {
3585 WLOGFE("Fail to found collaborator with type: %{public}d", collaboratorType);
3586 return;
3587 }
3588 auto collaborator = iter->second;
3589 if (collaborator != nullptr) {
3590 collaborator->NotifyMoveMissionToForeground(persistentId);
3591 }
3592 }
3593
NotifyClearSession(int32_t collaboratorType,int32_t persistentId)3594 void SceneSessionManager::NotifyClearSession(int32_t collaboratorType, int32_t persistentId)
3595 {
3596 WLOGFI("run NotifyClearSession with persistentId %{public}d", persistentId);
3597 auto iter = collaboratorMap_.find(collaboratorType);
3598 if (iter == collaboratorMap_.end()) {
3599 WLOGFE("Fail to found collaborator with type: %{public}d", collaboratorType);
3600 return;
3601 }
3602 auto collaborator = iter->second;
3603 if (collaborator != nullptr) {
3604 collaborator->NotifyClearMission(persistentId);
3605 }
3606 }
3607
PreHandleCollaborator(sptr<SceneSession> sceneSession)3608 void SceneSessionManager::PreHandleCollaborator(sptr<SceneSession> sceneSession)
3609 {
3610 WLOGFI("run PreHandleCollaborator");
3611 if (sceneSession == nullptr) {
3612 return;
3613 }
3614 SessionInfo& newSessionInfo = sceneSession->GetSessionInfo();
3615 if (newSessionInfo.abilityInfo == nullptr) {
3616 newSessionInfo.abilityInfo = std::make_shared<AppExecFwk::AbilityInfo>();
3617 if (newSessionInfo.abilityInfo != nullptr) {
3618 QueryAbilityInfoFromBMS(currentUserId_, newSessionInfo, *(newSessionInfo.abilityInfo));
3619 if (newSessionInfo.abilityInfo != nullptr) {
3620 WLOGFI("ability codePath: %{public}s", newSessionInfo.abilityInfo->applicationInfo.codePath.c_str());
3621 if (newSessionInfo.abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::RESERVE_TYPE)) {
3622 sceneSession->SetCollaboratorType(CollaboratorType::RESERVE_TYPE);
3623 } else if (newSessionInfo.abilityInfo->applicationInfo.codePath == std::to_string(CollaboratorType::OTHERS_TYPE)) {
3624 sceneSession->SetCollaboratorType(CollaboratorType::OTHERS_TYPE);
3625 }
3626 }
3627 }
3628 }
3629 if(CheckCollaboratorType(sceneSession->GetCollaboratorType())) {
3630 WLOGFI("try to run NotifyStartAbility and NotifySessionCreate");
3631 NotifyStartAbility(sceneSession->GetCollaboratorType(), newSessionInfo);
3632 if (newSessionInfo.want != nullptr) {
3633 WLOGFI("reset new persistentId: %{public}d", newSessionInfo.want->GetIntParam(AncoConsts::ANCO_SESSION_ID, 0));
3634 sceneSession->UpdateBrokerPersistentId(newSessionInfo.want->GetIntParam(AncoConsts::ANCO_SESSION_ID, 0));
3635 }
3636 NotifySessionCreate(sceneSession, newSessionInfo);
3637 }
3638 }
3639
3640 } // namespace OHOS::Rosen
3641