• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2024 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 */
15import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility';
16import common from '@ohos.app.ability.common';
17import window from '@ohos.window';
18import Want from '@ohos.app.ability.Want';
19import display from '@ohos.display';
20import GlobalContext from './GlobalContext';
21import { BusinessError } from '@ohos.base';
22
23const TAG = 'PasteboardProgressAbility: ';
24const BG_COLOR = '#00000000';
25let createWindowStatus = 'created';
26
27interface IRect {
28  left: number;
29  top: number;
30  width: number;
31  height: number;
32}
33
34interface StorageItem {
35  want: Want,
36  win: window.Window,
37  serviceContext: common.ServiceExtensionContext,
38  globalContext: GlobalContext
39}
40
41export default class PasteboardProgressAbility extends ServiceExtensionAbility {
42  onCreate(want: Want): void {
43    console.info(TAG + 'PasteboardProgressAbility onCreate, ability name is ' + want.abilityName);
44  }
45
46  async onRequest(want: Want, startId: number) {
47    try {
48      console.info(TAG + 'PasteboardProgressAbility onRequest, startId is' + startId);
49      console.info(TAG + 'want: ' + JSON.stringify(want));
50      if (!this.checkWantParamsValid(want)) {
51        return;
52      }
53      let displayClass = display.getDefaultDisplaySync();
54      let navigationBarRect: IRect = {
55        left: 0,
56        top: 0,
57        width: displayClass.width,
58        height: displayClass.height,
59      };
60      if (canIUse('SystemCapability.Window.SessionManager')) {
61        await window.getVisibleWindowInfo().then((infos: window.WindowInfo[]) => {
62          const targetWindowId = want.parameters?.windowId as number;
63          const targetWindowInfo = infos.find(info => info.windowId === targetWindowId);
64          navigationBarRect = targetWindowInfo?.rect as IRect;
65          console.info(TAG + `targetWindowInfo rect is ${JSON.stringify(navigationBarRect)}`);
66        }).catch((err: BusinessError) => {
67          console.error(TAG + 'Failed to getWindowInfo. Cause: ' + JSON.stringify(err));
68        });
69      }
70      this.createWindow(`PasteboardProgressDialog${startId}`, navigationBarRect, want);
71    } catch (exception) {
72      console.error(TAG + 'Failed to obtain the default display object. Code:' + JSON.stringify(exception))
73    }
74  }
75
76  onDestroy(): void {
77    console.info(TAG + 'PasteboardProgressAbility onDestroy.')
78  }
79
80  private checkWantParamsValid(want: Want): boolean {
81    let validParam = true;
82    const requiredParams = ['windowId', 'progressKey', 'tokenKey', 'promptText', 'ipcCallback'];
83    const missingParams = requiredParams.filter(param =>!(Reflect.has((want.parameters || {}), param)));
84    if (missingParams.length) {
85      validParam = false;
86      console.error(TAG + `params missing valid: ${missingParams.join(', ')}`);
87    }
88    return validParam;
89  }
90
91  private async createWindow(name: string, rect: IRect, want: Want): Promise<void> {
92    if (createWindowStatus === 'created') {
93      createWindowStatus = 'creating';
94      console.info(TAG + 'create progressWindow');
95    } else {
96      console.warn(TAG + 'window is creating');
97      return;
98    }
99    const progressKey = want.parameters?.['progressKey'] as string;
100    if (GlobalContext.getInstance().dialogSet.has(progressKey)) {
101      console.info(TAG + 'window already exists');
102      return;
103    }
104    try {
105      const win = await window.createWindow({
106        ctx: this.context,
107        name,
108        windowType: window.WindowType.TYPE_DIALOG
109      });
110      await win.bindDialogTarget((want.parameters?.['tokenKey'] as ESObject).value, () => {
111        win.destroyWindow();
112        console.info(TAG + 'destroyWindow');
113        GlobalContext.getInstance().dialogSet.delete(progressKey);
114        if (GlobalContext.getInstance().dialogSet.size === 0) {
115          this.context.terminateSelf();
116        }
117      });
118      let storageItem: StorageItem = {
119        want,
120        win,
121        globalContext: GlobalContext.getInstance(),
122        serviceContext: this.context
123      }
124      let storage: LocalStorage = new LocalStorage(storageItem);
125      await win.moveWindowTo(rect.left, rect.top);
126      await win.resize(rect.width, rect.height);
127      await win.loadContent('pages/PasteboardProgress', storage);
128      win.setWindowBackgroundColor(BG_COLOR);
129      await win.showWindow();
130      GlobalContext.getInstance().dialogSet.add(progressKey);
131      console.info(TAG + `dialogSet add, size is ${GlobalContext.getInstance().dialogSet.size}`);
132    } catch (err) {
133      console.error(TAG + `window create failed! code is ${err.code}, message is ${err.message}`);
134    } finally {
135      createWindowStatus = 'created';
136    }
137  }
138}