Honor ANDROID_ROOT and ANDROID_DATA

Change-Id: I8e43093830a734694bbf7308d08dd18527302270
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 32082d3..9d53f93 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -568,7 +568,8 @@
 bool ClassLinker::GenerateOatFile(const std::string& dex_filename,
                                   int oat_fd,
                                   const std::string& oat_cache_filename) {
-  std::string dex2oat_string("/system/bin/dex2oat");
+  std::string dex2oat_string(GetAndroidRoot());
+  dex2oat_string += "/bin/dex2oat";
 #ifndef NDEBUG
   dex2oat_string += 'd';
 #endif
diff --git a/src/common_test.h b/src/common_test.h
index d55dfbd..4457cec 100644
--- a/src/common_test.h
+++ b/src/common_test.h
@@ -396,7 +396,7 @@
       CHECK(host_dir != NULL);
       return StringPrintf("%s/framework/core-hostdex.jar", host_dir);
     }
-    return std::string("/system/framework/core.jar");
+    return StringPrintf("%s/framework/core.jar", GetAndroidRoot());
   }
 
   const DexFile* OpenTestDexFile(const char* name) {
diff --git a/src/dex2oat.cc b/src/dex2oat.cc
index 5a9256e..33672b3 100644
--- a/src/dex2oat.cc
+++ b/src/dex2oat.cc
@@ -529,8 +529,13 @@
 
   bool image = (image_filename != NULL);
   if (!image && boot_image_filename.empty()) {
-    boot_image_filename += host_prefix;
-    boot_image_filename += "/system/framework/boot.art";
+    if (host_prefix.empty()) {
+      boot_image_filename += GetAndroidRoot();
+    } else {
+      boot_image_filename += host_prefix;
+      boot_image_filename += "/system";
+    }
+    boot_image_filename += "/framework/boot.art";
   }
   std::string boot_image_option;
   if (boot_image_filename != NULL) {
diff --git a/src/runtime.cc b/src/runtime.cc
index 3f6bcca..338a06c 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -432,7 +432,9 @@
   }
 
   if (!parsed->is_compiler_ && parsed->images_.empty()) {
-    parsed->images_.push_back("/system/framework/boot.art");
+    std::string boot_art(GetAndroidRoot());
+    boot_art += "/framework/boot.art";
+    parsed->images_.push_back(boot_art);
   }
   if (parsed->heap_growth_limit_ == 0) {
     parsed->heap_growth_limit_ = parsed->heap_maximum_size_;
diff --git a/src/utils.cc b/src/utils.cc
index 97efcde..cb76636 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -700,21 +700,42 @@
   task_cpu = strtoull(fields[36].c_str(), NULL, 10);
 }
 
-std::string GetArtCacheOrDie() {
-  const char* data_root = getenv("ANDROID_DATA");
-  if (data_root == NULL) {
-    if (OS::DirectoryExists("/data")) {
-      data_root = "/data";
+const char* GetAndroidRoot() {
+  const char* android_root = getenv("ANDROID_ROOT");
+  if (android_root == NULL) {
+    if (OS::DirectoryExists("/system")) {
+      android_root = "/system";
     } else {
-      data_root = "/tmp";
+      LOG(FATAL) << "ANDROID_ROOT not set and /system does not exist";
+      return "";
     }
   }
-  if (!OS::DirectoryExists(data_root)) {
-    LOG(FATAL) << "Failed to find ANDROID_DATA directory " << data_root;
+  if (!OS::DirectoryExists(android_root)) {
+    LOG(FATAL) << "Failed to find ANDROID_ROOT directory " << android_root;
     return "";
   }
+  return android_root;
+}
 
-  std::string art_cache(StringPrintf("%s/art-cache", data_root));
+const char* GetAndroidData() {
+  const char* android_data = getenv("ANDROID_DATA");
+  if (android_data == NULL) {
+    if (OS::DirectoryExists("/data")) {
+      android_data = "/data";
+    } else {
+      LOG(FATAL) << "ANDROID_DATA not set and /data does not exist";
+      return "";
+    }
+  }
+  if (!OS::DirectoryExists(android_data)) {
+    LOG(FATAL) << "Failed to find ANDROID_DATA directory " << android_data;
+    return "";
+  }
+  return android_data;
+}
+
+std::string GetArtCacheOrDie() {
+  std::string art_cache(StringPrintf("%s/art-cache", GetAndroidData()));
 
   if (!OS::DirectoryExists(art_cache.c_str())) {
     if (StringPiece(art_cache).starts_with("/tmp/")) {
diff --git a/src/utils.h b/src/utils.h
index d88fa2b..7807299 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -270,6 +270,12 @@
 // implementation-defined limit.
 void SetThreadName(const char* name);
 
+// Find $ANDROID_ROOT, /system, or abort
+const char* GetAndroidRoot();
+
+// Find $ANDROID_DATA, /data, or abort
+const char* GetAndroidData();
+
 // Returns the art-cache location, or dies trying.
 std::string GetArtCacheOrDie();