Merge "Make CTS more opinionated about the platform's default MimeMap." am: a8bfed9104 am: ac8a5625d2 am: 7e2ac2ea09
am: 98fdb1d810
Change-Id: I5eb0bd3cf5fd50d180c8da61a375f3faa0737164
diff --git a/mime/Android.bp b/mime/Android.bp
index 0ae94d4..51290f6 100644
--- a/mime/Android.bp
+++ b/mime/Android.bp
@@ -12,24 +12,84 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+
+java_defaults {
+ name: "mimemap-defaults",
+ srcs: [
+ "java/android/content/type/DefaultMimeMapFactory.java",
+ ],
+ sdk_version: "core_platform",
+}
+
java_library {
name: "mimemap",
+ defaults: ["mimemap-defaults"],
+ static_libs: ["mimemap-res.jar"],
+ visibility: [
+ "//frameworks/base:__subpackages__",
+ ],
+}
+
+java_library {
+ name: "mimemap-testing",
+ defaults: ["mimemap-defaults"],
+ static_libs: ["mimemap-testing-res.jar"],
+ jarjar_rules: "jarjar-rules.txt",
visibility: [
"//cts/tests/tests/mimemap:__subpackages__",
"//frameworks/base:__subpackages__",
],
+}
- srcs: [
- "java/android/content/type/DefaultMimeMapFactory.java",
+// The mimemap-res.jar and mimemap-testing-res.jar genrules produce a .jar that
+// has the resource file in a subdirectory res/ and testres/, respectively.
+// Those paths need to They need to be in different paths because one of them
+// ends up on a bootclasspath jar whereas the other one ends up in a test jar.
+// Bootclasspath resources hide test or application resources under the same
+// path because ClassLoader.getResource(String) consults the parent ClassLoader
+// first.
+//
+// Further notes:
+// - the "cp" command will flatten any directory paths that occur in $(in),
+// but here they happen to already be in the root directory. If we needed
+// to preserve sub paths then we might want to zip the files first and then
+// unzip them below the new parent directory.
+// - the path names "res/" and "testres/" and duplicated in .java source files
+// (DefaultMimeMapFactory.java and MimeMapTest.java, as of October 2019).
+java_genrule {
+ name: "mimemap-res.jar",
+ tools: [
+ "soong_zip",
],
+ srcs: [":mime.types"],
+ out: ["mimemap-res.jar"],
+ cmd: "mkdir $(genDir)/res/ && cp $(in) $(genDir)/res/ && $(location soong_zip) -C $(genDir) -o $(out) -D $(genDir)/res/",
+}
- java_resources: [
+// The same as mimemap-res.jar except that the resources are placed in a different directory.
+// They get bundled with CTS so that CTS can compare a device's MimeMap implementation vs.
+// the stock Android one from when CTS was built.
+java_genrule {
+ name: "mimemap-testing-res.jar",
+ tools: [
+ "soong_zip",
+ ],
+ srcs: [":mime.types"],
+ out: ["mimemap-testing-res.jar"],
+ cmd: "mkdir $(genDir)/testres/ && cp $(in) $(genDir)/testres/ && $(location soong_zip) -C $(genDir) -o $(out) -D $(genDir)/testres/",
+}
+
+// Combination of all *mime.types resources.
+filegroup {
+ name: "mime.types",
+ visibility: [
+ "//visibility:private",
+ ],
+ srcs: [
":debian.mime.types",
":android.mime.types",
":vendor.mime.types",
],
-
- sdk_version: "core_platform",
}
filegroup {
diff --git a/mime/jarjar-rules.txt b/mime/jarjar-rules.txt
new file mode 100644
index 0000000..145d1db
--- /dev/null
+++ b/mime/jarjar-rules.txt
@@ -0,0 +1 @@
+rule android.content.type.DefaultMimeMapFactory android.content.type.cts.StockAndroidMimeMapFactory
\ No newline at end of file
diff --git a/mime/java/android/content/type/DefaultMimeMapFactory.java b/mime/java/android/content/type/DefaultMimeMapFactory.java
index 56b234f..13039a4 100644
--- a/mime/java/android/content/type/DefaultMimeMapFactory.java
+++ b/mime/java/android/content/type/DefaultMimeMapFactory.java
@@ -20,10 +20,13 @@
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 @@
* 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 @@
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);
}
}