• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2025 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 common from '@ohos.app.ability.common';
17import Want from '@ohos.app.ability.Want';
18import Constants from '../../../common/constant';
19import { HiLog } from '../../../common/HiLog';
20import { rpc } from '@kit.IPCKit';
21import OpeningDialogStub from '../stub/OpeningDialogStub';
22import { ability } from '@kit.AbilityKit';
23
24const TAG = 'OpeningDialogService';
25
26export default class OpeningDialogService {
27  private static instance: OpeningDialogService;
28  private _context?: common.UIExtensionContext;
29  private remoteProxy: rpc.IRemoteObject | null = null;
30  private connectionId: number | undefined;
31  private _disconnectTimer: number | null = null;
32  private connectOptions: common.ConnectOptions = {
33    onConnect: async (elementName, remoteProxy) => {
34      HiLog.info(TAG, 'OpeningDialogService onConnect success');
35      this.remoteProxy = remoteProxy;
36      await this.setRemoteObject();
37    },
38    onDisconnect: (elementName) => {
39      this.remoteProxy = null;
40      HiLog.info(TAG, 'OpeningDialogService onDisconnect');
41    },
42    onFailed: () => {
43      HiLog.info(TAG, 'OpeningDialogService onFailed');
44    }
45  };
46
47  static getInstance(): OpeningDialogService {
48    if (!OpeningDialogService.instance) {
49      OpeningDialogService.instance = new OpeningDialogService();
50    }
51    return OpeningDialogService.instance;
52  }
53
54  private constructor() {
55  }
56
57  public setContext(value: common.UIExtensionContext) {
58    this._context = value;
59  }
60
61  public getContext(): common.UIExtensionContext | undefined {
62    return this._context;
63  }
64
65  public async terminateOpeningDialog(): Promise<void> {
66    HiLog.info(TAG, 'OpeningDialogService terminateOpeningDialog');
67    if (!this._context) {
68      HiLog.error(TAG, 'terminateOpeningDialog context is undefined');
69      return;
70    }
71    try {
72      if (this._disconnectTimer) {
73        clearTimeout(this._disconnectTimer);
74        this._disconnectTimer = null;
75      }
76      await this._context.terminateSelf();
77      HiLog.info(TAG, 'terminateOpeningDialog success');
78    } catch (error) {
79      HiLog.wrapError(TAG, error, 'terminateOpeningDialog exception');
80    }
81  }
82
83  public connectViewAbility(): void {
84    HiLog.info(TAG, 'connectViewAbility start');
85    if (!this._context) {
86      HiLog.error(TAG, 'connectViewAbility context is undefined');
87      return;
88    }
89    let want: Want = {
90      bundleName: Constants.DLP_MANAGER_BUNDLE_NAME,
91      abilityName: Constants.DLP_VIEW_SERVICE,
92    };
93
94    try {
95      this.connectionId = this._context.connectServiceExtensionAbility(want, this.connectOptions);
96      AppStorage.setOrCreate(Constants.CONNECT_VIEW_ABILITY, this.connectionId);
97    } catch (err) {
98      HiLog.wrapError(TAG, err, 'connectServiceExtensionAbility err');
99    }
100  }
101
102  public async disconnectViewAbility(): Promise<void> {
103    HiLog.info(TAG, 'disconnectViewAbility start');
104    if (!this._context || !this.connectionId) {
105      HiLog.error(TAG, 'disconnectViewAbility context or connectionId is null');
106      return;
107    }
108    try {
109      await this._context.disconnectServiceExtensionAbility(this.connectionId);
110      HiLog.info(TAG, 'disconnectViewAbility success');
111    } catch (error) {
112      HiLog.wrapError(TAG, error, 'Failed to disconnectViewAbility');
113    }
114  }
115
116  public async disconnectViewAbilityWithTimeout(): Promise<void> {
117    HiLog.info(TAG, 'disconnectViewAbilityWithTimeout start');
118
119    if (!this._context) {
120      HiLog.error(TAG, 'disconnectViewAbilityWithTimeout context is undefined');
121      return;
122    }
123
124    if (this._disconnectTimer) {
125      clearTimeout(this._disconnectTimer);
126      this._disconnectTimer = null;
127    }
128
129    return new Promise<void>((resolve) => {
130      this._disconnectTimer = setTimeout(async () => {
131        try {
132          if (this._context && this.connectionId) {
133            await this._context.disconnectServiceExtensionAbility(this.connectionId);
134            HiLog.info(TAG, 'disconnectViewAbilityWithTimeout success');
135          } else {
136            HiLog.warn(TAG, 'disconnectViewAbilityWithTimeout skipped context null or connectionId null');
137          }
138        } catch (error) {
139          HiLog.wrapError(TAG, error, 'Failed to disconnectViewAbilityWithTimeout');
140        } finally {
141          this._disconnectTimer = null;
142          resolve();
143        }
144      }, Constants.DISCONNECT_VIEW_TIMEOUT);
145    });
146  }
147
148  private async setRemoteObject(): Promise<void> {
149    HiLog.info(TAG, `setRemoteObject start`);
150    if (!this.remoteProxy) {
151      HiLog.error(TAG, 'setRemoteObject remoteProxy is null');
152      return;
153    }
154    let option = new rpc.MessageOption();
155    let data = new rpc.MessageSequence();
156    let reply = new rpc.MessageSequence();
157    try {
158      data.writeInterfaceToken(Constants.DLP_MGR_OPENING_DIALOG_TOKEN);
159      let callback: OpeningDialogStub = new OpeningDialogStub('OpeningDialogStub');
160      data.writeRemoteObject(callback.asObject());
161      await this.remoteProxy.sendMessageRequest(Constants.COMMAND_SET_REMOTE_OBJECT, data, reply, option);
162      HiLog.info(TAG, 'setRemoteObject sendmsg success.');
163    } catch (error) {
164      HiLog.wrapError(TAG, error, 'setRemoteObject sendmsg error');
165    } finally {
166      data.reclaim();
167      reply.reclaim();
168    }
169  }
170
171  public async dialogDisappear(requestId: string): Promise<void> {
172    HiLog.info(TAG, `dialogDisappear requestId ${requestId}`);
173    if (!this.remoteProxy) {
174      HiLog.error(TAG, 'dialogDisappear remoteProxy is null');
175      return;
176    }
177    let option = new rpc.MessageOption();
178    let data = new rpc.MessageSequence();
179    let reply = new rpc.MessageSequence();
180    try {
181      data.writeInterfaceToken(Constants.DLP_MGR_OPENING_DIALOG_TOKEN);
182      data.writeString(requestId);
183      await this.remoteProxy.sendMessageRequest(Constants.COMMAND_DIALOG_DISAPPEAR, data, reply, option);
184      HiLog.info(TAG, 'dialogDisappear sendmsg success.');
185    } catch (error) {
186      HiLog.wrapError(TAG, error, 'dialogDisappear sendmsg error');
187    } finally {
188      data.reclaim();
189      reply.reclaim();
190    }
191  }
192
193  public async dialogTimeout(requestId: string): Promise<void> {
194    HiLog.info(TAG, `dialogTimeout requestId ${requestId}`);
195    if (!this.remoteProxy) {
196      HiLog.error(TAG, 'dialogTimeout remoteProxy is null');
197      return;
198    }
199    let option = new rpc.MessageOption();
200    let data = new rpc.MessageSequence();
201    let reply = new rpc.MessageSequence();
202    try {
203      data.writeInterfaceToken(Constants.DLP_MGR_OPENING_DIALOG_TOKEN);
204      data.writeString(requestId);
205      await this.remoteProxy.sendMessageRequest(Constants.COMMAND_DIALOG_TIMEOUT, data, reply, option);
206      HiLog.info(TAG, 'dialogTimeout sendmsg success.');
207    } catch (error) {
208      HiLog.wrapError(TAG, error, 'dialogTimeout sendmsg error');
209    } finally {
210      data.reclaim();
211      reply.reclaim();
212    }
213  }
214}