• 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 { BasePermissionStrategy } from '../base/BasePermissionStrategy';
17import { LocationStrategy } from './LocationStrategy';
18import { CameraStrategy } from './CameraStrategy';
19import { MicrophoneStrategy } from './MicrophoneStrategy';
20import { ContactsStrategy } from './ContactsStrategy';
21import { CalendarStrategy } from './CalendarStrategy';
22import { SportStrategy } from './SportStrategy';
23import { HealthStrategy } from './HealthStrategy';
24import { ImageAndVideosStrategy } from './ImageAndVideosStrategy';
25import { AudioStrategy } from './AudiosStrategy';
26import { DocumentsStrategy } from './DocumentsStrategy';
27import { AdsStrategy } from './AdsStrategy';
28import { GetInstalledBundleListStrategy } from './GetInstalledBundleListStrategy';
29import { DistributedDatasyncStrategy } from './DistributedDatasyncStrategy';
30import { BluetoothStrategy } from './BluetoothStrategy';
31import { PasteboardStrategy } from './PasteboardStrategy';
32import { DownloadDirectoryStrategy } from './DownloadDirectoryStrategy';
33import { DesktopDirectoryStrategy } from './DesktopDirectoryStrategy';
34import { DocumentsDirectoryStrategy } from './DocumentsDirectoryStrategy';
35import { NearlinkStrategy } from './NearlinkStrategy';
36import { ScreenCaptureStrategy } from './ScreenCaptureStrategy';
37import { Permission, PermissionGroup, PermissionOption, ButtonStatus, ClickOption } from '../model/definition';
38import { PermissionGroupConfig, CallerAppInfo, PermissionWithOption } from '../model/typedef';
39import { Log } from '../utils/utils';
40import common from '@ohos.app.ability.common';
41
42export class PermissionGroupManager {
43  private permissionStrategies: Map<PermissionGroup, BasePermissionStrategy> = new Map();
44  private static instance: PermissionGroupManager;
45
46  private constructor() {
47    // 位置信息
48    this.permissionStrategies.set(PermissionGroup.LOCATION, new LocationStrategy());
49    // 相机
50    this.permissionStrategies.set(PermissionGroup.CAMERA, new CameraStrategy());
51    // 麦克风
52    this.permissionStrategies.set(PermissionGroup.MICROPHONE, new MicrophoneStrategy());
53    // 通讯录
54    this.permissionStrategies.set(PermissionGroup.CONTACTS, new ContactsStrategy());
55    // 日历
56    this.permissionStrategies.set(PermissionGroup.CALENDAR, new CalendarStrategy());
57    // 运动健身
58    this.permissionStrategies.set(PermissionGroup.SPORT, new SportStrategy());
59    // 身体传感器
60    this.permissionStrategies.set(PermissionGroup.HEALTH, new HealthStrategy());
61    // 图片和视频
62    this.permissionStrategies.set(PermissionGroup.IMAGE_AND_VIDEOS, new ImageAndVideosStrategy());
63    // 音频
64    this.permissionStrategies.set(PermissionGroup.AUDIOS, new AudioStrategy());
65    // 文件
66    this.permissionStrategies.set(PermissionGroup.DOCUMENTS, new DocumentsStrategy());
67    // 应用跟踪
68    this.permissionStrategies.set(PermissionGroup.ADS, new AdsStrategy());
69    // 读取已安装应用列表
70    this.permissionStrategies.set(PermissionGroup.GET_INSTALLED_BUNDLE_LIST, new GetInstalledBundleListStrategy());
71    // 附近设备
72    this.permissionStrategies.set(PermissionGroup.DISTRIBUTED_DATASYNC, new DistributedDatasyncStrategy());
73    // 蓝牙
74    this.permissionStrategies.set(PermissionGroup.BLUETOOTH, new BluetoothStrategy());
75    // 剪贴板
76    this.permissionStrategies.set(PermissionGroup.PASTEBOARD, new PasteboardStrategy());
77    // 文件夹
78    this.permissionStrategies.set(PermissionGroup.DOWNLOAD_DIRECTORY, new DownloadDirectoryStrategy());
79    this.permissionStrategies.set(PermissionGroup.DESKTOP_DIRECTORY, new DesktopDirectoryStrategy());
80    this.permissionStrategies.set(PermissionGroup.DOCUMENTS_DIRECTORY, new DocumentsDirectoryStrategy());
81    // 星闪
82    this.permissionStrategies.set(PermissionGroup.NEARLINK, new NearlinkStrategy());
83    // 截屏
84    this.permissionStrategies.set(PermissionGroup.CUSTOM_SCREEN_CAPTURE, new ScreenCaptureStrategy());
85  }
86
87  public static getInstance(): PermissionGroupManager {
88    if (!PermissionGroupManager.instance) {
89      PermissionGroupManager.instance = new PermissionGroupManager();
90    }
91    return PermissionGroupManager.instance;
92  }
93
94  /**
95   * 获取所有权限组config
96   * return
97   */
98  public getAllGroupConfigs(): PermissionGroupConfig[] {
99    let allConfig: PermissionGroupConfig[] = [];
100    this.permissionStrategies.forEach((strategy, permissionGroup) => {
101      allConfig.push(strategy.getPermissionGroupConfig());
102    })
103    return allConfig;
104  }
105
106  /**
107   * 根据权限获取所在权限组名
108   * @param permission 权限
109   * @param allConfigs
110   * return
111   */
112  public getGroupNameByPermission(
113    permission: Permission, allConfigs: PermissionGroupConfig[]
114  ): PermissionGroup | undefined {
115    for (let index = 0; index < allConfigs.length; index++) {
116      const element = allConfigs[index];
117      if (element.permissions.includes(permission)) {
118        return element.groupName;
119      }
120    }
121    Log.error(`can not find permissionGroup, permission: ${permission}`);
122    return undefined;
123  }
124
125  /**
126   * 预处理待授权权限
127   * @param permission 权限
128   * @param groupName 权限组名
129   * @param tokenId 应用token
130   * return
131   */
132  public async preProcessPermission(
133    permission: Permission, groupName: PermissionGroup, tokenId: number
134  ): Promise<PermissionWithOption[]> {
135    const groupHandle = this.permissionStrategies.get(groupName);
136    if (groupHandle === undefined) {
137      return [];
138    }
139    let result = await groupHandle.preProcessingPermission(permission, tokenId);
140    return result;
141  }
142
143  /**
144   * 根据带申请权限获取所有权限组列表
145   * @param callerAppInfo 调用方信息
146   * @param context 应用上下文
147   * @param appName 应用名
148   * @param locationFlag 位置权限组flag
149   * @param pasteBoardName 剪贴板信息
150   * return
151   */
152  public getGroupConfigs(
153    callerAppInfo: CallerAppInfo,
154    context: common.ServiceExtensionContext,
155    appName: string,
156    locationFlag: number,
157    pasteBoardName: string
158  ): PermissionGroupConfig[] {
159    let groupConfigList: PermissionGroupConfig[] = [];
160    callerAppInfo.groupWithPermission.forEach((permissions, permissionGroup) => {
161      let groupHandle = this.permissionStrategies.get(permissionGroup);
162      if (groupHandle === undefined || groupHandle === null) {
163        Log.error(`get groupHandle faild, group: ${permissionGroup}.`);
164        return;
165      }
166      let groupConfig: PermissionGroupConfig = groupHandle.getPermissionGroupConfig();
167      let title: ResourceStr = groupHandle.getGroupTitle(appName, locationFlag);
168      let readAndWrite: ResourceStr = groupHandle.getReadAndWrite(permissions);
169      let reason: ResourceStr =
170        groupHandle.getReasonByPermission(groupConfig.permissions, permissions, context, callerAppInfo, pasteBoardName);
171      groupConfigList.push(new PermissionGroupConfig({
172        groupName: groupConfig.groupName,
173        permissions: groupConfig.permissions,
174        icon: groupConfig.icon,
175        title,
176        readAndWrite,
177        reason,
178        buttonList: groupHandle.getButtonList()
179      }))
180    })
181    return groupConfigList;
182  }
183
184  /**
185   * 根据点击状态,返回当前权限对应的操作
186   * @param permission 权限
187   * @param groupName 权限组名
188   * @param callerAppInfo 调用方信息
189   * @param locationFlag 位置权限组flag
190   * @param buttonStatus
191   * return
192   */
193  public getPermissionOption(
194    permission: Permission,
195    groupName: PermissionGroup,
196    callerAppInfo: CallerAppInfo,
197    locationFlag: number,
198    buttonStatus: ButtonStatus
199  ): PermissionOption {
200    const groupHandle = this.permissionStrategies.get(groupName);
201    let situation: ClickOption = this.getClickSituation(buttonStatus);
202    if (groupHandle) {
203      if (situation === ClickOption.GRANT) {
204        return groupHandle.grantHandle(permission, callerAppInfo, locationFlag, buttonStatus);
205      } else if (situation === ClickOption.DENY) {
206        return groupHandle.denyHandle(permission, callerAppInfo, locationFlag, buttonStatus);
207      } else {
208        return PermissionOption.SKIP;
209      }
210    }
211    return PermissionOption.SKIP;
212  }
213
214  /**
215   * 处理点击状态
216   * @param buttonStatus
217   * return
218   */
219  public getClickSituation(buttonStatus: ButtonStatus): ClickOption {
220    switch (buttonStatus) {
221      case ButtonStatus.ALLOW:
222      case ButtonStatus.ALLOW_THIS_TIME:
223      case ButtonStatus.THIS_TIME_ONLY:
224      case ButtonStatus.ALLOW_ONLY_DURING_USE:
225        return ClickOption.GRANT;
226      case ButtonStatus.CANCEL:
227        return ClickOption.CANCEL;
228      default:
229        return ClickOption.DENY;
230    }
231  }
232
233}