• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 "multi_screen_mode_change_manager.h"
17 
18 #include <hitrace_meter.h>
19 #include <transaction/rs_transaction.h>
20 
21 #include "window_manager_hilog.h"
22 
23 namespace OHOS::Rosen {
24 WM_IMPLEMENT_SINGLE_INSTANCE(MultiScreenModeChangeManager)
25 namespace {
26 const std::string SCREEN_EXTEND = "extend";
27 const std::string SCREEN_MIRROR = "mirror";
28 }
29 
InitMultiScreenModeChangeMap()30 void MultiScreenModeChangeManager::InitMultiScreenModeChangeMap()
31 {
32     if (handleMultiScreenModeChangeMap_.size() != 0) {
33         TLOGW(WmsLogTag::DMS, "recovery multi screen mode change map has init!");
34         return;
35     }
36     handleMultiScreenModeChangeMap_[{ ScreenCombination::SCREEN_MAIN, ScreenCombination::SCREEN_EXTEND}] =
37         [this](sptr<ScreenSession>& innerScreen, ScreenCombination innerTargetCombination,
38         sptr<ScreenSession>& externalScreen, ScreenCombination externalTargetCombination) {
39             return HandleInnerMainExternalExtendChange(innerScreen, innerTargetCombination,
40                 externalScreen, externalTargetCombination);
41         };
42 
43     handleMultiScreenModeChangeMap_[{ ScreenCombination::SCREEN_MAIN, ScreenCombination::SCREEN_MIRROR}] =
44         [this](sptr<ScreenSession>& innerScreen, ScreenCombination innerTargetCombination,
45         sptr<ScreenSession>& externalScreen, ScreenCombination externalTargetCombination) {
46             return HandleInnerMainExternalMirrorChange(innerScreen, innerTargetCombination,
47                 externalScreen, externalTargetCombination);
48         };
49 
50     handleMultiScreenModeChangeMap_[{ ScreenCombination::SCREEN_EXTEND, ScreenCombination::SCREEN_MAIN}] =
51         [this](sptr<ScreenSession>& innerScreen, ScreenCombination innerTargetCombination,
52         sptr<ScreenSession>& externalScreen, ScreenCombination externalTargetCombination) {
53             return HandleInnerExtendExternalMainChange(innerScreen, innerTargetCombination,
54                 externalScreen, externalTargetCombination);
55         };
56 
57     handleMultiScreenModeChangeMap_[{ ScreenCombination::SCREEN_MIRROR, ScreenCombination::SCREEN_MAIN}] =
58         [this](sptr<ScreenSession>& innerScreen, ScreenCombination innerTargetCombination,
59         sptr<ScreenSession>& externalScreen, ScreenCombination externalTargetCombination) {
60             return HandleInnerMirrorExternalMainChange(innerScreen, innerTargetCombination,
61                 externalScreen, externalTargetCombination);
62         };
63 }
64 
OnMultiScreenModeChangeRequest(sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen,const std::string & operateType)65 DMError MultiScreenModeChangeManager::OnMultiScreenModeChangeRequest(
66     sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen, const std::string& operateType)
67 {
68     DMError handleRet = DMError::DM_OK;
69     if (innerScreen == nullptr || externalScreen == nullptr) {
70         TLOGE(WmsLogTag::DMS, "parameters nullptr.");
71         return DMError::DM_ERROR_NULLPTR;
72     }
73     ScreenCombination innerTargetCombination = ScreenCombination::SCREEN_MAIN;
74     ScreenCombination externalTargetCombination = operateType == SCREEN_EXTEND ?
75         ScreenCombination::SCREEN_EXTEND : ScreenCombination::SCREEN_MIRROR;
76 
77     std::ostringstream oss;
78     oss << "innerScreen screenId: " << innerScreen->GetScreenId()
79         << ", rsId: " << innerScreen->GetRSScreenId()
80         << ", current combination: " << static_cast<int32_t>(innerScreen->GetScreenCombination())
81         << ", target combination: " << static_cast<int32_t>(innerTargetCombination)
82         << ", externalScreen screenId: " << externalScreen->GetScreenId()
83         << ", rsId: " << externalScreen->GetRSScreenId()
84         << ", current combination: " << static_cast<int32_t>(externalScreen->GetScreenCombination())
85         << ", target combination: " << static_cast<int32_t>(externalTargetCombination);
86     oss << std::endl;
87     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
88 
89     auto modeHandleCall = handleMultiScreenModeChangeMap_.find({innerScreen->GetScreenCombination(),
90         externalScreen->GetScreenCombination()});
91     if (modeHandleCall != handleMultiScreenModeChangeMap_.end()) {
92         auto modeHandleFunction = modeHandleCall->second;
93         handleRet = modeHandleFunction(innerScreen, innerTargetCombination, externalScreen,
94             externalTargetCombination);
95     } else {
96         TLOGE(WmsLogTag::DMS, "failed to find function handler!");
97         handleRet = DMError::DM_ERROR_INVALID_CALLING;
98     }
99     return handleRet;
100 }
101 
102 /* inner main external extend change */
InitMultiScreenInnerMainExternalExtendModeModeChangeMap()103 void MultiScreenModeChangeManager::InitMultiScreenInnerMainExternalExtendModeModeChangeMap()
104 {
105     if (handleMultiScreenInnerMainExternalExtendModeChangeMap_.size() != 0) {
106         TLOGW(WmsLogTag::DMS, "recovery multi screen inner main external extend mode change map has init!");
107         return;
108     }
109     /* inner main external extend change to inner main external mirror */
110     handleMultiScreenInnerMainExternalExtendModeChangeMap_[{
111         ScreenCombination::SCREEN_MAIN, ScreenCombination::SCREEN_MIRROR}] =
112         [this](sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen) {
113             return HandleInnerMainExternalExtendToInnerMainExternalMirrorChange(innerScreen, externalScreen);
114         };
115     /* inner main external extend change to inner extend external main */
116     handleMultiScreenInnerMainExternalExtendModeChangeMap_[{
117         ScreenCombination::SCREEN_EXTEND, ScreenCombination::SCREEN_MAIN}] =
118         [this](sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen) {
119             return HandleInnerMainExternalExtendToInnerExtendExternalMainChange(innerScreen, externalScreen);
120         };
121     /* inner main external extend change to inner mirror external main */
122     handleMultiScreenInnerMainExternalExtendModeChangeMap_[{
123         ScreenCombination::SCREEN_MIRROR, ScreenCombination::SCREEN_MAIN}] =
124         [this](sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen) {
125             return HandleInnerMainExternalExtendToInnerMirrorExternalMainChange(innerScreen, externalScreen);
126         };
127 }
128 
129 /* inner main external mirror change */
InitMultiScreenInnerMainExternalMirrorModeModeChangeMap()130 void MultiScreenModeChangeManager::InitMultiScreenInnerMainExternalMirrorModeModeChangeMap()
131 {
132     if (handleMultiScreenInnerMainExternalMirrorModeChangeMap_.size() != 0) {
133         TLOGW(WmsLogTag::DMS, "recovery multi screen inner main external mirror mode change map has init!");
134         return;
135     }
136     /* inner main external mirror change to inner main external extend */
137     handleMultiScreenInnerMainExternalMirrorModeChangeMap_[{
138         ScreenCombination::SCREEN_MAIN, ScreenCombination::SCREEN_EXTEND}] =
139         [this](sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen) {
140             return HandleInnerMainExternalMirrorToInnerMainExternalExtendChange(innerScreen, externalScreen);
141         };
142     /* inner main external mirror change to inner mirror external main */
143     handleMultiScreenInnerMainExternalMirrorModeChangeMap_[{
144         ScreenCombination::SCREEN_MIRROR, ScreenCombination::SCREEN_MAIN}] =
145         [this](sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen) {
146             return HandleInnerMainExternalMirrorToInnerMirrorExternalMainChange(innerScreen, externalScreen);
147         };
148     /* inner main external mirror change to inner extend external main */
149     handleMultiScreenInnerMainExternalMirrorModeChangeMap_[{
150         ScreenCombination::SCREEN_EXTEND, ScreenCombination::SCREEN_MAIN}] =
151         [this](sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen) {
152             return HandleInnerMainExternalMirrorToInnerExtendExternalMainChange(innerScreen, externalScreen);
153         };
154 }
155 
156 /* inner extend external main change */
InitMultiScreenInnerExtendExternalMainModeModeChangeMap()157 void MultiScreenModeChangeManager::InitMultiScreenInnerExtendExternalMainModeModeChangeMap()
158 {
159     if (handleMultiScreenInnerExtendExternalMainModeChangeMap_.size() != 0) {
160         TLOGW(WmsLogTag::DMS, "recovery multi screen inner extend external main mode change map has init!");
161         return;
162     }
163     /* inner extend external main change to inner mirror external main */
164     handleMultiScreenInnerExtendExternalMainModeChangeMap_[{
165         ScreenCombination::SCREEN_MIRROR, ScreenCombination::SCREEN_MAIN}] =
166         [this](sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen) {
167             return HandleInnerExtendExternalMainToInnerMirrorExternalMainChange(innerScreen, externalScreen);
168         };
169     /* inner extend external main change to inner main external extend */
170     handleMultiScreenInnerExtendExternalMainModeChangeMap_[{
171         ScreenCombination::SCREEN_MAIN, ScreenCombination::SCREEN_EXTEND}] =
172         [this](sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen) {
173             return HandleInnerExtendExternalMainToInnerMainExternalExtendChange(innerScreen, externalScreen);
174         };
175     /* inner extend external main change to inner main external mirror */
176     handleMultiScreenInnerExtendExternalMainModeChangeMap_[{
177         ScreenCombination::SCREEN_MAIN, ScreenCombination::SCREEN_MIRROR}] =
178         [this](sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen) {
179             return HandleInnerExtendExternalMainToInnerMainExternalMirrorChange(innerScreen, externalScreen);
180         };
181 }
182 
183 /* inner mirror external main change */
InitMultiScreenInnerMirrorExternalMainModeModeChangeMap()184 void MultiScreenModeChangeManager::InitMultiScreenInnerMirrorExternalMainModeModeChangeMap()
185 {
186     if (handleMultiScreenInnerMirrorExternalMainModeChangeMap_.size() != 0) {
187         TLOGW(WmsLogTag::DMS, "recovery multi screen inner mirror external main mode change map has init!");
188         return;
189     }
190     /* inner mirror external main change to inner extend external main */
191     handleMultiScreenInnerMirrorExternalMainModeChangeMap_[{
192         ScreenCombination::SCREEN_EXTEND, ScreenCombination::SCREEN_MAIN}] =
193         [this](sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen) {
194             return HandleInnerMirrorExternalMainToInnerExtendExternalMainChange(innerScreen, externalScreen);
195         };
196     /* inner mirror external main change to inner main external mirror */
197     handleMultiScreenInnerMirrorExternalMainModeChangeMap_[{
198         ScreenCombination::SCREEN_MAIN, ScreenCombination::SCREEN_MIRROR}] =
199         [this](sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen) {
200             return HandleInnerMirrorExternalMainToInnerMainExternalMirrorChange(innerScreen, externalScreen);
201         };
202     /* inner mirror external main change to inner main external extend */
203     handleMultiScreenInnerMirrorExternalMainModeChangeMap_[{
204         ScreenCombination::SCREEN_MAIN, ScreenCombination::SCREEN_EXTEND}] =
205         [this](sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen) {
206             return HandleInnerMirrorExternalMainToInnerMainExternalExtendChange(innerScreen, externalScreen);
207         };
208 }
209 
HandleInnerMainExternalExtendChange(sptr<ScreenSession> & innerScreen,ScreenCombination innerTargetCombination,sptr<ScreenSession> & externalScreen,ScreenCombination externalTargetCombination)210 DMError MultiScreenModeChangeManager::HandleInnerMainExternalExtendChange(
211     sptr<ScreenSession>& innerScreen, ScreenCombination innerTargetCombination,
212     sptr<ScreenSession>& externalScreen, ScreenCombination externalTargetCombination)
213 {
214     DMError handleRet = DMError::DM_OK;
215     if (innerScreen == nullptr || externalScreen == nullptr) {
216         TLOGE(WmsLogTag::DMS, "parameters nullptr.");
217         return DMError::DM_ERROR_NULLPTR;
218     }
219     auto modeHandleCall = handleMultiScreenInnerMainExternalExtendModeChangeMap_.find(
220         {innerTargetCombination, externalTargetCombination});
221     if (modeHandleCall != handleMultiScreenInnerMainExternalExtendModeChangeMap_.end()) {
222         auto modeHandleFunction = modeHandleCall->second;
223         handleRet = modeHandleFunction(innerScreen, externalScreen);
224         MultiScreenChangeUtils::SetExternalScreenOffScreenRendering(innerScreen, externalScreen);
225     } else {
226         TLOGE(WmsLogTag::DMS, "failed to find inner main external extend function handler!");
227         handleRet = DMError::DM_ERROR_INVALID_CALLING;
228     }
229     return handleRet;
230 }
231 
HandleInnerMainExternalMirrorChange(sptr<ScreenSession> & innerScreen,ScreenCombination innerTargetCombination,sptr<ScreenSession> & externalScreen,ScreenCombination externalTargetCombination)232 DMError MultiScreenModeChangeManager::HandleInnerMainExternalMirrorChange(
233     sptr<ScreenSession>& innerScreen, ScreenCombination innerTargetCombination,
234     sptr<ScreenSession>& externalScreen, ScreenCombination externalTargetCombination)
235 {
236     DMError handleRet = DMError::DM_OK;
237     if (innerScreen == nullptr || externalScreen == nullptr) {
238         TLOGE(WmsLogTag::DMS, "parameters nullptr.");
239         return DMError::DM_ERROR_NULLPTR;
240     }
241     auto modeHandleCall = handleMultiScreenInnerMainExternalMirrorModeChangeMap_.find(
242         {innerTargetCombination, externalTargetCombination});
243     if (modeHandleCall != handleMultiScreenInnerMainExternalMirrorModeChangeMap_.end()) {
244         auto modeHandleFunction = modeHandleCall->second;
245         handleRet = modeHandleFunction(innerScreen, externalScreen);
246         MultiScreenChangeUtils::SetExternalScreenOffScreenRendering(innerScreen, externalScreen);
247     } else {
248         TLOGE(WmsLogTag::DMS, "failed to find inner main external mirror function handler!");
249         handleRet = DMError::DM_ERROR_INVALID_CALLING;
250     }
251     return handleRet;
252 }
253 
HandleInnerExtendExternalMainChange(sptr<ScreenSession> & innerScreen,ScreenCombination innerTargetCombination,sptr<ScreenSession> & externalScreen,ScreenCombination externalTargetCombination)254 DMError MultiScreenModeChangeManager::HandleInnerExtendExternalMainChange(
255     sptr<ScreenSession>& innerScreen, ScreenCombination innerTargetCombination,
256     sptr<ScreenSession>& externalScreen, ScreenCombination externalTargetCombination)
257 {
258     DMError handleRet = DMError::DM_OK;
259     if (innerScreen == nullptr || externalScreen == nullptr) {
260         TLOGE(WmsLogTag::DMS, "parameters nullptr.");
261         return DMError::DM_ERROR_NULLPTR;
262     }
263     auto modeHandleCall = handleMultiScreenInnerExtendExternalMainModeChangeMap_.find(
264         {innerTargetCombination, externalTargetCombination});
265     if (modeHandleCall != handleMultiScreenInnerExtendExternalMainModeChangeMap_.end()) {
266         auto modeHandleFunction = modeHandleCall->second;
267         handleRet = modeHandleFunction(innerScreen, externalScreen);
268         MultiScreenChangeUtils::SetExternalScreenOffScreenRendering(innerScreen, externalScreen);
269     } else {
270         TLOGE(WmsLogTag::DMS, "failed to find inner extend external main function handler!");
271         handleRet = DMError::DM_ERROR_INVALID_CALLING;
272     }
273     return handleRet;
274 }
275 
HandleInnerMirrorExternalMainChange(sptr<ScreenSession> & innerScreen,ScreenCombination innerTargetCombination,sptr<ScreenSession> & externalScreen,ScreenCombination externalTargetCombination)276 DMError MultiScreenModeChangeManager::HandleInnerMirrorExternalMainChange(
277     sptr<ScreenSession>& innerScreen, ScreenCombination innerTargetCombination,
278     sptr<ScreenSession>& externalScreen, ScreenCombination externalTargetCombination)
279 {
280     DMError handleRet = DMError::DM_OK;
281     if (innerScreen == nullptr || externalScreen == nullptr) {
282         TLOGE(WmsLogTag::DMS, "parameters nullptr.");
283         return DMError::DM_ERROR_NULLPTR;
284     }
285     auto modeHandleCall = handleMultiScreenInnerMirrorExternalMainModeChangeMap_.find(
286         {innerTargetCombination, externalTargetCombination});
287     if (modeHandleCall != handleMultiScreenInnerMirrorExternalMainModeChangeMap_.end()) {
288         auto modeHandleFunction = modeHandleCall->second;
289         handleRet = modeHandleFunction(innerScreen, externalScreen);
290         MultiScreenChangeUtils::SetExternalScreenOffScreenRendering(innerScreen, externalScreen);
291     } else {
292         TLOGE(WmsLogTag::DMS, "failed to find inner mirror external main function handler!");
293         handleRet = DMError::DM_ERROR_INVALID_CALLING;
294     }
295     return handleRet;
296 }
297 
NotifyClientCreateExtendSessionOnly(sptr<IScreenSessionManagerClient> & ssmClient,sptr<ScreenSession> & screenSession)298 void MultiScreenModeChangeManager::NotifyClientCreateExtendSessionOnly(sptr<IScreenSessionManagerClient>& ssmClient,
299     sptr<ScreenSession>& screenSession)
300 {
301     if (ssmClient == nullptr || screenSession == nullptr) {
302         TLOGE(WmsLogTag::DMS, "displayNode/client/mainSession is nullptr.");
303         return;
304     }
305     TLOGW(WmsLogTag::DMS, "notify client create extend session only.");
306     MultiScreenChangeUtils::CreateExtendSession(screenSession);
307 
308     ssmClient->OnCreateScreenSessionOnly(screenSession->GetScreenId(), screenSession->GetRSScreenId(),
309         screenSession->GetName(), screenSession->GetIsExtend());
310 }
311 
NotifyClientCreateMirrorSessionOnly(sptr<IScreenSessionManagerClient> & ssmClient,sptr<ScreenSession> & screenSession,sptr<ScreenSession> & mainSession)312 void MultiScreenModeChangeManager::NotifyClientCreateMirrorSessionOnly(sptr<IScreenSessionManagerClient>& ssmClient,
313     sptr<ScreenSession>& screenSession, sptr<ScreenSession>& mainSession)
314 {
315     if (ssmClient == nullptr || screenSession == nullptr ||
316         mainSession == nullptr || mainSession->GetDisplayNode() == nullptr) {
317         TLOGE(WmsLogTag::DMS, "displayNode/client/mainSession is nullptr.");
318         return;
319     }
320     TLOGW(WmsLogTag::DMS, "notify client create mirror session only.");
321     MultiScreenChangeUtils::CreateMirrorSession(mainSession, screenSession);
322 
323     ssmClient->OnCreateScreenSessionOnly(screenSession->GetScreenId(), screenSession->GetRSScreenId(),
324         screenSession->GetName(), screenSession->GetIsExtend());
325 }
326 
ScreenChangeToMirrorMode(sptr<IScreenSessionManagerClient> ssmClient,sptr<ScreenSession> & screenSession,sptr<ScreenSession> & mainSession)327 void MultiScreenModeChangeManager::ScreenChangeToMirrorMode(sptr<IScreenSessionManagerClient> ssmClient,
328     sptr<ScreenSession>& screenSession, sptr<ScreenSession>& mainSession)
329 {
330     if (ssmClient == nullptr || screenSession == nullptr || mainSession == nullptr) {
331         TLOGE(WmsLogTag::DMS, "displayNode/client is nullptr.");
332         return;
333     }
334 
335     /* step1: notify client screen disconnect */
336     MultiScreenChangeUtils::ScreenConnectionChange(ssmClient, screenSession, ScreenEvent::DISCONNECTED);
337 
338     /* step2: create external screen mirror */
339     MultiScreenChangeUtils::CreateMirrorSession(mainSession, screenSession);
340 }
341 
ScreenChangeToExtendMode(sptr<IScreenSessionManagerClient> ssmClient,sptr<ScreenSession> & screenSession)342 void MultiScreenModeChangeManager::ScreenChangeToExtendMode(sptr<IScreenSessionManagerClient> ssmClient,
343     sptr<ScreenSession>& screenSession)
344 {
345     /* step1: create external screen mirror */
346     MultiScreenChangeUtils::CreateExtendSession(screenSession);
347 
348     /* step2: notify client external screen connect */
349     MultiScreenChangeUtils::ScreenConnectionChange(ssmClient, screenSession, ScreenEvent::CONNECTED);
350 }
351 
ScreenDisplayNodeChangeNotify(sptr<IScreenSessionManagerClient> ssmClient,sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen)352 DMError MultiScreenModeChangeManager::ScreenDisplayNodeChangeNotify(sptr<IScreenSessionManagerClient> ssmClient,
353     sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen)
354 {
355     ScreenId innerScreenId = innerScreen->GetScreenId();
356     ScreenId externalScreenId = externalScreen->GetScreenId();
357 
358     std::ostringstream oss;
359     oss << "innerScreen screenId: " << innerScreenId
360         << ", rsId: " << innerScreen->GetRSScreenId()
361         << ", externalScreen screenId: " << externalScreenId
362         << ", rsId: " << externalScreen->GetRSScreenId();
363     oss << std::endl;
364     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
365 
366     /* step1: scb client change display node */
367     bool changeRet = ssmClient->OnExtendDisplayNodeChange(innerScreenId, externalScreenId);
368     if (!changeRet) {
369         TLOGE(WmsLogTag::DMS, "client display node change failed.");
370         return DMError::DM_ERROR_REMOTE_CREATE_FAILED;
371     }
372     return DMError::DM_OK;
373 }
374 
375 /* inner main external extend change to inner main external mirror */
HandleInnerMainExternalExtendToInnerMainExternalMirrorChange(sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen)376 DMError MultiScreenModeChangeManager::HandleInnerMainExternalExtendToInnerMainExternalMirrorChange(
377     sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen)
378 {
379     /* step1: check current combination */
380     if (innerScreen->GetScreenCombination() == ScreenCombination::SCREEN_MAIN &&
381         externalScreen->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
382         TLOGE(WmsLogTag::DMS, "current combination not change.");
383         return DMError::DM_OK;
384     }
385     std::string trackInfo = "inner main external extend change to inner main external mirror";
386     MultiScreenChangeUtils::SetMultiScreenModeChangeTracker("InnerMainExternalExtendToInnerMainExternalMirrorChange");
387 
388     std::ostringstream oss;
389     oss << "innerScreen screenId: " << innerScreen->GetScreenId()
390         << ", rsId: " << innerScreen->GetRSScreenId()
391         << ", externalScreen screenId: " << externalScreen->GetScreenId()
392         << ", rsId: " << externalScreen->GetRSScreenId();
393     oss << std::endl;
394     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
395 
396     /* step2: create external screen mirror */
397     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "modeChange[%s]", trackInfo.c_str());
398     sptr<IScreenSessionManagerClient> ssmClient = ScreenSessionManager::GetInstance().GetClientProxy();
399     if (ssmClient == nullptr) {
400         TLOGE(WmsLogTag::DMS, "ssmClient null");
401         return DMError::DM_ERROR_NULLPTR;
402     }
403     ScreenChangeToMirrorMode(ssmClient, externalScreen, innerScreen);
404 
405     /* step3: change inner screen combination */
406     MultiScreenChangeUtils::ScreenCombinationChange(innerScreen, externalScreen, ScreenCombination::SCREEN_MIRROR);
407 
408     /* step4: set inner screen position */
409     MultiScreenChangeUtils::ScreenMainPositionChange(innerScreen, externalScreen);
410     TLOGW(WmsLogTag::DMS, "inner main external extend to inner main external mirror end.");
411     return DMError::DM_OK;
412 }
413 
414 /* inner main external extend change to inner extend external main */
HandleInnerMainExternalExtendToInnerExtendExternalMainChange(sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen)415 DMError MultiScreenModeChangeManager::HandleInnerMainExternalExtendToInnerExtendExternalMainChange(
416     sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen)
417 {
418     /* step1: check current combination */
419     if (innerScreen->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND &&
420         externalScreen->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) {
421         TLOGE(WmsLogTag::DMS, "current combination not change.");
422         return DMError::DM_OK;
423     }
424     std::string trackInfo = "inner main external extend change to inner extend external main";
425     MultiScreenChangeUtils::SetMultiScreenModeChangeTracker("InnerMainExternalExtendToInnerExtendExternalMainChange");
426 
427     std::ostringstream oss;
428     oss << "innerScreen screenId: " << innerScreen->GetScreenId()
429         << ", rsId: " << innerScreen->GetRSScreenId()
430         << ", externalScreen screenId: " << externalScreen->GetScreenId()
431         << ", rsId: " << externalScreen->GetRSScreenId();
432     oss << std::endl;
433     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
434 
435     sptr<IScreenSessionManagerClient> ssmClient = ScreenSessionManager::GetInstance().GetClientProxy();
436     if (ssmClient == nullptr) {
437         TLOGE(WmsLogTag::DMS, "ssmClient null");
438         return DMError::DM_ERROR_NULLPTR;
439     }
440 
441     /* step2: scb client change display node */
442     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "modeChange[%s]", trackInfo.c_str());
443     DMError displayNodeChangeRet = ScreenDisplayNodeChangeNotify(ssmClient, innerScreen, externalScreen);
444     if (displayNodeChangeRet != DMError::DM_OK) {
445         TLOGE(WmsLogTag::DMS, "change displayNode failed.");
446         return displayNodeChangeRet;
447     }
448 
449     /* step3: change physical screen info between inner and external screen */
450     MultiScreenChangeUtils::ScreenPhysicalInfoChange(innerScreen, externalScreen);
451 
452     /* step4: change position */
453     MultiScreenChangeUtils::ScreenExtendPositionChange(innerScreen, externalScreen);
454 
455     /* step5: notify external screen property change */
456     MultiScreenChangeUtils::ScreenPropertyChangeNotify(innerScreen, externalScreen);
457 
458     /* step6: dpi change*/
459     MultiScreenChangeUtils::ScreenDensityChangeNotify(innerScreen, externalScreen);
460 
461     /* step7: screen combination change*/
462     MultiScreenChangeUtils::ScreenCombinationChange(innerScreen, externalScreen, ScreenCombination::SCREEN_EXTEND);
463 
464     return DMError::DM_OK;
465 }
466 
467 /* inner main external extend change to inner mirror external main */
HandleInnerMainExternalExtendToInnerMirrorExternalMainChange(sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen)468 DMError MultiScreenModeChangeManager::HandleInnerMainExternalExtendToInnerMirrorExternalMainChange(
469     sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen)
470 {
471     /* step1: check current combination */
472     if (innerScreen->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR &&
473         externalScreen->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) {
474         TLOGE(WmsLogTag::DMS, "current combination not change.");
475         return DMError::DM_OK;
476     }
477     std::string trackInfo = "inner main external extend change to inner mirror external main";
478     MultiScreenChangeUtils::SetMultiScreenModeChangeTracker("InnerMainExternalExtendToInnerMirrorExternalMainChange");
479 
480     std::ostringstream oss;
481     oss << "innerScreen screenId: " << innerScreen->GetScreenId()
482         << ", rsId: " << innerScreen->GetRSScreenId()
483         << ", externalScreen screenId: " << externalScreen->GetScreenId()
484         << ", rsId: " << externalScreen->GetRSScreenId();
485     oss << std::endl;
486     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
487 
488     sptr<IScreenSessionManagerClient> ssmClient = ScreenSessionManager::GetInstance().GetClientProxy();
489     if (ssmClient == nullptr) {
490         TLOGE(WmsLogTag::DMS, "ssmClient null");
491         return DMError::DM_ERROR_NULLPTR;
492     }
493 
494     /* step2: scb client change display node */
495     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "modeChange[%s]", trackInfo.c_str());
496     DMError displayNodeChangeRet = ScreenDisplayNodeChangeNotify(ssmClient, innerScreen, externalScreen);
497     if (displayNodeChangeRet != DMError::DM_OK) {
498         TLOGE(WmsLogTag::DMS, "change displayNode failed.");
499         return displayNodeChangeRet;
500     }
501 
502     /* step3: change physical screen info between inner and external screen */
503     MultiScreenChangeUtils::ScreenPhysicalInfoChange(innerScreen, externalScreen);
504 
505     /* step4: change position */
506     MultiScreenChangeUtils::ScreenMainPositionChange(innerScreen, externalScreen);
507 
508     /* step5: notify external screen property change */
509     MultiScreenChangeUtils::ScreenPropertyChangeNotify(innerScreen, externalScreen);
510 
511     /* step6: dpi change */
512     MultiScreenChangeUtils::ScreenDensityChangeNotify(innerScreen, externalScreen);
513 
514     /* step7: notify client external screen disconnect and create mirror node */
515     ScreenChangeToMirrorMode(ssmClient, externalScreen, innerScreen);
516 
517     /* step8: screen combination change*/
518     MultiScreenChangeUtils::ScreenCombinationChange(innerScreen, externalScreen, ScreenCombination::SCREEN_MIRROR);
519 
520     return DMError::DM_OK;
521 }
522 
523 /* inner main external mirror change to inner main external extend */
HandleInnerMainExternalMirrorToInnerMainExternalExtendChange(sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen)524 DMError MultiScreenModeChangeManager::HandleInnerMainExternalMirrorToInnerMainExternalExtendChange(
525     sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen)
526 {
527     /* step1: check current combination */
528     if (innerScreen->GetScreenCombination() == ScreenCombination::SCREEN_MAIN &&
529         externalScreen->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND) {
530         TLOGE(WmsLogTag::DMS, "current combination not change.");
531         return DMError::DM_OK;
532     }
533     std::string trackInfo = "inner main external mirror change to inner main external extend";
534     MultiScreenChangeUtils::SetMultiScreenModeChangeTracker("InnerMainExternalMirrorToInnerMainExternalExtendChange");
535 
536     std::ostringstream oss;
537     oss << "innerScreen screenId: " << innerScreen->GetScreenId()
538         << ", rsId: " << innerScreen->GetRSScreenId()
539         << ", externalScreen screenId: " << externalScreen->GetScreenId()
540         << ", rsId: " << externalScreen->GetRSScreenId();
541     oss << std::endl;
542     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
543 
544     /* step2: change external screen from mirror to extend */
545     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "modeChange[%s]", trackInfo.c_str());
546     sptr<IScreenSessionManagerClient> ssmClient = ScreenSessionManager::GetInstance().GetClientProxy();
547     if (ssmClient == nullptr) {
548         TLOGE(WmsLogTag::DMS, "ssmClient null");
549         return DMError::DM_ERROR_NULLPTR;
550     }
551     ScreenChangeToExtendMode(ssmClient, externalScreen);
552 
553     /* step3: set inner screen combination */
554     MultiScreenChangeUtils::ScreenCombinationChange(innerScreen, externalScreen, ScreenCombination::SCREEN_EXTEND);
555 
556     /* step4: set relative position */
557     MultiScreenChangeUtils::ScreenExtendPositionChange(innerScreen, externalScreen);
558     return DMError::DM_OK;
559 }
560 
561 /* inner main external mirror change to inner mirror external main */
HandleInnerMainExternalMirrorToInnerMirrorExternalMainChange(sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen)562 DMError MultiScreenModeChangeManager::HandleInnerMainExternalMirrorToInnerMirrorExternalMainChange(
563     sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen)
564 {
565     /* step1: check current combination */
566     if (innerScreen->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR &&
567         externalScreen->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) {
568         TLOGE(WmsLogTag::DMS, "current combination not change.");
569         return DMError::DM_OK;
570     }
571     std::string trackInfo = "inner main external mirror change to inner mirror external main";
572     MultiScreenChangeUtils::SetMultiScreenModeChangeTracker("InnerMainExternalMirrorToInnerMirrorExternalMainChange");
573 
574     std::ostringstream oss;
575     oss << "innerScreen screenId: " << innerScreen->GetScreenId()
576         << ", rsId: " << innerScreen->GetRSScreenId()
577         << ", externalScreen screenId: " << externalScreen->GetScreenId()
578         << ", rsId: " << externalScreen->GetRSScreenId();
579     oss << std::endl;
580     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
581 
582     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "modeChange[%s]", trackInfo.c_str());
583     sptr<IScreenSessionManagerClient> ssmClient = ScreenSessionManager::GetInstance().GetClientProxy();
584     if (ssmClient == nullptr) {
585         TLOGE(WmsLogTag::DMS, "ssmClient null");
586         return DMError::DM_ERROR_NULLPTR;
587     }
588     /* step2: change external mirror to extend mode */
589     NotifyClientCreateMirrorSessionOnly(ssmClient, externalScreen, innerScreen);
590 
591     /* step3: notify scb change displayNode */
592     DMError displayNodeChangeRet = ScreenDisplayNodeChangeNotify(ssmClient, innerScreen, externalScreen);
593     if (displayNodeChangeRet != DMError::DM_OK) {
594         TLOGE(WmsLogTag::DMS, "change displayNode failed.");
595         return displayNodeChangeRet;
596     }
597 
598     /* step4: change physical screen info between inner and external screen */
599     MultiScreenChangeUtils::ScreenPhysicalInfoChange(innerScreen, externalScreen);
600 
601     /* step5: change position */
602     MultiScreenChangeUtils::ScreenMainPositionChange(innerScreen, externalScreen);
603 
604     /* step6: notify external screen property change */
605     MultiScreenChangeUtils::ScreenPropertyChangeNotify(innerScreen, externalScreen);
606 
607     /* step7: dpi change */
608     MultiScreenChangeUtils::ScreenDensityChangeNotify(innerScreen, externalScreen);
609 
610     /* step8: screen combination change */
611     MultiScreenChangeUtils::ScreenCombinationChange(innerScreen, externalScreen, ScreenCombination::SCREEN_MIRROR);
612     return DMError::DM_OK;
613 }
614 
615 /* inner main external mirror change to inner extend external main */
HandleInnerMainExternalMirrorToInnerExtendExternalMainChange(sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen)616 DMError MultiScreenModeChangeManager::HandleInnerMainExternalMirrorToInnerExtendExternalMainChange(
617     sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen)
618 {
619     /* step1: check current combination */
620     if (innerScreen->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND &&
621         externalScreen->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) {
622         TLOGE(WmsLogTag::DMS, "current combination not change.");
623         return DMError::DM_OK;
624     }
625     std::string trackInfo = "inner main external mirror change to inner extend external main";
626     MultiScreenChangeUtils::SetMultiScreenModeChangeTracker("InnerMainExternalMirrorToInnerExtendExternalMainChange");
627 
628     std::ostringstream oss;
629     oss << "innerScreen screenId: " << innerScreen->GetScreenId()
630         << ", rsId: " << innerScreen->GetRSScreenId()
631         << ", externalScreen screenId: " << externalScreen->GetScreenId()
632         << ", rsId: " << externalScreen->GetRSScreenId();
633     oss << std::endl;
634     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
635 
636     /* step2: create screen session for client */
637     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "modeChange[%s]", trackInfo.c_str());
638     sptr<IScreenSessionManagerClient> ssmClient = ScreenSessionManager::GetInstance().GetClientProxy();
639     if (ssmClient == nullptr) {
640         TLOGE(WmsLogTag::DMS, "ssmClient null");
641         return DMError::DM_ERROR_NULLPTR;
642     }
643 
644     /* step3: notify client create session only */
645     NotifyClientCreateExtendSessionOnly(ssmClient, externalScreen);
646 
647     /* step4: notify scb change displayNode */
648     DMError displayNodeChangeRet = ScreenDisplayNodeChangeNotify(ssmClient, innerScreen, externalScreen);
649     if (displayNodeChangeRet != DMError::DM_OK) {
650         TLOGE(WmsLogTag::DMS, "change displayNode failed.");
651         return displayNodeChangeRet;
652     }
653 
654     /* step5: change physical screen info between inner and external screen */
655     MultiScreenChangeUtils::ScreenPhysicalInfoChange(innerScreen, externalScreen);
656 
657     /* step6: change position */
658     MultiScreenChangeUtils::ScreenExtendPositionChange(innerScreen, externalScreen);
659 
660     /* step7: notify external screen property change */
661     MultiScreenChangeUtils::ScreenPropertyChangeNotify(innerScreen, externalScreen);
662 
663     /* step8: dpi change */
664     MultiScreenChangeUtils::ScreenDensityChangeNotify(innerScreen, externalScreen);
665 
666     /* step9: screen combination change */
667     MultiScreenChangeUtils::ScreenCombinationChange(innerScreen, externalScreen,
668         ScreenCombination::SCREEN_EXTEND);
669 
670     return DMError::DM_OK;
671 }
672 
673 /* inner extend external main change to inner mirror external main */
HandleInnerExtendExternalMainToInnerMirrorExternalMainChange(sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen)674 DMError MultiScreenModeChangeManager::HandleInnerExtendExternalMainToInnerMirrorExternalMainChange(
675     sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen)
676 {
677     /* step1: check current combination */
678     if (innerScreen->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR &&
679         externalScreen->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) {
680         TLOGE(WmsLogTag::DMS, "current combination not change.");
681         return DMError::DM_OK;
682     }
683     std::string trackInfo = "inner extend external main change to inner mirror external main";
684     MultiScreenChangeUtils::SetMultiScreenModeChangeTracker("InnerExtendExternalMainToInnerMirrorExternalMainChange");
685 
686     std::ostringstream oss;
687     oss << "innerScreen screenId: " << innerScreen->GetScreenId()
688         << ", rsId: " << innerScreen->GetRSScreenId()
689         << ", externalScreen screenId: " << externalScreen->GetScreenId()
690         << ", rsId: " << externalScreen->GetRSScreenId();
691     oss << std::endl;
692     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
693 
694     /* step2: notify client screen disconnect */
695     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "modeChange[%s]", trackInfo.c_str());
696     sptr<IScreenSessionManagerClient> ssmClient = ScreenSessionManager::GetInstance().GetClientProxy();
697     if (ssmClient == nullptr) {
698         TLOGE(WmsLogTag::DMS, "ssmClient null");
699         return DMError::DM_ERROR_NULLPTR;
700     }
701 
702     /* step3: create external screen mirror */
703     ScreenChangeToMirrorMode(ssmClient, innerScreen, externalScreen);
704 
705     /* step4: change inner screen combination */
706     MultiScreenChangeUtils::ScreenCombinationChange(innerScreen, externalScreen, ScreenCombination::SCREEN_MIRROR);
707 
708     /* step5: set inner screen position */
709     MultiScreenChangeUtils::ScreenMainPositionChange(externalScreen, innerScreen);
710     return DMError::DM_OK;
711 }
712 
713 /* inner extend external main change to inner main external extend */
HandleInnerExtendExternalMainToInnerMainExternalExtendChange(sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen)714 DMError MultiScreenModeChangeManager::HandleInnerExtendExternalMainToInnerMainExternalExtendChange(
715     sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen)
716 {
717     /* step1: check current combination */
718     if (innerScreen->GetScreenCombination() == ScreenCombination::SCREEN_MAIN &&
719         externalScreen->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND) {
720         TLOGE(WmsLogTag::DMS, "current combination not change.");
721         return DMError::DM_OK;
722     }
723     std::string trackInfo = "inner extend external main change to inner main external extend";
724     MultiScreenChangeUtils::SetMultiScreenModeChangeTracker("InnerExtendExternalMainToInnerMainExternalExtendChange");
725 
726     std::ostringstream oss;
727     oss << "innerScreen screenId: " << innerScreen->GetScreenId()
728         << ", rsId: " << innerScreen->GetRSScreenId()
729         << ", externalScreen screenId: " << externalScreen->GetScreenId()
730         << ", rsId: " << externalScreen->GetRSScreenId();
731     oss << std::endl;
732     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
733 
734     /* step2: create screenSession for client */
735     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "modeChange[%s]", trackInfo.c_str());
736     sptr<IScreenSessionManagerClient> ssmClient = ScreenSessionManager::GetInstance().GetClientProxy();
737     if (ssmClient == nullptr) {
738         TLOGE(WmsLogTag::DMS, "ssmClient null");
739         return DMError::DM_ERROR_NULLPTR;
740     }
741 
742     /* step3: notify scb change displayNode */
743     DMError displayNodeChangeRet = ScreenDisplayNodeChangeNotify(ssmClient, innerScreen, externalScreen);
744     if (displayNodeChangeRet != DMError::DM_OK) {
745         TLOGE(WmsLogTag::DMS, "change displayNode failed.");
746         return displayNodeChangeRet;
747     }
748 
749     /* step4: change physical screen info between inner and external screen */
750     MultiScreenChangeUtils::ScreenPhysicalInfoChange(innerScreen, externalScreen);
751 
752     /* step5: change position */
753     MultiScreenChangeUtils::ScreenExtendPositionChange(innerScreen, externalScreen);
754 
755     /* step6: notify external screen property change */
756     MultiScreenChangeUtils::ScreenPropertyChangeNotify(innerScreen, externalScreen);
757 
758     /* step7: dpi change */
759     MultiScreenChangeUtils::ScreenDensityChangeNotify(innerScreen, externalScreen);
760 
761     /* step8: screen combination change */
762     MultiScreenChangeUtils::ScreenCombinationChange(externalScreen, innerScreen, ScreenCombination::SCREEN_EXTEND);
763 
764     return DMError::DM_OK;
765 }
766 
767 /* inner extend external main change to inner main external mirror */
HandleInnerExtendExternalMainToInnerMainExternalMirrorChange(sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen)768 DMError MultiScreenModeChangeManager::HandleInnerExtendExternalMainToInnerMainExternalMirrorChange(
769     sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen)
770 {
771     /* step1: check current combination */
772     if (innerScreen->GetScreenCombination() == ScreenCombination::SCREEN_MAIN &&
773         externalScreen->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
774         TLOGE(WmsLogTag::DMS, "current combination not change.");
775         return DMError::DM_OK;
776     }
777     std::string trackInfo = "inner extend external main change to inner main external mirror";
778     MultiScreenChangeUtils::SetMultiScreenModeChangeTracker("InnerExtendExternalMainToInnerMainExternalMirrorChange");
779 
780     std::ostringstream oss;
781     oss << "innerScreen screenId: " << innerScreen->GetScreenId()
782         << ", rsId: " << innerScreen->GetRSScreenId()
783         << ", externalScreen screenId: " << externalScreen->GetScreenId()
784         << ", rsId: " << externalScreen->GetRSScreenId();
785     oss << std::endl;
786     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
787 
788     /* step2: create screenSession for client */
789     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "modeChange[%s]", trackInfo.c_str());
790     sptr<IScreenSessionManagerClient> ssmClient = ScreenSessionManager::GetInstance().GetClientProxy();
791     if (ssmClient == nullptr) {
792         TLOGE(WmsLogTag::DMS, "ssmClient null");
793         return DMError::DM_ERROR_NULLPTR;
794     }
795 
796     /* step3: notify scb change displayNode */
797     DMError displayNodeChangeRet = ScreenDisplayNodeChangeNotify(ssmClient, innerScreen, externalScreen);
798     if (displayNodeChangeRet != DMError::DM_OK) {
799         TLOGE(WmsLogTag::DMS, "change displayNode failed.");
800         return displayNodeChangeRet;
801     }
802 
803     /* step4: change physical screen info between inner and external screen */
804     MultiScreenChangeUtils::ScreenPhysicalInfoChange(innerScreen, externalScreen);
805 
806     /* step5: change position */
807     MultiScreenChangeUtils::ScreenMainPositionChange(externalScreen, innerScreen);
808 
809     /* step5: notify external screen property change */
810     MultiScreenChangeUtils::ScreenPropertyChangeNotify(innerScreen, externalScreen);
811 
812     /* step6: dpi change*/
813     MultiScreenChangeUtils::ScreenDensityChangeNotify(innerScreen, externalScreen);
814 
815     /* step7: notify client external screen disconnect and create mirror node */
816     ScreenChangeToMirrorMode(ssmClient, innerScreen, externalScreen);
817 
818     /* step8: change inner screen combination */
819     MultiScreenChangeUtils::ScreenCombinationChange(externalScreen, innerScreen, ScreenCombination::SCREEN_MIRROR);
820 
821     return DMError::DM_OK;
822 }
823 
824 /* inner mirror external main change to inner extend external main */
HandleInnerMirrorExternalMainToInnerExtendExternalMainChange(sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen)825 DMError MultiScreenModeChangeManager::HandleInnerMirrorExternalMainToInnerExtendExternalMainChange(
826     sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen)
827 {
828     /* step1: check current combination */
829     if (innerScreen->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND &&
830         externalScreen->GetScreenCombination() == ScreenCombination::SCREEN_MAIN) {
831         TLOGE(WmsLogTag::DMS, "current combination not change.");
832         return DMError::DM_OK;
833     }
834     std::string trackInfo = "inner mirror external main change to inner extend external main";
835     MultiScreenChangeUtils::SetMultiScreenModeChangeTracker("InnerMirrorExternalMainToInnerExtendExternalMainChange");
836 
837     std::ostringstream oss;
838     oss << "innerScreen screenId: " << innerScreen->GetScreenId()
839         << ", rsId: " << innerScreen->GetRSScreenId()
840         << ", externalScreen screenId: " << externalScreen->GetScreenId()
841         << ", rsId: " << externalScreen->GetRSScreenId();
842     oss << std::endl;
843     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
844 
845     /* step2: create inner extend mode */
846     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "modeChange[%s]", trackInfo.c_str());
847     sptr<IScreenSessionManagerClient> ssmClient = ScreenSessionManager::GetInstance().GetClientProxy();
848     if (ssmClient == nullptr) {
849         TLOGE(WmsLogTag::DMS, "ssmClient null");
850         return DMError::DM_ERROR_NULLPTR;
851     }
852     ScreenChangeToExtendMode(ssmClient, innerScreen);
853 
854     /* step3: change external screen combination */
855     MultiScreenChangeUtils::ScreenCombinationChange(externalScreen, innerScreen, ScreenCombination::SCREEN_EXTEND);
856 
857     /* step4: set inner screen position */
858     MultiScreenChangeUtils::ScreenExtendPositionChange(externalScreen, innerScreen);
859 
860     return DMError::DM_OK;
861 }
862 
863 /* inner mirror external main change to inner main external mirror */
HandleInnerMirrorExternalMainToInnerMainExternalMirrorChange(sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen)864 DMError MultiScreenModeChangeManager::HandleInnerMirrorExternalMainToInnerMainExternalMirrorChange(
865     sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen)
866 {
867     /* step1: check current combination */
868     if (innerScreen->GetScreenCombination() == ScreenCombination::SCREEN_MAIN &&
869         externalScreen->GetScreenCombination() == ScreenCombination::SCREEN_MIRROR) {
870         TLOGE(WmsLogTag::DMS, "current combination not change.");
871         return DMError::DM_OK;
872     }
873     std::string trackInfo = "inner mirror external main change to inner main external mirror";
874     MultiScreenChangeUtils::SetMultiScreenModeChangeTracker("InnerMirrorExternalMainToInnerMainExternalMirrorChange");
875 
876     std::ostringstream oss;
877     oss << "innerScreen screenId: " << innerScreen->GetScreenId()
878         << ", rsId: " << innerScreen->GetRSScreenId()
879         << ", externalScreen screenId: " << externalScreen->GetScreenId()
880         << ", rsId: " << externalScreen->GetRSScreenId();
881     oss << std::endl;
882     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
883 
884     /* step2: create client inner session only */
885     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "modeChange[%s]", trackInfo.c_str());
886     sptr<IScreenSessionManagerClient> ssmClient = ScreenSessionManager::GetInstance().GetClientProxy();
887     if (ssmClient == nullptr) {
888         TLOGE(WmsLogTag::DMS, "ssmClient null");
889         return DMError::DM_ERROR_NULLPTR;
890     }
891     NotifyClientCreateMirrorSessionOnly(ssmClient, innerScreen, externalScreen);
892 
893     /* step3: notify client change displayNode */
894     DMError displayNodeChangeRet = ScreenDisplayNodeChangeNotify(ssmClient, innerScreen, externalScreen);
895     if (displayNodeChangeRet != DMError::DM_OK) {
896         TLOGE(WmsLogTag::DMS, "change displayNode failed.");
897         return displayNodeChangeRet;
898     }
899 
900     /* step4: change physical screen info between inner and external screen */
901     MultiScreenChangeUtils::ScreenPhysicalInfoChange(innerScreen, externalScreen);
902 
903     /* step5: change position */
904     MultiScreenChangeUtils::ScreenMainPositionChange(innerScreen, externalScreen);
905 
906     /* step6: notify external screen property change */
907     MultiScreenChangeUtils::ScreenPropertyChangeNotify(innerScreen, externalScreen);
908 
909     /* step7: dpi change */
910     MultiScreenChangeUtils::ScreenDensityChangeNotify(innerScreen, nullptr);
911 
912     /* step8: combination change */
913     MultiScreenChangeUtils::ScreenCombinationChange(externalScreen, innerScreen, ScreenCombination::SCREEN_MIRROR);
914 
915     return DMError::DM_OK;
916 }
917 
918 /* inner mirror external main change to inner main external extend */
HandleInnerMirrorExternalMainToInnerMainExternalExtendChange(sptr<ScreenSession> & innerScreen,sptr<ScreenSession> & externalScreen)919 DMError MultiScreenModeChangeManager::HandleInnerMirrorExternalMainToInnerMainExternalExtendChange(
920     sptr<ScreenSession>& innerScreen, sptr<ScreenSession>& externalScreen)
921 {
922     /* step1: check current combination */
923     if (innerScreen->GetScreenCombination() == ScreenCombination::SCREEN_MAIN &&
924         externalScreen->GetScreenCombination() == ScreenCombination::SCREEN_EXTEND) {
925         TLOGE(WmsLogTag::DMS, "current combination not change.");
926         return DMError::DM_OK;
927     }
928     std::string trackInfo = "inner mirror external main change to inner main external extend";
929     MultiScreenChangeUtils::SetMultiScreenModeChangeTracker("InnerMirrorExternalMainToInnerMainExternalExtendChange");
930 
931     /* step2: create client inner session only */
932     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "modeChange[%s]", trackInfo.c_str());
933     sptr<IScreenSessionManagerClient> ssmClient = ScreenSessionManager::GetInstance().GetClientProxy();
934     if (ssmClient == nullptr) {
935         TLOGE(WmsLogTag::DMS, "ssmClient null");
936         return DMError::DM_ERROR_NULLPTR;
937     }
938 
939     std::ostringstream oss;
940     oss << "innerScreen screenId: " << innerScreen->GetScreenId()
941         << ", rsId: " << innerScreen->GetRSScreenId()
942         << ", externalScreen screenId: " << externalScreen->GetScreenId()
943         << ", rsId: " << externalScreen->GetRSScreenId();
944     oss << std::endl;
945     TLOGW(WmsLogTag::DMS, "%{public}s", oss.str().c_str());
946 
947     /* step3: change client inner session only*/
948     NotifyClientCreateExtendSessionOnly(ssmClient, innerScreen);
949 
950     /* step4: change client and local displayNode */
951     DMError displayNodeChangeRet = ScreenDisplayNodeChangeNotify(ssmClient, innerScreen, externalScreen);
952     if (displayNodeChangeRet != DMError::DM_OK) {
953         TLOGE(WmsLogTag::DMS, "change displayNode failed.");
954         return displayNodeChangeRet;
955     }
956 
957     /* step5: change physical screen info between inner and external screen */
958     MultiScreenChangeUtils::ScreenPhysicalInfoChange(innerScreen, externalScreen);
959 
960     /* step6: change to extend mode*/
961     ScreenChangeToExtendMode(ssmClient, innerScreen);
962 
963     /* step7: notify external screen property change */
964     MultiScreenChangeUtils::ScreenPropertyChangeNotify(innerScreen, externalScreen);
965 
966     /* step8: dpi change */
967     MultiScreenChangeUtils::ScreenDensityChangeNotify(innerScreen, externalScreen);
968 
969     /* step9: set inner and external screen combination */
970     MultiScreenChangeUtils::ScreenCombinationChange(externalScreen, innerScreen, ScreenCombination::SCREEN_EXTEND);
971 
972     /* step10: change position */
973     MultiScreenChangeUtils::ScreenExtendPositionChange(innerScreen, externalScreen);
974 
975     return DMError::DM_OK;
976 }
977 
MultiScreenModeChangeManager()978 MultiScreenModeChangeManager::MultiScreenModeChangeManager()
979 {
980     /* init screen mode change map */
981     InitMultiScreenModeChangeMap();
982 
983     /* init inner main external extend mode change map */
984     InitMultiScreenInnerMainExternalExtendModeModeChangeMap();
985 
986     /* init inner main external mirror mode change map */
987     InitMultiScreenInnerMainExternalMirrorModeModeChangeMap();
988 
989     /* init inner extend external main mode change map */
990     InitMultiScreenInnerExtendExternalMainModeModeChangeMap();
991 
992     /* init inner mirror external main mode change map */
993     InitMultiScreenInnerMirrorExternalMainModeModeChangeMap();
994 
995     TLOGW(WmsLogTag::DMS, "init multi screen mode change map.");
996 }
997 
~MultiScreenModeChangeManager()998 MultiScreenModeChangeManager::~MultiScreenModeChangeManager()
999 {
1000     handleMultiScreenModeChangeMap_.clear();
1001     handleMultiScreenInnerMainExternalExtendModeChangeMap_.clear();
1002     handleMultiScreenInnerMainExternalMirrorModeChangeMap_.clear();
1003     handleMultiScreenInnerExtendExternalMainModeChangeMap_.clear();
1004     handleMultiScreenInnerMirrorExternalMainModeChangeMap_.clear();
1005     TLOGI(WmsLogTag::DMS, "destructor");
1006 }
1007 } // namespace OHOS::Rosen