adb: add helper to get the ~/.android directory.

Extract the logic for creating ~/.android out of get_user_key_path into
its own function. Also, fall back to getpwuid_r when $HOME isn't
defined.

Change-Id: I676a7c750cb364f89b544818ffda07903d14fb97
Test: ran adb with ~/.android missing
diff --git a/adb_auth_host.cpp b/adb_auth_host.cpp
index 4f4f382..8366549 100644
--- a/adb_auth_host.cpp
+++ b/adb_auth_host.cpp
@@ -246,21 +246,7 @@
 }
 
 static std::string get_user_key_path() {
-    const std::string home = adb_get_homedir_path(true);
-    LOG(DEBUG) << "adb_get_homedir_path returned '" << home << "'";
-
-    const std::string android_dir = android::base::StringPrintf("%s%c.android", home.c_str(),
-                                                                OS_PATH_SEPARATOR);
-
-    struct stat buf;
-    if (stat(android_dir.c_str(), &buf) == -1) {
-        if (adb_mkdir(android_dir.c_str(), 0750) == -1) {
-            PLOG(ERROR) << "Cannot mkdir '" << android_dir << "'";
-            return "";
-        }
-    }
-
-    return android_dir + OS_PATH_SEPARATOR + "adbkey";
+    return adb_get_android_dir_path() + OS_PATH_SEPARATOR + "adbkey";
 }
 
 static bool get_user_key() {
diff --git a/adb_utils.cpp b/adb_utils.cpp
index 31ec8af..e138a90 100644
--- a/adb_utils.cpp
+++ b/adb_utils.cpp
@@ -25,6 +25,7 @@
 #include <unistd.h>
 
 #include <algorithm>
+#include <vector>
 
 #include <android-base/logging.h>
 #include <android-base/parseint.h>
@@ -41,6 +42,8 @@
 #  endif
 #  include "windows.h"
 #  include "shlobj.h"
+#else
+#include <pwd.h>
 #endif
 
 ADB_MUTEX_DEFINE(basename_lock);
@@ -263,14 +266,8 @@
     return true;
 }
 
-std::string adb_get_homedir_path(bool check_env_first) {
+std::string adb_get_homedir_path() {
 #ifdef _WIN32
-    if (check_env_first) {
-        if (const char* const home = getenv("ANDROID_SDK_HOME")) {
-            return home;
-        }
-    }
-
     WCHAR path[MAX_PATH];
     const HRESULT hr = SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, path);
     if (FAILED(hr)) {
@@ -286,6 +283,29 @@
     if (const char* const home = getenv("HOME")) {
         return home;
     }
+
+    struct passwd pwent;
+    struct passwd* result;
+    int pwent_max = sysconf(_SC_GETPW_R_SIZE_MAX);
+    std::vector<char> buf(pwent_max);
+    int rc = getpwuid_r(getuid(), &pwent, buf.data(), buf.size(), &result);
+    if (rc == 0 && result) {
+        return result->pw_dir;
+    }
+
+    LOG(FATAL) << "failed to get user home directory";
     return {};
 #endif
 }
+
+std::string adb_get_android_dir_path() {
+    std::string user_dir = adb_get_homedir_path();
+    std::string android_dir = user_dir + OS_PATH_SEPARATOR + ".android";
+    struct stat buf;
+    if (stat(android_dir.c_str(), &buf) == -1) {
+        if (adb_mkdir(android_dir.c_str(), 0750) == -1) {
+            PLOG(FATAL) << "Cannot mkdir '" << android_dir << "'";
+        }
+    }
+    return android_dir;
+}
diff --git a/adb_utils.h b/adb_utils.h
index f6b4b26..d08c411 100644
--- a/adb_utils.h
+++ b/adb_utils.h
@@ -33,10 +33,10 @@
 std::string adb_dirname(const std::string& path);
 
 // Return the user's home directory.
-// |check_env_first| - if true, on Windows check the ANDROID_SDK_HOME
-// environment variable before trying the WinAPI call (useful when looking for
-// the .android directory)
-std::string adb_get_homedir_path(bool check_env_first);
+std::string adb_get_homedir_path();
+
+// Return the adb user directory.
+std::string adb_get_android_dir_path();
 
 bool mkdirs(const std::string& path);
 
diff --git a/console.cpp b/console.cpp
index e9b90a5..9563eac 100644
--- a/console.cpp
+++ b/console.cpp
@@ -32,7 +32,7 @@
 static std::string adb_construct_auth_command() {
     static const char auth_token_filename[] = ".emulator_console_auth_token";
 
-    std::string auth_token_path = adb_get_homedir_path(false);
+    std::string auth_token_path = adb_get_homedir_path();
     auth_token_path += OS_PATH_SEPARATOR;
     auth_token_path += auth_token_filename;