aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/com/cyanogenmod/filemanager/activities/SearchActivity.java7
-rw-r--r--src/com/cyanogenmod/filemanager/commands/java/FolderUsageCommand.java7
-rw-r--r--src/com/cyanogenmod/filemanager/commands/secure/FolderUsageCommand.java9
-rw-r--r--src/com/cyanogenmod/filemanager/commands/shell/FolderUsageCommand.java6
-rw-r--r--src/com/cyanogenmod/filemanager/util/AmbiguousExtensionHelper.java86
-rw-r--r--src/com/cyanogenmod/filemanager/util/MimeTypeHelper.java127
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**/}
}