• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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