1/**
2 * Copyright (c) 2021-2022 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
16import ServiceExtension from '@ohos.app.ability.ServiceExtensionAbility';
17import display from '@ohos.display';
18import Want from '@ohos.app.ability.Want';
19import {
20  Log,
21  CommonConstants,
22  windowManager,
23  RdbStoreManager,
24  FormConstants,
25  FormListInfoCacheManager,
26  ResourceManager,
27  launcherAbilityManager,
28  navigationBarCommonEventManager,
29  localEventManager,
30  EventConstants,
31  DisplayManager
32} from '@ohos/common';
33import { GestureNavigationManager } from '@ohos/gesturenavigation';
34import StyleConstants from '../common/constants/StyleConstants';
35import { PageDesktopViewModel } from '@ohos/pagedesktop';
36import Window from '@ohos.window';
37import inputConsumer from '@ohos.multimodalInput.inputConsumer';
38import { KeyCode } from '@ohos.multimodalInput.keyCode';
39import window from '@ohos.window';
40import { PreferencesHelper } from '@ohos/common/src/main/ets/default/manager/PreferencesHelper';
41
42const TAG = 'LauncherMainAbility';
43
44export default class MainAbility extends ServiceExtension {
45  private displayManager: DisplayManager = undefined
46
47  onCreate(want: Want): void {
48    Log.showInfo(TAG,'onCreate start');
49    this.context.area = 0;
50    this.initLauncher();
51  }
52
53  async initLauncher(): Promise<void> {
54    // init Launcher context
55    globalThis.desktopContext = this.context;
56    // init rdb
57    let dbStore = RdbStoreManager.getInstance();
58    await dbStore.initRdbConfig();
59    await dbStore.createTable();
60
61    let registerWinEvent = (win: window.Window) => {
62      win.on('windowEvent', (stageEventType) => {
63        // 桌面获焦或失焦时,通知桌面的卡片变为可见状态
64        if (stageEventType === window.WindowEventType.WINDOW_ACTIVE) {
65          launcherAbilityManager.checkBundleMonitor();
66          localEventManager.sendLocalEventSticky(EventConstants.EVENT_REQUEST_FORM_ITEM_VISIBLE, null);
67          Log.showInfo(TAG, `lifeCycleEvent change: ${stageEventType}`);
68        }
69      })
70    };
71    // create Launcher entry view
72    windowManager.createWindow(globalThis.desktopContext, windowManager.DESKTOP_WINDOW_NAME,
73      windowManager.DESKTOP_RANK, 'pages/' + windowManager.DESKTOP_WINDOW_NAME, true, registerWinEvent);
74
75    await PreferencesHelper.getInstance().initPreference(this.context);
76    AppStorage.setOrCreate('firstActivate', true);
77    // init global const
78    this.initGlobalConst();
79    this.displayManager = DisplayManager.getInstance();
80
81    // init Gesture navigation
82    this.startGestureNavigation();
83    windowManager.registerWindowEvent();
84    navigationBarCommonEventManager.registerNavigationBarEvent();
85
86    // load recent
87    windowManager.createRecentWindow();
88    this.registerInputConsumer();
89  }
90
91  private registerInputConsumer(): void {
92    let onKeyCodeHome = {
93      preKeys: [],
94      finalKey: KeyCode.KEYCODE_HOME,
95      finalKeyDownDuration: 0,
96      isFinalKeyDown: true
97    }
98    // register/unregister HOME inputConsumer
99    inputConsumer.on('key', onKeyCodeHome, () => {
100      Log.showInfo(TAG, 'HOME inputConsumer homeEvent start');
101      globalThis.desktopContext.startAbility({
102        bundleName: CommonConstants.LAUNCHER_BUNDLE,
103        abilityName: CommonConstants.LAUNCHER_ABILITY
104      })
105        .then(() => {
106          Log.showDebug(TAG, 'HOME inputConsumer startAbility Promise in service successful.');
107        })
108        .catch(() => {
109          Log.showDebug(TAG, 'HOME inputConsumer startAbility Promise in service failed.');
110        });
111    });
112    let onKeyCodeFunction = {
113      preKeys: [],
114      finalKey: KeyCode.KEYCODE_FUNCTION,
115      finalKeyDownDuration: 0,
116      isFinalKeyDown: true
117    }
118    // register/unregister RECENT inputConsumer
119    inputConsumer.on('key', onKeyCodeFunction, () => {
120      Log.showInfo(TAG, 'RECENT inputConsumer recentEvent start');
121      windowManager.createWindowWithName(windowManager.RECENT_WINDOW_NAME, windowManager.RECENT_RANK);
122    });
123  }
124
125  private unregisterInputConsumer(): void {
126    let offKeyCodeHome = {
127      preKeys: [],
128      finalKey: KeyCode.KEYCODE_HOME,
129      finalKeyDownDuration: 0,
130      isFinalKeyDown: true
131    }
132    // unregister HOME inputConsumer
133    inputConsumer.off('key', offKeyCodeHome);
134    let offKeyCodeFunction = {
135      preKeys: [],
136      finalKey: KeyCode.KEYCODE_FUNCTION,
137      finalKeyDownDuration: 0,
138      isFinalKeyDown: true
139    }
140    // unregister RECENT inputConsumer
141    inputConsumer.off('key', offKeyCodeFunction);
142  }
143
144  private initGlobalConst(): void {
145    // init create window global function
146    globalThis.createWindowWithName = ((windowName: string, windowRank: number): void => {
147      Log.showInfo(TAG, `createWindowWithName begin windowName: ${windowName}`);
148      if (windowName === windowManager.RECENT_WINDOW_NAME) {
149        windowManager.createRecentWindow();
150      } else {
151        windowManager.createWindowIfAbsent(globalThis.desktopContext, windowName, windowRank, 'pages/' + windowName);
152      }
153    });
154  }
155
156  private startGestureNavigation(): void {
157    const gestureNavigationManage = GestureNavigationManager.getInstance();
158    let dis: display.Display = display.getDefaultDisplaySync();
159    dis && gestureNavigationManage.initWindowSize(dis);
160  }
161
162  onDestroy(): void {
163    windowManager.unregisterWindowEvent();
164    this.unregisterInputConsumer();
165    navigationBarCommonEventManager.unregisterNavigationBarEvent();
166    windowManager.destroyWindow(windowManager.DESKTOP_WINDOW_NAME);
167    windowManager.destroyRecentWindow();
168    this.displayManager?.destroySubDisplayWindow();
169    Log.showInfo(TAG, 'onDestroy success');
170  }
171
172  onRequest(want: Want, startId: number): void {
173    Log.showInfo(TAG,`onRequest, want:${want.abilityName}`);
174    // if app publish card to launcher
175    if(want.action === FormConstants.ACTION_PUBLISH_FORM) {
176      PageDesktopViewModel.getInstance().publishCardToDesktop(want.parameters);
177    }
178    if (startId !== 1) {
179      windowManager.minimizeAllApps();
180    }
181    windowManager.hideWindow(windowManager.RECENT_WINDOW_NAME);
182    localEventManager.sendLocalEventSticky(EventConstants.EVENT_OPEN_FOLDER_TO_CLOSE, null);
183  }
184
185  onConfigurationUpdate(config): void {
186    Log.showInfo(TAG, 'onConfigurationUpdated, config:' + JSON.stringify(config));
187    const systemLanguage = AppStorage.get('systemLanguage');
188    if(systemLanguage !== config.language) {
189      this.clearCacheWhenLanguageChange();
190    }
191    AppStorage.setOrCreate('systemLanguage', config.language);
192  }
193
194  private clearCacheWhenLanguageChange(): void {
195    FormListInfoCacheManager.getInstance().clearCache();
196    ResourceManager.getInstance().clearAppResourceCache();
197    launcherAbilityManager.cleanAppMapCache();
198    PageDesktopViewModel.getInstance().updateDesktopInfo();
199    PageDesktopViewModel.getInstance().updateForms();
200  }
201}
202