diff options
author | Tobias Thierer <tobiast@google.com> | 2019-09-27 20:27:29 +0100 |
---|---|---|
committer | Tobias Thierer <tobiast@google.com> | 2019-10-01 16:26:16 +0100 |
commit | adeea59b4dbdc65ea9b479c3d613a1e933fb9fb0 (patch) | |
tree | 39e11a78a27962df3b8c6fe83706963f81672fb1 /mime/java/android/content | |
parent | 324349142cf3dacf5684bc3664b90ee81363dee1 (diff) |
Make CTS more opinionated about the platform's default MimeMap.
Historically, the mapping implemented by MimeMap (formerly MimeUtils)
was largely untested and therefore differed between Android devices.
This CL topic makes CtsMimeMapTestCases a lot more opinionated by
checking that:
- MimeMap.getDefault() must respect all of the mappings supplied
in stock Android. This is enforced via CTS bundling a copy of:
- the {,android.,vendor.}mime.types data files
- DefaultMimeMapFactory (rewritten via jarjar to
android.content.type.cts.StockAndroidMimeMapFactory)
MimeMap.getDefault() is allowed to implement _additional_
mappings, but changed or removed mappings are not allowed.
- Public APIs android.webkit.MimeTypeMap and
URLConnection.getFileNameMap() must behave consistently with
MimeMap.getDefault() (in stock Android, those APIs are
implemented directly on top of MimeMap.getDefault()).
Test: atest CtsMimeMapTestCases
Test: atest CtsLibcoreTestCases:libcore.libcore.net.MimeMapTest
Test: The above atest runs pass on a device that contains an
additional mapping in vendor.mime.types that is not
present in CTS.
Test: Checked that on a device that changes a mapping in
android.mime.types, CtsLibcoreTestCases still passes
but CtsMimeMapTestCases fails.
Bug: 141842930
Bug: 139895945
Change-Id: I68e0e9c3ce53c1acf2a89f8b80519f4658c07217
Diffstat (limited to 'mime/java/android/content')
-rw-r--r-- | mime/java/android/content/type/DefaultMimeMapFactory.java | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/mime/java/android/content/type/DefaultMimeMapFactory.java b/mime/java/android/content/type/DefaultMimeMapFactory.java index 56b234fe0e1c..13039a4ab1e2 100644 --- a/mime/java/android/content/type/DefaultMimeMapFactory.java +++ b/mime/java/android/content/type/DefaultMimeMapFactory.java @@ -20,10 +20,13 @@ import libcore.net.MimeMap; import java.io.BufferedReader; import java.io.IOException; +import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Objects; +import java.util.function.Function; import java.util.regex.Pattern; /** @@ -45,21 +48,33 @@ public class DefaultMimeMapFactory { * Android's default mapping between MIME types and extensions. */ public static MimeMap create() { - MimeMap.Builder builder = MimeMap.builder(); - parseTypes(builder, true, "/mime.types"); - parseTypes(builder, true, "/android.mime.types"); - parseTypes(builder, false, "/vendor.mime.types"); - return builder.build(); + Class c = DefaultMimeMapFactory.class; + // The resources are placed into the res/ path by the "mimemap-res.jar" genrule. + return create(resourceName -> c.getResourceAsStream("/res/" + resourceName)); } private static final Pattern SPLIT_PATTERN = Pattern.compile("\\s+"); + /** + * Creates a {@link MimeMap} instance whose resources are loaded from the + * InputStreams looked up in {@code resourceSupplier}. + * + * @hide + */ + public static MimeMap create(Function<String, InputStream> resourceSupplier) { + MimeMap.Builder builder = MimeMap.builder(); + parseTypes(builder, true, resourceSupplier, "mime.types"); + parseTypes(builder, true, resourceSupplier, "android.mime.types"); + parseTypes(builder, false, resourceSupplier, "vendor.mime.types"); + return builder.build(); + } + private static void parseTypes(MimeMap.Builder builder, boolean allowOverwrite, - String resource) { - try (BufferedReader r = new BufferedReader( - new InputStreamReader(DefaultMimeMapFactory.class.getResourceAsStream(resource)))) { + Function<String, InputStream> resourceSupplier, String resourceName) { + try (InputStream inputStream = Objects.requireNonNull(resourceSupplier.apply(resourceName)); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) { String line; - while ((line = r.readLine()) != null) { + while ((line = reader.readLine()) != null) { int commentPos = line.indexOf('#'); if (commentPos >= 0) { line = line.substring(0, commentPos); @@ -78,7 +93,7 @@ public class DefaultMimeMapFactory { builder.put(specs.get(0), specs.subList(1, specs.size())); } } catch (IOException | RuntimeException e) { - throw new RuntimeException("Failed to parse " + resource, e); + throw new RuntimeException("Failed to parse " + resourceName, e); } } |