• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 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 extension from '@ohos.app.ability.ServiceExtensionAbility';
17import window from '@ohos.window';
18import display from '@ohos.display';
19import rpc from '@ohos.rpc';
20import { GlobalContext } from '../common/utils/globalContext';
21import dialogRequest from '@ohos.app.ability.dialogRequest';
22import deviceInfo from '@ohos.deviceInfo';
23
24const TAG = 'PermissionManager_Log: ';
25const BG_COLOR = '#00000000';
26const DEFAULT_CORNER_RADIUS_L = 16;
27const RESULT_CODE_1 = 1;
28const ACCESS_TOKEN = 'ohos.security.accesstoken.tokencallback';
29
30export default class ServiceExtensionAbility extends extension {
31  /**
32  * Lifecycle function, called back when a service extension is started for initialization.
33  */
34  onCreate(want): void {
35    console.info(TAG + 'ServiceExtensionAbility onCreate, ability name is ' + want.abilityName);
36
37    globalThis.windowNum = 0;
38  }
39
40  /**
41  * Lifecycle function, called back when a service extension is started or recall.
42  */
43  onRequest(want, startId): void {
44    console.info(TAG + 'ServiceExtensionAbility onRequest. start id is ' + startId);
45    console.info(TAG + 'want: ' + JSON.stringify(want));
46    if (deviceInfo.deviceType === 'wearable') {
47      this.context.terminateSelf();
48      console.info(TAG + 'ServiceExtensionAbility terminateSelf');
49      return;
50    }
51
52    try {
53      let dis = display.getDefaultDisplaySync();
54      let navigationBarRect = {
55        left: 0,
56        top: 0,
57        width: dis.width,
58        height: dis.height
59      };
60      this.createWindow('permissionDialog' + startId, window.WindowType.TYPE_DIALOG, navigationBarRect, want);
61    } catch (exception) {
62      console.error(TAG + 'Failed to obtain the default display object. Code: ' + JSON.stringify(exception));
63    };
64  }
65
66  /**
67  * Lifecycle function, called back before a service extension is destroyed.
68  */
69  onDestroy(): void {
70    console.info(TAG + 'ServiceExtensionAbility onDestroy.');
71  }
72
73  private async createWindow(name: string, windowType, rect, want): Promise<void> {
74    let requestInfo: dialogRequest.RequestInfo;
75    try {
76      requestInfo = dialogRequest.getRequestInfo(want);
77    } catch (err) {
78      console.error(`getRequestInfo err= ${JSON.stringify(err)}`);
79    }
80
81    console.info(TAG + 'create window start, requestInfo: ' + JSON.stringify(requestInfo));
82    let rectInfo = requestInfo ? requestInfo.windowRect : rect;
83    rectInfo = rectInfo.width === 0 ? rect : rectInfo;
84    try {
85      const win = await window.createWindow({ ctx: this.context, name, windowType });
86      console.info(TAG + 'createWindow end.');
87      let storage: LocalStorage = new LocalStorage({ 'want': want, 'win': win });
88      await this.BindDialogTarget(win, want);
89      console.info(TAG + 'bindDialogTarget end.');
90      await win.moveWindowTo(rectInfo.left, rectInfo.top);
91      console.info(TAG + 'moveWindowTo end.');
92      await win.resize(rectInfo.width, rectInfo.height);
93      console.info(TAG + 'resize end.');
94      await win.loadContent('pages/dialogPlus', storage);
95      win.setWindowBackgroundColor(BG_COLOR);
96      if (rectInfo.width < rect.width) {
97        win.setCornerRadius(DEFAULT_CORNER_RADIUS_L);
98      }
99      await win.showWindow();
100      console.info(TAG + 'showWindow end.');
101      globalThis.windowNum ++;
102      GlobalContext.store('windowNum', globalThis.windowNum);
103    } catch (err) {
104      console.error(TAG + `window create failed! err: ${JSON.stringify(err)}`);
105    }
106  }
107
108  private async BindDialogTarget(win, want): Promise<void> {
109    let proxy = want.parameters['ohos.ability.params.callback'].value;
110    win.bindDialogTarget(want.parameters['ohos.ability.params.token'].value, () => {
111      let option = new rpc.MessageOption();
112      let data = new rpc.MessageSequence();
113      let reply = new rpc.MessageSequence();
114      try {
115        data.writeInterfaceToken(ACCESS_TOKEN);
116        proxy.sendMessageRequest(RESULT_CODE_1, data, reply, option);
117      } catch (err) {
118        console.error(TAG + `write result failed: ${JSON.stringify(err)}`);
119      } finally {
120        data.reclaim();
121        reply.reclaim();
122      }
123      let windowNum = GlobalContext.load('windowNum');
124      windowNum --;
125      GlobalContext.store('windowNum', windowNum);
126      win.destroyWindow();
127      if (windowNum === 0) {
128        this.context.terminateSelf();
129      }
130    });
131  }
132};