summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-19 20:34:23 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-02-19 20:34:23 +0000
commitffaee18e8a876257e5a9fed3eca6afcd60f481e1 (patch)
treeeccb9ce482e600047b9e78aaf56ca048d2e9940e /base
parentc48ad0b05fa7c639f76c16909f8b0b32e24c559f (diff)
downloadchromium_src-ffaee18e8a876257e5a9fed3eca6afcd60f481e1.zip
chromium_src-ffaee18e8a876257e5a9fed3eca6afcd60f481e1.tar.gz
chromium_src-ffaee18e8a876257e5a9fed3eca6afcd60f481e1.tar.bz2
Add support for GetHomeDir for Mac and Windows.
Unifies the Path Service's base::DIR_HOME on Posix and base::DIR_PROFILE on Windows to just be base::DIR_HOME everywhere, and DIR_HOME will now work on Mac. This removes the AssertIOAllowed check in the Posix implementation because that was only executed in a fallback case that no developer is likely to ever hit. In addition, the we do call this type of function on the UI thread, so either we need to promote the assertion to be at the top of the function or delete it. It seemed unreasonable to disallow using this one key of the path service on the UI thread (the other ones are OK) so I just went for deleting the assertion. R=benwells@chromium.org Review URL: https://codereview.chromium.org/159833003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@252066 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/base_paths.cc35
-rw-r--r--base/base_paths.h4
-rw-r--r--base/base_paths_android.cc3
-rw-r--r--base/base_paths_mac.mm3
-rw-r--r--base/base_paths_posix.cc3
-rw-r--r--base/base_paths_posix.h2
-rw-r--r--base/base_paths_win.cc6
-rw-r--r--base/base_paths_win.h1
-rw-r--r--base/file_util.h10
-rw-r--r--base/file_util_mac.mm17
-rw-r--r--base/file_util_posix.cc11
-rw-r--r--base/file_util_unittest.cc11
-rw-r--r--base/file_util_win.cc17
-rw-r--r--base/path_service_unittest.cc5
14 files changed, 79 insertions, 49 deletions
diff --git a/base/base_paths.cc b/base/base_paths.cc
index b4fc28b..1b99e85 100644
--- a/base/base_paths.cc
+++ b/base/base_paths.cc
@@ -13,35 +13,34 @@ namespace base {
bool PathProvider(int key, FilePath* result) {
// NOTE: DIR_CURRENT is a special case in PathService::Get
- FilePath cur;
switch (key) {
case DIR_EXE:
- PathService::Get(FILE_EXE, &cur);
- cur = cur.DirName();
- break;
+ PathService::Get(FILE_EXE, result);
+ *result = result->DirName();
+ return true;
case DIR_MODULE:
- PathService::Get(FILE_MODULE, &cur);
- cur = cur.DirName();
- break;
+ PathService::Get(FILE_MODULE, result);
+ *result = result->DirName();
+ return true;
case DIR_TEMP:
- if (!base::GetTempDir(&cur))
+ if (!GetTempDir(result))
return false;
- break;
+ return true;
+ case base::DIR_HOME:
+ *result = GetHomeDir();
+ return true;
case DIR_TEST_DATA:
- if (!PathService::Get(DIR_SOURCE_ROOT, &cur))
+ if (!PathService::Get(DIR_SOURCE_ROOT, result))
return false;
- cur = cur.Append(FILE_PATH_LITERAL("base"));
- cur = cur.Append(FILE_PATH_LITERAL("test"));
- cur = cur.Append(FILE_PATH_LITERAL("data"));
- if (!base::PathExists(cur)) // We don't want to create this.
+ *result = result->Append(FILE_PATH_LITERAL("base"));
+ *result = result->Append(FILE_PATH_LITERAL("test"));
+ *result = result->Append(FILE_PATH_LITERAL("data"));
+ if (!PathExists(*result)) // We don't want to create this.
return false;
- break;
+ return true;
default:
return false;
}
-
- *result = cur;
- return true;
}
} // namespace base
diff --git a/base/base_paths.h b/base/base_paths.h
index f9601a2..26b2fd4 100644
--- a/base/base_paths.h
+++ b/base/base_paths.h
@@ -31,6 +31,10 @@ enum BasePathKey {
DIR_EXE, // Directory containing FILE_EXE.
DIR_MODULE, // Directory containing FILE_MODULE.
DIR_TEMP, // Temporary directory.
+ DIR_HOME, // User's root home directory. On Windows this will look
+ // like "C:\Users\you" (or on XP
+ // "C:\Document and Settings\you") which isn't necessarily
+ // a great place to put files.
FILE_EXE, // Path and filename of the current executable.
FILE_MODULE, // Path and filename of the module containing the code for
// the PathService (which could differ from FILE_EXE if the
diff --git a/base/base_paths_android.cc b/base/base_paths_android.cc
index 68cc5a7..27be24e 100644
--- a/base/base_paths_android.cc
+++ b/base/base_paths_android.cc
@@ -47,9 +47,6 @@ bool PathProviderAndroid(int key, FilePath* result) {
return base::android::GetCacheDirectory(result);
case base::DIR_ANDROID_APP_DATA:
return base::android::GetDataDirectory(result);
- case base::DIR_HOME:
- *result = GetHomeDir();
- return true;
case base::DIR_ANDROID_EXTERNAL_STORAGE:
return base::android::GetExternalStorageDirectory(result);
default:
diff --git a/base/base_paths_mac.mm b/base/base_paths_mac.mm
index 86d6a80..3930c44 100644
--- a/base/base_paths_mac.mm
+++ b/base/base_paths_mac.mm
@@ -106,9 +106,6 @@ bool PathProviderMac(int key, base::FilePath* result) {
#endif
case base::DIR_CACHE:
return base::mac::GetUserDirectory(NSCachesDirectory, result);
- case base::DIR_HOME:
- *result = base::mac::NSStringToFilePath(NSHomeDirectory());
- return true;
default:
return false;
}
diff --git a/base/base_paths_posix.cc b/base/base_paths_posix.cc
index b4147e9..cf136d4 100644
--- a/base/base_paths_posix.cc
+++ b/base/base_paths_posix.cc
@@ -109,9 +109,6 @@ bool PathProviderPosix(int key, FilePath* result) {
*result = cache_dir;
return true;
}
- case base::DIR_HOME:
- *result = GetHomeDir();
- return true;
}
return false;
}
diff --git a/base/base_paths_posix.h b/base/base_paths_posix.h
index 811c8cb..ef002ae 100644
--- a/base/base_paths_posix.h
+++ b/base/base_paths_posix.h
@@ -19,8 +19,6 @@ enum {
// browser cache can be a subdirectory.
// This is $XDG_CACHE_HOME on Linux and
// ~/Library/Caches on Mac.
- DIR_HOME, // $HOME on POSIX-like systems.
-
PATH_POSIX_END
};
diff --git a/base/base_paths_win.cc b/base/base_paths_win.cc
index bc88335..d4e11ae 100644
--- a/base/base_paths_win.cc
+++ b/base/base_paths_win.cc
@@ -127,12 +127,6 @@ bool PathProviderWin(int key, FilePath* result) {
return false;
cur = FilePath(system_buffer);
break;
- case base::DIR_PROFILE:
- if (FAILED(SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT,
- system_buffer)))
- return false;
- cur = FilePath(system_buffer);
- break;
case base::DIR_LOCAL_APP_DATA_LOW:
if (win::GetVersion() < win::VERSION_VISTA)
return false;
diff --git a/base/base_paths_win.h b/base/base_paths_win.h
index 11bc111..1c44578 100644
--- a/base/base_paths_win.h
+++ b/base/base_paths_win.h
@@ -25,7 +25,6 @@ enum {
DIR_START_MENU, // Usually "C:\Documents and Settings\<user>\
// Start Menu\Programs"
DIR_APP_DATA, // Application Data directory under the user profile.
- DIR_PROFILE, // Usually "C:\Documents and settings\<user>.
DIR_LOCAL_APP_DATA_LOW, // Local AppData directory for low integrity level.
DIR_LOCAL_APP_DATA, // "Local Settings\Application Data" directory under
// the user profile.
diff --git a/base/file_util.h b/base/file_util.h
index 9143c60..4c25b3a 100644
--- a/base/file_util.h
+++ b/base/file_util.h
@@ -221,16 +221,12 @@ BASE_EXPORT bool GetTempDir(FilePath* path);
// Only useful on POSIX; redirects to GetTempDir() on Windows.
BASE_EXPORT bool GetShmemTempDir(bool executable, FilePath* path);
-#if defined(OS_POSIX)
-// Get the home directory. This is more complicated than just getenv("HOME")
+// Get the home directory. This is more complicated than just getenv("HOME")
// as it knows to fall back on getpwent() etc.
//
-// This function is not currently implemented on Windows or Mac because we
-// don't use it. Generally you would use one of PathService's APP_DATA
-// directories on those platforms. If we need it, this could be implemented
-// there to return the appropriate directory.
+// You should not generally call this directly. Instead use DIR_HOME with the
+// path service which will use this function but cache the value.
BASE_EXPORT FilePath GetHomeDir();
-#endif // OS_POSIX
// Creates a temporary file. The full path is placed in |path|, and the
// function returns true if was successful in creating the file. The file will
diff --git a/base/file_util_mac.mm b/base/file_util_mac.mm
index 7a99426..02a0753 100644
--- a/base/file_util_mac.mm
+++ b/base/file_util_mac.mm
@@ -32,6 +32,23 @@ bool GetTempDir(base::FilePath* path) {
return true;
}
+FilePath GetHomeDir() {
+ NSString* tmp = NSHomeDirectory();
+ if (tmp != nil) {
+ FilePath mac_home_dir = base::mac::NSStringToFilePath(tmp);
+ if (!mac_home_dir.empty())
+ return mac_home_dir;
+ }
+
+ // Fall back on temp dir if no home directory is defined.
+ FilePath rv;
+ if (GetTempDir(&rv))
+ return rv;
+
+ // Last resort.
+ return FilePath("/tmp");
+}
+
bool GetShmemTempDir(bool executable, base::FilePath* path) {
return GetTempDir(path);
}
diff --git a/base/file_util_posix.cc b/base/file_util_posix.cc
index ec1a22c..f17b341 100644
--- a/base/file_util_posix.cc
+++ b/base/file_util_posix.cc
@@ -481,7 +481,7 @@ bool GetShmemTempDir(bool executable, FilePath* path) {
}
#endif // !defined(OS_MACOSX) && !defined(OS_ANDROID)
-#if !defined(OS_MACOSX)
+#if !defined(OS_MACOSX) // Mac implementation is in file_util_mac.mm.
FilePath GetHomeDir() {
#if defined(OS_CHROMEOS)
if (SysInfo::IsRunningOnChromeOS())
@@ -495,9 +495,12 @@ FilePath GetHomeDir() {
#if defined(OS_ANDROID)
DLOG(WARNING) << "OS_ANDROID: Home directory lookup not yet implemented.";
#elif defined(USE_GLIB) && !defined(OS_CHROMEOS)
- // g_get_home_dir calls getpwent, which can fall through to LDAP calls.
- ThreadRestrictions::AssertIOAllowed();
-
+ // g_get_home_dir calls getpwent, which can fall through to LDAP calls so
+ // this may do I/O. However, it should be rare that $HOME is not defined and
+ // this is typically called from the path service which has no threading
+ // restrictions. The path service will cache the result which limits the
+ // badness of blocking on I/O. As a result, we don't have a thread
+ // restriction here.
home_dir = g_get_home_dir();
if (home_dir && home_dir[0])
return FilePath(home_dir);
diff --git a/base/file_util_unittest.cc b/base/file_util_unittest.cc
index d36d4b2..93e82aa 100644
--- a/base/file_util_unittest.cc
+++ b/base/file_util_unittest.cc
@@ -1691,6 +1691,17 @@ TEST_F(FileUtilTest, GetShmemTempDirTest) {
EXPECT_TRUE(DirectoryExists(dir));
}
+TEST_F(FileUtilTest, GetHomeDirTest) {
+#if !defined(OS_ANDROID) // Not implemented on Android.
+ // We don't actually know what the home directory is supposed to be without
+ // calling some OS functions which would just duplicate the implementation.
+ // So here we just test that it returns something "reasonable".
+ FilePath home = GetHomeDir();
+ ASSERT_FALSE(home.empty());
+ ASSERT_TRUE(home.IsAbsolute());
+#endif
+}
+
TEST_F(FileUtilTest, CreateDirectoryTest) {
FilePath test_root =
temp_dir_.path().Append(FILE_PATH_LITERAL("create_directory_test"));
diff --git a/base/file_util_win.cc b/base/file_util_win.cc
index b2f69c8..e7aadc2 100644
--- a/base/file_util_win.cc
+++ b/base/file_util_win.cc
@@ -258,6 +258,23 @@ bool GetShmemTempDir(bool executable, FilePath* path) {
return GetTempDir(path);
}
+FilePath GetHomeDir() {
+ char16 result[MAX_PATH];
+ if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_PROFILE, NULL, SHGFP_TYPE_CURRENT,
+ result)) &&
+ result[0]) {
+ return FilePath(result);
+ }
+
+ // Fall back to the temporary directory on failure.
+ FilePath temp;
+ if (GetTempDir(&temp))
+ return temp;
+
+ // Last resort.
+ return FilePath(L"C:\\");
+}
+
bool CreateTemporaryFile(FilePath* path) {
ThreadRestrictions::AssertIOAllowed();
diff --git a/base/path_service_unittest.cc b/base/path_service_unittest.cc
index fbb2d76..8ac5323 100644
--- a/base/path_service_unittest.cc
+++ b/base/path_service_unittest.cc
@@ -100,8 +100,9 @@ typedef PlatformTest PathServiceTest;
TEST_F(PathServiceTest, Get) {
for (int key = base::PATH_START + 1; key < base::PATH_END; ++key) {
#if defined(OS_ANDROID)
- if (key == base::FILE_MODULE || key == base::DIR_USER_DESKTOP)
- continue; // Android doesn't implement FILE_MODULE and DIR_USER_DESKTOP;
+ if (key == base::FILE_MODULE || key == base::DIR_USER_DESKTOP ||
+ key == base::DIR_HOME)
+ continue; // Android doesn't implement these.
#elif defined(OS_IOS)
if (key == base::DIR_USER_DESKTOP)
continue; // iOS doesn't implement DIR_USER_DESKTOP;