Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(289)

Side by Side Diff: ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java

Issue 2649033007: Record whether a file picker specialized for media content can be used (Closed)
Patch Set: Record whether a file picker specialized for media content can be used Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/metrics/histograms/histograms.xml ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.ui.base; 5 package org.chromium.ui.base;
6 6
7 import android.Manifest; 7 import android.Manifest;
8 import android.annotation.TargetApi; 8 import android.annotation.TargetApi;
9 import android.app.Activity; 9 import android.app.Activity;
10 import android.content.ClipData; 10 import android.content.ClipData;
11 import android.content.ContentResolver; 11 import android.content.ContentResolver;
12 import android.content.Context; 12 import android.content.Context;
13 import android.content.Intent; 13 import android.content.Intent;
14 import android.content.pm.PackageManager; 14 import android.content.pm.PackageManager;
15 import android.net.Uri; 15 import android.net.Uri;
16 import android.os.AsyncTask; 16 import android.os.AsyncTask;
17 import android.os.Build; 17 import android.os.Build;
18 import android.provider.MediaStore; 18 import android.provider.MediaStore;
19 import android.text.TextUtils; 19 import android.text.TextUtils;
20 import android.util.Log; 20 import android.util.Log;
21 21
22 import org.chromium.base.ApiCompatibilityUtils; 22 import org.chromium.base.ApiCompatibilityUtils;
23 import org.chromium.base.ContentUriUtils; 23 import org.chromium.base.ContentUriUtils;
24 import org.chromium.base.ContextUtils; 24 import org.chromium.base.ContextUtils;
25 import org.chromium.base.ThreadUtils; 25 import org.chromium.base.ThreadUtils;
26 import org.chromium.base.VisibleForTesting; 26 import org.chromium.base.VisibleForTesting;
27 import org.chromium.base.annotations.CalledByNative; 27 import org.chromium.base.annotations.CalledByNative;
28 import org.chromium.base.annotations.JNINamespace; 28 import org.chromium.base.annotations.JNINamespace;
29 import org.chromium.base.annotations.MainDex; 29 import org.chromium.base.annotations.MainDex;
30 import org.chromium.base.metrics.RecordHistogram;
30 import org.chromium.ui.R; 31 import org.chromium.ui.R;
31 import org.chromium.ui.UiUtils; 32 import org.chromium.ui.UiUtils;
32 33
33 import java.io.File; 34 import java.io.File;
34 import java.io.IOException; 35 import java.io.IOException;
35 import java.util.ArrayList; 36 import java.util.ArrayList;
36 import java.util.Arrays; 37 import java.util.Arrays;
37 import java.util.List; 38 import java.util.List;
38 39
39 /** 40 /**
40 * A dialog that is triggered from a file input field that allows a user to sele ct a file based on 41 * A dialog that is triggered from a file input field that allows a user to sele ct a file based on
41 * a set of accepted file types. The path of the selected file is passed to the native dialog. 42 * a set of accepted file types. The path of the selected file is passed to the native dialog.
42 */ 43 */
43 @JNINamespace("ui") 44 @JNINamespace("ui")
44 @MainDex 45 @MainDex
45 public class SelectFileDialog 46 public class SelectFileDialog
46 implements WindowAndroid.IntentCallback, WindowAndroid.PermissionCallbac k { 47 implements WindowAndroid.IntentCallback, WindowAndroid.PermissionCallbac k {
47 private static final String TAG = "SelectFileDialog"; 48 private static final String TAG = "SelectFileDialog";
48 private static final String IMAGE_TYPE = "image/"; 49 private static final String IMAGE_TYPE = "image/";
49 private static final String VIDEO_TYPE = "video/"; 50 private static final String VIDEO_TYPE = "video/";
50 private static final String AUDIO_TYPE = "audio/"; 51 private static final String AUDIO_TYPE = "audio/";
51 private static final String ALL_IMAGE_TYPES = IMAGE_TYPE + "*"; 52 private static final String ALL_IMAGE_TYPES = IMAGE_TYPE + "*";
52 private static final String ALL_VIDEO_TYPES = VIDEO_TYPE + "*"; 53 private static final String ALL_VIDEO_TYPES = VIDEO_TYPE + "*";
53 private static final String ALL_AUDIO_TYPES = AUDIO_TYPE + "*"; 54 private static final String ALL_AUDIO_TYPES = AUDIO_TYPE + "*";
54 private static final String ANY_TYPES = "*/*"; 55 private static final String ANY_TYPES = "*/*";
55 56
56 /** 57 /**
58 * The SELECT_FILE_DIALOG_SCOPE_* enumerations are used to measure the sort of content that
59 * developers are requesting to be shown in the select file dialog. Values m ust be kept in sync
60 * with their definition in //tools/metrics/histograms/histograms.xml.
61 */
62 private static final int SELECT_FILE_DIALOG_SCOPE_GENERIC = 0;
63 private static final int SELECT_FILE_DIALOG_SCOPE_IMAGES = 1;
64 private static final int SELECT_FILE_DIALOG_SCOPE_IMAGES_AND_VIDEO = 2;
65 private static final int SELECT_FILE_DIALOG_SCOPE_MAX =
66 SELECT_FILE_DIALOG_SCOPE_IMAGES_AND_VIDEO;
67
68 /**
57 * If set, overrides the WindowAndroid passed in {@link selectFile()}. 69 * If set, overrides the WindowAndroid passed in {@link selectFile()}.
58 */ 70 */
59 private static WindowAndroid sOverrideWindowAndroid; 71 private static WindowAndroid sOverrideWindowAndroid;
60 72
61 private final long mNativeSelectFileDialog; 73 private final long mNativeSelectFileDialog;
62 private List<String> mFileTypes; 74 private List<String> mFileTypes;
63 private boolean mCapture; 75 private boolean mCapture;
64 private boolean mAllowMultiple; 76 private boolean mAllowMultiple;
65 private Uri mCameraOutputUri; 77 private Uri mCameraOutputUri;
66 private WindowAndroid mWindowAndroid; 78 private WindowAndroid mWindowAndroid;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
167 } else if (captureMicrophone() && soundRecorder != null) { 179 } else if (captureMicrophone() && soundRecorder != null) {
168 if (mWindowAndroid.showIntent(soundRecorder, this, R.string.low_memo ry_error)) return; 180 if (mWindowAndroid.showIntent(soundRecorder, this, R.string.low_memo ry_error)) return;
169 } 181 }
170 182
171 Intent getContentIntent = new Intent(Intent.ACTION_GET_CONTENT); 183 Intent getContentIntent = new Intent(Intent.ACTION_GET_CONTENT);
172 184
173 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && mAllo wMultiple) { 185 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && mAllo wMultiple) {
174 getContentIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); 186 getContentIntent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
175 } 187 }
176 188
189 RecordHistogram.recordEnumeratedHistogram("Android.SelectFileDialogScope ",
190 determineSelectFileDialogScope(), SELECT_FILE_DIALOG_SCOPE_MAX);
191
177 ArrayList<Intent> extraIntents = new ArrayList<Intent>(); 192 ArrayList<Intent> extraIntents = new ArrayList<Intent>();
178 if (!noSpecificType()) { 193 if (!noSpecificType()) {
179 // Create a chooser based on the accept type that was specified in t he webpage. Note 194 // Create a chooser based on the accept type that was specified in t he webpage. Note
180 // that if the web page specified multiple accept types, we will hav e built a generic 195 // that if the web page specified multiple accept types, we will hav e built a generic
181 // chooser above. 196 // chooser above.
182 if (shouldShowImageTypes()) { 197 if (shouldShowImageTypes()) {
183 if (camera != null) extraIntents.add(camera); 198 if (camera != null) extraIntents.add(camera);
184 getContentIntent.setType(ALL_IMAGE_TYPES); 199 getContentIntent.setType(ALL_IMAGE_TYPES);
185 } else if (shouldShowVideoTypes()) { 200 } else if (shouldShowVideoTypes()) {
186 if (camcorder != null) extraIntents.add(camcorder); 201 if (camcorder != null) extraIntents.add(camcorder);
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 return; 363 return;
349 } 364 }
350 } 365 }
351 launchSelectFileIntent(); 366 launchSelectFileIntent();
352 } 367 }
353 368
354 private void onFileNotSelected() { 369 private void onFileNotSelected() {
355 nativeOnFileNotSelected(mNativeSelectFileDialog); 370 nativeOnFileNotSelected(mNativeSelectFileDialog);
356 } 371 }
357 372
373 // Determines the scope of the requested select file dialog for use in a UMA histogram. Right
374 // now we want to distinguish between generic, photo and visual media picker s.
375 private int determineSelectFileDialogScope() {
Miguel Garcia 2017/01/24 18:42:26 So this will log as generic when asking for just v
376 if (!noSpecificType() && !shouldShowAudioTypes() && shouldShowImageTypes ()) {
377 if (shouldShowVideoTypes()) {
378 return SELECT_FILE_DIALOG_SCOPE_IMAGES_AND_VIDEO;
379 } else {
380 return SELECT_FILE_DIALOG_SCOPE_IMAGES;
381 }
382 }
383
384 return SELECT_FILE_DIALOG_SCOPE_GENERIC;
385 }
386
358 private boolean noSpecificType() { 387 private boolean noSpecificType() {
359 // We use a single Intent to decide the type of the file chooser we disp lay to the user, 388 // We use a single Intent to decide the type of the file chooser we disp lay to the user,
360 // which means we can only give it a single type. If there are multiple accept types 389 // which means we can only give it a single type. If there are multiple accept types
361 // specified, we will fallback to a generic chooser (unless a capture pa rameter has been 390 // specified, we will fallback to a generic chooser (unless a capture pa rameter has been
362 // specified, in which case we'll try to satisfy that first. 391 // specified, in which case we'll try to satisfy that first.
363 return mFileTypes.size() != 1 || mFileTypes.contains(ANY_TYPES); 392 return mFileTypes.size() != 1 || mFileTypes.contains(ANY_TYPES);
364 } 393 }
365 394
366 private boolean shouldShowTypes(String allTypes, String specificType) { 395 private boolean shouldShowTypes(String allTypes, String specificType) {
367 if (noSpecificType() || mFileTypes.contains(allTypes)) return true; 396 if (noSpecificType() || mFileTypes.contains(allTypes)) return true;
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
457 private static SelectFileDialog create(long nativeSelectFileDialog) { 486 private static SelectFileDialog create(long nativeSelectFileDialog) {
458 return new SelectFileDialog(nativeSelectFileDialog); 487 return new SelectFileDialog(nativeSelectFileDialog);
459 } 488 }
460 489
461 private native void nativeOnFileSelected(long nativeSelectFileDialogImpl, 490 private native void nativeOnFileSelected(long nativeSelectFileDialogImpl,
462 String filePath, String displayName); 491 String filePath, String displayName);
463 private native void nativeOnMultipleFilesSelected(long nativeSelectFileDialo gImpl, 492 private native void nativeOnMultipleFilesSelected(long nativeSelectFileDialo gImpl,
464 String[] filePathArray, String[] displayNameArray); 493 String[] filePathArray, String[] displayNameArray);
465 private native void nativeOnFileNotSelected(long nativeSelectFileDialogImpl) ; 494 private native void nativeOnFileNotSelected(long nativeSelectFileDialogImpl) ;
466 } 495 }
OLDNEW
« no previous file with comments | « tools/metrics/histograms/histograms.xml ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698