Add API for getting location of odex or oat file

Add an API for getting the file path of odex or oat file given a dex
path.

Bug 28251566

Change-Id: Ibebaa20f15d8135b25d9eb5927b7979801ebf0b2
diff --git a/runtime/native/dalvik_system_DexFile.cc b/runtime/native/dalvik_system_DexFile.cc
index 8c7c966..4bb83b6 100644
--- a/runtime/native/dalvik_system_DexFile.cc
+++ b/runtime/native/dalvik_system_DexFile.cc
@@ -554,6 +554,42 @@
   return oat_file != nullptr;
 }
 
+static jstring DexFile_getDexFileOutputPath(JNIEnv* env,
+                                            jclass,
+                                            jstring javaFilename,
+                                            jstring javaInstructionSet) {
+  ScopedUtfChars filename(env, javaFilename);
+  if (env->ExceptionCheck()) {
+    return nullptr;
+  }
+
+  ScopedUtfChars instruction_set(env, javaInstructionSet);
+  if (env->ExceptionCheck()) {
+    return nullptr;
+  }
+
+  const InstructionSet target_instruction_set = GetInstructionSetFromString(
+      instruction_set.c_str());
+  if (target_instruction_set == kNone) {
+    ScopedLocalRef<jclass> iae(env, env->FindClass("java/lang/IllegalArgumentException"));
+    std::string message(StringPrintf("Instruction set %s is invalid.", instruction_set.c_str()));
+    env->ThrowNew(iae.get(), message.c_str());
+    return nullptr;
+  }
+
+  OatFileAssistant oat_file_assistant(filename.c_str(),
+                                      target_instruction_set,
+                                      false /* profile_changed */,
+                                      false /* load_executable */);
+
+  std::unique_ptr<OatFile> best_oat_file = oat_file_assistant.GetBestOatFile();
+  if (best_oat_file == nullptr) {
+    return nullptr;
+  }
+
+  return env->NewStringUTF(best_oat_file->GetLocation().c_str());
+}
+
 static JNINativeMethod gMethods[] = {
   NATIVE_METHOD(DexFile, closeDexFile, "(Ljava/lang/Object;)Z"),
   NATIVE_METHOD(DexFile,
@@ -581,6 +617,8 @@
                 "(Ljava/lang/String;)Ljava/lang/String;"),
   NATIVE_METHOD(DexFile, isBackedByOatFile, "(Ljava/lang/Object;)Z"),
   NATIVE_METHOD(DexFile, getDexFileStatus,
+                "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;"),
+  NATIVE_METHOD(DexFile, getDexFileOutputPath,
                 "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;")
 };