diff options
author | Jorge Ruesga <jorge@ruesga.com> | 2012-11-17 01:56:01 +0100 |
---|---|---|
committer | Jorge Ruesga <jorge@ruesga.com> | 2012-12-11 22:06:02 +0100 |
commit | 0f3469ab6dd245913183484caed16df3bcb15893 (patch) | |
tree | 7e480a40d90b59481589f62f1fb8c5479174a705 /src/com | |
parent | 8936a55df7403b336f0fae12ed1f2d0db2496a7a (diff) | |
download | android_packages_apps_CMFileManager-0f3469ab6dd245913183484caed16df3bcb15893.tar.gz android_packages_apps_CMFileManager-0f3469ab6dd245913183484caed16df3bcb15893.tar.bz2 android_packages_apps_CMFileManager-0f3469ab6dd245913183484caed16df3bcb15893.zip |
CMFileManager: AOSP GET_CONTENT_DATA compatibility
This change brings compatibility to GET_CONTENT_DATA for AOSP apps when
using the PickerActivity:
* Detect crop extra; use the com.android.camera.action.CROP action of Gallery3d
to crop and return the requested image. This gets compatilibity for example with
the contacts app, when a user try to set the image of a contact.
* Detect android.provider.MediaStore.Audio.Media.EXTRA_MAX_BYTES; when this extra
is present the PickerActivity only display (and allow select) files with a size lower
than requested.
* Detect Intent.EXTRA_LOCAL_ONLY; useless until CMFM allow access remote file systems.
Change-Id: I1020458505b236653e869ec1c1f532dd6d686633
Diffstat (limited to 'src/com')
5 files changed, 251 insertions, 31 deletions
diff --git a/src/com/cyanogenmod/filemanager/activities/PickerActivity.java b/src/com/cyanogenmod/filemanager/activities/PickerActivity.java index e4010641..5d3c0336 100644 --- a/src/com/cyanogenmod/filemanager/activities/PickerActivity.java +++ b/src/com/cyanogenmod/filemanager/activities/PickerActivity.java @@ -19,6 +19,7 @@ package com.cyanogenmod.filemanager.activities; import android.app.Activity; import android.app.AlertDialog; import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnCancelListener; @@ -45,6 +46,7 @@ import com.cyanogenmod.filemanager.adapters.CheckableListAdapter; import com.cyanogenmod.filemanager.adapters.CheckableListAdapter.CheckableItem; import com.cyanogenmod.filemanager.console.ConsoleBuilder; import com.cyanogenmod.filemanager.model.FileSystemObject; +import com.cyanogenmod.filemanager.preferences.DisplayRestrictions; import com.cyanogenmod.filemanager.preferences.FileManagerSettings; import com.cyanogenmod.filemanager.preferences.Preferences; import com.cyanogenmod.filemanager.ui.ThemeManager; @@ -60,7 +62,9 @@ import com.cyanogenmod.filemanager.util.StorageHelper; import java.io.File; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * The activity for allow to use a {@link NavigationView} like, to pick a file from other @@ -84,7 +88,22 @@ public class PickerActivity extends Activity } }; - private String mMimeType; + // The result code + private static final int RESULT_CROP_IMAGE = 1; + + // The component that holds the crop operation. We use Gallery3d because we are confidence + // of his input parameters + private static final ComponentName CROP_COMPONENT = + new ComponentName( + "com.android.gallery3d", //$NON-NLS-1$ + "com.android.gallery3d.app.CropImage"); //$NON-NLS-1$ + + // Gallery crop editor action + private static final String ACTION_CROP = "com.android.camera.action.CROP"; //$NON-NLS-1$ + + // Extra data for Gallery CROP action + private static final String EXTRA_CROP = "crop"; //$NON-NLS-1$ + private FileSystemObject mFso; // The picked item private AlertDialog mDialog; private Handler mHandler; @@ -151,14 +170,38 @@ public class PickerActivity extends Activity private void init() { // Check that call has a valid request (GET_CONTENT a and mime type) String action = getIntent().getAction(); - this.mMimeType = getIntent().getType(); - if (action.compareTo(Intent.ACTION_GET_CONTENT.toString()) != 0 || - this.mMimeType == null) { + + if (action.compareTo(Intent.ACTION_GET_CONTENT.toString()) != 0) { setResult(Activity.RESULT_CANCELED); finish(); return; } + // Display restrictions + Map<DisplayRestrictions, Object> restrictions = new HashMap<DisplayRestrictions, Object>(); + //- Mime/Type restriction + String mimeType = getIntent().getType(); + if (mimeType != null) { + restrictions.put(DisplayRestrictions.MIME_TYPE_RESTRICTION, mimeType); + } + // Other restrictions + Bundle extras = getIntent().getExtras(); + if (extras != null) { + //-- File size + if (extras.containsKey(android.provider.MediaStore.Audio.Media.EXTRA_MAX_BYTES)) { + long size = + extras.getLong(android.provider.MediaStore.Audio.Media.EXTRA_MAX_BYTES); + restrictions.put(DisplayRestrictions.SIZE_RESTRICTION, Long.valueOf(size)); + } + //-- Local filesystems only + if (extras.containsKey(Intent.EXTRA_LOCAL_ONLY)) { + boolean localOnly = extras.getBoolean(Intent.EXTRA_LOCAL_ONLY); + restrictions.put( + DisplayRestrictions.LOCAL_FILESYSTEM_ONLY_RESTRICTION, + Boolean.valueOf(localOnly)); + } + } + // Create or use the console if (!initializeConsole()) { // Something when wrong. Display a message and exit @@ -187,7 +230,7 @@ public class PickerActivity extends Activity // Navigation view this.mNavigationView = (NavigationView)this.mRootView.findViewById(R.id.navigation_view); - this.mNavigationView.setMimeType(this.mMimeType); + this.mNavigationView.setRestrictions(restrictions); this.mNavigationView.setOnFilePickedListener(this); this.mNavigationView.setBreadcrumb(breadcrumb); @@ -269,12 +312,64 @@ public class PickerActivity extends Activity * {@inheritDoc} */ @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case RESULT_CROP_IMAGE: + // Return what the callee activity returns + setResult(resultCode, data); + finish(); + return; + + default: + break; + } + + // The response is not understood + Log.w(TAG, + String.format( + "Ignore response. requestCode: %s, resultCode: %s, data: %s", //$NON-NLS-1$ + Integer.valueOf(requestCode), + Integer.valueOf(resultCode), + data)); + DialogHelper.showToast(this, R.string.msgs_operation_failure, Toast.LENGTH_SHORT); + } + + /** + * {@inheritDoc} + */ + @Override public void onDismiss(DialogInterface dialog) { if (this.mFso != null) { + File src = new File(this.mFso.getFullPath()); + if (getIntent().getExtras() != null) { + // Some AOSP applications use the gallery to edit and crop the selected image + // with the Gallery crop editor. In this case pass the picked file to the + // CropActivity with the requested parameters + // Expected result is on onActivityResult + Bundle extras = getIntent().getExtras(); + String crop = extras.getString(EXTRA_CROP); + if (Boolean.parseBoolean(crop)) { + // We want to use the Gallery3d activity because we know about it, and his + // parameters. At least we have a compatible one. + Intent intent = new Intent(ACTION_CROP); + if (getIntent().getType() != null) { + intent.setType(getIntent().getType()); + } + intent.setData(Uri.fromFile(src)); + intent.putExtras(extras); + intent.setComponent(CROP_COMPONENT); + startActivityForResult(intent, RESULT_CROP_IMAGE); + return; + } + } + + // Return the picked file, as expected (this activity should fill the intent data + // and return RESULT_OK result) Intent result = new Intent(); - result.setData(Uri.fromFile(new File(this.mFso.getFullPath()))); + result.setData(Uri.fromFile(src)); setResult(Activity.RESULT_OK, result); finish(); + } else { cancel(); } diff --git a/src/com/cyanogenmod/filemanager/preferences/DisplayRestrictions.java b/src/com/cyanogenmod/filemanager/preferences/DisplayRestrictions.java new file mode 100644 index 00000000..2525ade4 --- /dev/null +++ b/src/com/cyanogenmod/filemanager/preferences/DisplayRestrictions.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2012 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.cyanogenmod.filemanager.preferences; + +/** + * An enumeration of the restrictions that can be applied when displaying list of files. + */ +public enum DisplayRestrictions { + /** + * Restriction for display only files with the category. + */ + CATEGORY_TYPE_RESTRICTION, + /** + * Restriction for display only files with the mime/type. + */ + MIME_TYPE_RESTRICTION, + /** + * Restriction for display only files with a size lower than the specified + */ + SIZE_RESTRICTION, + /** + * Restriction for display only files from the local file system. Avoid remote files. + */ + LOCAL_FILESYSTEM_ONLY_RESTRICTION +} diff --git a/src/com/cyanogenmod/filemanager/tasks/SearchResultDrawingAsyncTask.java b/src/com/cyanogenmod/filemanager/tasks/SearchResultDrawingAsyncTask.java index df91b877..c53d59c6 100644 --- a/src/com/cyanogenmod/filemanager/tasks/SearchResultDrawingAsyncTask.java +++ b/src/com/cyanogenmod/filemanager/tasks/SearchResultDrawingAsyncTask.java @@ -28,6 +28,7 @@ import com.cyanogenmod.filemanager.model.FileSystemObject; import com.cyanogenmod.filemanager.model.Query; import com.cyanogenmod.filemanager.model.SearchResult; import com.cyanogenmod.filemanager.preferences.AccessMode; +import com.cyanogenmod.filemanager.preferences.DisplayRestrictions; import com.cyanogenmod.filemanager.preferences.FileManagerSettings; import com.cyanogenmod.filemanager.preferences.NavigationSortMode; import com.cyanogenmod.filemanager.preferences.ObjectStringIdentifier; @@ -40,7 +41,9 @@ import com.cyanogenmod.filemanager.util.SearchHelper; import java.util.Collections; import java.util.Comparator; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * A class for paint the resulting file system object of a search. @@ -112,11 +115,17 @@ public class SearchResultDrawingAsyncTask extends AsyncTask<Object, Integer, Boo boolean chRooted = FileManagerApplication.getAccessMode().compareTo(AccessMode.SAFE) == 0; + // Create display restrictions + Map<DisplayRestrictions, Object> restrictions = + new HashMap<DisplayRestrictions, Object>(); + restrictions.put( + DisplayRestrictions.MIME_TYPE_RESTRICTION, MimeTypeHelper.ALL_MIME_TYPES); + //Process all the data final List<SearchResult> result = SearchHelper.convertToResults( FileHelper.applyUserPreferences( - this.mFiles, MimeTypeHelper.ALL_MIME_TYPES, true, chRooted), + this.mFiles, restrictions, true, chRooted), this.mQueries); if (mode.compareTo(SearchSortResultMode.NAME) == 0) { Collections.sort(result, new Comparator<SearchResult>() { diff --git a/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java b/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java index 24b1af59..dd15c7ef 100644 --- a/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java +++ b/src/com/cyanogenmod/filemanager/ui/widgets/NavigationView.java @@ -46,6 +46,7 @@ import com.cyanogenmod.filemanager.model.Symlink; import com.cyanogenmod.filemanager.parcelables.NavigationViewInfoParcelable; import com.cyanogenmod.filemanager.parcelables.SearchInfoParcelable; import com.cyanogenmod.filemanager.preferences.AccessMode; +import com.cyanogenmod.filemanager.preferences.DisplayRestrictions; import com.cyanogenmod.filemanager.preferences.FileManagerSettings; import com.cyanogenmod.filemanager.preferences.NavigationLayoutMode; import com.cyanogenmod.filemanager.preferences.ObjectIdentifier; @@ -60,11 +61,12 @@ import com.cyanogenmod.filemanager.util.CommandHelper; import com.cyanogenmod.filemanager.util.DialogHelper; import com.cyanogenmod.filemanager.util.ExceptionUtil; import com.cyanogenmod.filemanager.util.FileHelper; -import com.cyanogenmod.filemanager.util.MimeTypeHelper; import com.cyanogenmod.filemanager.util.StorageHelper; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * The file manager implementation view (contains the graphical representation and the input @@ -204,7 +206,8 @@ public class NavigationView extends RelativeLayout implements private NAVIGATION_MODE mNavigationMode; - private String mMimeType = MimeTypeHelper.ALL_MIME_TYPES; + // Restrictions + private Map<DisplayRestrictions, Object> mRestrictions; /** * @hide @@ -318,6 +321,9 @@ public class NavigationView extends RelativeLayout implements this.mNavigationMode = NAVIGATION_MODE.values()[mode]; } + // Initialize default restrictions (no restrictions) + this.mRestrictions = new HashMap<DisplayRestrictions, Object>(); + //Initialize variables this.mFiles = new ArrayList<FileSystemObject>(); @@ -345,23 +351,21 @@ public class NavigationView extends RelativeLayout implements } /** - * Method that returns the mime/type used by this class. Only the files with this mime/type - * are shown. + * Method that returns the display restrictions to apply to this view. * - * @return String The mime/type + * @return Map<DisplayRestrictions, Object> The restrictions to apply */ - public String getMimeType() { - return this.mMimeType; + public Map<DisplayRestrictions, Object> getRestrictions() { + return this.mRestrictions; } /** - * Method that sets the mime/type used by this class. Only the files with this mime/type - * are shown. + * Method that sets the display restrictions to apply to this view. * - * @param mimeType String The mime/type + * @param mRestrictions The restrictions to apply */ - public void setMimeType(String mimeType) { - this.mMimeType = mimeType; + public void setRestrictions(Map<DisplayRestrictions, Object> mRestrictions) { + this.mRestrictions = mRestrictions; } /** @@ -888,7 +892,7 @@ public class NavigationView extends RelativeLayout implements //Apply user preferences List<FileSystemObject> sortedFiles = - FileHelper.applyUserPreferences(files, this.mMimeType, this.mChRooted); + FileHelper.applyUserPreferences(files, this.mRestrictions, this.mChRooted); //Remove parent directory if we are in the root of a chrooted environment if (this.mChRooted && StorageHelper.isStorageVolume(newDir)) { diff --git a/src/com/cyanogenmod/filemanager/util/FileHelper.java b/src/com/cyanogenmod/filemanager/util/FileHelper.java index bd904979..f4f3612e 100644 --- a/src/com/cyanogenmod/filemanager/util/FileHelper.java +++ b/src/com/cyanogenmod/filemanager/util/FileHelper.java @@ -16,6 +16,7 @@ package com.cyanogenmod.filemanager.util; +import android.annotation.SuppressLint; import android.content.Context; import android.content.SharedPreferences; import android.content.res.Resources; @@ -39,10 +40,12 @@ import com.cyanogenmod.filemanager.model.RegularFile; import com.cyanogenmod.filemanager.model.Symlink; import com.cyanogenmod.filemanager.model.SystemFile; import com.cyanogenmod.filemanager.model.User; +import com.cyanogenmod.filemanager.preferences.DisplayRestrictions; import com.cyanogenmod.filemanager.preferences.FileManagerSettings; import com.cyanogenmod.filemanager.preferences.NavigationSortMode; import com.cyanogenmod.filemanager.preferences.ObjectIdentifier; import com.cyanogenmod.filemanager.preferences.Preferences; +import com.cyanogenmod.filemanager.util.MimeTypeHelper.MimeTypeCategory; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -53,7 +56,9 @@ import java.io.IOException; import java.util.Collections; import java.util.Comparator; import java.util.Date; +import java.util.Iterator; import java.util.List; +import java.util.Map; /** * A helper class with useful methods for deal with files. @@ -156,6 +161,7 @@ public final class FileHelper { * @param size The size in bytes * @return String The human readable size */ + @SuppressLint("DefaultLocale") public static String getHumanReadableSize(long size) { Resources res = FileManagerApplication.getInstance().getResources(); final String format = "%d %s"; //$NON-NLS-1$ @@ -458,13 +464,14 @@ public final class FileHelper { * (sort mode, hidden files, ...). * * @param files The listed files - * @param mimeType The mime-type to apply. if null returns all. + * @param restrictions The restrictions to apply when displaying files * @param chRooted If app run with no privileges * @return List<FileSystemObject> The applied mode listed files */ public static List<FileSystemObject> applyUserPreferences( - List<FileSystemObject> files, String mimeType, boolean chRooted) { - return applyUserPreferences(files, mimeType, false, chRooted); + List<FileSystemObject> files, Map<DisplayRestrictions, + Object> restrictions, boolean chRooted) { + return applyUserPreferences(files, restrictions, false, chRooted); } /** @@ -472,13 +479,14 @@ public final class FileHelper { * (sort mode, hidden files, ...). * * @param files The listed files - * @param mimeType The mime-type to apply. if null returns all. + * @param restrictions The restrictions to apply when displaying files * @param noSort If sort must be applied * @param chRooted If app run with no privileges * @return List<FileSystemObject> The applied mode listed files */ public static List<FileSystemObject> applyUserPreferences( - List<FileSystemObject> files, String mimeType, boolean noSort, boolean chRooted) { + List<FileSystemObject> files, Map<DisplayRestrictions, Object> restrictions, + boolean noSort, boolean chRooted) { //Retrieve user preferences SharedPreferences prefs = Preferences.getSharedPreferences(); FileManagerSettings sortModePref = FileManagerSettings.SETTINGS_SORT_MODE; @@ -522,12 +530,10 @@ public final class FileHelper { } } - //Mime/Type - if (chRooted && !isDirectory(file)) { - if (mimeType != null && mimeType.compareTo(MimeTypeHelper.ALL_MIME_TYPES) != 0) { - // NOTE: We don't need the context here, because mime-type database should - // be loaded prior to this call - if (!MimeTypeHelper.matchesMimeType(null, file, mimeType)) { + // Restrictions (only apply to files) + if (restrictions != null) { + if (!isDirectory(file)) { + if (!isDisplayAllowed(file, restrictions)) { files.remove(i); continue; } @@ -583,6 +589,73 @@ public final class FileHelper { } /** + * Method that check if a file should be displayed according to the restrictions + * + * @param fso The file system object to check + * @param restrictions The restrictions map + * @return boolean If the file should be displayed + */ + private static boolean isDisplayAllowed( + FileSystemObject fso, Map<DisplayRestrictions, Object> restrictions) { + Iterator<DisplayRestrictions> it = restrictions.keySet().iterator(); + while (it.hasNext()) { + DisplayRestrictions restriction = it.next(); + Object value = restrictions.get(restriction); + if (value == null) { + continue; + } + switch (restriction) { + case CATEGORY_TYPE_RESTRICTION: + if (value instanceof MimeTypeCategory) { + MimeTypeCategory cat1 = (MimeTypeCategory)value; + // NOTE: We don't need the context here, because mime-type + // database should be loaded prior to this call + MimeTypeCategory cat2 = MimeTypeHelper.getCategory(null, fso); + if (cat1.compareTo(cat2) != 0) { + return false; + } + } + break; + + case MIME_TYPE_RESTRICTION: + if (value instanceof String) { + String mimeType = (String)value; + if (mimeType.compareTo(MimeTypeHelper.ALL_MIME_TYPES) != 0) { + // NOTE: We don't need the context here, because mime-type + // database should be loaded prior to this call + if (!MimeTypeHelper.matchesMimeType(null, fso, mimeType)) { + return false; + } + } + } + break; + + case SIZE_RESTRICTION: + if (value instanceof Long) { + Long maxSize = (Long)value; + if (fso.getSize() > maxSize.longValue()) { + return false; + } + } + break; + + case LOCAL_FILESYSTEM_ONLY_RESTRICTION: + if (value instanceof Boolean) { + Boolean localOnly = (Boolean)value; + if (localOnly.booleanValue()) { + /** TODO Needed when CMFM gets networking **/ + } + } + break; + + default: + break; + } + } + return true; + } + + /** * Method that resolve the symbolic links of the list of files passed as argument.<br /> * This method invokes the {@link ResolveLinkCommand} in those files that hasn't a valid * symlink reference |