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