• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
15
16import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession';
17import UIExtensionAbility from '@ohos.app.ability.UIExtensionAbility';
18import dlpPermission from '@ohos.dlpPermission';
19import emitter from '@ohos.events.emitter';
20import Want from '@ohos.app.ability.Want';
21import { BusinessError } from '@ohos.base';
22import osAccount from '@ohos.account.osAccount';
23import { Configuration } from '@ohos.app.ability.Configuration';
24import Constants from '../common/constant';
25import {
26  getAuthPerm,
27  checkDomainAccountInfo,
28  getOsAccountInfo,
29  judgeIsSandBox,
30  getFileFd,
31  getAppId,
32  isPC,
33  DLPInfo,
34  getDLPInfo,
35  sendDlpManagerAccountLogin,
36  isValidPath,
37  startAlertAbility
38} from '../common/utils';
39import GlobalContext from '../common/GlobalContext';
40import HomeFeature from '../feature/HomeFeature';
41import { AccountTipsConfig } from '../common/AccountTipsConfig';
42import common from '@ohos.app.ability.common';
43
44const TAG = '[DLPManager_MainEx]';
45
46let direction: number = -1;
47let colorMode: number = -1;
48
49export default class MainAbility extends UIExtensionAbility {
50  authPerm: dlpPermission.DLPFileAccess = dlpPermission.DLPFileAccess.READ_ONLY;
51  callerToken:number = 0;
52  private homeFeature!: HomeFeature;
53
54  async onSessionCreate(want: Want, session: UIExtensionContentSession): Promise<void> {
55    console.log(TAG, 'want', JSON.stringify(want));
56    if (GlobalContext.load('session')) {
57      await startAlertAbility(this.context as common.UIExtensionContext,
58        { code: Constants.ERR_JS_APP_ENCRYPTING,
59          data: GlobalContext.load('abilityWant').parameters?.displayName
60        } as BusinessError, session);
61      return;
62    }
63    GlobalContext.store('session', session);
64    let dlpInfo:DLPInfo = await getDLPInfo();
65    GlobalContext.store('hiPNameId', dlpInfo.name);
66    GlobalContext.store('hiPVersionId', dlpInfo.versionCode);
67    GlobalContext.store('abilityWant', want);
68    GlobalContext.store('context', this.context);
69    GlobalContext.store('domainAccount', !isPC() ? false : true);
70    GlobalContext.store('uri', want.uri ?? '');
71    direction = this.context.config.direction ?? -1;
72
73    this.homeFeature = new HomeFeature(this.context);
74    GlobalContext.store('homeFeature', this.homeFeature);
75
76    this.homeFeature.connectServiceExtAbility(()=>{
77      this.getNewWantPage(session);
78    });
79  }
80
81  onConfigurationUpdate(newConfig: Configuration): void {
82    if (direction !== newConfig.direction) {
83      direction = newConfig.direction ?? -1;
84    }
85    let eventData: emitter.EventData = {
86      data: {
87        'direction': direction,
88      }};
89    let innerEvent: emitter.InnerEvent = {
90      eventId: Constants.ENCRYPTION_EMIT_DIRECTION_STATUS,
91      priority: emitter.EventPriority.HIGH
92    };
93    emitter.emit(innerEvent, eventData);
94
95    if (colorMode !== newConfig.colorMode) {
96      colorMode = newConfig.colorMode ?? -1;
97    }
98    let colorData: emitter.EventData = {
99      data: {
100        'colorMode': colorMode,
101      }};
102    let colorEvent: emitter.InnerEvent = {
103      eventId: Constants.ENCRYPTION_EMIT_COLOR_MODE,
104      priority: emitter.EventPriority.HIGH
105    };
106    emitter.emit(colorEvent, colorData);
107  }
108
109  onSessionDestroy(session: UIExtensionContentSession): void {
110    console.info(TAG, 'onSessionDestroy');
111    if (session === GlobalContext.load('session')) {
112      GlobalContext.store('session', '');
113    }
114    if (!(GlobalContext.load('requestIsFromSandBox') as boolean)) {
115      this.homeFeature.closeDLPFileHome(GlobalContext.load('uri'), (err: number) => {
116        if (err !== 0) {
117          console.error(TAG, 'closeDLPFile failed', err);
118        }
119      });
120    }
121  }
122
123  async gotoPage(session: UIExtensionContentSession): Promise<void> {
124    let accountInfo: osAccount.OsAccountInfo = GlobalContext.load('accountInfo');
125    let accountName: string = (GlobalContext.load('domainAccount') as boolean) ? accountInfo.domainInfo.accountName : accountInfo.distributedInfo.name;
126    this.authPerm = getAuthPerm(accountName, GlobalContext.load('dlpProperty'));
127
128    AppStorage.setOrCreate('authPerm', this.authPerm);
129    AppStorage.setOrCreate<string>('contactAccount', GlobalContext.load('dlpProperty').contactAccount);
130    AppStorage.setOrCreate('validity', GlobalContext.load('dlpProperty').expireTime)
131    if (this.authPerm < dlpPermission.DLPFileAccess.READ_ONLY ||
132      this.authPerm > dlpPermission.DLPFileAccess.FULL_CONTROL) {
133      await startAlertAbility(GlobalContext.load('context') as common.UIExtensionContext,
134        { code: Constants.ERR_JS_APP_INSIDE_ERROR } as BusinessError, session);
135      return;
136    }
137    if (this.authPerm === dlpPermission.DLPFileAccess.FULL_CONTROL) {
138      if (GlobalContext.load('domainAccount') as boolean) {
139        try {
140          await this.checkValidEnterpriseAndAccount(session);
141        } catch {
142          return;
143        }
144      }
145
146      let storage: LocalStorage = new LocalStorage({
147        'session': session,
148      } as Record<string, UIExtensionContentSession | string>);
149      session.loadContent('pages/changeEncryption', storage);
150      try {
151        session.setWindowBackgroundColor(Constants.TRANSPARENT_GREY_BACKGROUND_COLOR);
152      } catch (exception) {
153        console.error('Failed to set the background color. Cause: ' + JSON.stringify(exception));
154      }
155    } else {
156      let storage: LocalStorage = new LocalStorage({
157        'session': session,
158      } as Record<string, UIExtensionContentSession | string>);
159      session.loadContent('pages/permissionStatus', storage);
160      try {
161        session.setWindowBackgroundColor(Constants.TRANSPARENT_BACKGROUND_COLOR);
162      } catch (exception) {
163        console.error('Failed to set the background color. Cause: ' + JSON.stringify(exception));
164      }
165    }
166  }
167
168  async checkValidWant(): Promise<boolean> {
169    let parameters = (GlobalContext.load('abilityWant') as Want).parameters;
170    if (parameters === undefined) {
171      console.error(TAG, 'need parameters in want');
172      return false;
173    }
174    if (parameters.fileName === undefined) {
175      console.error(TAG, 'need fileName in want.parameters');
176      return false;
177    }
178    if ((parameters.fileName as Record<string, string>).name === undefined) {
179      console.error(TAG, 'need name in want.parameters.fileName');
180      return false;
181    }
182    if ((GlobalContext.load('abilityWant') as Want).uri === undefined) {
183      console.error(TAG, 'need uri in want');
184      return false;
185    }
186    this.callerToken = parameters['ohos.aafwk.param.callerToken'] as number;
187    let callerBundleName: string = parameters['ohos.aafwk.param.callerBundleName'] as string;
188    if (this.callerToken === undefined || callerBundleName === undefined) {
189      console.error(TAG, 'need caller info in want.parameters');
190      return false;
191    }
192    GlobalContext.store('hiPkgName', callerBundleName);
193    let uri = String((GlobalContext.load('abilityWant') as Want).uri);
194    if (!isValidPath(uri)) {
195      console.error(TAG, 'invalid uri in want.uri');
196      return false;
197    }
198    try {
199      await new Promise<void>((resolve, reject) => {
200        this.homeFeature.linkSetHome(uri, (err: number) => {
201          if (err === 0) {
202            console.error(TAG, 'invalid uri for opened link uri');
203            reject();
204          }
205          resolve();
206        })
207      })
208    } catch {
209      return false;
210    }
211
212    if (uri.indexOf(Constants.FUSE_PATH) !== -1) {
213      console.error(TAG, 'invalid uri in want.uri');
214      return false;
215    }
216    return true;
217  }
218
219  async checkValidEnterpriseAndAccount(session: UIExtensionContentSession): Promise<void> {
220    return new Promise(async (resolve, reject) => {
221      let accountInfo: osAccount.OsAccountInfo = GlobalContext.load('accountInfo');
222      AccountTipsConfig.getAccountInfo(accountInfo.domainInfo.accountName)
223        .then(() => {
224          resolve();
225        })
226        .catch(async (error: BusinessError) => {
227          await startAlertAbility(GlobalContext.load('context') as common.UIExtensionContext,
228            error, session);
229          reject();
230          return;
231        })
232    })
233  }
234
235  async checkValidWantAndAccount(session: UIExtensionContentSession): Promise<void> {
236    return new Promise(async (resolve, reject) => {
237      if (!this.checkValidWant()) {
238        await startAlertAbility(GlobalContext.load('context') as common.UIExtensionContext,
239          { code: Constants.ERR_JS_APP_PARAM_ERROR } as BusinessError, session);
240        reject();
241        return;
242      }
243      let accountInfo: osAccount.OsAccountInfo;
244      try {
245        accountInfo = await getOsAccountInfo();
246        GlobalContext.store('accountInfo', accountInfo);
247        resolve();
248      } catch (err) {
249        console.error(TAG, 'getOsAccountInfo failed', (err as BusinessError).code, (err as BusinessError).message);
250        await startAlertAbility(GlobalContext.load('context') as common.UIExtensionContext,
251          { code: Constants.ERR_JS_GET_ACCOUNT_ERROR } as BusinessError, session);
252        reject();
253        return;
254      }
255    })
256  }
257
258  async getNewWantPage(session: UIExtensionContentSession): Promise<void> {
259    console.log(TAG, 'getNewWantPage start');
260    try {
261      await this.checkValidWantAndAccount(session)
262    } catch {
263      return;
264    }
265    let codeMessage = checkDomainAccountInfo(GlobalContext.load('accountInfo'));
266    sendDlpManagerAccountLogin(0);
267    if (codeMessage) {
268      await startAlertAbility(GlobalContext.load('context') as common.UIExtensionContext,
269        { code: codeMessage } as BusinessError, session);
270      return;
271    }
272    let requestIsFromSandBox: boolean = await judgeIsSandBox();
273    GlobalContext.store('requestIsFromSandBox', requestIsFromSandBox);
274    console.info(TAG, 'request is from sandbox', requestIsFromSandBox);
275    if (requestIsFromSandBox) {
276      let abilityWant: Want = GlobalContext.load('abilityWant') as Want;
277      const linkFileName: string = (abilityWant.parameters?.linkFileName as Record<string, string>)?.name;
278      this.homeFeature.sandBoxLinkFileHome(linkFileName, this.callerToken, (err: number, data: dlpPermission.DLPProperty, uri: string) => {
279        if (err !== 0) {
280          return;
281        }
282        let dlpFileName: string = (abilityWant.parameters?.fileName as Record<string, string>)?.name;
283        GlobalContext.store('dlpFileName', dlpFileName);
284        GlobalContext.store('linkFileName', linkFileName);
285        GlobalContext.store('dlpProperty', data);
286        GlobalContext.store('uri', uri ?? '');
287        GlobalContext.store('permanent', data.expireTime === 0);
288        if (data.expireTime !== 0) {
289          GlobalContext.store('validity', new Date(data.expireTime as number));
290        }
291        this.gotoPage(session);
292      });
293    } else {
294      let fileName: string = ((GlobalContext.load('abilityWant') as Want).parameters?.fileName as Record<string, string>)?.name;
295      let isDlpSuffix: boolean = fileName.endsWith('.dlp');
296      if (!isDlpSuffix) {
297        console.info(TAG, fileName, 'is not a dlp file');
298        GlobalContext.store('originFileName', fileName);
299        GlobalContext.store('originFd', getFileFd(GlobalContext.load('uri') as string));
300        let storage: LocalStorage = new LocalStorage({
301          'session': session,
302        } as Record<string, UIExtensionContentSession | string>);
303        session.loadContent('pages/encryptionProtection', storage);
304        try {
305          session.setWindowBackgroundColor(Constants.TRANSPARENT_GREY_BACKGROUND_COLOR);
306        } catch (exception) {
307          console.error('Failed to set the background color. Cause: ' + JSON.stringify(exception));
308        }
309        return;
310      } else {
311        let uri: string = GlobalContext.load('uri') as string;
312        try {
313          await new Promise<void>((resolve, reject) => {
314            this.homeFeature.fileOpenHistoryHome(uri, async (err: number) => {
315              if (err === 0) {
316                await startAlertAbility(GlobalContext.load('context') as common.UIExtensionContext,
317                  { code: Constants.ERR_JS_APP_OPEN_REJECTED } as BusinessError, session);
318                reject();
319              }
320              resolve();
321            })
322          })
323        } catch {
324          return;
325        }
326        let dlpFileName: string = ((GlobalContext.load('abilityWant')as Want).parameters?.fileName as Record<string, string>)?.name;
327        GlobalContext.store('dlpFileName', dlpFileName);
328        let callerAppId: string;
329        try {
330          let callerBundleName = Constants.DLP_MANAGER_BUNDLE_NAME;
331          callerAppId = await getAppId(callerBundleName);
332          console.info(TAG, 'get AppId', callerAppId);
333        } catch {
334          console.log(TAG, 'get AppId failed');
335          return;
336        }
337        this.homeFeature.openDlpFileHome(uri, callerAppId, async (err: number, data: dlpPermission.DLPProperty, msg: string) => {
338          if (err !== 0) {
339            let ansErr: BusinessError<void> = {
340              code: err,
341              name: '',
342              message: msg,
343            }
344            await startAlertAbility(GlobalContext.load('context') as common.UIExtensionContext,
345              ansErr as BusinessError, session);
346            return;
347          } else {
348            GlobalContext.store('dlpProperty', data);
349            GlobalContext.store('permanent', data.expireTime === 0);
350            if (data.expireTime !== 0) {
351              GlobalContext.store('validity', new Date(data.expireTime as number));
352            }
353            this.gotoPage(session);
354          }
355        })
356      }
357    }
358  }
359
360  onWindowStageDestroy(): void {
361    console.info(TAG, 'onWindowStageDestroy');
362  }
363
364  onForeground(): void {
365    console.info(TAG, 'onForeground');
366  }
367
368  onBackground() {
369    console.info(TAG, 'onBackground');
370  }
371};
372