1/*
2 * Copyright (c) 2022 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 extension from '@ohos.app.ability.ServiceExtensionAbility';
17import type { Permissions } from '@ohos.abilityAccessCtrl';
18import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
19import rpc from '@ohos.rpc';
20import GlobalContext from '../common/GlobalContext';
21import * as notice_sub from '../InjectNotice/InjectNoticeStub';
22import {NOTICE_ID, injectNoticeUtil } from '../InjectNotice/InjectNoticeUtil';
23
24const TAG = 'InjectNotice';
25const ACCESS_TYPE_MASK = 0b11;
26const SHIFT_DIGIT = 27;
27const TOKEN_NATIVE = 1;
28
29export default class InjectNoticeAbility extends extension {
30  /**
31   * Lifecycle function, called back when a service extension is started for initialization.
32   */
33  onCreate(want): void {
34    console.debug(TAG, 'InjectNoticeAbility onCreate' + JSON.stringify(want));
35    GlobalContext.getContext().setObject('appcontext', this.context.getApplicationContext());
36    try {
37      injectNoticeUtil.init();
38    } catch (e) {
39      console.error(TAG, 'InjectNoticeAbility onCreate' + want.abilityName);
40    }
41    console.debug(TAG, 'InjectNoticeAbility onCreate end');
42  }
43
44  onConnect(want): rpc.RemoteObject {
45    console.debug(TAG, 'onConnect want: ' + JSON.stringify(want));
46    return new notice_sub.InjectNoticeStub('InjectNoticeStub');
47  }
48
49  onDisconnect(want): void {
50    console.info(TAG, 'onDisconnect');
51  }
52
53  /**
54   * Lifecycle function, called back when a service extension is started or recall.
55   */
56  onRequest(want, startId): void {
57    console.debug(TAG, `onRequest startId: ${startId} want:${JSON.stringify(want)}`);
58    if ('noticeId' in want.parameters) {
59      console.debug(TAG, `onRequest noticeId has value`);
60      if (want.parameters.noticeId === NOTICE_ID) {
61        console.debug(TAG, `onRequest startId: ${startId} close notice`);
62        injectNoticeUtil.cancelAuthorization();
63        injectNoticeUtil.cancelNotificationById(NOTICE_ID);
64        return;
65      }
66    }
67  }
68  /**
69   * Lifecycle function, called back before a service extension is destroyed.
70   */
71  onDestroy(): void {
72    console.debug(TAG, 'onDestroy.');
73  }
74
75  private isSystemAbility(callingTokenId: number): boolean {
76    let type: number = ACCESS_TYPE_MASK & (callingTokenId >> SHIFT_DIGIT);
77    console.debug(TAG, 'InjectNoticeAbility isSystemAbility, type:' + type);
78    return type === TOKEN_NATIVE;
79  }
80
81  private checkPermission(tokenID: number, permissionName: Permissions): boolean {
82    let aac = abilityAccessCtrl.createAtManager();
83    try {
84      let grantStatus = aac.verifyAccessTokenSync(tokenID, permissionName);
85      if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) {
86        console.error(TAG, `verify ${permissionName} fail`);
87      }
88    } catch (error) {
89      console.error(TAG, `verify ${permissionName}, ${error}`);
90    }
91    console.debug(TAG, `verify ${permissionName}, success`);
92    return true;
93  }
94}