Commit ffaee18e authored by brettw@chromium.org's avatar brettw@chromium.org

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
parent c48ad0b0
...@@ -13,35 +13,34 @@ namespace base { ...@@ -13,35 +13,34 @@ namespace base {
bool PathProvider(int key, FilePath* result) { bool PathProvider(int key, FilePath* result) {
// NOTE: DIR_CURRENT is a special case in PathService::Get // NOTE: DIR_CURRENT is a special case in PathService::Get
FilePath cur;
switch (key) { switch (key) {
case DIR_EXE: case DIR_EXE:
PathService::Get(FILE_EXE, &cur); PathService::Get(FILE_EXE, result);
cur = cur.DirName(); *result = result->DirName();
break; return true;
case DIR_MODULE: case DIR_MODULE:
PathService::Get(FILE_MODULE, &cur); PathService::Get(FILE_MODULE, result);
cur = cur.DirName(); *result = result->DirName();
break; return true;
case DIR_TEMP: case DIR_TEMP:
if (!base::GetTempDir(&cur)) if (!GetTempDir(result))
return false; return false;
break; return true;
case base::DIR_HOME:
*result = GetHomeDir();
return true;
case DIR_TEST_DATA: case DIR_TEST_DATA:
if (!PathService::Get(DIR_SOURCE_ROOT, &cur)) if (!PathService::Get(DIR_SOURCE_ROOT, result))
return false; return false;
cur = cur.Append(FILE_PATH_LITERAL("base")); *result = result->Append(FILE_PATH_LITERAL("base"));
cur = cur.Append(FILE_PATH_LITERAL("test")); *result = result->Append(FILE_PATH_LITERAL("test"));
cur = cur.Append(FILE_PATH_LITERAL("data")); *result = result->Append(FILE_PATH_LITERAL("data"));
if (!base::PathExists(cur)) // We don't want to create this. if (!PathExists(*result)) // We don't want to create this.
return false; return false;
break; return true;
default: default:
return false; return false;
} }
*result = cur;
return true;
} }
} // namespace base } // namespace base
...@@ -31,6 +31,10 @@ enum BasePathKey { ...@@ -31,6 +31,10 @@ enum BasePathKey {
DIR_EXE, // Directory containing FILE_EXE. DIR_EXE, // Directory containing FILE_EXE.
DIR_MODULE, // Directory containing FILE_MODULE. DIR_MODULE, // Directory containing FILE_MODULE.
DIR_TEMP, // Temporary directory. 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_EXE, // Path and filename of the current executable.
FILE_MODULE, // Path and filename of the module containing the code for FILE_MODULE, // Path and filename of the module containing the code for
// the PathService (which could differ from FILE_EXE if the // the PathService (which could differ from FILE_EXE if the
......
...@@ -47,9 +47,6 @@ bool PathProviderAndroid(int key, FilePath* result) { ...@@ -47,9 +47,6 @@ bool PathProviderAndroid(int key, FilePath* result) {
return base::android::GetCacheDirectory(result); return base::android::GetCacheDirectory(result);
case base::DIR_ANDROID_APP_DATA: case base::DIR_ANDROID_APP_DATA:
return base::android::GetDataDirectory(result); return base::android::GetDataDirectory(result);
case base::DIR_HOME:
*result = GetHomeDir();
return true;
case base::DIR_ANDROID_EXTERNAL_STORAGE: case base::DIR_ANDROID_EXTERNAL_STORAGE:
return base::android::GetExternalStorageDirectory(result); return base::android::GetExternalStorageDirectory(result);
default: default:
......
...@@ -106,9 +106,6 @@ bool PathProviderMac(int key, base::FilePath* result) { ...@@ -106,9 +106,6 @@ bool PathProviderMac(int key, base::FilePath* result) {
#endif #endif
case base::DIR_CACHE: case base::DIR_CACHE:
return base::mac::GetUserDirectory(NSCachesDirectory, result); return base::mac::GetUserDirectory(NSCachesDirectory, result);
case base::DIR_HOME:
*result = base::mac::NSStringToFilePath(NSHomeDirectory());
return true;
default: default:
return false; return false;
} }
......
...@@ -109,9 +109,6 @@ bool PathProviderPosix(int key, FilePath* result) { ...@@ -109,9 +109,6 @@ bool PathProviderPosix(int key, FilePath* result) {
*result = cache_dir; *result = cache_dir;
return true; return true;
} }
case base::DIR_HOME:
*result = GetHomeDir();
return true;
} }
return false; return false;
} }
......
...@@ -19,8 +19,6 @@ enum { ...@@ -19,8 +19,6 @@ enum {
// browser cache can be a subdirectory. // browser cache can be a subdirectory.
// This is $XDG_CACHE_HOME on Linux and // This is $XDG_CACHE_HOME on Linux and
// ~/Library/Caches on Mac. // ~/Library/Caches on Mac.
DIR_HOME, // $HOME on POSIX-like systems.
PATH_POSIX_END PATH_POSIX_END
}; };
......
...@@ -127,12 +127,6 @@ bool PathProviderWin(int key, FilePath* result) { ...@@ -127,12 +127,6 @@ bool PathProviderWin(int key, FilePath* result) {
return false; return false;
cur = FilePath(system_buffer); cur = FilePath(system_buffer);
break; 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: case base::DIR_LOCAL_APP_DATA_LOW:
if (win::GetVersion() < win::VERSION_VISTA) if (win::GetVersion() < win::VERSION_VISTA)
return false; return false;
......
...@@ -25,7 +25,6 @@ enum { ...@@ -25,7 +25,6 @@ enum {
DIR_START_MENU, // Usually "C:\Documents and Settings\<user>\ DIR_START_MENU, // Usually "C:\Documents and Settings\<user>\
// Start Menu\Programs" // Start Menu\Programs"
DIR_APP_DATA, // Application Data directory under the user profile. 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_LOW, // Local AppData directory for low integrity level.
DIR_LOCAL_APP_DATA, // "Local Settings\Application Data" directory under DIR_LOCAL_APP_DATA, // "Local Settings\Application Data" directory under
// the user profile. // the user profile.
......
...@@ -221,16 +221,12 @@ BASE_EXPORT bool GetTempDir(FilePath* path); ...@@ -221,16 +221,12 @@ BASE_EXPORT bool GetTempDir(FilePath* path);
// Only useful on POSIX; redirects to GetTempDir() on Windows. // Only useful on POSIX; redirects to GetTempDir() on Windows.
BASE_EXPORT bool GetShmemTempDir(bool executable, FilePath* path); 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. // as it knows to fall back on getpwent() etc.
// //
// This function is not currently implemented on Windows or Mac because we // You should not generally call this directly. Instead use DIR_HOME with the
// don't use it. Generally you would use one of PathService's APP_DATA // path service which will use this function but cache the value.
// directories on those platforms. If we need it, this could be implemented
// there to return the appropriate directory.
BASE_EXPORT FilePath GetHomeDir(); BASE_EXPORT FilePath GetHomeDir();
#endif // OS_POSIX
// Creates a temporary file. The full path is placed in |path|, and the // 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 // function returns true if was successful in creating the file. The file will
......
...@@ -32,6 +32,23 @@ bool GetTempDir(base::FilePath* path) { ...@@ -32,6 +32,23 @@ bool GetTempDir(base::FilePath* path) {
return true; 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) { bool GetShmemTempDir(bool executable, base::FilePath* path) {
return GetTempDir(path); return GetTempDir(path);
} }
......
...@@ -481,7 +481,7 @@ bool GetShmemTempDir(bool executable, FilePath* path) { ...@@ -481,7 +481,7 @@ bool GetShmemTempDir(bool executable, FilePath* path) {
} }
#endif // !defined(OS_MACOSX) && !defined(OS_ANDROID) #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() { FilePath GetHomeDir() {
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
if (SysInfo::IsRunningOnChromeOS()) if (SysInfo::IsRunningOnChromeOS())
...@@ -495,9 +495,12 @@ FilePath GetHomeDir() { ...@@ -495,9 +495,12 @@ FilePath GetHomeDir() {
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
DLOG(WARNING) << "OS_ANDROID: Home directory lookup not yet implemented."; DLOG(WARNING) << "OS_ANDROID: Home directory lookup not yet implemented.";
#elif defined(USE_GLIB) && !defined(OS_CHROMEOS) #elif defined(USE_GLIB) && !defined(OS_CHROMEOS)
// g_get_home_dir calls getpwent, which can fall through to LDAP calls. // g_get_home_dir calls getpwent, which can fall through to LDAP calls so
ThreadRestrictions::AssertIOAllowed(); // 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(); home_dir = g_get_home_dir();
if (home_dir && home_dir[0]) if (home_dir && home_dir[0])
return FilePath(home_dir); return FilePath(home_dir);
......
...@@ -1691,6 +1691,17 @@ TEST_F(FileUtilTest, GetShmemTempDirTest) { ...@@ -1691,6 +1691,17 @@ TEST_F(FileUtilTest, GetShmemTempDirTest) {
EXPECT_TRUE(DirectoryExists(dir)); 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) { TEST_F(FileUtilTest, CreateDirectoryTest) {
FilePath test_root = FilePath test_root =
temp_dir_.path().Append(FILE_PATH_LITERAL("create_directory_test")); temp_dir_.path().Append(FILE_PATH_LITERAL("create_directory_test"));
......
...@@ -258,6 +258,23 @@ bool GetShmemTempDir(bool executable, FilePath* path) { ...@@ -258,6 +258,23 @@ bool GetShmemTempDir(bool executable, FilePath* path) {
return GetTempDir(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) { bool CreateTemporaryFile(FilePath* path) {
ThreadRestrictions::AssertIOAllowed(); ThreadRestrictions::AssertIOAllowed();
......
...@@ -100,8 +100,9 @@ typedef PlatformTest PathServiceTest; ...@@ -100,8 +100,9 @@ typedef PlatformTest PathServiceTest;
TEST_F(PathServiceTest, Get) { TEST_F(PathServiceTest, Get) {
for (int key = base::PATH_START + 1; key < base::PATH_END; ++key) { for (int key = base::PATH_START + 1; key < base::PATH_END; ++key) {
#if defined(OS_ANDROID) #if defined(OS_ANDROID)
if (key == base::FILE_MODULE || key == base::DIR_USER_DESKTOP) if (key == base::FILE_MODULE || key == base::DIR_USER_DESKTOP ||
continue; // Android doesn't implement FILE_MODULE and DIR_USER_DESKTOP; key == base::DIR_HOME)
continue; // Android doesn't implement these.
#elif defined(OS_IOS) #elif defined(OS_IOS)
if (key == base::DIR_USER_DESKTOP) if (key == base::DIR_USER_DESKTOP)
continue; // iOS doesn't implement DIR_USER_DESKTOP; continue; // iOS doesn't implement DIR_USER_DESKTOP;
......
...@@ -128,18 +128,11 @@ base::FilePath PrettifyPath(const base::FilePath& source_path) { ...@@ -128,18 +128,11 @@ base::FilePath PrettifyPath(const base::FilePath& source_path) {
// Prettifies |source_path|, by replacing the user's home directory with "~" // Prettifies |source_path|, by replacing the user's home directory with "~"
// (if applicable). // (if applicable).
base::FilePath PrettifyPath(const base::FilePath& source_path) { base::FilePath PrettifyPath(const base::FilePath& source_path) {
#if defined(OS_WIN) || defined(OS_POSIX)
#if defined(OS_WIN)
int home_key = base::DIR_PROFILE;
#elif defined(OS_POSIX)
int home_key = base::DIR_HOME;
#endif
base::FilePath home_path; base::FilePath home_path;
base::FilePath display_path = base::FilePath::FromUTF8Unsafe("~"); base::FilePath display_path = base::FilePath::FromUTF8Unsafe("~");
if (PathService::Get(home_key, &home_path) if (PathService::Get(base::DIR_HOME, &home_path)
&& home_path.AppendRelativePath(source_path, &display_path)) && home_path.AppendRelativePath(source_path, &display_path))
return display_path; return display_path;
#endif
return source_path; return source_path;
} }
#endif // defined(OS_MACOSX) #endif // defined(OS_MACOSX)
...@@ -219,13 +212,11 @@ bool GetFileTypesFromAcceptOption( ...@@ -219,13 +212,11 @@ bool GetFileTypesFromAcceptOption(
const char kLastChooseEntryDirectory[] = "last_choose_file_directory"; const char kLastChooseEntryDirectory[] = "last_choose_file_directory";
const int kGraylistedPaths[] = { const int kGraylistedPaths[] = {
base::DIR_HOME,
#if defined(OS_WIN) #if defined(OS_WIN)
base::DIR_PROFILE,
base::DIR_PROGRAM_FILES, base::DIR_PROGRAM_FILES,
base::DIR_PROGRAM_FILESX86, base::DIR_PROGRAM_FILESX86,
base::DIR_WINDOWS, base::DIR_WINDOWS,
#elif defined(OS_POSIX)
base::DIR_HOME,
#endif #endif
}; };
......
...@@ -57,13 +57,7 @@ void AddSavedEntry(const base::FilePath& path_to_save, ...@@ -57,13 +57,7 @@ void AddSavedEntry(const base::FilePath& path_to_save,
extension->id(), "magic id", path_to_save, is_directory); extension->id(), "magic id", path_to_save, is_directory);
} }
#if defined(OS_WIN) || defined(OS_POSIX) const int kGraylistedPath = base::DIR_HOME;
#if defined(OS_WIN)
const int kGraylistedPath = base::DIR_PROFILE;
#elif defined(OS_POSIX)
const int kGraylistedPath = base::DIR_HOME;
#endif
#endif
} // namespace } // namespace
...@@ -157,12 +151,7 @@ IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiGetDisplayPath) { ...@@ -157,12 +151,7 @@ IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiGetDisplayPath) {
#if defined(OS_WIN) || defined(OS_POSIX) #if defined(OS_WIN) || defined(OS_POSIX)
IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiGetDisplayPathPrettify) { IN_PROC_BROWSER_TEST_F(FileSystemApiTest, FileSystemApiGetDisplayPathPrettify) {
#if defined(OS_WIN) ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded(base::DIR_HOME,
int override = base::DIR_PROFILE;
#elif defined(OS_POSIX)
int override = base::DIR_HOME;
#endif
ASSERT_TRUE(PathService::OverrideAndCreateIfNeeded(override,
test_root_folder_, false)); test_root_folder_, false));
base::FilePath test_file = test_root_folder_.AppendASCII("gold.txt"); base::FilePath test_file = test_root_folder_.AppendASCII("gold.txt");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment