• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2021-2023 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 ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility';
17import Want from '@ohos.app.ability.Want';
18import display from '@ohos.display';
19import window from '@ohos.window';
20import rpc from '@ohos.rpc';
21import Log from '../../../../../../../common/src/main/ets/default/Log';
22import Constants, { ServiceStubCode } from '../common/Constants';
23import SystemDialogController from '../controller/Controller';
24import type { IDialogParameters } from '../controller/Controller';
25
26const TAG = 'Dialog-ServiceExtensionAbility';
27
28const getConnectId = (...args) => {
29  return args.join('-');
30};
31
32const REPLY_SUCCESS_CODE = 0;
33
34class Stub extends rpc.RemoteObject {
35  onRemoteRequest(code: number, data, reply, option) {
36    const connectId = getConnectId(rpc.IPCSkeleton.getCallingPid(), rpc.IPCSkeleton.getCallingTokenId());
37    Log.showInfo(TAG, `onRemoteRequest start ${connectId}`);
38
39    if (code === ServiceStubCode.COMMAND_SEND_REMOTE_OBJECT) {
40      Log.showInfo(TAG, `onRemoteRequest code:${ServiceStubCode.COMMAND_SEND_REMOTE_OBJECT} start ${connectId}`);
41      const controller = globalThis[Constants.SYSTEM_DIALOG_CONTROLLER];
42      const remoteObject = data.readRemoteObject();
43      Log.showDebug(TAG, `onRemoteRequest code:${ServiceStubCode.COMMAND_SEND_REMOTE_OBJECT} ${remoteObject}`);
44
45      if (remoteObject) {
46        controller.addDataByKey(connectId, { remoteObject });
47        Log.showDebug(TAG, `onRemoteRequest code:${ServiceStubCode.COMMAND_SEND_REMOTE_OBJECT} end`);
48
49        reply.writeInt(REPLY_SUCCESS_CODE);
50        return true;
51      }
52
53      return false;
54    }
55
56    if (code === ServiceStubCode.COMMAND_START_DIALOG) {
57      Log.showInfo(TAG, `onRemoteRequest code:${ServiceStubCode.COMMAND_START_DIALOG} ${connectId}`);
58      const size = data.readInt();
59      const parameters: { [key: string]: any } = {};
60
61      for (let i = 0; i < size; i++) {
62        const key = data.readString();
63        const value = data.readString();
64        parameters[key] = value;
65      }
66
67      if (parameters.parameters) {
68        try {
69          const parse = JSON.parse(parameters.parameters);
70          if (typeof parse === 'object') {
71            parameters.parameters = parse;
72            Log.showDebug(TAG, `onRemoteRequest parameters ${parameters.parameters}`);
73          }
74        } catch {
75          parameters.parameters = undefined;
76        }
77      }
78
79      this.createWindow(connectId, parameters);
80
81      reply.writeInt(REPLY_SUCCESS_CODE);
82      return true;
83    }
84
85    return false;
86  }
87
88  async createWindow(connectId: string, parameters: IDialogParameters) {
89    const controller = globalThis[Constants.SYSTEM_DIALOG_CONTROLLER];
90    const current = controller.getData().get(connectId);
91    if (current && current.windowName) {
92      Log.showInfo(TAG, `createWindow <this same> connectId:${connectId}`);
93      controller.destroyWindow(connectId, false);
94    }
95
96    const windowName = `SystemDialog${++controller.count}`;
97    Log.showInfo(TAG, `createWindow <start> windowName:${windowName} connectId:${connectId} parameters:${JSON.stringify(parameters)}`);
98
99    controller.addDataByKey(connectId, { windowName, parameters });
100
101    const navigationBarRect = await display.getDefaultDisplay().then(dis => {
102      return {
103        left: 0,
104        top: 0,
105        width: dis.width,
106        height: dis.height
107      };
108    });
109    Log.showInfo(TAG, `createWindow <getDefaultDisplay> ${JSON.stringify(navigationBarRect)}`);
110    const win = await window.createWindow({
111      ctx: controller.getContext(),
112      name: windowName,
113      windowType: window.WindowType.TYPE_FLOAT
114    });
115    Log.showDebug(TAG, 'createWindow <window.createWindow>');
116
117    const localStorage = new LocalStorage({ windowName, connectId, parameters });
118
119    await win.moveWindowTo(navigationBarRect.left, navigationBarRect.top);
120    await win.resize(navigationBarRect.width, navigationBarRect.height);
121    await win.loadContent('pages/ExtIndex', localStorage);
122    await win.setWindowBackgroundColor('#00000000');
123    await win.showWindow();
124
125    Log.showDebug(TAG, `createWindow end`);
126  }
127}
128
129export default class DialogServiceExtAbility extends ServiceExtensionAbility {
130  onCreate(want: Want) {
131    Log.showInfo(TAG, 'onCreate');
132    globalThis[Constants.SYSTEM_DIALOG_CONTROLLER] = new SystemDialogController(this.context);
133  }
134
135  onConnect() {
136    Log.showInfo(TAG, 'onConnect');
137    return new Stub('SystemDialog');
138  }
139
140  onDisconnect() {
141    Log.showInfo(TAG, 'onDisconnect');
142  }
143
144  onDestroy() {
145    const controller = globalThis[Constants.SYSTEM_DIALOG_CONTROLLER];
146    controller.destroyAllWindow();
147    globalThis[Constants.SYSTEM_DIALOG_CONTROLLER] = undefined;
148
149    Log.showInfo(TAG, 'onDestroy end');
150  }
151}
152