1df226684Sopenharmony_ci/*
2df226684Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3df226684Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4df226684Sopenharmony_ci * you may not use this file except in compliance with the License.
5df226684Sopenharmony_ci * You may obtain a copy of the License at
6df226684Sopenharmony_ci *
7df226684Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8df226684Sopenharmony_ci *
9df226684Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10df226684Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11df226684Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12df226684Sopenharmony_ci * See the License for the specific language governing permissions and
13df226684Sopenharmony_ci * limitations under the License.
14df226684Sopenharmony_ci */
15df226684Sopenharmony_ci
16df226684Sopenharmony_ciimport { BusinessError } from '@ohos.base';
17df226684Sopenharmony_ciimport Want from '@ohos.app.ability.Want';
18df226684Sopenharmony_ciimport fileUri from '@ohos.file.fileuri';
19df226684Sopenharmony_ciimport ServiceExtension from '@ohos.app.ability.ServiceExtensionAbility';
20df226684Sopenharmony_ciimport fs from '@ohos.file.fs';
21df226684Sopenharmony_ciimport dlpPermission from '@ohos.dlpPermission';
22df226684Sopenharmony_ciimport IdlDlpRpcServiceStub from '../MainAbility/data/IIdlDlpRpcServiceTs/id_dlpRpc_service_stub';
23df226684Sopenharmony_ciimport {
24df226684Sopenharmony_ci  closeDlpFileCallback,
25df226684Sopenharmony_ci  sandBoxLinkFileCallback,
26df226684Sopenharmony_ci  fileOpenHistoryCallback,
27df226684Sopenharmony_ci  linkSetCallback,
28df226684Sopenharmony_ci  genDlpFileCallback,
29df226684Sopenharmony_ci  openDlpFileCallback,
30df226684Sopenharmony_ci  recoverDlpFileCallback,
31df226684Sopenharmony_ci  replaceDlpLinkFileCallback,
32df226684Sopenharmony_ci  resumeFuseLinkCallback,
33df226684Sopenharmony_ci  stopFuseLinkCallback
34df226684Sopenharmony_ci} from '../MainAbility/data/IIdlDlpRpcServiceTs/i_id_dlpRpc_service';
35df226684Sopenharmony_ciimport IDLDLPProperty from './sequenceable/dlpClass';
36df226684Sopenharmony_ciimport { IAuthUser } from './sequenceable/dlpClass';
37df226684Sopenharmony_ciimport GlobalContext from '../common/GlobalContext';
38df226684Sopenharmony_ciimport Constants from '../common/constant';
39df226684Sopenharmony_ciimport { HiLog } from '../common/HiLog';
40df226684Sopenharmony_ci
41df226684Sopenharmony_ciconst TAG = 'service_extability';
42df226684Sopenharmony_ci
43df226684Sopenharmony_ciclass DlpRpcServiceStub extends IdlDlpRpcServiceStub {
44df226684Sopenharmony_ci  private dlpFileMap: Map<string, dlpPermission.DLPFile | null> = new Map<string, dlpPermission.DLPFile | null>();
45df226684Sopenharmony_ci  private inFile: fs.File | undefined = undefined;
46df226684Sopenharmony_ci  private outFile: fs.File | undefined = undefined;
47df226684Sopenharmony_ci
48df226684Sopenharmony_ci  constructor(des: string) {
49df226684Sopenharmony_ci    super(des);
50df226684Sopenharmony_ci  }
51df226684Sopenharmony_ci
52df226684Sopenharmony_ci  getOpeningFile(inputUri: string) : dlpPermission.DLPFile | null {
53df226684Sopenharmony_ci    let sandbox2linkFile: Map<string, (number | string | dlpPermission.DLPFile)[][]> = GlobalContext.load('sandbox2linkFile') as Map<string, (number | string | dlpPermission.DLPFile)[][]>;
54df226684Sopenharmony_ci    if (sandbox2linkFile !== undefined) {
55df226684Sopenharmony_ci      for (let key of Array.from<(number | string | dlpPermission.DLPFile)[][]>(sandbox2linkFile.values())) {
56df226684Sopenharmony_ci        for (let j of key) {
57df226684Sopenharmony_ci          if (j[4] === inputUri) {
58df226684Sopenharmony_ci            let dlpFile: dlpPermission.DLPFile = j[0] as dlpPermission.DLPFile;
59df226684Sopenharmony_ci            return dlpFile;
60df226684Sopenharmony_ci          }
61df226684Sopenharmony_ci        }
62df226684Sopenharmony_ci      }
63df226684Sopenharmony_ci    }
64df226684Sopenharmony_ci
65df226684Sopenharmony_ci    if (this.dlpFileMap.has(inputUri)) {
66df226684Sopenharmony_ci      let dlpFile: dlpPermission.DLPFile = this.dlpFileMap.get(inputUri) as dlpPermission.DLPFile;
67df226684Sopenharmony_ci      return dlpFile;
68df226684Sopenharmony_ci    }
69df226684Sopenharmony_ci    return null;
70df226684Sopenharmony_ci  }
71df226684Sopenharmony_ci
72df226684Sopenharmony_ci  async genDlpFile(inputUri: string, outputUri: string, dlp: IDLDLPProperty, callback: genDlpFileCallback
73df226684Sopenharmony_ci  ): Promise<void> {
74df226684Sopenharmony_ci    HiLog.info(TAG, `genDlpFile in service`);
75df226684Sopenharmony_ci    let result: Record<string, number>;
76df226684Sopenharmony_ci    try {
77df226684Sopenharmony_ci      result = await this.genDlpFileFd(inputUri, outputUri);
78df226684Sopenharmony_ci    } catch (error) {
79df226684Sopenharmony_ci      callback(error);
80df226684Sopenharmony_ci      return;
81df226684Sopenharmony_ci    }
82df226684Sopenharmony_ci    let dlpP: dlpPermission.DLPProperty = {
83df226684Sopenharmony_ci      'ownerAccount' : dlp.ownerAccount,
84df226684Sopenharmony_ci      'ownerAccountID' : dlp.ownerAccountID,
85df226684Sopenharmony_ci      'ownerAccountType' : dlp.ownerAccountType,
86df226684Sopenharmony_ci      'authUserList' : dlp.authUserList,
87df226684Sopenharmony_ci      'contactAccount' : dlp.contactAccount,
88df226684Sopenharmony_ci      'offlineAccess' : dlp.offlineAccess,
89df226684Sopenharmony_ci      'everyoneAccessList' : dlp.everyoneAccessList,
90df226684Sopenharmony_ci      'expireTime': dlp.expireTime
91df226684Sopenharmony_ci    }
92df226684Sopenharmony_ci    try {
93df226684Sopenharmony_ci      let dlpFile = await dlpPermission.generateDLPFile(result.inFileFd, result.outFileFd, dlpP);
94df226684Sopenharmony_ci      if (!this.dlpFileMap.has(outputUri)) {
95df226684Sopenharmony_ci        this.dlpFileMap.set(outputUri, dlpFile);
96df226684Sopenharmony_ci        AppStorage.setOrCreate('dlpFileMap', this.dlpFileMap);
97df226684Sopenharmony_ci      } else {
98df226684Sopenharmony_ci        let rawDlpFile = this.dlpFileMap.get(outputUri) ?? null;
99df226684Sopenharmony_ci        if (rawDlpFile !== null) {
100df226684Sopenharmony_ci          try {
101df226684Sopenharmony_ci            await rawDlpFile.closeDLPFile();
102df226684Sopenharmony_ci          } catch (err) {
103df226684Sopenharmony_ci            HiLog.error(TAG, `closeDlpFile file: ${JSON.stringify(err)}`);
104df226684Sopenharmony_ci          }
105df226684Sopenharmony_ci        }
106df226684Sopenharmony_ci        this.dlpFileMap.delete(outputUri);
107df226684Sopenharmony_ci        this.dlpFileMap.set(outputUri, dlpFile);
108df226684Sopenharmony_ci        AppStorage.setOrCreate('dlpFileMap', this.dlpFileMap);
109df226684Sopenharmony_ci      }
110df226684Sopenharmony_ci      callback(0);
111df226684Sopenharmony_ci    } catch (err) {
112df226684Sopenharmony_ci      HiLog.info(TAG, `genDlpFile file: ${JSON.stringify(err)}`);
113df226684Sopenharmony_ci      await this.closeFile();
114df226684Sopenharmony_ci      callback((err as BusinessError).code);
115df226684Sopenharmony_ci    }
116df226684Sopenharmony_ci  }
117df226684Sopenharmony_ci
118df226684Sopenharmony_ci  async closeFile(): Promise<void> {
119df226684Sopenharmony_ci    try {
120df226684Sopenharmony_ci      await fs.close(this.inFile);
121df226684Sopenharmony_ci    } catch (err) {
122df226684Sopenharmony_ci      HiLog.info(TAG, `close fail: ${JSON.stringify(err)}`);
123df226684Sopenharmony_ci    }
124df226684Sopenharmony_ci    try {
125df226684Sopenharmony_ci      await fs.close(this.outFile);
126df226684Sopenharmony_ci    } catch (err) {
127df226684Sopenharmony_ci      HiLog.info(TAG, `close fail: ${JSON.stringify(err)}`);
128df226684Sopenharmony_ci    }
129df226684Sopenharmony_ci  }
130df226684Sopenharmony_ci
131df226684Sopenharmony_ci  async genDlpFileFd(inputUri: string, outputUri: string): Promise<Record<string, number>> {
132df226684Sopenharmony_ci    return new Promise(async (resolve, reject) => {
133df226684Sopenharmony_ci      let inFileFd: number = -1;
134df226684Sopenharmony_ci      let outFileFd: number = -1;
135df226684Sopenharmony_ci      try {
136df226684Sopenharmony_ci        this.inFile = await fs.open(inputUri, fs.OpenMode.READ_WRITE);
137df226684Sopenharmony_ci        inFileFd = this.inFile.fd;
138df226684Sopenharmony_ci      } catch (error) {
139df226684Sopenharmony_ci        HiLog.error(TAG, `open: ${inputUri}, failed: ${JSON.stringify(error)}`);
140df226684Sopenharmony_ci        reject((error as BusinessError).code);
141df226684Sopenharmony_ci        return;
142df226684Sopenharmony_ci      }
143df226684Sopenharmony_ci      let uriInfo: fileUri.FileUri = new fileUri.FileUri('');
144df226684Sopenharmony_ci      try {
145df226684Sopenharmony_ci        uriInfo = new fileUri.FileUri(outputUri);
146df226684Sopenharmony_ci      } catch (err) {
147df226684Sopenharmony_ci        HiLog.error(TAG, `fileUri fail: ${JSON.stringify(err)}`);
148df226684Sopenharmony_ci      }
149df226684Sopenharmony_ci      try {
150df226684Sopenharmony_ci        this.outFile = await fs.open(outputUri, fs.OpenMode.READ_WRITE);
151df226684Sopenharmony_ci        outFileFd = this.outFile.fd;
152df226684Sopenharmony_ci      } catch (error) {
153df226684Sopenharmony_ci        try {
154df226684Sopenharmony_ci          await fs.close(this.inFile);
155df226684Sopenharmony_ci          await fs.unlink(uriInfo.path);
156df226684Sopenharmony_ci        } catch (err) {
157df226684Sopenharmony_ci          HiLog.error(TAG, `unlink fail: ${JSON.stringify(err)}`);
158df226684Sopenharmony_ci        }
159df226684Sopenharmony_ci        reject((error as BusinessError).code);
160df226684Sopenharmony_ci        return;
161df226684Sopenharmony_ci      }
162df226684Sopenharmony_ci      let result = {
163df226684Sopenharmony_ci        'inFileFd': inFileFd,
164df226684Sopenharmony_ci        'outFileFd': outFileFd
165df226684Sopenharmony_ci      } as Record<string, number>;
166df226684Sopenharmony_ci      resolve(result);
167df226684Sopenharmony_ci    })
168df226684Sopenharmony_ci  }
169df226684Sopenharmony_ci
170df226684Sopenharmony_ci  async openDlpFile(srcUri: string, callerAppId: string, callback: openDlpFileCallback): Promise<void> {
171df226684Sopenharmony_ci    HiLog.info(TAG, `openDlpFile start: ${srcUri}`);
172df226684Sopenharmony_ci    let inFile = await fs.open(srcUri, fs.OpenMode.READ_WRITE);
173df226684Sopenharmony_ci    let dlpFile: dlpPermission.DLPFile;
174df226684Sopenharmony_ci    let authUserListNew: IAuthUser[] = [];
175df226684Sopenharmony_ci    try {
176df226684Sopenharmony_ci      dlpFile = await dlpPermission.openDLPFile(inFile.fd, callerAppId);
177df226684Sopenharmony_ci      dlpFile.dlpProperty.authUserList?.forEach(item => {
178df226684Sopenharmony_ci        authUserListNew.push(
179df226684Sopenharmony_ci          new IAuthUser(
180df226684Sopenharmony_ci            item.authAccount,
181df226684Sopenharmony_ci            item.authAccountType,
182df226684Sopenharmony_ci            item.dlpFileAccess,
183df226684Sopenharmony_ci            item.permExpiryTime
184df226684Sopenharmony_ci          ))
185df226684Sopenharmony_ci      })
186df226684Sopenharmony_ci      let _dlp = new IDLDLPProperty(
187df226684Sopenharmony_ci        dlpFile.dlpProperty.ownerAccount,
188df226684Sopenharmony_ci        dlpFile.dlpProperty.ownerAccountID,
189df226684Sopenharmony_ci        dlpFile.dlpProperty.ownerAccountType,
190df226684Sopenharmony_ci        authUserListNew,
191df226684Sopenharmony_ci        dlpFile.dlpProperty.contactAccount,
192df226684Sopenharmony_ci        dlpFile.dlpProperty.offlineAccess,
193df226684Sopenharmony_ci        dlpFile.dlpProperty.everyoneAccessList ?? [],
194df226684Sopenharmony_ci        dlpFile.dlpProperty.expireTime ?? 0,
195df226684Sopenharmony_ci      );
196df226684Sopenharmony_ci      callback(0, _dlp, '');
197df226684Sopenharmony_ci      if (!this.dlpFileMap.has(srcUri)) {
198df226684Sopenharmony_ci        this.dlpFileMap.set(srcUri, dlpFile);
199df226684Sopenharmony_ci        AppStorage.setOrCreate('dlpFileMap', this.dlpFileMap);
200df226684Sopenharmony_ci      } else {
201df226684Sopenharmony_ci        HiLog.info(TAG, `map is overwrite`);
202df226684Sopenharmony_ci        this.dlpFileMap.delete(srcUri);
203df226684Sopenharmony_ci        this.dlpFileMap.set(srcUri, dlpFile);
204df226684Sopenharmony_ci        AppStorage.setOrCreate('dlpFileMap', this.dlpFileMap);
205df226684Sopenharmony_ci      }
206df226684Sopenharmony_ci    } catch (err) {
207df226684Sopenharmony_ci      let _dlp = new IDLDLPProperty('', '', 0, [], '', true, [], 0);
208df226684Sopenharmony_ci      callback((err as BusinessError).code, _dlp, (err as BusinessError).message);
209df226684Sopenharmony_ci    } finally {
210df226684Sopenharmony_ci      if (inFile) {
211df226684Sopenharmony_ci        fs.closeSync(inFile);
212df226684Sopenharmony_ci      }
213df226684Sopenharmony_ci    }
214df226684Sopenharmony_ci  }
215df226684Sopenharmony_ci
216df226684Sopenharmony_ci  async stopFuseLink(uri: string, callback: stopFuseLinkCallback): Promise<void> {
217df226684Sopenharmony_ci    HiLog.info(TAG, `stopFuseLink start: ${uri}`);
218df226684Sopenharmony_ci    let dlpFile: dlpPermission.DLPFile | null = this.getOpeningFile(uri);
219df226684Sopenharmony_ci    if (dlpFile !== null) {
220df226684Sopenharmony_ci      await dlpFile.stopFuseLink();
221df226684Sopenharmony_ci    } else {
222df226684Sopenharmony_ci      HiLog.info(TAG, `stopFuseLink not find: ${uri}`);
223df226684Sopenharmony_ci      callback(-1);
224df226684Sopenharmony_ci    }
225df226684Sopenharmony_ci  }
226df226684Sopenharmony_ci
227df226684Sopenharmony_ci  async resumeFuseLink(uri: string, callback: resumeFuseLinkCallback): Promise<void> {
228df226684Sopenharmony_ci    HiLog.info(TAG, `resumeFuseLink start`);
229df226684Sopenharmony_ci    let dlpFile: dlpPermission.DLPFile | null = this.getOpeningFile(uri);
230df226684Sopenharmony_ci    if (dlpFile !== null) {
231df226684Sopenharmony_ci      await dlpFile.resumeFuseLink();
232df226684Sopenharmony_ci    } else {
233df226684Sopenharmony_ci      HiLog.info(TAG, `resumeFuseLink not find: ${uri}`);
234df226684Sopenharmony_ci      callback(-1);
235df226684Sopenharmony_ci    }
236df226684Sopenharmony_ci  }
237df226684Sopenharmony_ci
238df226684Sopenharmony_ci  async replaceDlpLinkFile(srcUri: string, linkFileName: string, callback: replaceDlpLinkFileCallback): Promise<void> {
239df226684Sopenharmony_ci    GlobalContext.load('sandbox2linkFile');
240df226684Sopenharmony_ci    if (this.dlpFileMap.has(srcUri)) {
241df226684Sopenharmony_ci      let dlpFile: dlpPermission.DLPFile = this.dlpFileMap.get(srcUri) as dlpPermission.DLPFile;
242df226684Sopenharmony_ci      let sandbox2linkFile: Map<string, (number | string | dlpPermission.DLPFile)[][]> = GlobalContext.load('sandbox2linkFile') as Map<string, (number | string | dlpPermission.DLPFile)[][]>;
243df226684Sopenharmony_ci      for (let key of Array.from<(number | string | dlpPermission.DLPFile)[][]>(sandbox2linkFile.values())) {
244df226684Sopenharmony_ci        for (let j of key) {
245df226684Sopenharmony_ci          if (j[1] === linkFileName) {
246df226684Sopenharmony_ci            j[0] = dlpFile;
247df226684Sopenharmony_ci          }
248df226684Sopenharmony_ci        }
249df226684Sopenharmony_ci      }
250df226684Sopenharmony_ci      await dlpFile.replaceDLPLinkFile(linkFileName);
251df226684Sopenharmony_ci    } else {
252df226684Sopenharmony_ci      HiLog.info(TAG, `replaceDLPLinkFile not find: ${srcUri}`);
253df226684Sopenharmony_ci      callback(-1);
254df226684Sopenharmony_ci    }
255df226684Sopenharmony_ci  }
256df226684Sopenharmony_ci
257df226684Sopenharmony_ci  async recoverDlpFile(srcUri: string, pathUri: string, callback: recoverDlpFileCallback): Promise<void> {
258df226684Sopenharmony_ci    let dlpFile: dlpPermission.DLPFile | null = this.getOpeningFile(srcUri);
259df226684Sopenharmony_ci    if (dlpFile !== null) {
260df226684Sopenharmony_ci      let inFile: fs.File | undefined;
261df226684Sopenharmony_ci      try {
262df226684Sopenharmony_ci        inFile = await fs.open(pathUri, fs.OpenMode.READ_WRITE);
263df226684Sopenharmony_ci        await dlpFile.recoverDLPFile(inFile.fd);
264df226684Sopenharmony_ci      } catch (err) {
265df226684Sopenharmony_ci        HiLog.error(TAG, `recoverDlpFileInner4: ${JSON.stringify(err)}`);
266df226684Sopenharmony_ci        callback((err as BusinessError).code);
267df226684Sopenharmony_ci      } finally {
268df226684Sopenharmony_ci        if (inFile) {
269df226684Sopenharmony_ci          fs.closeSync(inFile);
270df226684Sopenharmony_ci        }
271df226684Sopenharmony_ci      }
272df226684Sopenharmony_ci    } else {
273df226684Sopenharmony_ci      HiLog.info(TAG, `recoverDlpFile not find: ${srcUri}`);
274df226684Sopenharmony_ci      callback(-1);
275df226684Sopenharmony_ci    }
276df226684Sopenharmony_ci  }
277df226684Sopenharmony_ci
278df226684Sopenharmony_ci  async closeDlpFile(srcUri: string, callback: closeDlpFileCallback): Promise<void> {
279df226684Sopenharmony_ci    HiLog.info(TAG, `closeDlpFile start`);
280df226684Sopenharmony_ci    let dlpFile: dlpPermission.DLPFile | null = this.getOpeningFile(srcUri);
281df226684Sopenharmony_ci    if (dlpFile !== null) {
282df226684Sopenharmony_ci      try {
283df226684Sopenharmony_ci        await dlpFile.closeDLPFile();
284df226684Sopenharmony_ci        if (this.dlpFileMap.has(srcUri)) {
285df226684Sopenharmony_ci          this.dlpFileMap.delete(srcUri);
286df226684Sopenharmony_ci          AppStorage.setOrCreate('dlpFileMap', this.dlpFileMap);
287df226684Sopenharmony_ci        }
288df226684Sopenharmony_ci        callback(0);
289df226684Sopenharmony_ci      } catch (err) {
290df226684Sopenharmony_ci        HiLog.error(TAG, `closeDlpFile file: ${JSON.stringify(err)}`);
291df226684Sopenharmony_ci        callback((err as BusinessError).code);
292df226684Sopenharmony_ci      }
293df226684Sopenharmony_ci    }
294df226684Sopenharmony_ci  }
295df226684Sopenharmony_ci
296df226684Sopenharmony_ci  async sandBoxLinkFile(linkFileName: string, callerToken: number, callback: sandBoxLinkFileCallback): Promise<void> {
297df226684Sopenharmony_ci    let sandbox2linkFile: Map<string, (number | string | dlpPermission.DLPFile)[][]> = GlobalContext.load('sandbox2linkFile') as Map<string, (number | string | dlpPermission.DLPFile)[][]>;
298df226684Sopenharmony_ci    for (let value of Array.from<(number | string | dlpPermission.DLPFile)[][]>(sandbox2linkFile.values())) {
299df226684Sopenharmony_ci      for (let linkFile of value) {
300df226684Sopenharmony_ci        let _dlp = new IDLDLPProperty('', '', 0, [], '', true, [], 0);
301df226684Sopenharmony_ci        if (linkFile[Constants.FILE_OPEN_HISTORY_ONE] === linkFileName) {
302df226684Sopenharmony_ci          let authUserListNew: IAuthUser[] = [];
303df226684Sopenharmony_ci          if (callerToken !== linkFile[Constants.FILE_OPEN_HISTORY_THREE]) {
304df226684Sopenharmony_ci            HiLog.error(TAG, `found file, but token invalid: ${linkFileName}`);
305df226684Sopenharmony_ci            callback(-1, _dlp, '');
306df226684Sopenharmony_ci          } else {
307df226684Sopenharmony_ci            let linkFileInfo: Record<number, number | string | dlpPermission.DLPFile> =
308df226684Sopenharmony_ci              linkFile[0] as Record<number, number | string | dlpPermission.DLPFile>;
309df226684Sopenharmony_ci            linkFileInfo['dlpProperty'].authUserList.forEach((item: IAuthUser)=> {
310df226684Sopenharmony_ci              authUserListNew.push(
311df226684Sopenharmony_ci                new IAuthUser(
312df226684Sopenharmony_ci                  item.authAccount,
313df226684Sopenharmony_ci                  item.authAccountType,
314df226684Sopenharmony_ci                  item.dlpFileAccess,
315df226684Sopenharmony_ci                  item.permExpiryTime
316df226684Sopenharmony_ci                ))
317df226684Sopenharmony_ci            })
318df226684Sopenharmony_ci            _dlp = new IDLDLPProperty(
319df226684Sopenharmony_ci              linkFileInfo['dlpProperty'].ownerAccount,
320df226684Sopenharmony_ci              linkFileInfo['dlpProperty'].ownerAccountID,
321df226684Sopenharmony_ci              linkFileInfo['dlpProperty'].ownerAccountType,
322df226684Sopenharmony_ci              authUserListNew,
323df226684Sopenharmony_ci              linkFileInfo['dlpProperty'].contactAccount,
324df226684Sopenharmony_ci              linkFileInfo['dlpProperty'].offlineAccess,
325df226684Sopenharmony_ci              linkFileInfo['dlpProperty'].everyoneAccessList ?? [],
326df226684Sopenharmony_ci              linkFileInfo['dlpProperty'].expireTime ?? 0
327df226684Sopenharmony_ci            );
328df226684Sopenharmony_ci            let fileUri = linkFile[4];
329df226684Sopenharmony_ci            callback(0, _dlp, fileUri.toString());
330df226684Sopenharmony_ci          }
331df226684Sopenharmony_ci        } else {
332df226684Sopenharmony_ci          HiLog.error(TAG, `request from sandbox, but can not find dlp file by linkFileName: ${linkFileName}`);
333df226684Sopenharmony_ci          callback(-1, _dlp, '');
334df226684Sopenharmony_ci        }
335df226684Sopenharmony_ci      }
336df226684Sopenharmony_ci    }
337df226684Sopenharmony_ci  }
338df226684Sopenharmony_ci
339df226684Sopenharmony_ci  async fileOpenHistory(uri: string, callback: fileOpenHistoryCallback): Promise<void> {
340df226684Sopenharmony_ci    HiLog.info(TAG, `fileOpenHistory start`);
341df226684Sopenharmony_ci    if ((GlobalContext.load('fileOpenHistory') as Map<string, (number | string)[]>)?.has(uri)) {
342df226684Sopenharmony_ci      callback(0);
343df226684Sopenharmony_ci    } else {
344df226684Sopenharmony_ci      callback(-1);
345df226684Sopenharmony_ci    }
346df226684Sopenharmony_ci  }
347df226684Sopenharmony_ci
348df226684Sopenharmony_ci  async linkSet(uri: string, callback: linkSetCallback): Promise<void> {
349df226684Sopenharmony_ci    HiLog.info(TAG, `linkSet start`);
350df226684Sopenharmony_ci    if ((GlobalContext.load('linkSet') as Map<string, (number | string)[]>)?.has(uri)) {
351df226684Sopenharmony_ci      callback(0);
352df226684Sopenharmony_ci    } else {
353df226684Sopenharmony_ci      callback(-1);
354df226684Sopenharmony_ci    }
355df226684Sopenharmony_ci  }
356df226684Sopenharmony_ci}
357df226684Sopenharmony_ci
358df226684Sopenharmony_ciexport default class ServiceExtAbility extends ServiceExtension {
359df226684Sopenharmony_ci  onCreate(want: Want) {
360df226684Sopenharmony_ci    HiLog.info(TAG, `onCreate, want: ${want.abilityName}`);
361df226684Sopenharmony_ci  }
362df226684Sopenharmony_ci
363df226684Sopenharmony_ci  onRequest(want: Want, startId: number) {
364df226684Sopenharmony_ci    HiLog.info(TAG, `onRequest, want: ${want.abilityName}`);
365df226684Sopenharmony_ci  }
366df226684Sopenharmony_ci
367df226684Sopenharmony_ci  onConnect(want: Want) {
368df226684Sopenharmony_ci    HiLog.info(TAG, `service onConnect, want: ${want.abilityName}`);
369df226684Sopenharmony_ci    return new DlpRpcServiceStub('dlpRpc service stub');
370df226684Sopenharmony_ci  }
371df226684Sopenharmony_ci
372df226684Sopenharmony_ci  onDisconnect(want: Want): void {
373df226684Sopenharmony_ci    HiLog.info(TAG, `onDisconnect, want: ${want.abilityName}`);
374df226684Sopenharmony_ci  }
375df226684Sopenharmony_ci
376df226684Sopenharmony_ci  onDestroy(): void {
377df226684Sopenharmony_ci    HiLog.info(TAG, `onDestroy`);
378df226684Sopenharmony_ci  }
379df226684Sopenharmony_ci}