diff options
Diffstat (limited to 'src')
6 files changed, 216 insertions, 26 deletions
diff --git a/src/com/cyanogenmod/filemanager/activities/SearchActivity.java b/src/com/cyanogenmod/filemanager/activities/SearchActivity.java index 615e6ce..f89c2ee 100644 --- a/src/com/cyanogenmod/filemanager/activities/SearchActivity.java +++ b/src/com/cyanogenmod/filemanager/activities/SearchActivity.java @@ -1025,7 +1025,7 @@ public class SearchActivity extends Activity // all of the video files in the current search will also be sent as an extra in the // intent along with the item that was clicked MimeTypeCategory fileCategory = MimeTypeHelper.getCategoryFromExt(this, - FileHelper.getExtension(fso)); + FileHelper.getExtension(fso), fso.getFullPath()); if (fileCategory == MimeTypeCategory.VIDEO) { ArrayList<FileSystemObject> filteredList = filterSearchResults(fileCategory); @@ -1075,8 +1075,9 @@ public class SearchActivity extends Activity if (mAdapter.getCount() < 1) return filteredList; for (FileSystemObject fso : mAdapter.getFiles()) { - if (MimeTypeHelper.getCategoryFromExt(this, FileHelper.getExtension(fso)) - == category) { + if (MimeTypeHelper.getCategoryFromExt(this, + FileHelper.getExtension(fso), + fso.getFullPath()) == category) { filteredList.add(fso); } } diff --git a/src/com/cyanogenmod/filemanager/commands/java/FolderUsageCommand.java b/src/com/cyanogenmod/filemanager/commands/java/FolderUsageCommand.java index c201dfb..d15c5dc 100644 --- a/src/com/cyanogenmod/filemanager/commands/java/FolderUsageCommand.java +++ b/src/com/cyanogenmod/filemanager/commands/java/FolderUsageCommand.java @@ -24,6 +24,7 @@ import com.cyanogenmod.filemanager.console.ExecutionException; import com.cyanogenmod.filemanager.console.InsufficientPermissionsException; import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory; import com.cyanogenmod.filemanager.model.FolderUsage; +import com.cyanogenmod.filemanager.util.FileHelper; import com.cyanogenmod.filemanager.util.MimeTypeHelper; import com.cyanogenmod.filemanager.util.MimeTypeHelper.MimeTypeCategory; @@ -149,8 +150,12 @@ public class FolderUsageCommand extends Program implements FolderUsageExecutable } else { this.mFolderUsage.addFile(); // Compute statistics and size + File file = files[i]; + String ext = FileHelper.getExtension(file.getName()); MimeTypeCategory category = - MimeTypeHelper.getCategory(null, files[i]); + MimeTypeHelper.getCategoryFromExt(null, + ext, + file.getAbsolutePath()); this.mFolderUsage.addFileToCategory(category); this.mFolderUsage.addSize(files[i].length()); } diff --git a/src/com/cyanogenmod/filemanager/commands/secure/FolderUsageCommand.java b/src/com/cyanogenmod/filemanager/commands/secure/FolderUsageCommand.java index 5049a01..ad5412e 100644 --- a/src/com/cyanogenmod/filemanager/commands/secure/FolderUsageCommand.java +++ b/src/com/cyanogenmod/filemanager/commands/secure/FolderUsageCommand.java @@ -24,11 +24,14 @@ import com.cyanogenmod.filemanager.console.ExecutionException; import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory; import com.cyanogenmod.filemanager.console.secure.SecureConsole; import com.cyanogenmod.filemanager.model.FolderUsage; +import com.cyanogenmod.filemanager.util.FileHelper; import com.cyanogenmod.filemanager.util.MimeTypeHelper; import com.cyanogenmod.filemanager.util.MimeTypeHelper.MimeTypeCategory; import de.schlichtherle.truezip.file.TFile; +import java.io.File; + /** * A class for retrieve the disk usage of a folder. */ @@ -149,8 +152,12 @@ public class FolderUsageCommand extends Program implements FolderUsageExecutable } else { this.mFolderUsage.addFile(); // Compute statistics and size + File file = files[i]; + String ext = FileHelper.getExtension(file.getName()); MimeTypeCategory category = - MimeTypeHelper.getCategory(null, files[i]); + MimeTypeHelper.getCategoryFromExt(null, + ext, + file.getAbsolutePath()); this.mFolderUsage.addFileToCategory(category); this.mFolderUsage.addSize(files[i].length()); } diff --git a/src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommand.java b/src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommand.java index 6555381..134a3e3 100644 --- a/src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommand.java +++ b/src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommand.java @@ -36,6 +36,7 @@ import com.cyanogenmod.filemanager.util.MimeTypeHelper; import com.cyanogenmod.filemanager.util.MimeTypeHelper.MimeTypeCategory; import java.io.BufferedReader; +import java.io.File; import java.io.StringReader; import java.util.ArrayList; import java.util.List; @@ -174,8 +175,11 @@ public class FolderUsageCommand extends AsyncResultProgram implements FolderUsag long size = Long.parseLong(fields[4]); String name = fields[fields.length-1];// We only need the extension String ext = FileHelper.getExtension(name); + File file = new File(mDirectory, name); MimeTypeCategory category = - MimeTypeHelper.getCategoryFromExt(null, ext); + MimeTypeHelper.getCategoryFromExt(null, + ext, + file.getAbsolutePath()); this.mFolderUsage.addFile(); this.mFolderUsage.addFileToCategory(category); this.mFolderUsage.addSize(size); diff --git a/src/com/cyanogenmod/filemanager/util/AmbiguousExtensionHelper.java b/src/com/cyanogenmod/filemanager/util/AmbiguousExtensionHelper.java new file mode 100644 index 0000000..567ae5d --- /dev/null +++ b/src/com/cyanogenmod/filemanager/util/AmbiguousExtensionHelper.java @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2015 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.util; + +import android.media.MediaMetadataRetriever; +import java.util.HashMap; + +/** + * Provides the ability to determine the mimetype of a known file extension that can support + * multiple mimetypes. + */ +public abstract class AmbiguousExtensionHelper { + /** + * All available ambiguous extension helpers. + */ + public static final HashMap<String, AmbiguousExtensionHelper> AMBIGUOUS_EXTENSIONS_MAP = new + HashMap<String, AmbiguousExtensionHelper>(); + + static { + addAmbiguousHelperToMap(new ThreeGPExtensionHelper()); + } + + public abstract String getMimeType(String absolutePath, String extension); + public abstract String[] getSupportedExtensions(); + + private static void addAmbiguousHelperToMap(AmbiguousExtensionHelper instance) { + for(String extension : instance.getSupportedExtensions()) { + AmbiguousExtensionHelper.AMBIGUOUS_EXTENSIONS_MAP.put(extension, instance); + } + } + + /** + * An AmbiguousExtensionHelper subclass that can distinguish the mimetype of a given + * .g3p, .g3pp, .3g2 or .3gpp2 file. The 3GP and 3G2 file formats support both audio and + * video, and a file with that extension has the possibility of multiple mimetypes, depending + * on the content of the file. + */ + public static class ThreeGPExtensionHelper extends AmbiguousExtensionHelper { + private static final String[] sSupportedExtensions = {"3gp", "3gpp", "3g2", "3gpp2"}; + public static final String VIDEO_3GPP_MIME_TYPE = "video/3gpp"; + public static final String AUDIO_3GPP_MIME_TYPE = "audio/3gpp"; + public static final String VIDEO_3GPP2_MIME_TYPE = "video/3gpp2"; + public static final String AUDIO_3GPP2_MIME_TYPE = "audio/3gpp2"; + + @Override + public String getMimeType(String absolutePath, String extension) { + MediaMetadataRetriever retriever = new MediaMetadataRetriever(); + retriever.setDataSource(absolutePath); + boolean hasVideo = + retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO) != null; + if (is3GPP(extension)) { + return hasVideo ? VIDEO_3GPP_MIME_TYPE : AUDIO_3GPP_MIME_TYPE; + } else if (is3GPP2(extension)) { + return hasVideo ? VIDEO_3GPP2_MIME_TYPE : AUDIO_3GPP2_MIME_TYPE; + } + return null; + } + + @Override + public String[] getSupportedExtensions() { + return sSupportedExtensions; + } + + private boolean is3GPP(String ext) { + return "3gp".equals(ext) || "3gpp".equals(ext); + } + + private boolean is3GPP2(String ext) { + return "3g2".equals(ext) || "3gpp2".equals(ext); + } + } +} diff --git a/src/com/cyanogenmod/filemanager/util/MimeTypeHelper.java b/src/com/cyanogenmod/filemanager/util/MimeTypeHelper.java index 34563db..3687462 100644 --- a/src/com/cyanogenmod/filemanager/util/MimeTypeHelper.java +++ b/src/com/cyanogenmod/filemanager/util/MimeTypeHelper.java @@ -33,6 +33,7 @@ import com.cyanogenmod.filemanager.model.Symlink; import com.cyanogenmod.filemanager.model.SystemFile; import java.io.File; +import java.util.ArrayList; import java.util.Enumeration; import java.util.HashMap; import java.util.Locale; @@ -212,7 +213,11 @@ public final class MimeTypeHelper { */ public static final String ALL_MIME_TYPES = "*/*"; //$NON-NLS-1$ - private static Map<String, MimeTypeInfo> sMimeTypes; + private static Map<String, ArrayList<MimeTypeInfo>> sMimeTypes; + /** + * Maps from a combination key of <extension> + <mimetype> to MimeTypeInfo objects. + */ + private static HashMap<String, MimeTypeInfo> sExtensionMimeTypes; /** * Constructor of <code>MimeTypeHelper</code>. @@ -239,10 +244,12 @@ public final class MimeTypeHelper { return false; } - for (MimeTypeInfo info : sMimeTypes.values()) { - String mimeTypeRegExp = convertToRegExp(mimeType); - if (info.mMimeType.matches(mimeTypeRegExp)) { - return true; + for (ArrayList<MimeTypeInfo> mimeTypeInfoList : sMimeTypes.values()) { + for (MimeTypeInfo info : mimeTypeInfoList) { + String mimeTypeRegExp = convertToRegExp(mimeType); + if (info.mMimeType.matches(mimeTypeRegExp)) { + return true; + } } } @@ -281,7 +288,8 @@ public final class MimeTypeHelper { //Get the extension and delivery String ext = FileHelper.getExtension(fso); if (ext != null) { - MimeTypeInfo mimeTypeInfo = sMimeTypes.get(ext.toLowerCase(Locale.ROOT)); + MimeTypeInfo mimeTypeInfo = getMimeTypeInternal(fso, ext); + if (mimeTypeInfo != null) { // Create a new drawable if (!TextUtils.isEmpty(mimeTypeInfo.mDrawable)) { @@ -398,14 +406,74 @@ public final class MimeTypeHelper { return res.getString(R.string.mime_unknown); } + /** + * Gets the mimetype of a file, if there are multiple possibilities given it's extension. + * @param absolutePath The absolute path of the file for which to find the mimetype. + * @param ext The extension of the file. + * @return The correct mimetype for this file, or null if the mimetype cannot be determined + * or is not ambiguous. + */ + private static final String getAmbiguousExtensionMimeType(String absolutePath, String ext) { + if (AmbiguousExtensionHelper.AMBIGUOUS_EXTENSIONS_MAP.containsKey(ext)) { + AmbiguousExtensionHelper helper = + AmbiguousExtensionHelper.AMBIGUOUS_EXTENSIONS_MAP.get(ext); + String mimeType = helper.getMimeType(absolutePath, ext); + if (!TextUtils.isEmpty(mimeType)) { + return mimeType; + } + } + return null; + } + + /** + * Get the MimeTypeInfo that describes this file. + * @param fso The file. + * @param ext The extension of the file. + * @return The MimeTypeInfo object that describes this file, or null if it cannot be retrieved. + */ + private static final MimeTypeInfo getMimeTypeInternal(FileSystemObject fso, String ext) { + return getMimeTypeInternal(fso.getFullPath(), ext); + } + /** + * Get the MimeTypeInfo that describes this file. + * @param absolutePath The absolute path of the file. + * @param ext The extension of the file. + * @return The MimeTypeInfo object that describes this file, or null if it cannot be retrieved. + */ + private static final MimeTypeInfo getMimeTypeInternal(String absolutePath, String ext) { + MimeTypeInfo mimeTypeInfo = null; + ArrayList<MimeTypeInfo> mimeTypeInfoList = sMimeTypes.get(ext.toLowerCase(Locale.ROOT)); + // Multiple mimetypes map to the same extension, try to resolve it. + if (mimeTypeInfoList != null && mimeTypeInfoList.size() > 1) { + if (absolutePath != null) { + String mimeType = getAmbiguousExtensionMimeType(absolutePath, ext); + mimeTypeInfo = sExtensionMimeTypes.get(ext + mimeType); + } else { + // We don't have the ability to read the file to resolve the ambiguity, + // so default to the first available mimetype. + mimeTypeInfo = mimeTypeInfoList.get(0); + } + } else if (mimeTypeInfoList != null && mimeTypeInfoList.size() == 1) { + // Only one possible mimetype, so pick that one. + mimeTypeInfo = mimeTypeInfoList.get(0); + } + return mimeTypeInfo; + } + private static final String getMimeTypeFromExtension(final FileSystemObject fso) { String ext = FileHelper.getExtension(fso); if (ext == null) { return null; } + // If this extension is ambiguous, attempt to resolve it. + String mimeType = getAmbiguousExtensionMimeType(fso.getFullPath(), ext); + if (mimeType != null) { + return mimeType; + } + //Load from the database of mime types - MimeTypeInfo mimeTypeInfo = sMimeTypes.get(ext.toLowerCase(Locale.ROOT)); + MimeTypeInfo mimeTypeInfo = getMimeTypeInternal(fso, ext); if (mimeTypeInfo == null) { return null; } @@ -418,9 +486,11 @@ public final class MimeTypeHelper { * * @param context The current context * @param ext The extension of the file + * @param absolutePath The absolute path of the file. Can be null if not available. * @return MimeTypeCategory The mime/type category */ - public static final MimeTypeCategory getCategoryFromExt(Context context, String ext) { + public static final MimeTypeCategory getCategoryFromExt(Context context, String ext, + String absolutePath) { // Ensure that have a context if (context == null && sMimeTypes == null) { // No category @@ -432,7 +502,7 @@ public final class MimeTypeHelper { } if (ext != null) { //Load from the database of mime types - MimeTypeInfo mimeTypeInfo = sMimeTypes.get(ext.toLowerCase(Locale.ROOT)); + MimeTypeInfo mimeTypeInfo = getMimeTypeInternal(absolutePath, ext); if (mimeTypeInfo != null) { return mimeTypeInfo.mCategory; } @@ -466,7 +536,9 @@ public final class MimeTypeHelper { } //Get the extension and delivery - return getCategoryFromExt(context, FileHelper.getExtension(file.getName())); + return getCategoryFromExt(context, + FileHelper.getExtension(file.getName()), + file.getAbsolutePath()); } /** @@ -497,7 +569,7 @@ public final class MimeTypeHelper { //Get the extension and delivery final MimeTypeCategory category = getCategoryFromExt(context, - FileHelper.getExtension(fso)); + FileHelper.getExtension(fso), fso.getFullPath()); // Check system file if (category == MimeTypeCategory.NONE && fso instanceof SystemFile) { @@ -558,20 +630,35 @@ public final class MimeTypeHelper { // Parse the properties to an in-memory structure // Format: <extension> = <category> | <mime type> | <drawable> - sMimeTypes = new HashMap<String, MimeTypeInfo>(mimeTypes.size()); + sMimeTypes = new HashMap<String, ArrayList<MimeTypeInfo>>(); + sExtensionMimeTypes = new HashMap<String, MimeTypeInfo>(); Enumeration<Object> e = mimeTypes.keys(); while (e.hasMoreElements()) { try { String extension = (String)e.nextElement(); String data = mimeTypes.getProperty(extension); - String[] mimeData = data.split("\\|"); //$NON-NLS-1$ - - // Create a reference of MimeType - MimeTypeInfo mimeTypeInfo = new MimeTypeInfo(); - mimeTypeInfo.mCategory = MimeTypeCategory.valueOf(mimeData[0].trim()); - mimeTypeInfo.mMimeType = mimeData[1].trim(); - mimeTypeInfo.mDrawable = mimeData[2].trim(); - sMimeTypes.put(extension, mimeTypeInfo); + String[] datas = data.split(","); + for (String theData : datas) { + String[] mimeData = theData.split("\\|"); //$NON-NLS-1$ + + // Create a reference of MimeType + MimeTypeInfo mimeTypeInfo = new MimeTypeInfo(); + mimeTypeInfo.mCategory = MimeTypeCategory.valueOf(mimeData[0].trim()); + mimeTypeInfo.mMimeType = mimeData[1].trim(); + mimeTypeInfo.mDrawable = mimeData[2].trim(); + + // If no list exists yet for this mimetype, create one. + // Else, add it to the existing list. + if (sMimeTypes.get(extension) == null) { + ArrayList<MimeTypeInfo> infoList = new ArrayList<MimeTypeInfo>(); + infoList.add(mimeTypeInfo); + sMimeTypes.put(extension, infoList); + } else { + sMimeTypes.get(extension).add(mimeTypeInfo); + } + sExtensionMimeTypes.put(extension + mimeTypeInfo.mMimeType, + mimeTypeInfo); + } } catch (Exception e2) { /**NON BLOCK**/} } |
