summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Tobias Thierer <tobiast@google.com> 2019-09-27 19:22:39 +0100
committer Tobias Thierer <tobiast@google.com> 2019-09-30 17:10:53 +0100
commit324349142cf3dacf5684bc3664b90ee81363dee1 (patch)
treebb035dc9888b89ff6fa1fd3f011f94cd185f55a0
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
-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;
+ }
+
}