Add DexFile.getStaticSizeOfFile function.

Bug: b/69729799
Test: art/test/testrunner/testrunner.py -b -t 071-dexfile-get-static-size

Change-Id: I7d524bd0f8c8bab74b1831b1db35f5952e8ce2aa
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 2235563..c0de374 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -744,6 +744,23 @@
   return result;
 }
 
+static jlong DexFile_getStaticSizeOfDexFile(JNIEnv* env, jclass, jobject cookie) {
+  const OatFile* oat_file = nullptr;
+  std::vector<const DexFile*> dex_files;
+  if (!ConvertJavaArrayToDexFiles(env, cookie, /*out */ dex_files, /* out */ oat_file)) {
+    DCHECK(env->ExceptionCheck());
+    return 0;
+  }
+
+  uint64_t file_size = 0;
+  for (auto& dex_file : dex_files) {
+    if (dex_file) {
+      file_size += dex_file->GetHeader().file_size_;
+    }
+  }
+  return static_cast<jlong>(file_size);
+}
+
 static JNINativeMethod gMethods[] = {
   NATIVE_METHOD(DexFile, closeDexFile, "(Ljava/lang/Object;)Z"),
   NATIVE_METHOD(DexFile,
@@ -779,7 +796,8 @@
   NATIVE_METHOD(DexFile, getDexFileStatus,
                 "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),
   NATIVE_METHOD(DexFile, getDexFileOutputPaths,
-                "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;")
+                "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;"),
+  NATIVE_METHOD(DexFile, getStaticSizeOfDexFile, "(Ljava/lang/Object;)J")
 };
 
 void register_dalvik_system_DexFile(JNIEnv* env) {
diff --git a/test/071-dexfile-get-static-size/build b/test/071-dexfile-get-static-size/build
new file mode 100755
index 0000000..0bba66d
--- /dev/null
+++ b/test/071-dexfile-get-static-size/build
@@ -0,0 +1,30 @@
+#!/bin/bash
+#
+# Copyright 2017 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.
+
+./default-build "$@"
+
+# Create and add as resources to the test jar file:
+# 1. test1.dex
+# 2. test2.dex
+# 3. test-jar.jar, containing test1.dex as classes.dex
+# 4. multi-jar.jar, containing test1.dex as classes.dex and test2.dex as classes2.dex
+mkdir test-jar
+cp test1.dex test-jar/classes.dex
+cp test2.dex test-jar/classes2.dex
+zip -j test-jar.jar test-jar/classes.dex
+zip -j multi-jar.jar test-jar/classes.dex test-jar/classes2.dex
+jar uf ${TEST_NAME}.jar test1.dex test2.dex test-jar.jar multi-jar.jar
+
diff --git a/test/071-dexfile-get-static-size/expected.txt b/test/071-dexfile-get-static-size/expected.txt
new file mode 100644
index 0000000..dfb77c3
--- /dev/null
+++ b/test/071-dexfile-get-static-size/expected.txt
@@ -0,0 +1,4 @@
+Size for test1.dex: 1864
+Size for test2.dex: 1264
+Size for test-jar.jar: 1864
+Size for multi-jar.jar: 3128
diff --git a/test/071-dexfile-get-static-size/info.txt b/test/071-dexfile-get-static-size/info.txt
new file mode 100644
index 0000000..5b528e8
--- /dev/null
+++ b/test/071-dexfile-get-static-size/info.txt
@@ -0,0 +1,3 @@
+Test DexFile.getStaticSizeOfDexFile API.
+
+test1.dex and test2.dex are arbitrary valid dex files.
diff --git a/test/071-dexfile-get-static-size/src/Main.java b/test/071-dexfile-get-static-size/src/Main.java
new file mode 100644
index 0000000..4bf4538
--- /dev/null
+++ b/test/071-dexfile-get-static-size/src/Main.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2017 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.
+ */
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.FileOutputStream;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+
+public class Main {
+    private static void extractResource(String resource, String filename) throws Exception {
+        ClassLoader loader = Main.class.getClassLoader();
+        InputStream is = loader.getResourceAsStream(resource);
+        OutputStream os = new FileOutputStream(filename);
+        int read;
+        byte[] buf = new byte[4096];
+        while ((read = is.read(buf)) >= 0) {
+          os.write(buf, 0, read);
+        }
+        is.close();
+        os.close();
+    }
+
+    private static long getDexFileSize(String filename) throws Exception {
+        ClassLoader loader = Main.class.getClassLoader();
+        Class<?> DexFile = loader.loadClass("dalvik.system.DexFile");
+        Method DexFile_loadDex = DexFile.getMethod("loadDex",
+                                                   String.class,
+                                                   String.class,
+                                                   Integer.TYPE);
+        Method DexFile_getStaticSizeOfDexFile = DexFile.getMethod("getStaticSizeOfDexFile");
+        Object dexFile = DexFile_loadDex.invoke(null, filename, null, 0);
+        return (Long) DexFile_getStaticSizeOfDexFile.invoke(dexFile);
+    }
+
+    private static void test(String resource) throws Exception {
+        String filename = System.getenv("DEX_LOCATION") + "/" + resource;
+        extractResource(resource, filename);
+        long size = getDexFileSize(filename);
+        System.out.println("Size for " + resource + ": " + size);
+    }
+
+    public static void main(String[] args) throws Exception {
+        test("test1.dex");
+        test("test2.dex");
+        test("test-jar.jar");
+        test("multi-jar.jar");
+    }
+}
diff --git a/test/071-dexfile-get-static-size/test1.dex b/test/071-dexfile-get-static-size/test1.dex
new file mode 100644
index 0000000..84602d0
--- /dev/null
+++ b/test/071-dexfile-get-static-size/test1.dex
Binary files differ
diff --git a/test/071-dexfile-get-static-size/test2.dex b/test/071-dexfile-get-static-size/test2.dex
new file mode 100644
index 0000000..a07c46e
--- /dev/null
+++ b/test/071-dexfile-get-static-size/test2.dex
Binary files differ