16e80583aSopenharmony_ci/**
26e80583aSopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
36e80583aSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
46e80583aSopenharmony_ci * you may not use this file except in compliance with the License.
56e80583aSopenharmony_ci * You may obtain a copy of the License at
66e80583aSopenharmony_ci *
76e80583aSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0
86e80583aSopenharmony_ci *
96e80583aSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
106e80583aSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
116e80583aSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
126e80583aSopenharmony_ci * See the License for the specific language governing permissions and
136e80583aSopenharmony_ci * limitations under the License.
146e80583aSopenharmony_ci */
156e80583aSopenharmony_ci
166e80583aSopenharmony_ciimport window from '@ohos.window';
176e80583aSopenharmony_ciimport display from '@ohos.display';
186e80583aSopenharmony_ciimport commonEventMgr from '@ohos.commonEventManager';
196e80583aSopenharmony_ciimport common from '@ohos.app.ability.common';
206e80583aSopenharmony_ciimport { AsyncCallback, BusinessError } from '@ohos.base';
216e80583aSopenharmony_ciimport AbilityConstant from '@ohos.app.ability.AbilityConstant';
226e80583aSopenharmony_ciimport commonEventManager from './CommonEventManager'
236e80583aSopenharmony_ciimport { Log } from '../utils/Log';
246e80583aSopenharmony_ciimport { StyleConstants } from '../constants/StyleConstants';
256e80583aSopenharmony_ci
266e80583aSopenharmony_ciconst TAG = 'WindowManager';
276e80583aSopenharmony_ci
286e80583aSopenharmony_ci/**
296e80583aSopenharmony_ci * Wrapper class for window interfaces.
306e80583aSopenharmony_ci */
316e80583aSopenharmony_ciclass WindowManager {
326e80583aSopenharmony_ci  private mDisplayData: display.Display | null = null;
336e80583aSopenharmony_ci
346e80583aSopenharmony_ci  private static subscriber: commonEventMgr.CommonEventSubscriber;
356e80583aSopenharmony_ci
366e80583aSopenharmony_ci  private static eventCallback: AsyncCallback<commonEventMgr.CommonEventData>;
376e80583aSopenharmony_ci
386e80583aSopenharmony_ci  RECENT_WINDOW_NAME = 'RecentView';
396e80583aSopenharmony_ci
406e80583aSopenharmony_ci  DESKTOP_WINDOW_NAME = 'EntryView';
416e80583aSopenharmony_ci
426e80583aSopenharmony_ci  APP_CENTER_WINDOW_NAME = 'AppCenterView';
436e80583aSopenharmony_ci
446e80583aSopenharmony_ci  FORM_MANAGER_WINDOW_NAME = 'FormManagerView';
456e80583aSopenharmony_ci
466e80583aSopenharmony_ci  FORM_SERVICE_WINDOW_NAME = 'FormServiceView';
476e80583aSopenharmony_ci
486e80583aSopenharmony_ci  DESKTOP_RANK = window.WindowType.TYPE_DESKTOP;
496e80583aSopenharmony_ci
506e80583aSopenharmony_ci  RECENT_RANK = window.WindowType.TYPE_LAUNCHER_RECENT;
516e80583aSopenharmony_ci
526e80583aSopenharmony_ci  DOCK_RANK = window.WindowType.TYPE_LAUNCHER_DOCK;
536e80583aSopenharmony_ci
546e80583aSopenharmony_ci  recentMode?: number;
556e80583aSopenharmony_ci
566e80583aSopenharmony_ci  /**
576e80583aSopenharmony_ci   * get WindowManager instance
586e80583aSopenharmony_ci   *
596e80583aSopenharmony_ci   * @return WindowManager singleton
606e80583aSopenharmony_ci   */
616e80583aSopenharmony_ci  static getInstance(): WindowManager {
626e80583aSopenharmony_ci    if (globalThis.WindowManager == null) {
636e80583aSopenharmony_ci      globalThis.WindowManager = new WindowManager();
646e80583aSopenharmony_ci      this.eventCallback = this.winEventCallback.bind(this);
656e80583aSopenharmony_ci      this.initSubscriber();
666e80583aSopenharmony_ci    }
676e80583aSopenharmony_ci    return globalThis.WindowManager;
686e80583aSopenharmony_ci  }
696e80583aSopenharmony_ci
706e80583aSopenharmony_ci  /**
716e80583aSopenharmony_ci   * get window width
726e80583aSopenharmony_ci   *
736e80583aSopenharmony_ci   * @return windowWidth
746e80583aSopenharmony_ci   */
756e80583aSopenharmony_ci  getWindowWidth(): number {
766e80583aSopenharmony_ci    if (this.mDisplayData == null) {
776e80583aSopenharmony_ci      this.mDisplayData = this.getWindowDisplayData();
786e80583aSopenharmony_ci    }
796e80583aSopenharmony_ci    return this.mDisplayData?.width as number;
806e80583aSopenharmony_ci  }
816e80583aSopenharmony_ci
826e80583aSopenharmony_ci  /**
836e80583aSopenharmony_ci   * get window height
846e80583aSopenharmony_ci   *
856e80583aSopenharmony_ci   * @return windowHeight
866e80583aSopenharmony_ci   */
876e80583aSopenharmony_ci  getWindowHeight(): number {
886e80583aSopenharmony_ci    if (this.mDisplayData == null) {
896e80583aSopenharmony_ci      this.mDisplayData = this.getWindowDisplayData();
906e80583aSopenharmony_ci    }
916e80583aSopenharmony_ci    return this.mDisplayData?.height as number;
926e80583aSopenharmony_ci  }
936e80583aSopenharmony_ci
946e80583aSopenharmony_ci  private getWindowDisplayData(): display.Display | null {
956e80583aSopenharmony_ci    let displayData: display.Display | null = null;
966e80583aSopenharmony_ci    try {
976e80583aSopenharmony_ci      displayData = display.getDefaultDisplaySync();
986e80583aSopenharmony_ci    } catch(err) {
996e80583aSopenharmony_ci      Log.showError(TAG, `display.getDefaultDisplaySync error: ${JSON.stringify(err)}`);
1006e80583aSopenharmony_ci    }
1016e80583aSopenharmony_ci    return displayData;
1026e80583aSopenharmony_ci  }
1036e80583aSopenharmony_ci
1046e80583aSopenharmony_ci  isSplitWindowMode(mode): boolean {
1056e80583aSopenharmony_ci    if ((mode === AbilityConstant.WindowMode.WINDOW_MODE_SPLIT_PRIMARY) ||
1066e80583aSopenharmony_ci    (mode === AbilityConstant.WindowMode.WINDOW_MODE_SPLIT_SECONDARY)) {
1076e80583aSopenharmony_ci      return true;
1086e80583aSopenharmony_ci    }
1096e80583aSopenharmony_ci    return false;
1106e80583aSopenharmony_ci  }
1116e80583aSopenharmony_ci
1126e80583aSopenharmony_ci  /**
1136e80583aSopenharmony_ci   * set window size
1146e80583aSopenharmony_ci   *
1156e80583aSopenharmony_ci   * @param width window width
1166e80583aSopenharmony_ci   * @param height window height
1176e80583aSopenharmony_ci   */
1186e80583aSopenharmony_ci  async setWindowSize(width: number, height: number): Promise<void> {
1196e80583aSopenharmony_ci    const abilityWindow = await window.getLastWindow(globalThis.desktopContext as common.BaseContext);
1206e80583aSopenharmony_ci    void abilityWindow.resize(width, height);
1216e80583aSopenharmony_ci  }
1226e80583aSopenharmony_ci
1236e80583aSopenharmony_ci  /**
1246e80583aSopenharmony_ci   * set window position
1256e80583aSopenharmony_ci   *
1266e80583aSopenharmony_ci   * @param x coordinate x
1276e80583aSopenharmony_ci   * @param y coordinate y
1286e80583aSopenharmony_ci   */
1296e80583aSopenharmony_ci  async setWindowPosition(x: number, y: number): Promise<void> {
1306e80583aSopenharmony_ci    const abilityWindow = await window.getLastWindow(globalThis.desktopContext as common.BaseContext);
1316e80583aSopenharmony_ci    void abilityWindow.moveWindowTo(x, y);
1326e80583aSopenharmony_ci  }
1336e80583aSopenharmony_ci
1346e80583aSopenharmony_ci  /**
1356e80583aSopenharmony_ci   * 隐藏状态栏
1366e80583aSopenharmony_ci   *
1376e80583aSopenharmony_ci   * @param name windowName
1386e80583aSopenharmony_ci   */
1396e80583aSopenharmony_ci  hideWindowStatusBar(name: string) {
1406e80583aSopenharmony_ci    let names: Array<'status'|'navigation'> = ['navigation'];
1416e80583aSopenharmony_ci    this.setWindowSystemBar(name, names);
1426e80583aSopenharmony_ci  }
1436e80583aSopenharmony_ci
1446e80583aSopenharmony_ci  /**
1456e80583aSopenharmony_ci   * 显示状态栏
1466e80583aSopenharmony_ci   *
1476e80583aSopenharmony_ci   * @param name
1486e80583aSopenharmony_ci   */
1496e80583aSopenharmony_ci  showWindowStatusBar(name: string) {
1506e80583aSopenharmony_ci    let names: Array<'status'|'navigation'> = ['navigation', 'status'];
1516e80583aSopenharmony_ci    this.setWindowSystemBar(name, names);
1526e80583aSopenharmony_ci  }
1536e80583aSopenharmony_ci
1546e80583aSopenharmony_ci  /**
1556e80583aSopenharmony_ci   * 设置状态栏与导航栏显隐
1566e80583aSopenharmony_ci   *
1576e80583aSopenharmony_ci   * @param windowName
1586e80583aSopenharmony_ci   * @param names 值为 'status'|'navigation' 枚举
1596e80583aSopenharmony_ci   */
1606e80583aSopenharmony_ci  private setWindowSystemBar(windowName: string, names: Array<'status'|'navigation'>) {
1616e80583aSopenharmony_ci    this.findWindow(windowName, win => {
1626e80583aSopenharmony_ci      win.setWindowSystemBarEnable(names).then(() => {
1636e80583aSopenharmony_ci        Log.showInfo(TAG, 'set statusBar success');
1646e80583aSopenharmony_ci      }).catch(err => {
1656e80583aSopenharmony_ci        Log.showInfo(TAG, `set statusBar failed, Cause: ${JSON.stringify(err)}`);
1666e80583aSopenharmony_ci      })
1676e80583aSopenharmony_ci    })
1686e80583aSopenharmony_ci  }
1696e80583aSopenharmony_ci
1706e80583aSopenharmony_ci  createWindow(context: common.ServiceExtensionContext, name: string, windowType: number, loadContent: string,
1716e80583aSopenharmony_ci               isShow: boolean, callback?: Function) {
1726e80583aSopenharmony_ci    let cfg: window.Configuration = {
1736e80583aSopenharmony_ci      name: name,
1746e80583aSopenharmony_ci      windowType: windowType,
1756e80583aSopenharmony_ci      ctx: context
1766e80583aSopenharmony_ci    };
1776e80583aSopenharmony_ci    try {
1786e80583aSopenharmony_ci      window.createWindow(cfg)
1796e80583aSopenharmony_ci        .then((win: window.Window) => {
1806e80583aSopenharmony_ci          win.setPreferredOrientation(window.Orientation.AUTO_ROTATION_RESTRICTED);
1816e80583aSopenharmony_ci          win.setUIContent(loadContent)
1826e80583aSopenharmony_ci            .then(() => {
1836e80583aSopenharmony_ci              win.setWindowSystemBarProperties({
1846e80583aSopenharmony_ci                navigationBarColor: StyleConstants.DEFAULT_SYSTEM_UI_COLOR,
1856e80583aSopenharmony_ci                statusBarColor: StyleConstants.DEFAULT_SYSTEM_UI_COLOR
1866e80583aSopenharmony_ci              }).then(() => {
1876e80583aSopenharmony_ci                win.setWindowBackgroundColor(StyleConstants.DEFAULT_SYSTEM_UI_COLOR);
1886e80583aSopenharmony_ci                Log.showDebug(TAG, `then begin ${name} window loadContent in then!`);
1896e80583aSopenharmony_ci                if (name !== this.RECENT_WINDOW_NAME) {
1906e80583aSopenharmony_ci                  win.setWindowLayoutFullScreen(true).then(() => {
1916e80583aSopenharmony_ci                    Log.showDebug(TAG, `${name} setLayoutFullScreen`);
1926e80583aSopenharmony_ci                  });
1936e80583aSopenharmony_ci                }
1946e80583aSopenharmony_ci                if (callback) {
1956e80583aSopenharmony_ci                  callback(win);
1966e80583aSopenharmony_ci                }
1976e80583aSopenharmony_ci                // there is a low probability that white flashes when no delay because of setBackgroundColor is asynchronous
1986e80583aSopenharmony_ci                setTimeout(() => {
1996e80583aSopenharmony_ci                  isShow && this.showWindow(name);
2006e80583aSopenharmony_ci                }, StyleConstants.WINDOW_SHOW_DELAY)
2016e80583aSopenharmony_ci              });
2026e80583aSopenharmony_ci            }, (err: BusinessError) => {
2036e80583aSopenharmony_ci              Log.showError(TAG, `createWindow, setUIContent error: ${JSON.stringify(err)}`);
2046e80583aSopenharmony_ci            });
2056e80583aSopenharmony_ci        })
2066e80583aSopenharmony_ci        .catch((err: BusinessError) => {
2076e80583aSopenharmony_ci          Log.showError(TAG, `createWindow, createWindow error: ${JSON.stringify(err)}`);
2086e80583aSopenharmony_ci        })
2096e80583aSopenharmony_ci    } catch (err) {
2106e80583aSopenharmony_ci      let _err = err as BusinessError;
2116e80583aSopenharmony_ci      Log.showError(TAG, `createWindow, error: ${JSON.stringify(_err)}`);
2126e80583aSopenharmony_ci    }
2136e80583aSopenharmony_ci  }
2146e80583aSopenharmony_ci
2156e80583aSopenharmony_ci  createWindowIfAbsent(context: common.ServiceExtensionContext, name: string, windowType: number, loadContent: string): void {
2166e80583aSopenharmony_ci    Log.showDebug(TAG, `create, name ${name}`);
2176e80583aSopenharmony_ci    try {
2186e80583aSopenharmony_ci      let win: window.Window = window.findWindow(name);
2196e80583aSopenharmony_ci      win.showWindow().then(() => {
2206e80583aSopenharmony_ci        Log.showDebug(TAG, `show launcher ${name}`);
2216e80583aSopenharmony_ci      });
2226e80583aSopenharmony_ci    } catch (err) {
2236e80583aSopenharmony_ci      let _err = err as BusinessError;
2246e80583aSopenharmony_ci      Log.showError(TAG, `${name} ability is not created, because ${_err.message}`);
2256e80583aSopenharmony_ci      this.createWindow(context, name, windowType, loadContent, true);
2266e80583aSopenharmony_ci    }
2276e80583aSopenharmony_ci  }
2286e80583aSopenharmony_ci
2296e80583aSopenharmony_ci  resetSizeWindow(name: string, rect: {
2306e80583aSopenharmony_ci    width: number,
2316e80583aSopenharmony_ci    height: number
2326e80583aSopenharmony_ci  }, callback?: Function): void {
2336e80583aSopenharmony_ci    Log.showDebug(TAG, `resetSizeWindow, name ${name} rect: ${JSON.stringify(rect)}`);
2346e80583aSopenharmony_ci    this.findWindow(name, (win) => {
2356e80583aSopenharmony_ci      Log.showDebug(TAG, `resetSizeWindow, findWindow callback name: ${name}`);
2366e80583aSopenharmony_ci      win.resetSize(rect.width, rect.height).then(() => {
2376e80583aSopenharmony_ci        Log.showDebug(TAG, `resetSizeWindow, resetSize then name: ${name}`);
2386e80583aSopenharmony_ci        if (callback) {
2396e80583aSopenharmony_ci          callback(win);
2406e80583aSopenharmony_ci        }
2416e80583aSopenharmony_ci      });
2426e80583aSopenharmony_ci    });
2436e80583aSopenharmony_ci  }
2446e80583aSopenharmony_ci
2456e80583aSopenharmony_ci  showWindow(name: string, callback?: Function): void {
2466e80583aSopenharmony_ci    Log.showDebug(TAG, `showWindow, name ${name}`);
2476e80583aSopenharmony_ci    this.findWindow(name, (win) => {
2486e80583aSopenharmony_ci      Log.showDebug(TAG, `showWindow, findWindow callback name: ${name}`);
2496e80583aSopenharmony_ci      win.show().then(() => {
2506e80583aSopenharmony_ci        Log.showDebug(TAG, `showWindow, show then name: ${name}`);
2516e80583aSopenharmony_ci        if (callback) {
2526e80583aSopenharmony_ci          callback(win);
2536e80583aSopenharmony_ci        }
2546e80583aSopenharmony_ci      });
2556e80583aSopenharmony_ci    });
2566e80583aSopenharmony_ci  }
2576e80583aSopenharmony_ci
2586e80583aSopenharmony_ci  hideWindow(name: string, callback?: Function): void {
2596e80583aSopenharmony_ci    Log.showDebug(TAG, `hideWindow, name ${name}`);
2606e80583aSopenharmony_ci    this.findWindow(name, (win) => {
2616e80583aSopenharmony_ci      Log.showDebug(TAG, `hideWindow, findWindow callback name: ${name}`);
2626e80583aSopenharmony_ci      win.hide().then(() => {
2636e80583aSopenharmony_ci        Log.showDebug(TAG, `hideWindow, hide then name: ${name}`);
2646e80583aSopenharmony_ci        if (callback) {
2656e80583aSopenharmony_ci          callback(win);
2666e80583aSopenharmony_ci        }
2676e80583aSopenharmony_ci      });
2686e80583aSopenharmony_ci    });
2696e80583aSopenharmony_ci  }
2706e80583aSopenharmony_ci
2716e80583aSopenharmony_ci  minimizeAllApps(): void {
2726e80583aSopenharmony_ci    try {
2736e80583aSopenharmony_ci      let dis: display.Display = display.getDefaultDisplaySync();
2746e80583aSopenharmony_ci      window.minimizeAll(dis.id).then(() => {
2756e80583aSopenharmony_ci        Log.showDebug(TAG, 'Launcher minimizeAll');
2766e80583aSopenharmony_ci      });
2776e80583aSopenharmony_ci    } catch (err) {
2786e80583aSopenharmony_ci      let errCode = (err as BusinessError).code;
2796e80583aSopenharmony_ci      let errMsg = (err as BusinessError).message;
2806e80583aSopenharmony_ci      Log.showError(TAG, `minimizeAllApps errCode: ${errCode}, errMsg: ${errMsg}`);
2816e80583aSopenharmony_ci    }
2826e80583aSopenharmony_ci    this.destroyWindow(this.FORM_MANAGER_WINDOW_NAME);
2836e80583aSopenharmony_ci    this.destroyWindow(this.FORM_SERVICE_WINDOW_NAME);
2846e80583aSopenharmony_ci  }
2856e80583aSopenharmony_ci
2866e80583aSopenharmony_ci  destroyWindow(name: string, callback?: Function): void {
2876e80583aSopenharmony_ci    Log.showDebug(TAG, `destroyWindow, name ${name}`);
2886e80583aSopenharmony_ci    this.findWindow(name, (win) => {
2896e80583aSopenharmony_ci      Log.showDebug(TAG, `hideWindow, findWindow callback name: ${name}`);
2906e80583aSopenharmony_ci      win.destroy().then(() => {
2916e80583aSopenharmony_ci        Log.showDebug(TAG, `destroyWindow, destroy then name: ${name}`);
2926e80583aSopenharmony_ci        if (callback) {
2936e80583aSopenharmony_ci          callback(win);
2946e80583aSopenharmony_ci        }
2956e80583aSopenharmony_ci      });
2966e80583aSopenharmony_ci    });
2976e80583aSopenharmony_ci  }
2986e80583aSopenharmony_ci
2996e80583aSopenharmony_ci  findWindow(name: string, callback?: Function): void {
3006e80583aSopenharmony_ci    Log.showDebug(TAG, `findWindow, name ${name}`);
3016e80583aSopenharmony_ci    try {
3026e80583aSopenharmony_ci      let win: window.Window = window.findWindow(name);
3036e80583aSopenharmony_ci      Log.showDebug(TAG, `findWindow, find then name: ${name}`);
3046e80583aSopenharmony_ci      if (callback) {
3056e80583aSopenharmony_ci        callback(win);
3066e80583aSopenharmony_ci      }
3076e80583aSopenharmony_ci    } catch (err) {
3086e80583aSopenharmony_ci      let _err = err as BusinessError;
3096e80583aSopenharmony_ci      Log.showError(TAG, `findWindow errCode: ${_err.code}, errMsg: ${_err.message}`);
3106e80583aSopenharmony_ci    }
3116e80583aSopenharmony_ci  }
3126e80583aSopenharmony_ci
3136e80583aSopenharmony_ci  createRecentWindow(mode?: number) {
3146e80583aSopenharmony_ci    Log.showDebug(TAG, 'createRecentWindow Begin, mode=' + mode);
3156e80583aSopenharmony_ci    let setWinMode = (mode && this.isSplitWindowMode(mode)) ? (win) => {
3166e80583aSopenharmony_ci      windowManager.recentMode = mode;
3176e80583aSopenharmony_ci      win.setWindowMode(mode).then();
3186e80583aSopenharmony_ci    } : (win) => {
3196e80583aSopenharmony_ci      windowManager.recentMode = AbilityConstant.WindowMode.WINDOW_MODE_FULLSCREEN;
3206e80583aSopenharmony_ci      win.setFullScreen(true).then(() => {
3216e80583aSopenharmony_ci        Log.showDebug(TAG, `${this.RECENT_WINDOW_NAME} setFullScreen`);
3226e80583aSopenharmony_ci      });
3236e80583aSopenharmony_ci    };
3246e80583aSopenharmony_ci    try {
3256e80583aSopenharmony_ci      let win: window.Window = window.findWindow(windowManager.RECENT_WINDOW_NAME);
3266e80583aSopenharmony_ci      setWinMode(win);
3276e80583aSopenharmony_ci      win.showWindow()
3286e80583aSopenharmony_ci        .then(() => {
3296e80583aSopenharmony_ci          Log.showDebug(TAG, 'show launcher recent ability');
3306e80583aSopenharmony_ci        });
3316e80583aSopenharmony_ci    } catch (err) {
3326e80583aSopenharmony_ci      Log.showDebug(TAG, `recent window is not created, because ${JSON.stringify(err)}`);
3336e80583aSopenharmony_ci      let callback = (win) => {
3346e80583aSopenharmony_ci        Log.showDebug(TAG, 'Post recent window created');
3356e80583aSopenharmony_ci        setWinMode(win);
3366e80583aSopenharmony_ci      }
3376e80583aSopenharmony_ci      this.createWindow(globalThis.desktopContext, windowManager.RECENT_WINDOW_NAME, windowManager.RECENT_RANK,
3386e80583aSopenharmony_ci        'pages/' + windowManager.RECENT_WINDOW_NAME, false, callback);
3396e80583aSopenharmony_ci    }
3406e80583aSopenharmony_ci  }
3416e80583aSopenharmony_ci
3426e80583aSopenharmony_ci  destroyRecentWindow() {
3436e80583aSopenharmony_ci    this.findWindow(windowManager.RECENT_WINDOW_NAME, win => {
3446e80583aSopenharmony_ci      win.off('windowEvent', (win) => {
3456e80583aSopenharmony_ci        win.destroy().then(() => {
3466e80583aSopenharmony_ci          Log.showDebug(TAG, 'destroyRecentWindow');
3476e80583aSopenharmony_ci        });
3486e80583aSopenharmony_ci      })
3496e80583aSopenharmony_ci    });
3506e80583aSopenharmony_ci  }
3516e80583aSopenharmony_ci
3526e80583aSopenharmony_ci  private static initSubscriber() {
3536e80583aSopenharmony_ci    if (WindowManager.subscriber != null) {
3546e80583aSopenharmony_ci      return;
3556e80583aSopenharmony_ci    }
3566e80583aSopenharmony_ci    const subscribeInfo: commonEventMgr.CommonEventSubscribeInfo = {
3576e80583aSopenharmony_ci      events: [commonEventManager.RECENT_FULL_SCREEN, commonEventManager.RECENT_SPLIT_SCREEN]
3586e80583aSopenharmony_ci    };
3596e80583aSopenharmony_ci    commonEventMgr.createSubscriber(subscribeInfo).then((commonEventSubscriber: commonEventMgr.CommonEventSubscriber) => {
3606e80583aSopenharmony_ci      Log.showDebug(TAG, 'init SPLIT_SCREEN subscriber success');
3616e80583aSopenharmony_ci      WindowManager.subscriber = commonEventSubscriber;
3626e80583aSopenharmony_ci    }, (err) => {
3636e80583aSopenharmony_ci      Log.showError(TAG, `Failed to createSubscriber ${err}`)
3646e80583aSopenharmony_ci    })
3656e80583aSopenharmony_ci  }
3666e80583aSopenharmony_ci
3676e80583aSopenharmony_ci  /**
3686e80583aSopenharmony_ci   * Register window event listener.
3696e80583aSopenharmony_ci   */
3706e80583aSopenharmony_ci  public registerWindowEvent() {
3716e80583aSopenharmony_ci    commonEventManager.registerCommonEvent(WindowManager.subscriber, WindowManager.eventCallback);
3726e80583aSopenharmony_ci  }
3736e80583aSopenharmony_ci
3746e80583aSopenharmony_ci  /**
3756e80583aSopenharmony_ci   * Unregister window event listener.
3766e80583aSopenharmony_ci   */
3776e80583aSopenharmony_ci  public unregisterWindowEvent() {
3786e80583aSopenharmony_ci    commonEventManager.unregisterCommonEvent(WindowManager.subscriber, WindowManager.eventCallback);
3796e80583aSopenharmony_ci  }
3806e80583aSopenharmony_ci
3816e80583aSopenharmony_ci  /**
3826e80583aSopenharmony_ci   * Window event handler.
3836e80583aSopenharmony_ci   */
3846e80583aSopenharmony_ci  private static async winEventCallback(error: BusinessError, data: commonEventMgr.CommonEventData) {
3856e80583aSopenharmony_ci    Log.showDebug(TAG,`Launcher WindowManager winEventCallback receive data: ${JSON.stringify(data)}.`);
3866e80583aSopenharmony_ci    if (data.code !== 0) {
3876e80583aSopenharmony_ci      Log.showError(TAG, `get winEventCallback error: ${JSON.stringify(error)}`);
3886e80583aSopenharmony_ci      return;
3896e80583aSopenharmony_ci    }
3906e80583aSopenharmony_ci
3916e80583aSopenharmony_ci    switch (data.event) {
3926e80583aSopenharmony_ci      case commonEventManager.RECENT_FULL_SCREEN:
3936e80583aSopenharmony_ci        // full screen recent window
3946e80583aSopenharmony_ci        windowManager.minimizeAllApps();
3956e80583aSopenharmony_ci        windowManager.createRecentWindow();
3966e80583aSopenharmony_ci        break;
3976e80583aSopenharmony_ci      case commonEventManager.RECENT_SPLIT_SCREEN:
3986e80583aSopenharmony_ci        // split window mode
3996e80583aSopenharmony_ci        const windowModeMap = {
4006e80583aSopenharmony_ci          'Primary': AbilityConstant.WindowMode.WINDOW_MODE_SPLIT_PRIMARY,
4016e80583aSopenharmony_ci          'Secondary': AbilityConstant.WindowMode.WINDOW_MODE_SPLIT_SECONDARY
4026e80583aSopenharmony_ci        };
4036e80583aSopenharmony_ci        if (data.parameters.windowMode !== 'Primary' && data.parameters.windowMode !== 'Secondary') {
4046e80583aSopenharmony_ci          break;
4056e80583aSopenharmony_ci        }
4066e80583aSopenharmony_ci        windowManager.createRecentWindow(windowModeMap[data.parameters.windowMode]);
4076e80583aSopenharmony_ci        globalThis.splitMissionId = data.parameters.missionId;
4086e80583aSopenharmony_ci        await WindowManager.subscriber.setCode(0);
4096e80583aSopenharmony_ci        await WindowManager.subscriber.finishCommonEvent();
4106e80583aSopenharmony_ci        break;
4116e80583aSopenharmony_ci      default:
4126e80583aSopenharmony_ci        break;
4136e80583aSopenharmony_ci    }
4146e80583aSopenharmony_ci  }
4156e80583aSopenharmony_ci
4166e80583aSopenharmony_ci  /**
4176e80583aSopenharmony_ci   * Screen rotation callback.
4186e80583aSopenharmony_ci   */
4196e80583aSopenharmony_ci  public async onPortrait(mediaQueryResult) {
4206e80583aSopenharmony_ci    if (mediaQueryResult.matches) {
4216e80583aSopenharmony_ci      Log.showInfo(TAG, 'screen change to landscape');
4226e80583aSopenharmony_ci      AppStorage.setOrCreate('isPortrait', false);
4236e80583aSopenharmony_ci    } else {
4246e80583aSopenharmony_ci      Log.showInfo(TAG, 'screen change to portrait');
4256e80583aSopenharmony_ci      AppStorage.setOrCreate('isPortrait', true);
4266e80583aSopenharmony_ci    }
4276e80583aSopenharmony_ci    try {
4286e80583aSopenharmony_ci      let dis: display.Display = display.getDefaultDisplaySync();
4296e80583aSopenharmony_ci      Log.showInfo(TAG, `change to display: ${JSON.stringify(dis)}`);
4306e80583aSopenharmony_ci      AppStorage.setOrCreate('screenWidth', px2vp(dis.width));
4316e80583aSopenharmony_ci      AppStorage.setOrCreate('screenHeight', px2vp(dis.height));
4326e80583aSopenharmony_ci      Log.showDebug(TAG, `screenWidth and screenHeight: ${AppStorage.get('screenWidth')},${AppStorage.get('screenHeight')}`);
4336e80583aSopenharmony_ci    } catch (err) {
4346e80583aSopenharmony_ci      Log.showError(TAG, `onPortrait error: ${JSON.stringify(err)}`);
4356e80583aSopenharmony_ci    }
4366e80583aSopenharmony_ci  }
4376e80583aSopenharmony_ci
4386e80583aSopenharmony_ci  createWindowWithName = ((windowName: string, windowRank: number): void => {
4396e80583aSopenharmony_ci    Log.showInfo(TAG, `createWindowWithName begin windowName: ${windowName}`);
4406e80583aSopenharmony_ci    if (windowName === windowManager.RECENT_WINDOW_NAME) {
4416e80583aSopenharmony_ci      windowManager.createRecentWindow();
4426e80583aSopenharmony_ci    } else {
4436e80583aSopenharmony_ci      windowManager.createWindowIfAbsent(globalThis.desktopContext, windowName, windowRank, 'pages/' + windowName);
4446e80583aSopenharmony_ci    }
4456e80583aSopenharmony_ci  })
4466e80583aSopenharmony_ci
4476e80583aSopenharmony_ci}
4486e80583aSopenharmony_ci
4496e80583aSopenharmony_ciexport const windowManager = WindowManager.getInstance();