blob: fb74763631e3249d0e6866922003983e69108a09 [file] [log] [blame]
Michael Kolb8233fac2010-10-26 16:08:53 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Bijan Amirzada41242f22014-03-21 12:12:18 -070017package com.android.browser;
Michael Kolb8233fac2010-10-26 16:08:53 -070018
19import android.app.Activity;
Ben Murdoche4c0cae2011-02-18 11:25:38 +000020import android.content.ActivityNotFoundException;
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -070021import android.content.ComponentName;
Vivek Sekharb54614f2014-05-01 19:03:37 -070022import android.content.ContentResolver;
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -070023import android.content.ContentUris;
24import android.content.Context;
Michael Kolb8233fac2010-10-26 16:08:53 -070025import android.content.Intent;
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -070026import android.content.pm.PackageManager;
27import android.content.pm.ResolveInfo;
28import android.content.pm.ActivityInfo;
kaiyiz4b59d262013-07-30 10:41:38 +080029import android.database.Cursor;
Michael Kolb8233fac2010-10-26 16:08:53 -070030import android.net.Uri;
31import android.os.Environment;
32import android.provider.MediaStore;
33import android.webkit.ValueCallback;
Vivek Sekharb54614f2014-05-01 19:03:37 -070034import android.util.Log;
Ben Murdoche4c0cae2011-02-18 11:25:38 +000035import android.widget.Toast;
Michael Kolb8233fac2010-10-26 16:08:53 -070036
Bijan Amirzada41242f22014-03-21 12:12:18 -070037import com.android.browser.R;
38import com.android.browser.reflect.ReflectHelper;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080039
Michael Kolb8233fac2010-10-26 16:08:53 -070040import java.io.File;
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -070041import java.util.ArrayList;
Axesh R. Ajmeracdbedf12014-12-09 15:25:40 -080042import java.util.Iterator;
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -070043import java.util.List;
Michael Kolb8233fac2010-10-26 16:08:53 -070044
45/**
46 * Handle the file upload callbacks from WebView here
47 */
48public class UploadHandler {
49
Vivek Sekharb54614f2014-05-01 19:03:37 -070050 private static final String TAG = "UploadHandler";
Michael Kolb8233fac2010-10-26 16:08:53 -070051 /*
52 * The Object used to inform the WebView of the file to upload.
53 */
54 private ValueCallback<Uri> mUploadMessage;
Vivek Sekharb54614f2014-05-01 19:03:37 -070055 private ValueCallback<String[]> mUploadFilePaths;
Michael Kolb8233fac2010-10-26 16:08:53 -070056 private String mCameraFilePath;
57
Ben Murdoch51f6a2f2011-02-21 12:27:07 +000058 private boolean mHandled;
59 private boolean mCaughtActivityNotFoundException;
60
Michael Kolb8233fac2010-10-26 16:08:53 -070061 private Controller mController;
62
63 public UploadHandler(Controller controller) {
64 mController = controller;
65 }
66
67 String getFilePath() {
68 return mCameraFilePath;
69 }
70
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -070071 protected boolean handled() {
Ben Murdoch51f6a2f2011-02-21 12:27:07 +000072 return mHandled;
73 }
74
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -070075 protected void setHandled(boolean handled) {
76 mHandled = handled;
77 mCaughtActivityNotFoundException = false;
Axesh R. Ajmera699fd512015-01-13 16:20:45 -080078 // If upload dialog shown to the user got dismissed
79 if (!mHandled) {
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -070080 mUploadFilePaths.onReceiveValue(null);
Axesh R. Ajmera699fd512015-01-13 16:20:45 -080081 }
82 mUploadFilePaths = null;
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -070083 }
Ben Murdoch51f6a2f2011-02-21 12:27:07 +000084
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -070085 void onResult(int resultCode, Intent intent) {
Ben Murdoch51f6a2f2011-02-21 12:27:07 +000086 if (resultCode == Activity.RESULT_CANCELED && mCaughtActivityNotFoundException) {
87 // Couldn't resolve an activity, we are going to try again so skip
88 // this result.
89 mCaughtActivityNotFoundException = false;
90 return;
91 }
92
Michael Kolb8233fac2010-10-26 16:08:53 -070093 Uri result = intent == null || resultCode != Activity.RESULT_OK ? null
94 : intent.getData();
95
96 // As we ask the camera to save the result of the user taking
97 // a picture, the camera application does not return anything other
98 // than RESULT_OK. So we need to check whether the file we expected
99 // was written to disk in the in the case that we
100 // did not get an intent returned but did get a RESULT_OK. If it was,
101 // we assume that this result has came back from the camera.
102 if (result == null && intent == null && resultCode == Activity.RESULT_OK) {
103 File cameraFile = new File(mCameraFilePath);
104 if (cameraFile.exists()) {
105 result = Uri.fromFile(cameraFile);
106 // Broadcast to the media scanner that we have a new photo
107 // so it will be added into the gallery for the user.
108 mController.getActivity().sendBroadcast(
109 new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, result));
110 }
111 }
112
Vivek Sekharb54614f2014-05-01 19:03:37 -0700113 boolean hasGoodFilePath = false;
114 String filePath = null;
115 if (result != null) {
116 String scheme = result.getScheme();
Axesh R. Ajmerac3d90452014-10-29 18:12:19 -0700117 // try to get local file path from uri
Vivek Sekharb54614f2014-05-01 19:03:37 -0700118 if ("file".equals(scheme)) {
119 filePath = result.getPath();
120 hasGoodFilePath = filePath != null && !filePath.isEmpty();
121 } else if ("content".equals(scheme)) {
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -0700122 filePath = getFilePath(mController.getContext(), result);
123 hasGoodFilePath = filePath != null && !filePath.isEmpty();
Vivek Sekharb54614f2014-05-01 19:03:37 -0700124 }
Axesh R. Ajmerac3d90452014-10-29 18:12:19 -0700125
126 // The native layer only accepts path based on file scheme
127 // and skips anything else passed to it
128 filePath = "file://"+filePath;
Vivek Sekharb54614f2014-05-01 19:03:37 -0700129 }
130
Panos Thomas4bdb5252014-11-13 16:20:11 -0800131 // Add for carrier feature - prevent uploading DRM type files based on file extension. This
132 // is not a secure implementation since malicious users can trivially modify the filename.
133 // DRM files can be securely detected by inspecting their integrity protected content.
134 boolean drmUploadEnabled = BrowserConfig.getInstance(mController.getContext())
135 .hasFeature(BrowserConfig.Feature.DRM_UPLOADS);
Vivek Sekharb54614f2014-05-01 19:03:37 -0700136 boolean isDRMFileType = false;
Bijan Amirzadae75909d2014-05-06 14:18:54 -0700137 if (drmUploadEnabled && filePath != null
Vivek Sekharb54614f2014-05-01 19:03:37 -0700138 && (filePath.endsWith(".fl") || filePath.endsWith(".dm")
139 || filePath.endsWith(".dcf") || filePath.endsWith(".dr")
140 || filePath.endsWith(".dd"))) {
141 isDRMFileType = true;
142 Toast.makeText(mController.getContext(), R.string.drm_file_unsupported,
143 Toast.LENGTH_LONG).show();
144 }
145
146 if (mUploadMessage != null) {
147 if (!isDRMFileType) {
148 mUploadMessage.onReceiveValue(result);
149 } else {
150 mUploadMessage.onReceiveValue(null);
151 }
152 }
153
154 if (mUploadFilePaths != null) {
155 if (hasGoodFilePath && !isDRMFileType) {
156 Log.d(TAG, "upload file path:" + filePath);
157 mUploadFilePaths.onReceiveValue(new String[]{filePath});
158 } else {
159 mUploadFilePaths.onReceiveValue(null);
160 }
kaiyiz4b59d262013-07-30 10:41:38 +0800161 }
162
Axesh R. Ajmera699fd512015-01-13 16:20:45 -0800163 setHandled(true);
Michael Kolb8233fac2010-10-26 16:08:53 -0700164 }
165
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -0700166
167 public String getDocumentId(final Uri uri) {
168 String id = null;
169 try {
170 Object[] params = {(android.net.Uri)uri};
171 Class[] type = new Class[] {Class.forName("android.net.Uri") };
172 id = (String) ReflectHelper.invokeMethod(
173 "android.provider.DocumentsContract","getDocumentId",
174 type, params);
175
176 } catch(java.lang.ClassNotFoundException e) {
177
178 }
179 return id;
180 }
181
182
183 public String getFilePath(final Context context, final Uri uri) {
184 String id = getDocumentId(uri);
185
186 // DocumentProvider is new API exposed in Kitkat
187 // Its a way of exposing unified file explorer
188 if (id != null) {
189 // ExternalStorageProvider
190 if (isExternalStorageDocument(uri)) {
191 final String docId = id;
192 final String[] split = docId.split(":");
193 final String type = split[0];
194
195 if ("primary".equalsIgnoreCase(type)) {
196 return Environment.getExternalStorageDirectory() + "/" + split[1];
197 }
198 }
199 // DownloadsProvider
200 else if (isDownloadsDocument(uri)) {
201 final Uri contentUri = ContentUris.withAppendedId(
202 Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
203 return getDataColumn(context, contentUri, null, null);
204 }
205 // MediaProvider
206 else if (isMediaDocument(uri)) {
207 final String docId = id;
208 final String[] split = docId.split(":");
209 final String type = split[0];
210
211 Uri contentUri = null;
212 if ("image".equals(type)) {
213 contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
214 } else if ("video".equals(type)) {
215 contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
216 } else if ("audio".equals(type)) {
217 contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
218 }
219
220 final String selection = "_id=?";
221 final String[] selectionArgs = new String[] {
222 split[1]
223 };
224
225 return getDataColumn(context, contentUri, selection, selectionArgs);
226 }
227 }
228 // MediaStore (and general)
229 else if ("content".equalsIgnoreCase(uri.getScheme())) {
230 return getDataColumn(context, uri, null, null);
231 }
232
233 return null;
234 }
235
236 /**
237 * Get the value of the data column for this Uri. This is useful for
238 * MediaStore Uris, and other file-based ContentProviders.
239 * @return The value of the _data column, which is typically a file path.
240 */
241 private String getDataColumn(Context context, Uri uri, String selection,
242 String[] selectionArgs) {
243
244 Cursor cursor = null;
245 final String column = "_data";
246 final String[] projection = { column };
247
248 try {
249 cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
250 null);
251 if (cursor != null && cursor.moveToFirst()) {
252 final int column_index = cursor.getColumnIndexOrThrow(column);
253 return cursor.getString(column_index);
254 }
255 } finally {
256 if (cursor != null)
257 cursor.close();
258 }
259 return null;
260 }
261
262 /**
263 * @return Whether the Uri authority is ExternalStorageProvider.
264 */
265 private boolean isExternalStorageDocument(Uri uri) {
266 return "com.android.externalstorage.documents".equals(uri.getAuthority());
267 }
268
269 /**
270 * @return Whether the Uri authority is DownloadsProvider.
271 */
272 private boolean isDownloadsDocument(Uri uri) {
273 return "com.android.providers.downloads.documents".equals(uri.getAuthority());
274 }
275
276 /**
277 * @return Whether the Uri authority is MediaProvider.
278 */
279 public static boolean isMediaDocument(Uri uri) {
280 return "com.android.providers.media.documents".equals(uri.getAuthority());
281 }
282
283
Ben Murdoch8cad4132012-01-11 10:56:43 +0000284 void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
Michael Kolb8233fac2010-10-26 16:08:53 -0700285
286 final String imageMimeType = "image/*";
287 final String videoMimeType = "video/*";
288 final String audioMimeType = "audio/*";
289 final String mediaSourceKey = "capture";
290 final String mediaSourceValueCamera = "camera";
291 final String mediaSourceValueFileSystem = "filesystem";
292 final String mediaSourceValueCamcorder = "camcorder";
293 final String mediaSourceValueMicrophone = "microphone";
294
Ben Murdoche4c0cae2011-02-18 11:25:38 +0000295 // According to the spec, media source can be 'filesystem' or 'camera' or 'camcorder'
Ben Murdoch8cad4132012-01-11 10:56:43 +0000296 // or 'microphone' and the default value should be 'filesystem'.
297 String mediaSource = mediaSourceValueFileSystem;
Michael Kolb8233fac2010-10-26 16:08:53 -0700298
Michael Kolb8233fac2010-10-26 16:08:53 -0700299 if (mUploadMessage != null) {
300 // Already a file picker operation in progress.
301 return;
302 }
303
304 mUploadMessage = uploadMsg;
305
306 // Parse the accept type.
307 String params[] = acceptType.split(";");
308 String mimeType = params[0];
309
Ben Murdoch8cad4132012-01-11 10:56:43 +0000310 if (capture.length() > 0) {
311 mediaSource = capture;
312 }
313
314 if (capture.equals(mediaSourceValueFileSystem)) {
315 // To maintain backwards compatibility with the previous implementation
316 // of the media capture API, if the value of the 'capture' attribute is
317 // "filesystem", we should examine the accept-type for a MIME type that
318 // may specify a different capture value.
319 for (String p : params) {
320 String[] keyValue = p.split("=");
321 if (keyValue.length == 2) {
322 // Process key=value parameters.
323 if (mediaSourceKey.equals(keyValue[0])) {
324 mediaSource = keyValue[1];
325 }
Michael Kolb8233fac2010-10-26 16:08:53 -0700326 }
327 }
328 }
329
Ben Murdoche4c0cae2011-02-18 11:25:38 +0000330 //Ensure it is not still set from a previous upload.
331 mCameraFilePath = null;
332
333 if (mimeType.equals(imageMimeType)) {
334 if (mediaSource.equals(mediaSourceValueCamera)) {
335 // Specified 'image/*' and requested the camera, so go ahead and launch the
336 // camera directly.
337 startActivity(createCameraIntent());
338 return;
Ben Murdoche4c0cae2011-02-18 11:25:38 +0000339 } else {
Ben Murdoch8cad4132012-01-11 10:56:43 +0000340 // Specified just 'image/*', capture=filesystem, or an invalid capture parameter.
341 // In all these cases we show a traditional picker filetered on accept type
342 // so launch an intent for both the Camera and image/* OPENABLE.
Ben Murdoche4c0cae2011-02-18 11:25:38 +0000343 Intent chooser = createChooserIntent(createCameraIntent());
344 chooser.putExtra(Intent.EXTRA_INTENT, createOpenableIntent(imageMimeType));
345 startActivity(chooser);
346 return;
347 }
348 } else if (mimeType.equals(videoMimeType)) {
349 if (mediaSource.equals(mediaSourceValueCamcorder)) {
350 // Specified 'video/*' and requested the camcorder, so go ahead and launch the
351 // camcorder directly.
352 startActivity(createCamcorderIntent());
353 return;
Ben Murdoch8cad4132012-01-11 10:56:43 +0000354 } else {
355 // Specified just 'video/*', capture=filesystem or an invalid capture parameter.
356 // In all these cases we show an intent for the traditional file picker, filtered
357 // on accept type so launch an intent for both camcorder and video/* OPENABLE.
Ben Murdoche4c0cae2011-02-18 11:25:38 +0000358 Intent chooser = createChooserIntent(createCamcorderIntent());
359 chooser.putExtra(Intent.EXTRA_INTENT, createOpenableIntent(videoMimeType));
360 startActivity(chooser);
361 return;
362 }
363 } else if (mimeType.equals(audioMimeType)) {
364 if (mediaSource.equals(mediaSourceValueMicrophone)) {
365 // Specified 'audio/*' and requested microphone, so go ahead and launch the sound
366 // recorder.
367 startActivity(createSoundRecorderIntent());
368 return;
Ben Murdoche4c0cae2011-02-18 11:25:38 +0000369 } else {
Ben Murdoch8cad4132012-01-11 10:56:43 +0000370 // Specified just 'audio/*', capture=filesystem of an invalid capture parameter.
371 // In all these cases so go ahead and launch an intent for both the sound
Ben Murdoche4c0cae2011-02-18 11:25:38 +0000372 // recorder and audio/* OPENABLE.
373 Intent chooser = createChooserIntent(createSoundRecorderIntent());
374 chooser.putExtra(Intent.EXTRA_INTENT, createOpenableIntent(audioMimeType));
375 startActivity(chooser);
376 return;
377 }
378 }
379
380 // No special handling based on the accept type was necessary, so trigger the default
381 // file upload chooser.
382 startActivity(createDefaultOpenableIntent());
383 }
384
Vivek Sekharb54614f2014-05-01 19:03:37 -0700385 void showFileChooser(ValueCallback<String[]> uploadFilePaths, String acceptTypes,
386 boolean capture) {
387
388 final String imageMimeType = "image/*";
389 final String videoMimeType = "video/*";
390 final String audioMimeType = "audio/*";
391
392 if (mUploadFilePaths != null) {
393 // Already a file picker operation in progress.
394 return;
395 }
396
397 mUploadFilePaths = uploadFilePaths;
398
399 // Parse the accept type.
400 String params[] = acceptTypes.split(";");
401 String mimeType = params[0];
402
403 // Ensure it is not still set from a previous upload.
404 mCameraFilePath = null;
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -0700405 List<Intent> intentList = new ArrayList<Intent>();
Vivek Sekharb54614f2014-05-01 19:03:37 -0700406
407 if (mimeType.equals(imageMimeType)) {
408 if (capture) {
409 // Specified 'image/*' and capture=true, so go ahead and launch the
410 // camera directly.
411 startActivity(createCameraIntent());
412 return;
413 } else {
414 // Specified just 'image/*', capture=false, or no capture value.
415 // In all these cases we show a traditional picker filetered on accept type
416 // so launch an intent for both the Camera and image/* OPENABLE.
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -0700417 intentList.add(createCameraIntent());
418 createUploadDialog(imageMimeType, intentList);
Vivek Sekharb54614f2014-05-01 19:03:37 -0700419 return;
420 }
421 } else if (mimeType.equals(videoMimeType)) {
422 if (capture) {
423 // Specified 'video/*' and capture=true, so go ahead and launch the
424 // camcorder directly.
425 startActivity(createCamcorderIntent());
426 return;
427 } else {
428 // Specified just 'video/*', capture=false, or no capture value.
429 // In all these cases we show an intent for the traditional file picker, filtered
430 // on accept type so launch an intent for both camcorder and video/* OPENABLE.
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -0700431 intentList.add(createCamcorderIntent());
432 createUploadDialog(videoMimeType, intentList);
Vivek Sekharb54614f2014-05-01 19:03:37 -0700433 return;
434 }
435 } else if (mimeType.equals(audioMimeType)) {
436 if (capture) {
437 // Specified 'audio/*' and capture=true, so go ahead and launch the sound
438 // recorder.
439 startActivity(createSoundRecorderIntent());
440 return;
441 } else {
442 // Specified just 'audio/*', capture=false, or no capture value.
443 // In all these cases so go ahead and launch an intent for both the sound
444 // recorder and audio/* OPENABLE.
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -0700445 intentList.add(createSoundRecorderIntent());
446 createUploadDialog(audioMimeType, intentList);
Vivek Sekharb54614f2014-05-01 19:03:37 -0700447 return;
448 }
449 }
450
451 // No special handling based on the accept type was necessary, so trigger the default
452 // file upload chooser.
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -0700453 createUploadDialog("*/*", null);
Vivek Sekharb54614f2014-05-01 19:03:37 -0700454 }
455
456
Ben Murdoche4c0cae2011-02-18 11:25:38 +0000457 private void startActivity(Intent intent) {
458 try {
459 mController.getActivity().startActivityForResult(intent, Controller.FILE_SELECTED);
460 } catch (ActivityNotFoundException e) {
461 // No installed app was able to handle the intent that
462 // we sent, so fallback to the default file upload control.
463 try {
Ben Murdoch51f6a2f2011-02-21 12:27:07 +0000464 mCaughtActivityNotFoundException = true;
Ben Murdoche4c0cae2011-02-18 11:25:38 +0000465 mController.getActivity().startActivityForResult(createDefaultOpenableIntent(),
466 Controller.FILE_SELECTED);
467 } catch (ActivityNotFoundException e2) {
468 // Nothing can return us a file, so file upload is effectively disabled.
469 Toast.makeText(mController.getActivity(), R.string.uploads_disabled,
470 Toast.LENGTH_LONG).show();
471 }
472 }
473 }
474
475 private Intent createDefaultOpenableIntent() {
476 // Create and return a chooser with the default OPENABLE
477 // actions including the camera, camcorder and sound
478 // recorder where available.
Michael Kolb8233fac2010-10-26 16:08:53 -0700479 Intent i = new Intent(Intent.ACTION_GET_CONTENT);
480 i.addCategory(Intent.CATEGORY_OPENABLE);
Ben Murdoche4c0cae2011-02-18 11:25:38 +0000481 i.setType("*/*");
Michael Kolb8233fac2010-10-26 16:08:53 -0700482
Ben Murdoche4c0cae2011-02-18 11:25:38 +0000483 Intent chooser = createChooserIntent(createCameraIntent(), createCamcorderIntent(),
484 createSoundRecorderIntent());
485 chooser.putExtra(Intent.EXTRA_INTENT, i);
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -0700486
Ben Murdoche4c0cae2011-02-18 11:25:38 +0000487 return chooser;
488 }
489
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -0700490
491 private void createUploadDialog(String openableMimeType, List<Intent> intentList) {
492
493 Intent openable = new Intent(Intent.ACTION_GET_CONTENT);
494 openable.addCategory(Intent.CATEGORY_OPENABLE);
495 openable.setType(openableMimeType);
496
497 if (openableMimeType.equals("*/*") && intentList == null) {
498 intentList = new ArrayList<Intent>();
499 intentList.add(createCameraIntent());
500 intentList.add(createCamcorderIntent());
501 intentList.add(createSoundRecorderIntent());
502 }
503
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -0700504 PackageManager pm = mController.getActivity().getPackageManager();
Axesh R. Ajmera025fed32014-09-04 11:18:47 -0700505 ArrayList<ResolveInfo> uploadApps = new ArrayList<ResolveInfo>();
506
507 //Step 1:- resolve all apps for IntentList passed
Axesh R. Ajmeracdbedf12014-12-09 15:25:40 -0800508 for (Iterator<Intent> iterator = intentList.iterator(); iterator.hasNext();) {
509 List<ResolveInfo> intentAppsList = pm.queryIntentActivities(iterator.next(),
Axesh R. Ajmera025fed32014-09-04 11:18:47 -0700510 PackageManager.MATCH_DEFAULT_ONLY);
Axesh R. Ajmeracdbedf12014-12-09 15:25:40 -0800511
512 // Check whether any apps are available
513 if (intentAppsList!= null && intentAppsList.size() > 0){
514 // limit only to first activity
515 uploadApps.add(intentAppsList.get(0));
516 } else {
517 iterator.remove();
518 }
519
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -0700520 }
521
Axesh R. Ajmera025fed32014-09-04 11:18:47 -0700522 // Step 2:- get all openable apps list and create corresponding intents
523 List<ResolveInfo> openableAppsList = pm.queryIntentActivities(openable,
524 PackageManager.MATCH_DEFAULT_ONLY);
525 // limit only to first activity
526 ResolveInfo topOpenableApp = openableAppsList.get(0);
527 uploadApps.add(topOpenableApp);
528 ActivityInfo activityInfo = topOpenableApp.activityInfo;
529 ComponentName name = new ComponentName(activityInfo.applicationInfo.packageName,
530 activityInfo.name);
531 Intent i = new Intent(Intent.ACTION_GET_CONTENT);
532 i.setType(openableMimeType);
533 i.setComponent(name);
Tarun Nainani7620d492015-02-04 16:50:38 -0800534 i.addCategory(Intent.CATEGORY_OPENABLE);
Axesh R. Ajmera025fed32014-09-04 11:18:47 -0700535 intentList.add(i);
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -0700536
Axesh R. Ajmera025fed32014-09-04 11:18:47 -0700537 // Step 3: Pass all the apps and their corresponding intents to uploaddialog
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -0700538 UploadDialog upDialog = new UploadDialog(mController.getActivity());
Axesh R. Ajmera025fed32014-09-04 11:18:47 -0700539 upDialog.getUploadableApps(uploadApps, intentList);
Axesh R. Ajmera3aae1012014-07-03 16:37:53 -0700540 upDialog.loadView(this);
541 }
542
543 public void initiateActivity(Intent intent) {
544 startActivity(intent);
545 }
546
Ben Murdoche4c0cae2011-02-18 11:25:38 +0000547 private Intent createChooserIntent(Intent... intents) {
548 Intent chooser = new Intent(Intent.ACTION_CHOOSER);
549 chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents);
550 chooser.putExtra(Intent.EXTRA_TITLE,
551 mController.getActivity().getResources()
552 .getString(R.string.choose_upload));
553 return chooser;
554 }
555
556 private Intent createOpenableIntent(String type) {
557 Intent i = new Intent(Intent.ACTION_GET_CONTENT);
558 i.addCategory(Intent.CATEGORY_OPENABLE);
559 i.setType(type);
560 return i;
561 }
562
563 private Intent createCameraIntent() {
Michael Kolb8233fac2010-10-26 16:08:53 -0700564 Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
565 File externalDataDir = Environment.getExternalStoragePublicDirectory(
566 Environment.DIRECTORY_DCIM);
567 File cameraDataDir = new File(externalDataDir.getAbsolutePath() +
568 File.separator + "browser-photos");
569 cameraDataDir.mkdirs();
570 mCameraFilePath = cameraDataDir.getAbsolutePath() + File.separator +
571 System.currentTimeMillis() + ".jpg";
572 cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(mCameraFilePath)));
Ben Murdoche4c0cae2011-02-18 11:25:38 +0000573 return cameraIntent;
Michael Kolb8233fac2010-10-26 16:08:53 -0700574 }
575
Ben Murdoche4c0cae2011-02-18 11:25:38 +0000576 private Intent createCamcorderIntent() {
577 return new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
578 }
579
580 private Intent createSoundRecorderIntent() {
581 return new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
Michael Kolb8233fac2010-10-26 16:08:53 -0700582 }
583
584}