• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023-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 */
15const pickerHelper = requireInternal('file.picker');
16
17let gContext = undefined;
18
19const PhotoViewMIMETypes = {
20  IMAGE_TYPE: 'image/*',
21  VIDEO_TYPE: 'video/*',
22  IMAGE_VIDEO_TYPE: '*/*',
23  INVALID_TYPE: ''
24};
25
26const DocumentSelectMode = {
27  FILE: 0,
28  FOLDER: 1,
29  MIXED: 2,
30};
31
32const MergeTypeMode = {
33  DEFAULT: 0,
34  AUDIO: 1,
35  VIDEO: 2,
36  DOCUMENT: 3,
37  PICTURE: 4,
38};
39
40const DocumentPickerMode = {
41  DEFAULT: 0,
42  DOWNLOAD: 1,
43};
44
45const ExtTypes = {
46  DOWNLOAD_TYPE: 'filePicker',
47  AUDIO_PICKER_TYPE: 'audioPicker',
48  PHOTO_PICKER_TYPE: 'photoPicker',
49};
50
51const PickerDetailType = {
52  FILE_MGR_AUTH: 'downloadAuth',
53  FILE_MGR_SELECT:'select',
54  FILE_MGR_SAVE:'save',
55};
56
57const ErrCode = {
58  INVALID_ARGS: 13900020,
59  RESULT_ERROR: 13900042,
60  NAME_TOO_LONG: 13900030,
61  CONTEXT_NO_EXIST: 16000011,
62};
63
64const ERRCODE_MAP = new Map([
65  [ErrCode.INVALID_ARGS, 'Invalid argument'],
66  [ErrCode.RESULT_ERROR, 'Unknown error'],
67  [ErrCode.NAME_TOO_LONG, 'File name too long'],
68  [ErrCode.CONTEXT_NO_EXIST, 'Current ability failed to obtain context'],
69]);
70
71const PHOTO_VIEW_MIME_TYPE_MAP = new Map([
72  [PhotoViewMIMETypes.IMAGE_TYPE, 'FILTER_MEDIA_TYPE_IMAGE'],
73  [PhotoViewMIMETypes.VIDEO_TYPE, 'FILTER_MEDIA_TYPE_VIDEO'],
74  [PhotoViewMIMETypes.IMAGE_VIDEO_TYPE, 'FILTER_MEDIA_TYPE_ALL'],
75]);
76
77const ACTION = {
78  SELECT_ACTION: 'ohos.want.action.OPEN_FILE',
79  SELECT_ACTION_MODAL: 'ohos.want.action.OPEN_FILE_SERVICE',
80  SAVE_ACTION: 'ohos.want.action.CREATE_FILE',
81  SAVE_ACTION_MODAL: 'ohos.want.action.CREATE_FILE_SERVICE',
82};
83
84const CREATE_FILE_NAME_LENGTH_LIMIT = 256;
85const ARGS_ZERO = 0;
86const ARGS_ONE = 1;
87const ARGS_TWO = 2;
88const RESULT_CODE_ERROR = -1;
89const RESULT_CODE_OK = 0;
90const LENGTH_TWO = 2;
91const LENGTH_THREE = 3;
92let suffixIndex = -1;
93
94/*
95* UTF-8字符编码数值对应的存储长度:
96* 0000 - 0x007F (eg: a~z A~Z 0~9)
97* 0080 - 0x07FF (eg: 希腊字母)
98* 0800 - 0xFFFF (eg: 中文)
99* 其他 (eg: 平面符号)
100*/
101function strSizeUTF8(str) {
102  let strLen = str.length;
103  let bytesLen = 0;
104  let greeceLen = 2;
105  let chineseLen = 3;
106  let othersLen = 4;
107  for (let i = 0; i < strLen; i++) {
108    let charCode = str.charCodeAt(i);
109    if (charCode <= 0x007f) {
110      bytesLen++;
111    } else if (charCode <= 0x07ff) {
112      bytesLen += greeceLen;
113    } else if (charCode <= 0xffff) {
114      bytesLen += chineseLen;
115    } else {
116      bytesLen += othersLen;
117    }
118  }
119  return bytesLen;
120}
121
122function checkArguments(args) {
123  let checkArgumentsResult = undefined;
124  if (args.length === ARGS_TWO && typeof args[ARGS_ONE] !== 'function') {
125    checkArgumentsResult = getErr(ErrCode.INVALID_ARGS);
126  }
127
128  if (args.length > 0 && typeof args[ARGS_ZERO] === 'object') {
129    let option = args[ARGS_ZERO];
130    if (option.maxSelectNumber !== undefined) {
131      if (option.maxSelectNumber.toString().indexOf('.') !== -1) {
132        checkArgumentsResult = getErr(ErrCode.INVALID_ARGS);
133      }
134    }
135
136    if (option.newFileNames === undefined || option.newFileNames.length <= 0) {
137      return checkArgumentsResult;
138    }
139
140    for (let i = 0; i < option.newFileNames.length; i++) {
141      let value = option.newFileNames[i];
142      if (strSizeUTF8(value) >= CREATE_FILE_NAME_LENGTH_LIMIT) {
143        console.log('[picker] checkArguments Invalid name: ' + value);
144        checkArgumentsResult = getErr(ErrCode.NAME_TOO_LONG);
145      }
146    }
147  }
148
149  return checkArgumentsResult;
150}
151
152function getErr(errCode) {
153  return {code: errCode, message: ERRCODE_MAP.get(errCode)};
154}
155
156function parsePhotoPickerSelectOption(args) {
157  let config = {
158    action: 'ohos.want.action.photoPicker',
159    type: 'multipleselect',
160    parameters: {
161      uri: 'multipleselect',
162      extType: ExtTypes.PHOTO_PICKER_TYPE,
163    },
164  };
165
166  if (args.length > ARGS_ZERO && typeof args[ARGS_ZERO] === 'object') {
167    let option = args[ARGS_ZERO];
168    if (option.maxSelectNumber && option.maxSelectNumber > 0) {
169      let select = (option.maxSelectNumber === 1) ? 'singleselect' : 'multipleselect';
170      config.type = select;
171      config.parameters.uri = select;
172      config.parameters.maxSelectCount = option.maxSelectNumber;
173    }
174    if (option.MIMEType && PHOTO_VIEW_MIME_TYPE_MAP.has(option.MIMEType)) {
175      config.parameters.filterMediaType = PHOTO_VIEW_MIME_TYPE_MAP.get(option.MIMEType);
176    }
177  }
178
179  return config;
180}
181
182function anonymousPathArray(geturi) {
183  let anonymousPathArrays = [];
184  let anonymousPath = '';
185  if (geturi === undefined) {
186    return anonymousPathArrays;
187  }
188  for (let i = 0; i < geturi.length; ++i) {
189    let lastSlashIndex = geturi[i].lastIndexOf('/');
190    if (lastSlashIndex === -1) {
191      anonymousPathArrays.push(geturi[i]);
192    } else {
193      let dirPath = geturi[i].substring(0, lastSlashIndex + 1);
194      let fileName = geturi[i].substring(lastSlashIndex + 1);
195      if (fileName.length <= 0) {
196        anonymousPath = '******';
197      } else {
198        let lastLetter = fileName.slice(-1);
199        let maskedName = '******' + lastLetter;
200        anonymousPath = dirPath + maskedName;
201      }
202      anonymousPathArrays.push(anonymousPath);
203    }
204    }
205  return anonymousPathArrays;
206}
207
208function getPhotoPickerSelectResult(args) {
209  let selectResult = {
210    error: undefined,
211    data: undefined,
212  };
213
214  if (args.resultCode === 0) {
215    let uris = args.photoUris;
216    if (uris === undefined) {
217      console.log('[picker] Photo uris is undefined');
218      uris = [];
219    }
220    let isOriginal = args.isOriginal;
221    selectResult.data = new PhotoSelectResult(uris, isOriginal);
222  } else if (args.resultCode === -1) {
223    selectResult.data = new PhotoSelectResult([], undefined);
224  } else {
225    selectResult.error = getErr(ErrCode.RESULT_ERROR);
226  }
227
228  return selectResult;
229}
230
231async function photoPickerSelect(...args) {
232  if (args.length !== LENGTH_TWO) {
233    console.error('[picker] args error: ' + args.length);
234    return undefined;
235  }
236  let checkPhotoArgsResult = checkArguments(args[ARGS_ZERO]);
237  if (checkPhotoArgsResult !== undefined) {
238    console.log('[picker] Photo Invalid argument');
239    throw checkPhotoArgsResult;
240  }
241
242  const config = parsePhotoPickerSelectOption(args[ARGS_ZERO]);
243  console.log('[picker] Photo config: ' + JSON.stringify(config));
244
245  let photoSelectContext = undefined;
246  let photoSelectWindow = undefined;
247  try {
248    if (args[ARGS_ONE] !== undefined) {
249      photoSelectContext = args[ARGS_ONE];
250    } else {
251      photoSelectContext = getContext(this);
252    }
253  } catch (getContextError) {
254    console.error('[picker] getContext error: ' + getContextError);
255    throw getErr(ErrCode.CONTEXT_NO_EXIST);
256  }
257  try {
258    if (photoSelectContext === undefined) {
259      console.error('[picker] photoSelectContext == undefined');
260      throw getErr(ErrCode.CONTEXT_NO_EXIST);
261    }
262    let modalSelectResult = await modalPicker(photoSelectContext, config, photoSelectWindow);
263    console.log('[picker] photo select result: ' + JSON.stringify(modalSelectResult));
264    const photoSelectResult = getPhotoPickerSelectResult(modalSelectResult);
265    console.log('[picker] photoSelectResult: ' + JSON.stringify(photoSelectResult));
266    let inputArgs = args[ARGS_ZERO];
267    if (inputArgs.length === ARGS_TWO && typeof inputArgs[ARGS_ONE] === 'function') {
268      return inputArgs[ARGS_ONE](photoSelectResult.error, photoSelectResult.data);
269    } else if (inputArgs.length === ARGS_ONE && typeof inputArgs[ARGS_ZERO] === 'function') {
270      return inputArgs[ARGS_ZERO](photoSelectResult.error, photoSelectResult.data);
271    }
272    return new Promise((resolve, reject) => {
273      if (photoSelectResult.data !== undefined) {
274        resolve(photoSelectResult.data);
275      } else {
276        reject(photoSelectResult.error);
277      }
278    });
279  } catch (error) {
280    console.error('[picker] photo select error: ' + error);
281  }
282  return undefined;
283}
284
285function parseDocumentPickerSelectOption(args, action) {
286  let config = {
287    action: action,
288    parameters: {
289      startMode: 'choose',
290      extType: ExtTypes.DOWNLOAD_TYPE,
291      pickerType: PickerDetailType.FILE_MGR_SELECT,
292    }
293  };
294
295  if (args.length > ARGS_ZERO && typeof args[ARGS_ZERO] === 'object') {
296    let option = args[ARGS_ZERO];
297    config.parameters.key_select_mode = option.selectMode;
298    config.parameters.key_merge_type_mode = option.mergeMode;
299    console.log('[picker] parseDocumentPickerSelectOption: ' + JSON.stringify(option));
300
301    if ((option.maxSelectNumber !== undefined) && option.maxSelectNumber > 0) {
302      config.parameters.key_pick_num = option.maxSelectNumber;
303    }
304    if (option.defaultFilePathUri !== undefined) {
305      config.parameters.key_pick_dir_path = option.defaultFilePathUri;
306    }
307    if ((option.fileSuffixFilters !== undefined) && option.fileSuffixFilters.length > 0) {
308      config.parameters.key_file_suffix_filter = option.fileSuffixFilters;
309    }
310    if (option.authMode !== undefined) {
311      config.parameters.key_auth_mode = option.authMode;
312    }
313    config.parameters.key_mult_auth_mode = option.multiAuthMode;
314    if (option.multiUriArray !== undefined) {
315      config.parameters.key_mult_uri_arr = option.multiUriArray;
316      console.log('[picker] parseDocumentPickerSelectOption multiUriArray length: ' + option.multiUriArray.length);
317    }
318  }
319
320  console.log('[picker] document select config: ' + JSON.stringify(config));
321  return config;
322}
323
324function parseAudioPickerSelectOption(args, action) {
325  let config = {
326    action: action,
327    parameters: {
328      extType: ExtTypes.AUDIO_PICKER_TYPE,
329    }
330  };
331  if (args.length > ARGS_ZERO && typeof args[ARGS_ZERO] === 'object') {
332    let option = args[ARGS_ZERO];
333    if ((option.maxSelectNumber !== undefined) && option.maxSelectNumber > 0) {
334      config.parameters.key_pick_num = option.maxSelectNumber;
335    }
336  }
337  console.log('[picker] audio select config: ' + JSON.stringify(config));
338  return config;
339}
340
341function getDocumentPickerSelectResult(args) {
342  let selectResult = {
343    error: undefined,
344    data: undefined
345  };
346  if (args === undefined || args.resultCode === undefined) {
347    selectResult.error = getErr(ErrCode.RESULT_ERROR);
348    console.log('[picker] document select selectResult: ' + JSON.stringify(selectResult));
349    return selectResult;
350  }
351  if (args.resultCode === RESULT_CODE_OK) {
352    if (args.ability_params_stream) {
353      selectResult.data = args.ability_params_stream;
354      selectResult.error = args.resultCode;
355    }
356  } else if (args.resultCode === RESULT_CODE_ERROR) {
357    selectResult.data = [];
358    selectResult.error = args.resultCode;
359  }
360
361  console.log('[picker] document select selectResult: : errorcode is = ' + selectResult.error +
362              ', selecturi is = ' + anonymousPathArray(selectResult.data));
363  return selectResult;
364}
365
366async function documentPickerSelect(...args) {
367  if (args.length !== LENGTH_THREE) {
368    console.error('[picker] args error: ' + args.length);
369    return undefined;
370  }
371  let checkDocumentSelectArgsResult = checkArguments(args[ARGS_ZERO]);
372  if (checkDocumentSelectArgsResult !== undefined) {
373    console.log('[picker] Document Select Invalid argument');
374    throw checkDocumentSelectArgsResult;
375  }
376
377  let documentSelectContext = undefined;
378  let documentSelectConfig = undefined;
379  let documentSelectResult = undefined;
380  let selectResult = undefined;
381  let documentSelectWindow = undefined;
382
383  try {
384    if (args[ARGS_ONE] !== undefined) {
385      documentSelectContext = args[ARGS_ONE];
386    } else {
387      documentSelectContext = getContext(this);
388    }
389  } catch (getContextError) {
390    console.error('[picker] getContext error: ' + getContextError);
391    throw getErr(ErrCode.CONTEXT_NO_EXIST);
392  }
393  try {
394    if (documentSelectContext === undefined) {
395      console.error('[picker] documentSelectContext == undefined');
396      throw getErr(ErrCode.CONTEXT_NO_EXIST);
397    }
398    if (args[ARGS_TWO] !== undefined) {
399        documentSelectWindow = args[ARGS_TWO];
400    }
401    documentSelectConfig = parseDocumentPickerSelectOption(args[ARGS_ZERO], ACTION.SELECT_ACTION_MODAL);
402    console.error('[picker] DocumentSelect documentSelectConfig: ' + JSON.stringify(documentSelectConfig));
403    documentSelectResult = await modalPicker(documentSelectContext, documentSelectConfig, documentSelectWindow);
404  } catch (paramError) {
405    console.error('[picker] DocumentSelect paramError: ' + JSON.stringify(paramError));
406  }
407  selectResult = getDocumentPickerSelectResult(documentSelectResult);
408  return sendResult(args[ARGS_ZERO], selectResult);
409}
410
411function parseDocumentPickerSaveOption(args, action) {
412  let config = {
413    action: action,
414    parameters: {
415      startMode: 'save',
416      pickerMode: DocumentPickerMode.DEFAULT,
417      extType: ExtTypes.DOWNLOAD_TYPE,
418      pickerType: PickerDetailType.FILE_MGR_SAVE,
419    }
420  };
421
422  if (args.length > ARGS_ZERO && typeof args[ARGS_ZERO] === 'object') {
423    let option = args[ARGS_ZERO];
424    console.log('[picker] document save option: ' + JSON.stringify(option));
425    if ((option.newFileNames !== undefined) && option.newFileNames.length > 0) {
426      config.parameters.key_pick_file_name = option.newFileNames;
427      config.parameters.saveFile = option.newFileNames[0];
428    }
429
430    if (option.defaultFilePathUri !== undefined) {
431      config.parameters.key_pick_dir_path = option.defaultFilePathUri;
432    }
433    if ((option.fileSuffixChoices !== undefined) && option.fileSuffixChoices.length > 0) {
434      config.parameters.key_file_suffix_choices = option.fileSuffixChoices;
435    }
436    if (option.pickerMode === DocumentPickerMode.DOWNLOAD) {
437      config.parameters.pickerMode = option.pickerMode;
438      config.parameters.pickerType = PickerDetailType.FILE_MGR_AUTH;
439    }
440  }
441
442  console.log('[picker] document save config: ' + JSON.stringify(config));
443  return config;
444}
445
446function getAudioPickerSelectResult(args) {
447  let selectResult = {
448    error: undefined,
449    data: undefined
450  };
451  if (args === undefined || args.resultCode === undefined) {
452    selectResult.error = getErr(ErrCode.RESULT_ERROR);
453    console.log('[picker] getAudioPickerSelectResult selectResult: ' + JSON.stringify(selectResult));
454    return selectResult;
455  }
456  if (args.resultCode === RESULT_CODE_OK) {
457    if (args.uriArr) {
458      selectResult.data = args.uriArr;
459      selectResult.error = args.resultCode;
460    } else {
461      selectResult.data = [];
462      selectResult.error = args.resultCode;
463    }
464  } else if (args.resultCode === RESULT_CODE_ERROR) {
465    selectResult.data = [];
466    selectResult.error = args.resultCode;
467  }
468
469  console.log('[picker] getAudioPickerSelectResult selectResult: errorcode is = ' + selectResult.error +
470              ', selecturi is = ' + anonymousPathArray(selectResult.data));
471  return selectResult;
472}
473
474
475function getDocumentPickerSaveResult(args) {
476  let saveResult = {
477    error: undefined,
478    data: undefined,
479    suffix: -1
480  };
481  if (args === undefined || args.resultCode === undefined) {
482    saveResult.error = getErr(ErrCode.RESULT_ERROR);
483    console.log('[picker] getDocumentPickerSaveResult saveResult: ' + JSON.stringify(saveResult));
484    return saveResult;
485  }
486  if (args.resultCode === RESULT_CODE_OK) {
487    if (args.ability_params_stream) {
488      saveResult.data = args.ability_params_stream;
489      saveResult.error = args.resultCode;
490      if (args.userSuffixIndex >= 0) {
491        saveResult.suffix = args.userSuffixIndex;
492      }
493    }
494  } else if (args.resultCode === RESULT_CODE_ERROR) {
495    saveResult.data = [];
496    saveResult.error = args.resultCode;
497  }
498
499  console.log('[picker] getDocumentPickerSaveResult saveResult: errorcode is = ' + saveResult.error +
500              ', selecturi is = ' + anonymousPathArray(saveResult.data) + ', usersavesuffix =' + saveResult.suffix);
501  return saveResult;
502}
503
504function startModalPicker(context, config, window) {
505  if (context === undefined) {
506    throw Error('[picker] Context undefined.');
507  }
508  if (config === undefined) {
509    throw Error('[picker] Config undefined.');
510  }
511  gContext = context;
512  if (pickerHelper === undefined) {
513    throw Error('[picker] PickerHelper undefined.');
514  }
515  let helper;
516  if (window !== undefined) {
517    helper = pickerHelper.startModalPicker(gContext, config, window);
518  } else {
519    helper = pickerHelper.startModalPicker(gContext, config);
520  }
521  if (helper === undefined) {
522    throw Error('[picker] Please check the parameter you entered.');
523  }
524  return helper;
525}
526
527async function modalPicker(context, config, window) {
528  try {
529    console.log('[picker] Config: ' + JSON.stringify(config));
530    let modalResult = await startModalPicker(context, config, window);
531    return modalResult;
532  } catch (resultError) {
533    console.error('[picker] Result error: ' + resultError);
534    return undefined;
535  }
536}
537
538async function documentPickerSave(...args) {
539  if (args.length < LENGTH_TWO || args.length > LENGTH_THREE) {
540    console.error('[picker] args error: ' + args.length);
541    return undefined;
542  }
543  let checkDocumentSaveArgsResult = checkArguments(args[ARGS_ZERO]);
544  if (checkDocumentSaveArgsResult !== undefined) {
545    console.log('[picker] Document Save Invalid argument');
546    throw checkDocumentSaveArgsResult;
547  }
548
549  let documentSaveContext = undefined;
550  let documentSaveConfig = undefined;
551  let documentSaveResult = undefined;
552  let saveResult = undefined;
553  let documentSaveWindow = undefined;
554
555  try {
556    if (args[ARGS_ONE] !== undefined) {
557      documentSaveContext = args[ARGS_ONE];
558    } else {
559      documentSaveContext = getContext(this);
560    }
561  } catch (getContextError) {
562    console.error('[picker] getContext error: ' + getContextError);
563    throw getErr(ErrCode.CONTEXT_NO_EXIST);
564  }
565  if (args.length === LENGTH_THREE && args[ARGS_TWO] !== undefined) {
566      documentSaveWindow = args[ARGS_TWO];
567  }
568
569  documentSaveConfig = parseDocumentPickerSaveOption(args[ARGS_ZERO], ACTION.SAVE_ACTION_MODAL);
570  console.log('[picker] document save start');
571
572  documentSaveResult = await modalPicker(documentSaveContext, documentSaveConfig, documentSaveWindow);
573  saveResult = getDocumentPickerSaveResult(documentSaveResult);
574  suffixIndex = saveResult.suffix;
575  return sendResult(args[ARGS_ZERO], saveResult);
576}
577
578function getSelectedSuffixIndex() {
579  console.log('[picker] Get Selected Suffix Index start');
580  let index = suffixIndex;
581  suffixIndex = -1;
582  console.log('[picker] Get Selected Suffix Index end: ' + index);
583  return index;
584}
585async function sendResult(args, result) {
586  try {
587    if (result === undefined) {
588      console.log('[picker] modal picker: result is undefined.');
589      return undefined;
590    }
591    if (args.length === ARGS_TWO && typeof args[ARGS_ONE] === 'function') {
592      return args[ARGS_ONE](result.error, result.data);
593    } else if (args.length === ARGS_ONE && typeof args[ARGS_ZERO] === 'function') {
594      return args[ARGS_ZERO](result.error, result.data);
595    }
596    return new Promise((resolve, reject) => {
597      if (result.data !== undefined) {
598        resolve(result.data);
599      } else {
600        reject(result.error);
601      }
602    });
603  } catch (resultError) {
604    console.error('[picker] Result error: ' + resultError);
605  }
606  return undefined;
607}
608
609async function audioPickerSelect(...args) {
610  if (args.length !== LENGTH_TWO) {
611    console.error('[picker] args error: ' + args.length);
612    return undefined;
613  }
614  let checkAudioArgsResult = checkArguments(args[ARGS_ZERO]);
615  if (checkAudioArgsResult !== undefined) {
616    console.log('[picker] Audio Invalid argument');
617    throw checkAudioArgsResult;
618  }
619
620  const audioSelectConfig = parseAudioPickerSelectOption(args[ARGS_ZERO], ACTION.SELECT_ACTION);
621  console.log('[picker] audio select config: ' + JSON.stringify(audioSelectConfig));
622
623  let audioSelectContext = undefined;
624  let audipSelectWindow = undefined;
625  try {
626    if (args[ARGS_ONE] !== undefined) {
627      audioSelectContext = args[ARGS_ONE];
628    } else {
629      audioSelectContext = getContext(this);
630    }
631  } catch (getContextError) {
632    console.error('[picker] getContext error: ' + getContextError);
633    throw getErr(ErrCode.CONTEXT_NO_EXIST);
634  }
635  try {
636    if (audioSelectContext === undefined) {
637      console.error('[picker] audioSelectContext == undefined');
638      throw getErr(ErrCode.CONTEXT_NO_EXIST);
639    }
640    let modalSelectResult = await modalPicker(audioSelectContext, audioSelectConfig, audipSelectWindow);
641    let saveResult = getAudioPickerSelectResult(modalSelectResult);
642    return sendResult(args[ARGS_ZERO], saveResult);
643  } catch (error) {
644    console.error('[picker] audio select error: ' + error);
645  }
646  return undefined;
647}
648
649class PhotoSelectOptions {
650  constructor() {
651    this.MIMEType = PhotoViewMIMETypes.INVALID_TYPE;
652    this.maxSelectNumber = -1;
653  }
654}
655
656class PhotoSelectResult {
657  constructor(uris, isOriginalPhoto) {
658    this.photoUris = uris;
659    this.isOriginalPhoto = isOriginalPhoto;
660  }
661}
662
663class PhotoSaveOptions {
664  constructor() {
665    this.newFileNames = undefined;
666  }
667}
668
669class DocumentSelectOptions {
670  constructor() {
671    this.defaultFilePathUri = undefined;
672    this.fileSuffixFilters = undefined;
673    this.maxSelectNumber = undefined;
674    this.authMode = false;
675    this.selectMode = DocumentSelectMode.FILE;
676    this.mergeMode = MergeTypeMode.DEFAULT;
677    this.multiAuthMode = false;
678    this.multiUriArray = undefined;
679  }
680}
681
682class DocumentSaveOptions {
683  constructor() {
684    this.newFileNames = undefined;
685    this.defaultFilePathUri = undefined;
686    this.fileSuffixChoices = undefined;
687    this.pickerMode = DocumentPickerMode.DEFAULT;
688  }
689}
690
691class AudioSelectOptions {
692  constructor() {}
693}
694
695class AudioSaveOptions {
696  constructor() {
697    this.newFileNames = undefined;
698  }
699}
700
701function ParseContext(args)
702{
703  if (args.length > ARGS_TWO || args.length < ARGS_ZERO || typeof args[ARGS_ZERO] !== 'object') {
704    return undefined;
705  }
706  return args[ARGS_ZERO];
707}
708
709function parseWindow(args)
710{
711  if (args.length !== ARGS_TWO) {
712    console.log('[picker] ParseWindow: not window mode.');
713    return undefined;
714  }
715  if (args.length === ARGS_TWO && typeof args[ARGS_ONE] !== 'object') {
716    console.log('[picker] ParseWindow: not window mode or type err.');
717    return undefined;
718  }
719  console.log('[picker] ParseWindow: window mode.');
720  return args[ARGS_ONE];
721}
722
723class PhotoViewPicker {
724  constructor(...args) {
725    this.context = ParseContext(args);
726  }
727  select(...args) {
728    return photoPickerSelect(args, this.context);
729  }
730  save(...args) {
731    return documentPickerSave(args, this.context);
732  }
733}
734
735class DocumentViewPicker {
736  constructor(...args) {
737    this.context = ParseContext(args);
738    this.window = parseWindow(args);
739  }
740  select(...args) {
741    return documentPickerSelect(args, this.context, this.window);
742  }
743  save(...args) {
744    return documentPickerSave(args, this.context, this.window);
745  }
746  getSelectedIndex() {
747    return getSelectedSuffixIndex();
748  }
749}
750
751class AudioViewPicker {
752  constructor(...args) {
753    this.context = ParseContext(args);
754  }
755  select(...args) {
756    return audioPickerSelect(args, this.context);
757  }
758  save(...args) {
759    return documentPickerSave(args, this.context);
760  }
761}
762
763export default {
764  getSelectedSuffixIndex,
765  startModalPicker,
766  ExtTypes : ExtTypes,
767  PickerDetailType: PickerDetailType,
768  PhotoViewMIMETypes : PhotoViewMIMETypes,
769  PhotoSelectOptions : PhotoSelectOptions,
770  PhotoSelectResult : PhotoSelectResult,
771  PhotoSaveOptions : PhotoSaveOptions,
772  DocumentSelectMode : DocumentSelectMode,
773  DocumentPickerMode : DocumentPickerMode,
774  MergeTypeMode : MergeTypeMode,
775  DocumentSelectOptions : DocumentSelectOptions,
776  DocumentSaveOptions : DocumentSaveOptions,
777  AudioSelectOptions : AudioSelectOptions,
778  AudioSaveOptions : AudioSaveOptions,
779  PhotoViewPicker : PhotoViewPicker,
780  DocumentViewPicker: DocumentViewPicker,
781  AudioViewPicker : AudioViewPicker,
782};
783