1bea4f105Sopenharmony_ci/* 2bea4f105Sopenharmony_ci * Copyright (c) 2021-2023 Huawei Device Co., Ltd. 3bea4f105Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4bea4f105Sopenharmony_ci * you may not use this file except in compliance with the License. 5bea4f105Sopenharmony_ci * You may obtain a copy of the License at 6bea4f105Sopenharmony_ci * 7bea4f105Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8bea4f105Sopenharmony_ci * 9bea4f105Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10bea4f105Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11bea4f105Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12bea4f105Sopenharmony_ci * See the License for the specific language governing permissions and 13bea4f105Sopenharmony_ci * limitations under the License. 14bea4f105Sopenharmony_ci */ 15bea4f105Sopenharmony_ci 16bea4f105Sopenharmony_ciimport { toast } from '../../base/utils/Common'; 17bea4f105Sopenharmony_ciimport { FileMimeTypeUtil } from '../../base/utils/FileMimeTypeUtil'; 18bea4f105Sopenharmony_ciimport { FILE_SUFFIX, SELECT_MODE } from '../constants/Constant'; 19bea4f105Sopenharmony_ciimport ObjectUtil from './ObjectUtil'; 20bea4f105Sopenharmony_ciimport { ability, Want } from '@kit.AbilityKit'; 21bea4f105Sopenharmony_ciimport Logger from '../log/Logger'; 22bea4f105Sopenharmony_ciimport { PickerWindowType } from '../constants/FilePickerItems'; 23bea4f105Sopenharmony_ciimport { StartModeOptions } from '../model/StartModeOptions'; 24bea4f105Sopenharmony_ciimport AbilityCommonUtil from './AbilityCommonUtil'; 25bea4f105Sopenharmony_ciimport ctx from '@ohos.app.ability.common'; 26bea4f105Sopenharmony_ci 27bea4f105Sopenharmony_ciinterface abilityResultInterface { 28bea4f105Sopenharmony_ci want: Want, 29bea4f105Sopenharmony_ci resultCode: number 30bea4f105Sopenharmony_ci}; 31bea4f105Sopenharmony_ci 32bea4f105Sopenharmony_ciconst TAG = 'FilePickerUtil'; 33bea4f105Sopenharmony_ci 34bea4f105Sopenharmony_ciexport namespace FilePickerUtil { 35bea4f105Sopenharmony_ci export function returnAbilityResult(want: Want, resultCode: number, options: StartModeOptions) { 36bea4f105Sopenharmony_ci Logger.i(TAG, 'returnPicker start'); 37bea4f105Sopenharmony_ci let context = getContext() as ctx.UIAbilityContext; 38bea4f105Sopenharmony_ci if (options.windowType === PickerWindowType.ABILITY) { 39bea4f105Sopenharmony_ci let abilityResult: abilityResultInterface = { 40bea4f105Sopenharmony_ci want: want, 41bea4f105Sopenharmony_ci resultCode: resultCode 42bea4f105Sopenharmony_ci }; 43bea4f105Sopenharmony_ci Logger.i(TAG, 'terminateSelfWithResult start'); 44bea4f105Sopenharmony_ci context.terminateSelfWithResult(abilityResult, (error) => { 45bea4f105Sopenharmony_ci Logger.e(TAG, 'terminateSelfWithResult is called = ' + error.code); 46bea4f105Sopenharmony_ci }); 47bea4f105Sopenharmony_ci } else { 48bea4f105Sopenharmony_ci let abilityResult: ability.AbilityResult = { 49bea4f105Sopenharmony_ci resultCode: resultCode, 50bea4f105Sopenharmony_ci want: want 51bea4f105Sopenharmony_ci }; 52bea4f105Sopenharmony_ci options.session?.terminateSelfWithResult(abilityResult, (error) => { 53bea4f105Sopenharmony_ci Logger.e(TAG, 'closeUIExtFilePicker terminateSelfWithResult is called = ' + error?.code); 54bea4f105Sopenharmony_ci }); 55bea4f105Sopenharmony_ci } 56bea4f105Sopenharmony_ci } 57bea4f105Sopenharmony_ci 58bea4f105Sopenharmony_ci export function getStartModeOptions(want: Want): StartModeOptions { 59bea4f105Sopenharmony_ci let options = new StartModeOptions(); 60bea4f105Sopenharmony_ci if (!want) { 61bea4f105Sopenharmony_ci Logger.e(TAG, 'getDocumentSelectOptions want is undefined') 62bea4f105Sopenharmony_ci return options; 63bea4f105Sopenharmony_ci } 64bea4f105Sopenharmony_ci options.action = want.action as string || ''; 65bea4f105Sopenharmony_ci options.callerAbilityName = want.parameters?.['ohos.aafwk.param.callerAbilityName'] as string || ''; 66bea4f105Sopenharmony_ci options.callerBundleName = want.parameters?.['ohos.aafwk.param.callerBundleName'] as string || ''; 67bea4f105Sopenharmony_ci options.callerUid = want?.parameters?.[AbilityCommonUtil.CALLER_UID] as number || 0; 68bea4f105Sopenharmony_ci options.defaultFilePathUri = want.parameters?.key_pick_dir_path as string || ''; 69bea4f105Sopenharmony_ci options.extType = want.parameters?.extType as string || ''; 70bea4f105Sopenharmony_ci options.pickerType = want.parameters?.pickerType as string || ''; 71bea4f105Sopenharmony_ci if (options.isOpenFileMode()) { 72bea4f105Sopenharmony_ci options.fileSuffixFilters = want.parameters?.key_file_suffix_filter as string[] || []; 73bea4f105Sopenharmony_ci options.maxSelectNumber = want.parameters?.key_pick_num as number || 1; 74bea4f105Sopenharmony_ci options.setSelectMode(want.parameters?.key_select_mode as number); 75bea4f105Sopenharmony_ci options.isAuthMode = want.parameters?.key_auth_mode as boolean || false; 76bea4f105Sopenharmony_ci } else if (options.isCreateFileMode()) { 77bea4f105Sopenharmony_ci options.setNewFileNames(want.parameters?.key_pick_file_name as string[]); 78bea4f105Sopenharmony_ci options.fileSuffixChoices = want.parameters?.key_file_suffix_choices as string[] || []; 79bea4f105Sopenharmony_ci } else { 80bea4f105Sopenharmony_ci Logger.e(TAG, 'getDocumentSelectOptions mode is error') 81bea4f105Sopenharmony_ci } 82bea4f105Sopenharmony_ci Logger.i(TAG, 'getDocumentOptions : ' + JSON.stringify(options)); 83bea4f105Sopenharmony_ci return options; 84bea4f105Sopenharmony_ci } 85bea4f105Sopenharmony_ci 86bea4f105Sopenharmony_ci export function getStartOptionsFromStorage(): StartModeOptions { 87bea4f105Sopenharmony_ci let storage: LocalStorage = LocalStorage.getShared(); 88bea4f105Sopenharmony_ci if (!storage) { 89bea4f105Sopenharmony_ci Logger.i(TAG, `Storage is null`) 90bea4f105Sopenharmony_ci return new StartModeOptions(); 91bea4f105Sopenharmony_ci } 92bea4f105Sopenharmony_ci let options: StartModeOptions | undefined = storage.get<StartModeOptions>('startModeOptions'); 93bea4f105Sopenharmony_ci if (options === undefined) { 94bea4f105Sopenharmony_ci options = new StartModeOptions(); 95bea4f105Sopenharmony_ci storage.setOrCreate('startModeOptions', options); 96bea4f105Sopenharmony_ci } 97bea4f105Sopenharmony_ci return options; 98bea4f105Sopenharmony_ci } 99bea4f105Sopenharmony_ci} 100bea4f105Sopenharmony_ci 101bea4f105Sopenharmony_ci/** 102bea4f105Sopenharmony_ci * 文件选择器文件状态 103bea4f105Sopenharmony_ci * 104bea4f105Sopenharmony_ci * @param item 文件对象 105bea4f105Sopenharmony_ci * @param checkedNum 选中数量 106bea4f105Sopenharmony_ci * @return 是否超限 选择类型是否不匹配 107bea4f105Sopenharmony_ci */ 108bea4f105Sopenharmony_ciexport function pickerStatus(item, checkedNum, startModeOptions:StartModeOptions) { 109bea4f105Sopenharmony_ci return { 110bea4f105Sopenharmony_ci // 选择是否超限 111bea4f105Sopenharmony_ci exceedLimit: checkedNum >= globalThis.filePickNum && !item.isChecked, 112bea4f105Sopenharmony_ci // 选择类型是否不匹配 113bea4f105Sopenharmony_ci differentTypes: !checkFileSelectable(item, startModeOptions) 114bea4f105Sopenharmony_ci }; 115bea4f105Sopenharmony_ci} 116bea4f105Sopenharmony_ci 117bea4f105Sopenharmony_ci/** 118bea4f105Sopenharmony_ci * 根据文件后缀判断文件是否可选 119bea4f105Sopenharmony_ci * @param item 120bea4f105Sopenharmony_ci */ 121bea4f105Sopenharmony_cifunction checkFileSelectable(item, startModeOptions: StartModeOptions): boolean { 122bea4f105Sopenharmony_ci // selectMode检查 123bea4f105Sopenharmony_ci let selectMode: number = startModeOptions.selectMode; 124bea4f105Sopenharmony_ci let isFolder = false; 125bea4f105Sopenharmony_ci if (ObjectUtil.hasKey(item, 'isFolder')) { 126bea4f105Sopenharmony_ci isFolder = item.isFolder; 127bea4f105Sopenharmony_ci } 128bea4f105Sopenharmony_ci // 文件夹模式,直接返回 129bea4f105Sopenharmony_ci if (selectMode === SELECT_MODE.FOLDER) { 130bea4f105Sopenharmony_ci return isFolder; 131bea4f105Sopenharmony_ci } 132bea4f105Sopenharmony_ci 133bea4f105Sopenharmony_ci if (isFolder) { 134bea4f105Sopenharmony_ci // 混选模式下,文件夹直接返回 135bea4f105Sopenharmony_ci if (selectMode === SELECT_MODE.MIX) { 136bea4f105Sopenharmony_ci return true; 137bea4f105Sopenharmony_ci } 138bea4f105Sopenharmony_ci // 文件模式下,文件夹直接返回false 139bea4f105Sopenharmony_ci return false; 140bea4f105Sopenharmony_ci } 141bea4f105Sopenharmony_ci // 后缀检查 142bea4f105Sopenharmony_ci let keyFileSuffixFilter: string[] = startModeOptions.fileSuffixFilters; 143bea4f105Sopenharmony_ci if (Array.isArray(keyFileSuffixFilter) && keyFileSuffixFilter.length > 0) { 144bea4f105Sopenharmony_ci return checkFileSuffix(item.fileName, keyFileSuffixFilter); 145bea4f105Sopenharmony_ci } 146bea4f105Sopenharmony_ci 147bea4f105Sopenharmony_ci // mimeType检查 148bea4f105Sopenharmony_ci return checkFileMimetype(item.fileName, startModeOptions); 149bea4f105Sopenharmony_ci} 150bea4f105Sopenharmony_ci 151bea4f105Sopenharmony_ci/** 152bea4f105Sopenharmony_ci * 校验选中的文件后缀 153bea4f105Sopenharmony_ci * 154bea4f105Sopenharmony_ci * @param fileName 文件名称 155bea4f105Sopenharmony_ci * @param keyFileSuffixFilter 指定后缀 156bea4f105Sopenharmony_ci * @return 如果文件后缀满足三方指定,则返回true 157bea4f105Sopenharmony_ci */ 158bea4f105Sopenharmony_cifunction checkFileSuffix(fileName: string, keyFileSuffixFilter: Array<string>): boolean { 159bea4f105Sopenharmony_ci if (keyFileSuffixFilter) { 160bea4f105Sopenharmony_ci if (fileName) { 161bea4f105Sopenharmony_ci const suffix = FILE_SUFFIX.SUFFIX_START + FileMimeTypeUtil.getFileSuffix(fileName); 162bea4f105Sopenharmony_ci if (keyFileSuffixFilter.includes(suffix)) { 163bea4f105Sopenharmony_ci return true; 164bea4f105Sopenharmony_ci } 165bea4f105Sopenharmony_ci } 166bea4f105Sopenharmony_ci return false; 167bea4f105Sopenharmony_ci } 168bea4f105Sopenharmony_ci return true; 169bea4f105Sopenharmony_ci} 170bea4f105Sopenharmony_ci 171bea4f105Sopenharmony_ci/** 172bea4f105Sopenharmony_ci * 校验选中的文件mimetype 173bea4f105Sopenharmony_ci * 174bea4f105Sopenharmony_ci * @param fileName 文件名称 175bea4f105Sopenharmony_ci * @return 条件满足返回true 176bea4f105Sopenharmony_ci */ 177bea4f105Sopenharmony_cifunction checkFileMimetype(fileName: string, startModeOptions: StartModeOptions): boolean { 178bea4f105Sopenharmony_ci if (!fileName) { 179bea4f105Sopenharmony_ci return false; 180bea4f105Sopenharmony_ci } 181bea4f105Sopenharmony_ci let keyPickTypeList: string[] = startModeOptions.phonePickerTypeList; 182bea4f105Sopenharmony_ci // 输入的类型全转换成小写,避免大小敏感问题 183bea4f105Sopenharmony_ci keyPickTypeList.forEach(item => item.toLowerCase()); 184bea4f105Sopenharmony_ci // 类型列表为空或包含*或*/*时,可选择所有文件 185bea4f105Sopenharmony_ci if (!keyPickTypeList || keyPickTypeList.length === 0 || 186bea4f105Sopenharmony_ci keyPickTypeList.includes('*') || keyPickTypeList.includes('*/*')) { 187bea4f105Sopenharmony_ci return true; 188bea4f105Sopenharmony_ci } 189bea4f105Sopenharmony_ci 190bea4f105Sopenharmony_ci const mimeTypeObj = FileMimeTypeUtil.getFileMimeType(fileName); 191bea4f105Sopenharmony_ci const mimeType = mimeTypeObj.getMimeType(); 192bea4f105Sopenharmony_ci 193bea4f105Sopenharmony_ci // mimeType未知不可选 194bea4f105Sopenharmony_ci if (!mimeType) { 195bea4f105Sopenharmony_ci return false; 196bea4f105Sopenharmony_ci } 197bea4f105Sopenharmony_ci 198bea4f105Sopenharmony_ci // mimeType完全匹配 199bea4f105Sopenharmony_ci if (keyPickTypeList.includes(mimeType)) { 200bea4f105Sopenharmony_ci return true; 201bea4f105Sopenharmony_ci } 202bea4f105Sopenharmony_ci 203bea4f105Sopenharmony_ci let fileCategory = mimeType; 204bea4f105Sopenharmony_ci const index = mimeType.indexOf('/'); 205bea4f105Sopenharmony_ci if (index > 0) { 206bea4f105Sopenharmony_ci fileCategory = mimeType.substring(0, index); 207bea4f105Sopenharmony_ci } 208bea4f105Sopenharmony_ci // 某一类文件 209bea4f105Sopenharmony_ci if (keyPickTypeList.includes(fileCategory) || keyPickTypeList.includes(`${fileCategory}/*`)) { 210bea4f105Sopenharmony_ci return true; 211bea4f105Sopenharmony_ci } 212bea4f105Sopenharmony_ci 213bea4f105Sopenharmony_ci return false; 214bea4f105Sopenharmony_ci} 215bea4f105Sopenharmony_ci 216bea4f105Sopenharmony_ci/** 217bea4f105Sopenharmony_ci * 文件选择器 选择超限提示 218bea4f105Sopenharmony_ci * 219bea4f105Sopenharmony_ci * @param isImmersion 是否沉浸式 220bea4f105Sopenharmony_ci */ 221bea4f105Sopenharmony_ciexport const filePickerTip = (startModeOptions: StartModeOptions) => { 222bea4f105Sopenharmony_ci globalThis.abilityContext.resourceManager.getPluralString($r('app.plural.filePickerTip').id, 223bea4f105Sopenharmony_ci startModeOptions.maxSelectNumber) 224bea4f105Sopenharmony_ci .then((value) => { 225bea4f105Sopenharmony_ci toast(value) 226bea4f105Sopenharmony_ci }) 227bea4f105Sopenharmony_ci} 228bea4f105Sopenharmony_ci 229bea4f105Sopenharmony_ci 230