1/* 2 * Copyright (c) 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 */ 15import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility'; 16import Want from '@ohos.app.ability.Want'; 17import fileio from '@ohos.fileio'; 18import dlpPermission from '@ohos.dlpPermission'; 19import GlobalContext from '../common/GlobalContext'; 20import { BusinessError } from '@ohos.base'; 21import common from '@ohos.app.ability.common'; 22 23let TAG = '[DLPManager_DataAbility]'; 24const INDEX_TWO = 2; 25const INDEX_ONE = 1; 26const INDEX_ZERO = 0; 27const INDEX_THREE = 3; 28const INDEX_FOUR = 4; 29const INDEX_FIVE = 5; 30export default class DataAbility extends ServiceExtensionAbility { 31 isSubscriber = false; 32 async subscribeCallback(data: dlpPermission.DLPSandboxState): Promise<void> { 33 let bundleName: string = data.bundleName; 34 let sandboxAppIndex: number = data.appIndex; 35 let key: string = bundleName + sandboxAppIndex; 36 37 let authPerm2Sandbox:Map<dlpPermission.DLPFileAccess, (number | string)[]> = GlobalContext.load('authPerm2Sandbox') as Map<dlpPermission.DLPFileAccess, (number | string)[]>; 38 for (let item of Array.from<(dlpPermission.DLPFileAccess|(number | string)[])[]>(authPerm2Sandbox)) { 39 let itemKey = item[0]; 40 let itemValue = item[1]; 41 const app: string = (itemValue[0] as string) + (itemValue[1] as number); 42 if (key === app) { 43 authPerm2Sandbox.delete(itemKey as dlpPermission.DLPFileAccess); 44 } 45 } 46 47 let token2File:Map<number, (number | string | dlpPermission.DLPFile)[]> = GlobalContext.load('token2File') as Map<number, (number | string | dlpPermission.DLPFile)[]>; 48 for (let item of Array.from<(number|(number | string | dlpPermission.DLPFile)[])[]>(token2File)) { 49 let itemKey = item[0]; 50 let itemValue = item[1]; 51 const APP_ID: string = (itemValue[INDEX_ONE] as string) + (itemValue[INDEX_TWO] as number); 52 if (key === APP_ID) { 53 token2File.delete(itemKey as number); 54 } 55 } 56 try { 57 let sandbox2linkFile: Map<string, (number | string | dlpPermission.DLPFile)[][]> = GlobalContext.load('sandbox2linkFile') as Map<string, (number | string | dlpPermission.DLPFile)[][]>; 58 if (sandbox2linkFile.has(key)) { 59 let fileArray: (number | string | dlpPermission.DLPFile)[][] = sandbox2linkFile.get(key) as (number | string | dlpPermission.DLPFile)[][]; 60 for (let i of fileArray) { 61 let linkFile: (number | string | dlpPermission.DLPFile)[] = i; 62 let dlpFile: dlpPermission.DLPFile = linkFile[INDEX_ZERO] as dlpPermission.DLPFile; 63 try { 64 await dlpFile.deleteDLPLinkFile(linkFile[INDEX_ONE] as string); 65 } catch (err) { 66 console.error(TAG, 'deleteDLPLinkFile failed', (err as BusinessError).code, (err as BusinessError).message); 67 } 68 try { 69 await dlpFile.closeDLPFile(); 70 } catch (err) { 71 console.error(TAG, 'closeDLPFile failed', (err as BusinessError).code, (err as BusinessError).message); 72 } 73 try { 74 let dlpFd: number = linkFile[INDEX_TWO] as number; 75 fileio.closeSync(dlpFd); 76 } catch (err) { 77 console.error(TAG, 'closeDLPFile failed', (err as BusinessError).code, (err as BusinessError).message); 78 } 79 } 80 sandbox2linkFile.delete(key); 81 82 let fileOpenHistory:Map<string, (number | string)[]> = GlobalContext.load('fileOpenHistory') as Map<string, (number | string)[]>; 83 for (let item of Array.from<(string|(number | string)[])[]>(fileOpenHistory)) { 84 let itemKey = item[0]; 85 let itemValue = item[1]; 86 let tmp: string = (itemValue[0] as string) + (itemValue[1] as number); 87 if (tmp === key) { 88 let linkUri: string = itemValue[INDEX_THREE] as string; 89 (GlobalContext.load('linkSet') as Set<string>).delete(linkUri); 90 fileOpenHistory.delete(itemKey as string); 91 } 92 } 93 94 if (sandbox2linkFile.size === 0) { 95 console.info(TAG, 'sandbox2linkFile empty'); 96 (GlobalContext.load('dataContext') as common.ServiceExtensionContext).terminateSelf(); 97 } 98 } 99 } catch (err) { 100 console.error(TAG, 'release resource error', JSON.stringify(err)); 101 } 102 } 103 104 createSubscriber(): void { 105 console.info(TAG, 'createSubscriber'); 106 try { 107 dlpPermission.on('uninstallDLPSandbox', this.subscribeCallback); 108 this.isSubscriber = true; 109 } catch (err) { 110 console.info(TAG, 'createSubscriber uninstallDLPSandbox failed', (err as BusinessError).code, (err as BusinessError).message); 111 } 112 } 113 114 onCreate(want: Want): void { 115 const context = this.context; 116 GlobalContext.store('dataContext', context); 117 } 118 119 onRequest(want: Want, startId: number): void { 120 if (!this.isSubscriber) { 121 this.createSubscriber(); 122 } 123 } 124 125 onDestroy(): void { 126 console.info(TAG, 'onDestroy'); 127 if (this.isSubscriber) { 128 console.info(TAG, 'cancelSubscriber uninstallDLPSandbox'); 129 try { 130 dlpPermission.off('uninstallDLPSandbox'); 131 this.isSubscriber = false; 132 } catch (err) { 133 console.error(TAG, 'cancelSubscriber uninstallDLPSandbox error', JSON.stringify(err)); 134 } 135 } 136 } 137} 138