summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTobias Thierer <tobiast@google.com>2019-09-30 09:15:53 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2019-09-30 09:15:53 +0000
commit6ed8fce33fde155b04262e839a1b6c64e61ae882 (patch)
treed49b3e778e95e71e7d3a7b4e9ec745f1387e01eb
parent417aed2c6148770ecc6e3022d0702d107de87ffe (diff)
parentaf0cef987da359955023fde97f0f4c7444fd5e76 (diff)
Merge changes from topics "bug136256059_attempt2", "bug136256059_builder"
* changes: MimeMapImpl.createDefaultInstance() -> DefaultMimeMapFactory.create(). Make MimeMap final and introduce MimeMap.Builder. Move default MimeMap implementation to frameworks.
-rw-r--r--Android.bp14
-rw-r--r--core/java/com/android/internal/os/RuntimeInit.java11
-rw-r--r--mime/Android.bp43
-rw-r--r--mime/java-res/android.mime.types146
-rw-r--r--mime/java/android/content/type/DefaultMimeMapFactory.java81
5 files changed, 294 insertions, 1 deletions
diff --git a/Android.bp b/Android.bp
index 75773535610f..05675df20575 100644
--- a/Android.bp
+++ b/Android.bp
@@ -112,6 +112,14 @@ filegroup {
}
filegroup {
+ name: "framework-mime-sources",
+ srcs: [
+ "mime/java/**/*.java",
+ ],
+ path: "mime/java",
+}
+
+filegroup {
name: "framework-opengl-sources",
srcs: [
"opengl/java/**/*.java",
@@ -176,6 +184,7 @@ filegroup {
":framework-mca-effect-sources",
":framework-mca-filterfw-sources",
":framework-mca-filterpacks-sources",
+ ":framework-mime-sources",
":framework-opengl-sources",
":framework-rs-sources",
":framework-sax-sources",
@@ -310,7 +319,10 @@ java_defaults {
jarjar_rules: ":framework-jarjar-rules",
- static_libs: ["framework-internal-utils"],
+ static_libs: [
+ "framework-internal-utils",
+ "mimemap",
+ ],
required: [
// TODO: remove gps_debug when the build system propagates "required" properly.
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index d6caa0930243..9fff447c2478 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -20,6 +20,7 @@ import android.annotation.UnsupportedAppUsage;
import android.app.ActivityManager;
import android.app.ActivityThread;
import android.app.ApplicationErrorReport;
+import android.content.type.DefaultMimeMapFactory;
import android.os.Build;
import android.os.DeadObjectException;
import android.os.Debug;
@@ -33,6 +34,9 @@ import com.android.internal.logging.AndroidConfig;
import com.android.server.NetworkManagementSocketTagger;
import dalvik.system.RuntimeHooks;
import dalvik.system.VMRuntime;
+
+import libcore.net.MimeMap;
+
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
@@ -199,6 +203,13 @@ public class RuntimeInit {
public static void preForkInit() {
if (DEBUG) Slog.d(TAG, "Entered preForkInit.");
RuntimeInit.enableDdms();
+ /*
+ * Replace libcore's minimal default mapping between MIME types and file
+ * extensions with a mapping that's suitable for Android. Android's mapping
+ * contains many more entries that are derived from IANA registrations but
+ * with several customizations (extensions, overrides).
+ */
+ MimeMap.setDefault(DefaultMimeMapFactory.create());
}
@UnsupportedAppUsage
diff --git a/mime/Android.bp b/mime/Android.bp
new file mode 100644
index 000000000000..17bad746e039
--- /dev/null
+++ b/mime/Android.bp
@@ -0,0 +1,43 @@
+// Copyright (C) 2019 The Android Open Source 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.
+
+java_library {
+ name: "mimemap",
+ visibility: [
+ "//cts/tests/tests/mimemap:__subpackages__",
+ "//frameworks/base:__subpackages__",
+ ],
+
+ srcs: [
+ "java/android/content/type/DefaultMimeMapFactory.java",
+ ],
+
+ java_resources: [
+ ":debian.mime.types",
+ ":android.mime.types",
+ ],
+
+ sdk_version: "core_platform",
+}
+
+filegroup {
+ name: "android.mime.types",
+ visibility: [
+ "//visibility:private",
+ ],
+ path: "java-res/",
+ srcs: [
+ "java-res/android.mime.types",
+ ],
+}
diff --git a/mime/java-res/android.mime.types b/mime/java-res/android.mime.types
new file mode 100644
index 000000000000..1ca912e8510b
--- /dev/null
+++ b/mime/java-res/android.mime.types
@@ -0,0 +1,146 @@
+
+###############################################################################
+#
+# Android-specific MIME type <-> extension mappings
+#
+# Each line below defines an mapping from one MIME type to the first of the
+# listed extensions, and from listed extension back to the MIME type.
+# A mapping overrides any previous mapping _from_ that same MIME type or
+# extension (put() semantics), unless that MIME type / extension is prefixed with '?'
+# (putIfAbsent() semantics).
+#
+#
+###############################################################################
+#
+# EXAMPLES
+#
+# A line of the form:
+#
+# ?mime ext1 ?ext2 ext3
+#
+# affects the current mappings along the lines of the following pseudo code:
+#
+# mimeToExt.putIfAbsent("mime", "ext1");
+# extToMime.put("ext1", "mime");
+# extToMime.putIfAbsent("ext2", "mime");
+# extToMime.put("ext3", "mime");
+#
+# The line:
+#
+# ?text/plain txt
+#
+# leaves any earlier mapping for "text/plain" untouched, or maps that MIME type
+# to the file extension ".txt" if there is no earlier mapping. The line also
+# sets the mapping from file extension ".txt" to be the MIME type "text/plain",
+# regardless of whether a previous mapping existed.
+#
+###############################################################################
+
+
+# File extensions that Android wants to override to point to the given MIME type.
+#
+# After processing a line of the form:
+# ?<mimeType> <extension1> <extension2>
+# If <mimeType> was not already mapped to an extension then it will be
+# mapped to <extension1>.
+# <extension1> and <extension2> are mapped (or remapped) to <mimeType>.
+
+?application/epub+zip epub
+?application/pkix-cert cer
+?application/rss+xml rss
+?application/vnd.android.ota ota
+?application/vnd.apple.mpegurl m3u8
+?application/vnd.ms-pki.stl stl
+?application/vnd.ms-powerpoint pot
+?application/vnd.ms-wpl wpl
+?application/vnd.stardivision.impress sdp
+?application/vnd.stardivision.writer vor
+?application/vnd.youtube.yt yt
+?application/x-android-drm-fl fl
+?application/x-flac flac
+?application/x-font pcf
+?application/x-mpegurl m3u m3u8
+?application/x-pem-file pem
+?application/x-pkcs12 p12 pfx
+?application/x-webarchive webarchive
+?application/x-webarchive-xml webarchivexml
+?application/x-x509-server-cert crt
+?application/x-x509-user-cert crt
+
+?audio/3gpp 3gpp
+?audio/aac-adts aac
+?audio/imelody imy
+?audio/midi rtttl xmf
+?audio/mobile-xmf mxmf
+?audio/mp4 m4a
+?audio/mpegurl m3u
+?audio/sp-midi smf
+?audio/x-matroska mka
+?audio/x-pn-realaudio ra
+
+?image/bmp bmp
+?image/heic heic
+?image/heic-sequence heics
+?image/heif heif hif
+?image/heif-sequence heifs
+?image/ico cur
+?image/webp webp
+?image/x-adobe-dng dng
+?image/x-fuji-raf raf
+?image/x-icon ico
+?image/x-nikon-nrw nrw
+?image/x-panasonic-rw2 rw2
+?image/x-pentax-pef pef
+?image/x-samsung-srw srw
+?image/x-sony-arw arw
+
+?text/comma-separated-values csv
+?text/plain diff po
+?text/rtf rtf
+?text/text phps
+?text/xml xml
+?text/x-vcard vcf
+
+?video/3gpp2 3gpp2 3g2
+?video/3gpp 3gpp
+?video/avi avi
+?video/m4v m4v
+?video/mp2p mpeg
+?video/mp2t m2ts mts
+?video/mp2ts ts
+?video/vnd.youtube.yt yt
+?video/x-webex wrf
+
+# Optional additions that should not override any previous mapping.
+
+?application/x-wifi-config ?xml
+
+# Special cases where Android has a strong opinion about mappings, so we
+# define them very last and make them override in both directions (no "?").
+#
+# Lines here are of the form:
+# <mimeType> <extension1> <extension2> ...
+#
+# After processing each line,
+# <mimeType> is mapped to <extension1>
+# <extension1>, <extension2>, ... are all mapped to <mimeType>
+# This overrides any mappings for this <mimeType> / for these extensions
+# that may have been defined earlier.
+
+application/pgp-signature pgp
+application/x-x509-ca-cert crt
+audio/aac aac
+audio/basic snd
+audio/flac flac
+audio/midi rtx
+audio/mpeg mp3 m4a m4r
+audio/x-mpegurl m3u m3u8
+image/jpeg jpg
+image/x-ms-bmp bmp
+text/plain txt
+text/x-c++hdr hpp
+text/x-c++src cpp
+video/3gpp 3gpp
+video/mpeg mpeg
+video/quicktime mov
+video/x-matroska mkv
diff --git a/mime/java/android/content/type/DefaultMimeMapFactory.java b/mime/java/android/content/type/DefaultMimeMapFactory.java
new file mode 100644
index 000000000000..545fb3cbb5cd
--- /dev/null
+++ b/mime/java/android/content/type/DefaultMimeMapFactory.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2019 The Android Open Source 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 android.content.type;
+
+import libcore.net.MimeMap;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * Creates the framework default {@link MimeMap}, a bidirectional mapping
+ * between MIME types and file extensions.
+ *
+ * This default mapping is loaded from data files that start with some mappings
+ * recognized by IANA plus some custom extensions and overrides.
+ *
+ * @hide
+ */
+public class DefaultMimeMapFactory {
+
+ private DefaultMimeMapFactory() {
+ }
+
+ /**
+ * Creates and returns a new {@link MimeMap} instance that implements.
+ * 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);
+ }
+ return builder.build();
+ }
+
+ private static void parseTypes(MimeMap.Builder builder, String resource) {
+ try (BufferedReader r = new BufferedReader(
+ new InputStreamReader(DefaultMimeMapFactory.class.getResourceAsStream(resource)))) {
+ String line;
+ while ((line = r.readLine()) != null) {
+ int commentPos = line.indexOf('#');
+ if (commentPos >= 0) {
+ line = line.substring(0, commentPos);
+ }
+ line = line.trim();
+ if (line.isEmpty()) {
+ continue;
+ }
+ List<String> specs = Arrays.asList(SPLIT_PATTERN.split(line));
+ builder.put(specs.get(0), specs.subList(1, specs.size()));
+ }
+ } catch (IOException | RuntimeException e) {
+ throw new RuntimeException("Failed to parse " + resource, e);
+ }
+ }
+
+}