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 fileAccess from '@ohos.file.fileAccess'
17bea4f105Sopenharmony_ciimport Logger from '../log/Logger'
18bea4f105Sopenharmony_ciimport abilityAccessCtrl from '@ohos.abilityAccessCtrl'
19bea4f105Sopenharmony_ciimport { Permissions } from '@ohos.abilityAccessCtrl'
20bea4f105Sopenharmony_ciimport FileShare from '@ohos.fileshare'
21bea4f105Sopenharmony_ciimport wantConstant from '@ohos.app.ability.wantConstant'
22bea4f105Sopenharmony_ciimport { FILE_MANAGER_PREFERENCES, FILE_SUFFIX, SELECT_MODE } from '../constants/Constant'
23bea4f105Sopenharmony_ciimport { ArrayUtil } from './ArrayUtil'
24bea4f105Sopenharmony_ciimport { getPreferences } from './PreferencesUtil'
25bea4f105Sopenharmony_ciimport { ability, Want } from '@kit.AbilityKit'
26bea4f105Sopenharmony_ciimport { StartModeOptions } from '../model/StartModeOptions'
27bea4f105Sopenharmony_ciimport { PickerWindowType } from '../constants/FilePickerItems'
28bea4f105Sopenharmony_ciimport { photoAccessHelper } from '@kit.MediaLibraryKit'
29bea4f105Sopenharmony_ci
30bea4f105Sopenharmony_ciconst TAG = 'AbilityCommonUtil'
31bea4f105Sopenharmony_ci
32bea4f105Sopenharmony_ciconst BUNDLE_NAME = 'com.ohos.filepicker'
33bea4f105Sopenharmony_cilet photoManageHelper: photoAccessHelper.PhotoAccessHelper = null
34bea4f105Sopenharmony_ci
35bea4f105Sopenharmony_ci/**
36bea4f105Sopenharmony_ci * picker对外返回的响应码
37bea4f105Sopenharmony_ci */
38bea4f105Sopenharmony_ciexport enum ResultCodePicker {
39bea4f105Sopenharmony_ci  SUCCESS = 0,
40bea4f105Sopenharmony_ci  CANCEL = -1
41bea4f105Sopenharmony_ci}
42bea4f105Sopenharmony_ci
43bea4f105Sopenharmony_ciinterface abilityResultInterface {
44bea4f105Sopenharmony_ci  want: Want,
45bea4f105Sopenharmony_ci  resultCode: number
46bea4f105Sopenharmony_ci};
47bea4f105Sopenharmony_ci
48bea4f105Sopenharmony_ci/**
49bea4f105Sopenharmony_ci * Ability公共工具类
50bea4f105Sopenharmony_ci */
51bea4f105Sopenharmony_cinamespace AbilityCommonUtil {
52bea4f105Sopenharmony_ci
53bea4f105Sopenharmony_ci  /**
54bea4f105Sopenharmony_ci   * 需要用户授权的权限列表
55bea4f105Sopenharmony_ci   */
56bea4f105Sopenharmony_ci  export const PERMISSION_LIST: Array<Permissions> = [
57bea4f105Sopenharmony_ci    "ohos.permission.MEDIA_LOCATION",
58bea4f105Sopenharmony_ci    "ohos.permission.READ_MEDIA",
59bea4f105Sopenharmony_ci    "ohos.permission.WRITE_MEDIA"
60bea4f105Sopenharmony_ci  ]
61bea4f105Sopenharmony_ci
62bea4f105Sopenharmony_ci  /**
63bea4f105Sopenharmony_ci   * 用来获取startAbility调用方应用uid的key
64bea4f105Sopenharmony_ci   */
65bea4f105Sopenharmony_ci  export const CALLER_UID = 'ohos.aafwk.param.callerUid'
66bea4f105Sopenharmony_ci
67bea4f105Sopenharmony_ci  export const CALLER_BUNDLE_NAME = 'ohos.aafwk.param.callerBundleName'
68bea4f105Sopenharmony_ci
69bea4f105Sopenharmony_ci  /**
70bea4f105Sopenharmony_ci   * 最大选择文件的个数
71bea4f105Sopenharmony_ci   */
72bea4f105Sopenharmony_ci  export const MAX_FILE_PICK_NUM = 500
73bea4f105Sopenharmony_ci
74bea4f105Sopenharmony_ci  /**
75bea4f105Sopenharmony_ci   * 后缀最大长度,包括'.'
76bea4f105Sopenharmony_ci   */
77bea4f105Sopenharmony_ci  export const SUFFIX_MAX_LENGTH: number = 255;
78bea4f105Sopenharmony_ci
79bea4f105Sopenharmony_ci  /**
80bea4f105Sopenharmony_ci   * 三方传入的后缀数组长度最大100
81bea4f105Sopenharmony_ci   */
82bea4f105Sopenharmony_ci  export const SUFFIX_LIST_MAX_LENGTH: number = 100;
83bea4f105Sopenharmony_ci
84bea4f105Sopenharmony_ci  /**
85bea4f105Sopenharmony_ci   * picker对外返回的响应码
86bea4f105Sopenharmony_ci   */
87bea4f105Sopenharmony_ci  export const RESULT_CODE = {
88bea4f105Sopenharmony_ci    SUCCESS: 0,
89bea4f105Sopenharmony_ci    CANCEL: -1
90bea4f105Sopenharmony_ci  }
91bea4f105Sopenharmony_ci
92bea4f105Sopenharmony_ci  export const ABILITY_LIST = {
93bea4f105Sopenharmony_ci    FILE_MANAGER: 'FileManagerAbility',
94bea4f105Sopenharmony_ci    FILE_PICKER: 'FilePickerAbility',
95bea4f105Sopenharmony_ci    PATH_PICKER: 'PathPickerAbility'
96bea4f105Sopenharmony_ci  }
97bea4f105Sopenharmony_ci
98bea4f105Sopenharmony_ci  /**
99bea4f105Sopenharmony_ci   * 拉起Ability时必要的初始化操作
100bea4f105Sopenharmony_ci   */
101bea4f105Sopenharmony_ci  export function init(): Promise<void[]> {
102bea4f105Sopenharmony_ci    const fileAccessHelperPromise = createFileAccessHelper();
103bea4f105Sopenharmony_ci    getPhotoManageHelper();
104bea4f105Sopenharmony_ci    const getRequestPermission = requestPermission();
105bea4f105Sopenharmony_ci    const initData = initLastSelectPath();
106bea4f105Sopenharmony_ci    return Promise.all([fileAccessHelperPromise, getRequestPermission, initData]);
107bea4f105Sopenharmony_ci  }
108bea4f105Sopenharmony_ci
109bea4f105Sopenharmony_ci  /**
110bea4f105Sopenharmony_ci   * 获取FileAccessHelper,用于获取文件和操作文件
111bea4f105Sopenharmony_ci   */
112bea4f105Sopenharmony_ci  export function createFileAccessHelper(): Promise<void> {
113bea4f105Sopenharmony_ci    if (globalThis.fileAccessHelper) {
114bea4f105Sopenharmony_ci      return Promise.resolve()
115bea4f105Sopenharmony_ci    }
116bea4f105Sopenharmony_ci    return new Promise(async (resolve, reject) => {
117bea4f105Sopenharmony_ci      try {
118bea4f105Sopenharmony_ci        let wants = await fileAccess.getFileAccessAbilityInfo()
119bea4f105Sopenharmony_ci        globalThis.fileAcsHelper = fileAccess.createFileAccessHelper(globalThis.abilityContext, wants)
120bea4f105Sopenharmony_ci        // 获取设备根节点信息
121bea4f105Sopenharmony_ci        const rootIterator: fileAccess.RootIterator = await globalThis.fileAcsHelper.getRoots()
122bea4f105Sopenharmony_ci        let rootInfoArr = []
123bea4f105Sopenharmony_ci        let result = rootIterator.next()
124bea4f105Sopenharmony_ci        let isDone = result.done
125bea4f105Sopenharmony_ci        while (!isDone) {
126bea4f105Sopenharmony_ci          const rootInfo: fileAccess.RootInfo = result.value
127bea4f105Sopenharmony_ci          Logger.i(TAG, 'RootInfo: ' + rootInfo.uri + ', ' + rootInfo.deviceType + ', ' + rootInfo.deviceFlags + ', ' +
128bea4f105Sopenharmony_ci          rootInfo.displayName + ',' + rootInfo.relativePath)
129bea4f105Sopenharmony_ci          rootInfoArr.push(rootInfo)
130bea4f105Sopenharmony_ci          result = rootIterator.next()
131bea4f105Sopenharmony_ci          isDone = result.done
132bea4f105Sopenharmony_ci        }
133bea4f105Sopenharmony_ci        globalThis.rootInfoArr = rootInfoArr
134bea4f105Sopenharmony_ci      } catch (err) {
135bea4f105Sopenharmony_ci        Logger.e(TAG, 'createFileAccessHelper fail, error:' + JSON.stringify(err))
136bea4f105Sopenharmony_ci      } finally {
137bea4f105Sopenharmony_ci        resolve()
138bea4f105Sopenharmony_ci      }
139bea4f105Sopenharmony_ci    })
140bea4f105Sopenharmony_ci  }
141bea4f105Sopenharmony_ci
142bea4f105Sopenharmony_ci  /**
143bea4f105Sopenharmony_ci   * Ability初始化时,加载最新保存的路径Uri
144bea4f105Sopenharmony_ci   */
145bea4f105Sopenharmony_ci  export function initLastSelectPath(): Promise<void> {
146bea4f105Sopenharmony_ci    return new Promise((resolve, reject) => {
147bea4f105Sopenharmony_ci      const defaultValue = FILE_MANAGER_PREFERENCES.lastSelectPath.defaultValue;
148bea4f105Sopenharmony_ci      const lastSelectPathKey = FILE_MANAGER_PREFERENCES.lastSelectPath.key;
149bea4f105Sopenharmony_ci      getPreferences(FILE_MANAGER_PREFERENCES.name).then(preferences => {
150bea4f105Sopenharmony_ci        preferences.get(lastSelectPathKey, defaultValue).then((result: string) => {
151bea4f105Sopenharmony_ci          AppStorage.SetOrCreate<string>(lastSelectPathKey, result);
152bea4f105Sopenharmony_ci          resolve();
153bea4f105Sopenharmony_ci          Logger.i(TAG, 'initLastSelectPath result: ' + result);
154bea4f105Sopenharmony_ci        }).catch((error) => {
155bea4f105Sopenharmony_ci          AppStorage.SetOrCreate<string>(lastSelectPathKey, defaultValue);
156bea4f105Sopenharmony_ci          Logger.e(TAG, 'initLastSelectPath preferences.get fail, error:' + JSON.stringify(error));
157bea4f105Sopenharmony_ci          resolve();
158bea4f105Sopenharmony_ci        })
159bea4f105Sopenharmony_ci      }).catch(err => {
160bea4f105Sopenharmony_ci        AppStorage.SetOrCreate<string>(lastSelectPathKey, defaultValue);
161bea4f105Sopenharmony_ci        Logger.e(TAG, 'initLastSelectPath getPreferences fail, error: ' + JSON.stringify(err));
162bea4f105Sopenharmony_ci        resolve();
163bea4f105Sopenharmony_ci      })
164bea4f105Sopenharmony_ci    })
165bea4f105Sopenharmony_ci  }
166bea4f105Sopenharmony_ci
167bea4f105Sopenharmony_ci  /**
168bea4f105Sopenharmony_ci   * 申请文件管理器需用户授权的权限
169bea4f105Sopenharmony_ci   */
170bea4f105Sopenharmony_ci  export function requestPermission(): Promise<void> {
171bea4f105Sopenharmony_ci    let atManager = abilityAccessCtrl.createAtManager()
172bea4f105Sopenharmony_ci    try {
173bea4f105Sopenharmony_ci      return atManager.requestPermissionsFromUser(globalThis.abilityContext, PERMISSION_LIST).then((data) => {
174bea4f105Sopenharmony_ci        if (data.authResults.some(item => item !== 0)) {
175bea4f105Sopenharmony_ci          Logger.e(TAG, 'requestPermissionsFromUser some permission request fail, result:' + JSON.stringify(data))
176bea4f105Sopenharmony_ci        } else {
177bea4f105Sopenharmony_ci          Logger.i(TAG, 'requestPermissionsFromUser success, result:' + JSON.stringify(data))
178bea4f105Sopenharmony_ci        }
179bea4f105Sopenharmony_ci      }).catch((error) => {
180bea4f105Sopenharmony_ci        Logger.e(TAG, 'requestPermissionsFromUser fail, error:' + JSON.stringify(error))
181bea4f105Sopenharmony_ci      })
182bea4f105Sopenharmony_ci    } catch (error) {
183bea4f105Sopenharmony_ci      Logger.e(TAG, 'requestPermissionsFromUser error occurred, error:' + JSON.stringify(error))
184bea4f105Sopenharmony_ci    }
185bea4f105Sopenharmony_ci  }
186bea4f105Sopenharmony_ci
187bea4f105Sopenharmony_ci  /**
188bea4f105Sopenharmony_ci   * uri授权
189bea4f105Sopenharmony_ci   * @param uriList 待授权的uri列表
190bea4f105Sopenharmony_ci   * @param bundleName 授权应用的包名
191bea4f105Sopenharmony_ci   */
192bea4f105Sopenharmony_ci  export function grantUriPermission(uriList: Array<string>, bundleName: string): Promise<boolean> {
193bea4f105Sopenharmony_ci    return new Promise(async (resolve, reject) => {
194bea4f105Sopenharmony_ci      Logger.i(TAG, "grantUriPermission start,grantSize = " + uriList?.length);
195bea4f105Sopenharmony_ci      let grantSuccessCount: number = 0;
196bea4f105Sopenharmony_ci      for (let uri of uriList) {
197bea4f105Sopenharmony_ci        try {
198bea4f105Sopenharmony_ci          await FileShare.grantUriPermission(
199bea4f105Sopenharmony_ci            uri,
200bea4f105Sopenharmony_ci            bundleName,
201bea4f105Sopenharmony_ci            wantConstant.Flags.FLAG_AUTH_READ_URI_PERMISSION | wantConstant.Flags.FLAG_AUTH_WRITE_URI_PERMISSION);
202bea4f105Sopenharmony_ci          grantSuccessCount++;
203bea4f105Sopenharmony_ci        } catch (error) {
204bea4f105Sopenharmony_ci          resolve(false);
205bea4f105Sopenharmony_ci          Logger.e(TAG,
206bea4f105Sopenharmony_ci            `grantUriPermission fail,grantSuccessCount:${grantSuccessCount}}, uri: ${uri}, error: ${JSON.stringify(error)}`);
207bea4f105Sopenharmony_ci          return;
208bea4f105Sopenharmony_ci        }
209bea4f105Sopenharmony_ci      }
210bea4f105Sopenharmony_ci      Logger.i(TAG, "grantUriPermission end,grantSuccessCount = " + grantSuccessCount);
211bea4f105Sopenharmony_ci      resolve(true)
212bea4f105Sopenharmony_ci    })
213bea4f105Sopenharmony_ci  }
214bea4f105Sopenharmony_ci
215bea4f105Sopenharmony_ci  /**
216bea4f105Sopenharmony_ci   * 文件选择完成,返回uri列表
217bea4f105Sopenharmony_ci   * @param resultCode
218bea4f105Sopenharmony_ci   * @param result
219bea4f105Sopenharmony_ci   * @param message
220bea4f105Sopenharmony_ci   */
221bea4f105Sopenharmony_ci  export async function terminateFilePicker(result: string[] = [],
222bea4f105Sopenharmony_ci    resultCode: number = ResultCodePicker.SUCCESS, startModeOptions: StartModeOptions): Promise<void> {
223bea4f105Sopenharmony_ci    Logger.i(TAG, 'enter terminateFilePicker, result length: ' + result.length + ', resultCode:' + resultCode);
224bea4f105Sopenharmony_ci    let want: Want = {
225bea4f105Sopenharmony_ci      bundleName: BUNDLE_NAME,
226bea4f105Sopenharmony_ci      flags: wantConstant.Flags.FLAG_AUTH_WRITE_URI_PERMISSION,
227bea4f105Sopenharmony_ci      parameters: {
228bea4f105Sopenharmony_ci        'ability.params.stream': result
229bea4f105Sopenharmony_ci      }
230bea4f105Sopenharmony_ci    };
231bea4f105Sopenharmony_ci    returnAbilityResult(want, resultCode, startModeOptions);
232bea4f105Sopenharmony_ci  }
233bea4f105Sopenharmony_ci
234bea4f105Sopenharmony_ci  /**
235bea4f105Sopenharmony_ci   * 文件创建完成,返回uri列表
236bea4f105Sopenharmony_ci   * @param result
237bea4f105Sopenharmony_ci   * @param resultCode
238bea4f105Sopenharmony_ci   * @param message
239bea4f105Sopenharmony_ci   */
240bea4f105Sopenharmony_ci  export async function terminatePathPicker(result: string[],
241bea4f105Sopenharmony_ci    resultCode: number = ResultCodePicker.SUCCESS, startModeOptions: StartModeOptions): Promise<void> {
242bea4f105Sopenharmony_ci
243bea4f105Sopenharmony_ci    Logger.i(TAG, 'enter terminatePathPicker, result length: ' + result.length + ', resultCode:' + resultCode);
244bea4f105Sopenharmony_ci    let want: Want = {
245bea4f105Sopenharmony_ci      bundleName: BUNDLE_NAME,
246bea4f105Sopenharmony_ci      abilityName: ABILITY_LIST.PATH_PICKER,
247bea4f105Sopenharmony_ci      flags: wantConstant.Flags.FLAG_AUTH_WRITE_URI_PERMISSION,
248bea4f105Sopenharmony_ci      parameters: {
249bea4f105Sopenharmony_ci        'ability.params.stream': result,
250bea4f105Sopenharmony_ci        KEY_PICK_SELECT_CLOUD_DISK: false
251bea4f105Sopenharmony_ci      }
252bea4f105Sopenharmony_ci    };
253bea4f105Sopenharmony_ci    returnAbilityResult(want, resultCode, startModeOptions);
254bea4f105Sopenharmony_ci  }
255bea4f105Sopenharmony_ci
256bea4f105Sopenharmony_ci
257bea4f105Sopenharmony_ci
258bea4f105Sopenharmony_ci  export function returnAbilityResult(want: Want, resultCode: number, options: StartModeOptions) {
259bea4f105Sopenharmony_ci    Logger.i(TAG, 'returnPicker start');
260bea4f105Sopenharmony_ci    if (options.windowType === PickerWindowType.ABILITY) {
261bea4f105Sopenharmony_ci      let abilityResult: abilityResultInterface = {
262bea4f105Sopenharmony_ci        want: want,
263bea4f105Sopenharmony_ci        resultCode: resultCode
264bea4f105Sopenharmony_ci      };
265bea4f105Sopenharmony_ci      Logger.i(TAG, 'uiContext terminateSelfWithResult start');
266bea4f105Sopenharmony_ci      options.uiContext.terminateSelfWithResult(abilityResult, (error) => {
267bea4f105Sopenharmony_ci        Logger.i(TAG, 'terminateSelfWithResult is called = ' + error.code);
268bea4f105Sopenharmony_ci      });
269bea4f105Sopenharmony_ci    } else {
270bea4f105Sopenharmony_ci      let abilityResult: ability.AbilityResult = {
271bea4f105Sopenharmony_ci        resultCode: resultCode,
272bea4f105Sopenharmony_ci        want: want
273bea4f105Sopenharmony_ci      };
274bea4f105Sopenharmony_ci      Logger.i(TAG, 'session terminateSelfWithResult start');
275bea4f105Sopenharmony_ci      options.session.terminateSelfWithResult(abilityResult, (error) => {
276bea4f105Sopenharmony_ci        Logger.e(TAG, 'closeUIExtFilePicker terminateSelfWithResult is called = ' + error?.code);
277bea4f105Sopenharmony_ci      });
278bea4f105Sopenharmony_ci    }
279bea4f105Sopenharmony_ci  }
280bea4f105Sopenharmony_ci
281bea4f105Sopenharmony_ci  /**
282bea4f105Sopenharmony_ci   * 获取选择文件的最大个数
283bea4f105Sopenharmony_ci   * @param num 调用方传入的个数
284bea4f105Sopenharmony_ci   */
285bea4f105Sopenharmony_ci  export function getPickFileNum(num: any): number {
286bea4f105Sopenharmony_ci    if (typeof num === 'number') {
287bea4f105Sopenharmony_ci      if (num > 0 && num <= MAX_FILE_PICK_NUM) {
288bea4f105Sopenharmony_ci        return num;
289bea4f105Sopenharmony_ci      }
290bea4f105Sopenharmony_ci    }
291bea4f105Sopenharmony_ci    return MAX_FILE_PICK_NUM;
292bea4f105Sopenharmony_ci  }
293bea4f105Sopenharmony_ci
294bea4f105Sopenharmony_ci  /**
295bea4f105Sopenharmony_ci   * 获取选择文件的类型列表
296bea4f105Sopenharmony_ci   * @param keyPickType 调用方传入文件类型(兼容双框架action)
297bea4f105Sopenharmony_ci   * @param keyPickTypeList 调用方传入文件类型列表
298bea4f105Sopenharmony_ci   */
299bea4f105Sopenharmony_ci  export function getKeyPickTypeList(keyPickType, keyPickTypeList): Array<string> {
300bea4f105Sopenharmony_ci    let typeList = []
301bea4f105Sopenharmony_ci    if (keyPickType) {
302bea4f105Sopenharmony_ci      typeList.push(keyPickType)
303bea4f105Sopenharmony_ci    }
304bea4f105Sopenharmony_ci    if (keyPickTypeList && keyPickTypeList.length !== 0) {
305bea4f105Sopenharmony_ci      typeList = typeList.concat(keyPickTypeList)
306bea4f105Sopenharmony_ci    }
307bea4f105Sopenharmony_ci    return typeList.filter(item => item)
308bea4f105Sopenharmony_ci  }
309bea4f105Sopenharmony_ci
310bea4f105Sopenharmony_ci  /**
311bea4f105Sopenharmony_ci   * 获取选择文件Mode,默认选择文件
312bea4f105Sopenharmony_ci   * @param keySelectMode 调用方传入文件mode
313bea4f105Sopenharmony_ci   */
314bea4f105Sopenharmony_ci  export function getKeySelectMode(keySelectMode: any): number {
315bea4f105Sopenharmony_ci    if (typeof keySelectMode === 'number') {
316bea4f105Sopenharmony_ci      if (keySelectMode === SELECT_MODE.FILE
317bea4f105Sopenharmony_ci        || keySelectMode === SELECT_MODE.FOLDER
318bea4f105Sopenharmony_ci        || keySelectMode === SELECT_MODE.MIX) {
319bea4f105Sopenharmony_ci        return keySelectMode;
320bea4f105Sopenharmony_ci      }
321bea4f105Sopenharmony_ci    }
322bea4f105Sopenharmony_ci    return SELECT_MODE.FILE;
323bea4f105Sopenharmony_ci  }
324bea4f105Sopenharmony_ci
325bea4f105Sopenharmony_ci  /**
326bea4f105Sopenharmony_ci   * 获取支持的文件后缀列表
327bea4f105Sopenharmony_ci   * @param keyFileSuffixFilter 调用方传入文件后缀列表
328bea4f105Sopenharmony_ci   */
329bea4f105Sopenharmony_ci  export function getKeyFileSuffixFilter(keyFileSuffixFilter: string[]): Array<string> {
330bea4f105Sopenharmony_ci    let suffixList = [];
331bea4f105Sopenharmony_ci    if (!ArrayUtil.isEmpty(keyFileSuffixFilter)) {
332bea4f105Sopenharmony_ci      let len = keyFileSuffixFilter.length;
333bea4f105Sopenharmony_ci      let size = len > SUFFIX_LIST_MAX_LENGTH ? SUFFIX_LIST_MAX_LENGTH : len;
334bea4f105Sopenharmony_ci      for (let index = 0; index < size; index++) {
335bea4f105Sopenharmony_ci        const suffixStr = keyFileSuffixFilter[index];
336bea4f105Sopenharmony_ci        if (typeof suffixStr === 'string') {
337bea4f105Sopenharmony_ci          const suffixArray = suffixStr.split(FILE_SUFFIX.SUFFIX_SPLIT);
338bea4f105Sopenharmony_ci          for (let index = 0; index < suffixArray.length; index++) {
339bea4f105Sopenharmony_ci            const suffix = suffixArray[index];
340bea4f105Sopenharmony_ci            if (checkFileSuffix(suffix)) {
341bea4f105Sopenharmony_ci              suffixList.push(suffix.toUpperCase())
342bea4f105Sopenharmony_ci            }
343bea4f105Sopenharmony_ci          }
344bea4f105Sopenharmony_ci        }
345bea4f105Sopenharmony_ci      }
346bea4f105Sopenharmony_ci    }
347bea4f105Sopenharmony_ci    return suffixList.filter((item, index, array) => {
348bea4f105Sopenharmony_ci      return array.indexOf(item) === index;
349bea4f105Sopenharmony_ci    });
350bea4f105Sopenharmony_ci  }
351bea4f105Sopenharmony_ci
352bea4f105Sopenharmony_ci  export function checkFileSuffix(fileSuffix: String): boolean {
353bea4f105Sopenharmony_ci    return fileSuffix && fileSuffix.length <= SUFFIX_MAX_LENGTH && fileSuffix.startsWith(FILE_SUFFIX.SUFFIX_START);
354bea4f105Sopenharmony_ci  }
355bea4f105Sopenharmony_ci
356bea4f105Sopenharmony_ci  /**
357bea4f105Sopenharmony_ci   * 路径选择器获取支持的文件后缀,只支持获取第一个文件后缀
358bea4f105Sopenharmony_ci   * @param keyFileSuffixChoices 调用方传入文件后缀列表
359bea4f105Sopenharmony_ci   */
360bea4f105Sopenharmony_ci  export function getKeyFileSuffixChoices(keyFileSuffixChoices: string[]): string {
361bea4f105Sopenharmony_ci    if (!ArrayUtil.isEmpty(keyFileSuffixChoices)) {
362bea4f105Sopenharmony_ci      let len = keyFileSuffixChoices.length;
363bea4f105Sopenharmony_ci      let size = len > SUFFIX_LIST_MAX_LENGTH ? SUFFIX_LIST_MAX_LENGTH : len;
364bea4f105Sopenharmony_ci      for (let index = 0; index < size; index++) {
365bea4f105Sopenharmony_ci        const suffixStr = keyFileSuffixChoices[index];
366bea4f105Sopenharmony_ci        if (typeof suffixStr === 'string') {
367bea4f105Sopenharmony_ci          const suffixArray = suffixStr.split(FILE_SUFFIX.SUFFIX_SPLIT);
368bea4f105Sopenharmony_ci          for (let index = 0; index < suffixArray.length; index++) {
369bea4f105Sopenharmony_ci            const suffix = suffixArray[index];
370bea4f105Sopenharmony_ci            if (checkFileSuffix(suffix)) {
371bea4f105Sopenharmony_ci              return suffix;
372bea4f105Sopenharmony_ci            }
373bea4f105Sopenharmony_ci          }
374bea4f105Sopenharmony_ci        }
375bea4f105Sopenharmony_ci      }
376bea4f105Sopenharmony_ci    }
377bea4f105Sopenharmony_ci    return '';
378bea4f105Sopenharmony_ci  }
379bea4f105Sopenharmony_ci
380bea4f105Sopenharmony_ci  /**
381bea4f105Sopenharmony_ci   * 获取媒体库对象实例的统一接口
382bea4f105Sopenharmony_ci   */
383bea4f105Sopenharmony_ci  export function getPhotoManageHelper(): photoAccessHelper.PhotoAccessHelper {
384bea4f105Sopenharmony_ci    if (!photoManageHelper) {
385bea4f105Sopenharmony_ci      try {
386bea4f105Sopenharmony_ci        photoManageHelper = photoAccessHelper.getPhotoAccessHelper(globalThis.abilityContext)
387bea4f105Sopenharmony_ci      } catch (error) {
388bea4f105Sopenharmony_ci        Logger.e(TAG, 'getPhotoManageHelper fail, error:' + JSON.stringify(error))
389bea4f105Sopenharmony_ci      }
390bea4f105Sopenharmony_ci    }
391bea4f105Sopenharmony_ci    return photoManageHelper
392bea4f105Sopenharmony_ci  }
393bea4f105Sopenharmony_ci
394bea4f105Sopenharmony_ci  export function releasePhotoManageHelper(): void {
395bea4f105Sopenharmony_ci    if (!photoManageHelper) {
396bea4f105Sopenharmony_ci      try {
397bea4f105Sopenharmony_ci        photoManageHelper.release()
398bea4f105Sopenharmony_ci      } catch (error) {
399bea4f105Sopenharmony_ci        Logger.e(TAG, 'releasePhotoManageHelper fail, error: ' + JSON.stringify(error))
400bea4f105Sopenharmony_ci      }
401bea4f105Sopenharmony_ci    }
402bea4f105Sopenharmony_ci  }
403bea4f105Sopenharmony_ci}
404bea4f105Sopenharmony_ci
405bea4f105Sopenharmony_ciexport default AbilityCommonUtil
406