summaryrefslogtreecommitdiff
path: root/mime
diff options
context:
space:
mode:
authorTobias Thierer <tobiast@google.com>2019-09-27 19:22:39 +0100
committerTobias Thierer <tobiast@google.com>2019-09-30 17:10:53 +0100
commit324349142cf3dacf5684bc3664b90ee81363dee1 (patch)
treebb035dc9888b89ff6fa1fd3f011f94cd185f55a0 /mime
parente25c54f3282d64e8a139ab8176859d6ab738ef85 (diff)
Introduce vendor.mime.types
Like mime.types and android.mime.types, this file specifies mappings between MIME types and file extensions. Unlike those files, it can only be used to define _additional_ mapping but not modify (change, remove) any mappings defined by those files. This is done by prepending '?' to every line element from vendor.mime.types that doesn't already have one; when there is a leading "?", it is ignored so that it's okay to move a line from {android,vendor}.mime.types without necessarily changing it. Test: Checked manually that vendor.mime.types works as expected. Specifically, after adding these lines to vendor.mime.type: audio/mpeg testmpeg audio/testmpeg mp3 ?mime/foo ?fooext the following test passes: MimeTypeMap map = MimeTypeMap.getSingleton(); // Original mapping is unchanged assertEquals("mp3", map.getExtensionFromMimeType("audio/mpeg")); assertEquals("audio/mpeg", map.getMimeTypeFromExtension("mp3")); // Map from the key to existing value is added assertEquals("audio/mpeg", map.getMimeTypeFromExtension("testmpeg")); assertEquals("mp3", map.getExtensionFromMimeType("audio/testmpeg")); // Completely new mapping is added both ways assertEquals("mime/foo", map.getMimeTypeFromExtension("fooext")); assertEquals("fooext", map.getExtensionFromMimeType("mime/foo")); Bug: 141842825 Change-Id: Iaf918ce39324709ff58a8e0f9612e4827a673323
Diffstat (limited to 'mime')
-rw-r--r--mime/Android.bp12
-rw-r--r--mime/java-res/vendor.mime.types41
-rw-r--r--mime/java/android/content/type/DefaultMimeMapFactory.java35
3 files changed, 78 insertions, 10 deletions
diff --git a/mime/Android.bp b/mime/Android.bp
index 17bad746e039..0ae94d44061d 100644
--- a/mime/Android.bp
+++ b/mime/Android.bp
@@ -26,6 +26,7 @@ java_library {
java_resources: [
":debian.mime.types",
":android.mime.types",
+ ":vendor.mime.types",
],
sdk_version: "core_platform",
@@ -41,3 +42,14 @@ filegroup {
"java-res/android.mime.types",
],
}
+
+filegroup {
+ name: "vendor.mime.types",
+ visibility: [
+ "//visibility:private",
+ ],
+ path: "java-res/",
+ srcs: [
+ "java-res/vendor.mime.types",
+ ],
+}
diff --git a/mime/java-res/vendor.mime.types b/mime/java-res/vendor.mime.types
new file mode 100644
index 000000000000..afb8f9e4ef39
--- /dev/null
+++ b/mime/java-res/vendor.mime.types
@@ -0,0 +1,41 @@
+###############################################################################
+#
+# Vendor-specific MIME type <-> extension mappings
+#
+# Each line below defines a mapping from one MIME type to the first of the
+# listed extensions, and from listed extension back to the MIME type.
+#
+# This file can _add_ additional mappings that are not in the default set,
+# but it it cannot _modify_ (replace or remove) any platform default mapping
+# (defined in files mime.types and android.mime.types).
+#
+###############################################################################
+#
+# EXAMPLES
+#
+# A line of the form (without the leading '#''):
+#
+# mime ext1 ext2 ext3
+#
+# affects the current mappings along the lines of the following pseudo code:
+#
+# mimeToExt.putIfAbsent("mime", "ext1");
+# extToMime.putIfAbsent("ext1", "mime");
+# extToMime.putIfAbsent("ext2", "mime");
+# extToMime.putIfAbsent("ext3", "mime");
+#
+# Optionally, MIME types or extensions may be prefixed by a single '?', which
+# will be ignored. I.e., the following example lines all have the same semantics:
+#
+# mime ext1 ext2 ext3
+# ?mime ext1 ext2 ext3
+# mime ?ext1 ext2 ?ext3
+# ?mime ?ext1 ?ext2 ?ext3
+#
+# By default, this file contains no mappings (which means that the platform
+# default mapping is used unmodified).
+#
+###############################################################################
+#
+# Add your custom mappings below this line (with no "#" at the start of the line):
+
diff --git a/mime/java/android/content/type/DefaultMimeMapFactory.java b/mime/java/android/content/type/DefaultMimeMapFactory.java
index 545fb3cbb5cd..56b234fe0e1c 100644
--- a/mime/java/android/content/type/DefaultMimeMapFactory.java
+++ b/mime/java/android/content/type/DefaultMimeMapFactory.java
@@ -21,6 +21,7 @@ import libcore.net.MimeMap;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
@@ -44,20 +45,17 @@ public class DefaultMimeMapFactory {
* Android's default mapping between MIME types and extensions.
*/
public static MimeMap create() {
- return parseFromResources("/mime.types", "/android.mime.types");
- }
-
- private static final Pattern SPLIT_PATTERN = Pattern.compile("\\s+");
-
- static MimeMap parseFromResources(String... resourceNames) {
MimeMap.Builder builder = MimeMap.builder();
- for (String resourceName : resourceNames) {
- parseTypes(builder, resourceName);
- }
+ parseTypes(builder, true, "/mime.types");
+ parseTypes(builder, true, "/android.mime.types");
+ parseTypes(builder, false, "/vendor.mime.types");
return builder.build();
}
- private static void parseTypes(MimeMap.Builder builder, String resource) {
+ private static final Pattern SPLIT_PATTERN = Pattern.compile("\\s+");
+
+ private static void parseTypes(MimeMap.Builder builder, boolean allowOverwrite,
+ String resource) {
try (BufferedReader r = new BufferedReader(
new InputStreamReader(DefaultMimeMapFactory.class.getResourceAsStream(resource)))) {
String line;
@@ -71,6 +69,12 @@ public class DefaultMimeMapFactory {
continue;
}
List<String> specs = Arrays.asList(SPLIT_PATTERN.split(line));
+ if (!allowOverwrite) {
+ // Pretend that the mimeType and each file extension listed in the line
+ // carries a "?" prefix, which means that it can add new mappings but
+ // not modify existing mappings (putIfAbsent() semantics).
+ specs = ensurePrefix("?", specs);
+ }
builder.put(specs.get(0), specs.subList(1, specs.size()));
}
} catch (IOException | RuntimeException e) {
@@ -78,4 +82,15 @@ public class DefaultMimeMapFactory {
}
}
+ private static List<String> ensurePrefix(String prefix, List<String> strings) {
+ List<String> result = new ArrayList<>(strings.size());
+ for (String s : strings) {
+ if (!s.startsWith(prefix)) {
+ s = prefix + s;
+ }
+ result.add(s);
+ }
+ return result;
+ }
+
}