1/* 2 * Copyright (c) 2021-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 abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl'; 17import i18n from '@ohos.i18n'; 18import hilog from '@ohos.hilog'; 19import { 20 permissionInfos, 21 groups, 22 userGrantPermissions, 23 only2in1AndTabletSupportedPermissions 24} from '../model/permissionGroup'; 25import { Permission, PermissionGroup } from '../model/definition'; 26import Constants from '../utils/constant'; 27import { BundleInfoUtils } from './bundleInfoUtils'; 28import { CommonUtils } from './commonUtils'; 29import { GroupInfo, AppInfo, ApplicationObj } from '../model/typedef'; 30import systemParameterEnhance from '@ohos.systemParameterEnhance'; 31import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession'; 32import uiExtensionHost from '@ohos.uiExtensionHost'; 33import window from '@ohos.window'; 34import { deviceInfo } from '@kit.BasicServicesKit'; 35import { GlobalContext } from './globalContext'; 36 37const TAG = 'PermissionManager_Log '; 38 39/** 40 * verify permission 41 * @param {Number} accessTokenId 42 * @param {String} permission permission name 43 */ 44export function verifyAccessToken(accessTokenId: number, permission: Permissions) { 45 return new Promise<number>((resolve) => { 46 let atManager = abilityAccessCtrl.createAtManager(); 47 let data = atManager.verifyAccessTokenSync(accessTokenId, permission); 48 if (data == abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) { 49 resolve(data); 50 } else { 51 try { 52 atManager.getPermissionFlags(accessTokenId, permission).then((flag: number) => { 53 if (flag == Constants.PERMISSION_COMPONENT_SET) { 54 resolve(abilityAccessCtrl.GrantStatus.PERMISSION_DENIED); 55 } else { 56 resolve(data); 57 } 58 }) 59 } catch (err) { 60 Log.error('getPermissionFlags error: ' + JSON.stringify(err)); 61 resolve(data); 62 } 63 } 64 }) 65} 66 67/** 68 * Omit display when application name is too long 69 * @param {String} Application name 70 */ 71export function titleTrim(title: string): string { 72 const length: number = title.length; 73 if (length > Constants.MAXIMUM_HEADER_LENGTH) { 74 let str = ''; 75 str = title.substring(0, Constants.MAXIMUM_HEADER_LENGTH) + '...'; 76 return str; 77 } else { 78 return title; 79 } 80} 81 82export const indexValue: string[] = [ 83 '#', 84 'A', 85 'B', 86 'C', 87 'D', 88 'E', 89 'F', 90 'G', 91 'H', 92 'I', 93 'J', 94 'K', 95 'L', 96 'M', 97 'N', 98 'O', 99 'P', 100 'Q', 101 'R', 102 'S', 103 'T', 104 'U', 105 'V', 106 'W', 107 'X', 108 'Y', 109 'Z' 110]; // Array of alphabetically indexed names 111 112export function addLocalTag(info: AppInfo) { 113 let isZh = i18n.System.getSystemLanguage().indexOf('zh') >= 0; 114 let appName: string = info.label; 115 let upperCase = CommonUtils.isEmpty(appName) ? '' : appName[0].toLocaleUpperCase(); 116 let regexEn: RegExp = new RegExp('[A-Z]'); 117 let regexNm: RegExp = new RegExp('[0-9]'); 118 119 if (isZh) { 120 if (upperCase.match(regexEn)) { 121 info.zhTag = BundleInfoUtils.getStringZh(appName); 122 info.indexTag = upperCase; 123 info.language = 'EN'; 124 } else { 125 info.zhTag = appName; 126 info.language = 'CN'; 127 if (upperCase.match(regexNm)) { 128 info.indexTag = '#'; 129 } else { 130 info.indexTag = BundleInfoUtils.findZhIndex(upperCase); 131 } 132 } 133 } else { 134 if (upperCase.match(regexEn)) { 135 info.zhTag = appName; 136 info.indexTag = upperCase; 137 info.language = 'EN'; 138 } else { 139 info.zhTag = appName; 140 info.indexTag = '#'; 141 info.language = 'CN'; 142 } 143 } 144} 145 146let enComparator = new Intl.Collator('en'); 147let zhComparator = new Intl.Collator('zh-Hans-CN'); 148 149export function sortByName(appArray: Array<AppInfo | ApplicationObj>): Array<AppInfo | ApplicationObj> { 150 return appArray.sort((item1: AppInfo | ApplicationObj, item2: AppInfo | ApplicationObj) => { 151 if (item1.indexTag !== item2.indexTag) { 152 return enComparator.compare(item1.indexTag, item2.indexTag); 153 } 154 155 let isEn1 = item1.language === 'EN'; 156 let isEn2 = item2.language === 'EN'; 157 158 if (isEn1 && isEn2) { 159 return enComparator.compare(item1.label, item2.label); 160 } else if (isEn1 && !isEn2) { 161 return 1; 162 } else if (!isEn1 && isEn2) { 163 return -1; 164 } else { 165 return zhComparator.compare(item1.zhTag, item2.zhTag); 166 } 167 }) 168} 169 170/** 171 * Get permission label 172 * @param {String} permission name 173 */ 174export function getPermissionLabel(permission: Permission): ResourceStr { 175 let permissionInfo = permissionInfos.get(permission); 176 if (!permissionInfo) { 177 return ''; 178 } 179 return permissionInfo.label; 180} 181 182/** 183 * Get the corresponding permission group id according to the permission 184 * @param {String} permission app name id 185 * @return {GroupInfo} group 186 */ 187export function getPermissionGroup(permission: Permission): GroupInfo { 188 let permissionInfo = permissionInfos.get(permission); 189 if (!permissionInfo) { 190 return new GroupInfo(PermissionGroup.OTHER, '', '', '', [], '', [], [], false); 191 } 192 return groups[permissionInfo.groupId]; 193} 194 195/** 196 * Obtain a permission group by its name 197 * @param {String} group name 198 * @return {GroupInfo} group 199 */ 200export function getPermissionGroupByName(name: string): GroupInfo { 201 for (let i = 0; i < groups.length; i++) { 202 if (groups[i].name === name) { 203 return groups[i]; 204 } 205 } 206 return groups[0]; 207} 208 209/** 210 * Obtain the permission group ID by permission name 211 * @param {String} permission name 212 * @return {number} groupId 213 */ 214export function getGroupIdByPermission(permission: Permission): number { 215 let permissionInfo = permissionInfos.get(permission); 216 if (!permissionInfo) { 217 return -1; 218 } 219 return permissionInfo.groupId; 220} 221 222export function PermissionDialogException(code: number, session: UIExtensionContentSession): void { 223 session.terminateSelfWithResult({ 224 resultCode: -1, 225 want: { 226 parameters: { 227 'ohos.user.setting.permission.result': [], 228 'ohos.user.setting.error_code': code, 229 } 230 } 231 }) 232} 233 234export function PermissionDialogReturn(resultArray: Array<number>, session: UIExtensionContentSession): void { 235 session.terminateSelfWithResult({ 236 resultCode: 0, 237 want: { 238 parameters: { 239 'ohos.user.setting.permission.result': resultArray, 240 'ohos.user.setting.error_code': 0 241 } 242 } 243 }) 244} 245 246// check if the permissions provided are in the same group 247export function checkPermissionGroup(appPermissions: Permission[]): PermissionGroup | null { 248 if (appPermissions.length == 0) { 249 return null; 250 } 251 let groupName = PermissionGroup.OTHER; // index of group in permissionGroup 252 // check if permission is a valid permission 253 for (const permission of appPermissions) { 254 let permissionInfo = permissionInfos.get(permission); 255 // if permission not found in known permissions , return false 256 if (!permissionInfo) { 257 Log.error(TAG + 'unknown info ' + permission); 258 return null; 259 } 260 // if groupName not set , set groupName 261 if (groupName == PermissionGroup.OTHER) { 262 groupName = permissionInfo.groupName; 263 } 264 // if current groupName is not the same to the previous , not the same group 265 if (permissionInfo.groupName != groupName) { 266 Log.error(TAG + 'permission ' + permission + ' is not in current group ' + groupName); 267 return null; 268 } 269 } 270 return groupName; 271} 272 273export function setAvoidArea(proxy: uiExtensionHost.UIExtensionHostWindowProxy) { 274 let avoidArea = proxy.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); 275 let btmAvoidHeight: string = avoidArea.bottomRect.height.toString(); 276 Log.info(TAG + 'avoid area height: ' + btmAvoidHeight + 'px'); // assure unit in pixels 277 GlobalContext.store('avoidAreaHeight', btmAvoidHeight + 'px'); 278} 279 280export function getFontSizeScale(): boolean { 281 const FONT_SIZE_SCALE_PARAM = 'persist.sys.font_scale_for_user0'; 282 let fontSizeScale = Number.parseFloat(systemParameterEnhance.getSync(FONT_SIZE_SCALE_PARAM, '1')); 283 return fontSizeScale > 1; 284} 285 286export function supportPermission(): Permission[] { 287 if (deviceInfo.deviceType === '2in1' || deviceInfo.deviceType === 'tablet') { 288 return userGrantPermissions; 289 } 290 let supportGroup: Permission[] = []; 291 supportGroup = 292 userGrantPermissions.filter(permission => only2in1AndTabletSupportedPermissions.includes(permission) === false); 293 return supportGroup; 294} 295 296export class Log { 297 public static domain: number = 0x8214; 298 public static tag: string = 'PermissionManager_Log'; 299 300 public static debug(message: string): void { 301 hilog.debug(Log.domain, Log.tag, message); 302 } 303 304 public static info(message: string): void { 305 hilog.info(Log.domain, Log.tag, message); 306 } 307 308 public static warn(message: string): void { 309 hilog.warn(Log.domain, Log.tag, message); 310 } 311 312 public static error(message: string): void { 313 hilog.error(Log.domain, Log.tag, message); 314 } 315}