summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-16 21:03:44 +0000
committermark@chromium.org <mark@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-09-16 21:03:44 +0000
commit405a64b63ae9a6869923aa5b80cc77acf66e71bf (patch)
tree7881c66b26cc96095a454585a5ae40d3b5863c39
parent3fcec6daa921d2cf2ecdfa69740ad095700f9ddd (diff)
downloadchromium_src-405a64b63ae9a6869923aa5b80cc77acf66e71bf.zip
chromium_src-405a64b63ae9a6869923aa5b80cc77acf66e71bf.tar.gz
chromium_src-405a64b63ae9a6869923aa5b80cc77acf66e71bf.tar.bz2
Set OS X cache directory to ~/Library/Caches/[app name]/[profile name]
- Added implementation of GetUserCacheDirectory() for OS X. - Added FilePath::GetRelativePath(). - Implemented per-profile cache directories for OS X. Patch by Fred Akalin <akalin@gmail.com> Code review URL: http://codereview.chromium.org/174053 Review URL: http://codereview.chromium.org/204043 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@26387 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/base_paths_mac.h4
-rw-r--r--base/base_paths_mac.mm24
-rw-r--r--base/file_path.cc10
-rw-r--r--base/file_path.h10
-rw-r--r--base/file_path_unittest.cc70
-rw-r--r--base/path_service_unittest.cc6
-rw-r--r--chrome/browser/profile.cc38
-rw-r--r--chrome/common/chrome_paths_mac.mm13
8 files changed, 160 insertions, 15 deletions
diff --git a/base/base_paths_mac.h b/base/base_paths_mac.h
index 23ae7fe..324fc6c 100644
--- a/base/base_paths_mac.h
+++ b/base/base_paths_mac.h
@@ -18,8 +18,8 @@ enum {
FILE_MODULE, // path and filename of the module containing the code for the
// PathService (which could differ from FILE_EXE if the
// PathService were compiled into a library, for example)
- DIR_APP_DATA, // ~/Library/Application Support/Google/Chrome
- DIR_LOCAL_APP_DATA, // same as above (can we remove?)
+ DIR_CACHE, // ~/Library/Caches
+ DIR_APP_DATA, // ~/Library/Application Support
DIR_SOURCE_ROOT, // Returns the root of the source tree. This key is useful
// for tests that need to locate various resources. It
// should not be used outside of test code.
diff --git a/base/base_paths_mac.mm b/base/base_paths_mac.mm
index 965d9d3..7549827 100644
--- a/base/base_paths_mac.mm
+++ b/base/base_paths_mac.mm
@@ -15,6 +15,26 @@
namespace base {
+namespace {
+
+// TODO(akalin): Export this function somewhere and use it in
+// chrome_paths_mac.mm and mac_util.mm. This is tricky because
+// NSSearchPathDirectory is declared in an Objective C header so we
+// cannot put it in one of the usual locations (where pure C++ files
+// would include them).
+bool GetUserDirectory(NSSearchPathDirectory directory, FilePath* result) {
+ NSArray* dirs =
+ NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, YES);
+ if ([dirs count] < 1) {
+ return false;
+ }
+ NSString* path = [dirs objectAtIndex:0];
+ *result = FilePath([path fileSystemRepresentation]);
+ return true;
+}
+
+} // namespace
+
bool PathProviderMac(int key, FilePath* result) {
std::string cur;
switch (key) {
@@ -27,6 +47,10 @@ bool PathProviderMac(int key, FilePath* result) {
cur = [path fileSystemRepresentation];
break;
}
+ case base::DIR_CACHE:
+ return GetUserDirectory(NSCachesDirectory, result);
+ case base::DIR_APP_DATA:
+ return GetUserDirectory(NSApplicationSupportDirectory, result);
case base::DIR_SOURCE_ROOT: {
FilePath path;
PathService::Get(base::DIR_EXE, &path);
diff --git a/base/file_path.cc b/base/file_path.cc
index a521b37..1d90674 100644
--- a/base/file_path.cc
+++ b/base/file_path.cc
@@ -159,6 +159,11 @@ bool FilePath::operator!=(const FilePath& that) const {
}
bool FilePath::IsParent(const FilePath& child) const {
+ return AppendRelativePath(child, NULL);
+}
+
+bool FilePath::AppendRelativePath(const FilePath& child,
+ FilePath* path) const {
std::vector<FilePath::StringType> parent_components;
std::vector<FilePath::StringType> child_components;
GetComponents(&parent_components);
@@ -194,6 +199,11 @@ bool FilePath::IsParent(const FilePath& child) const {
++child_comp;
}
+ if (path != NULL) {
+ for (; child_comp != child_components.end(); ++child_comp) {
+ *path = path->Append(*child_comp);
+ }
+ }
return true;
}
diff --git a/base/file_path.h b/base/file_path.h
index e1dbd22..672d589 100644
--- a/base/file_path.h
+++ b/base/file_path.h
@@ -157,6 +157,16 @@ class FilePath {
// parent.
bool IsParent(const FilePath& child) const;
+ // If IsParent(child) holds, appends to path (if non-NULL) the
+ // relative path to child and returns true. For example, if parent
+ // holds "/Users/johndoe/Library/Application Support", child holds
+ // "/Users/johndoe/Library/Application Support/Google/Chrome/Default", and
+ // *path holds "/Users/johndoe/Library/Caches", then after
+ // parent.AppendRelativePath(child, path) is called *path will hold
+ // "/Users/johndoe/Library/Caches/Google/Chrome/Default". Otherwise,
+ // returns false.
+ bool AppendRelativePath(const FilePath& child, FilePath* path) const;
+
// Returns a FilePath corresponding to the directory containing the path
// named by this object, stripping away the file component. If this object
// only contains one component, returns a FilePath identifying
diff --git a/base/file_path_unittest.cc b/base/file_path_unittest.cc
index e14bbca..a2afa1e 100644
--- a/base/file_path_unittest.cc
+++ b/base/file_path_unittest.cc
@@ -485,6 +485,76 @@ TEST_F(FilePathTest, IsParentTest) {
}
}
+TEST_F(FilePathTest, AppendRelativePathTest) {
+ const struct BinaryTestData cases[] = {
+ { { FPL("/"), FPL("/foo/bar/baz") }, FPL("foo/bar/baz")},
+ { { FPL("/foo/bar"), FPL("/foo/bar/baz") }, FPL("baz")},
+ { { FPL("/foo/bar/"), FPL("/foo/bar/baz") }, FPL("baz")},
+ { { FPL("//foo/bar/"), FPL("//foo/bar/baz") }, FPL("baz")},
+ { { FPL("/foo/bar"), FPL("/foo2/bar/baz") }, FPL("")},
+ { { FPL("/foo/bar.txt"), FPL("/foo/bar/baz") }, FPL("")},
+ { { FPL("/foo/bar"), FPL("/foo/bar2/baz") }, FPL("")},
+ { { FPL("/foo/bar"), FPL("/foo/bar") }, FPL("")},
+ { { FPL("/foo/bar/baz"), FPL("/foo/bar") }, FPL("")},
+ { { FPL("foo/bar"), FPL("foo/bar/baz") }, FPL("baz")},
+ { { FPL("foo/bar"), FPL("foo2/bar/baz") }, FPL("")},
+ { { FPL("foo/bar"), FPL("foo/bar2/baz") }, FPL("")},
+ { { FPL(""), FPL("foo") }, FPL("")},
+#if defined(FILE_PATH_USES_DRIVE_LETTERS)
+ { { FPL("c:/foo/bar"), FPL("c:/foo/bar/baz") }, FPL("baz")},
+ { { FPL("E:/foo/bar"), FPL("e:/foo/bar/baz") }, FPL("baz")},
+ { { FPL("f:/foo/bar"), FPL("F:/foo/bar/baz") }, FPL("baz")},
+ { { FPL("E:/Foo/bar"), FPL("e:/foo/bar/baz") }, FPL("")},
+ { { FPL("f:/foo/bar"), FPL("F:/foo/Bar/baz") }, FPL("")},
+ { { FPL("c:/"), FPL("c:/foo/bar/baz") }, FPL("foo/bar/baz")},
+ { { FPL("c:"), FPL("c:/foo/bar/baz") }, FPL("foo/bar/baz")},
+ { { FPL("c:/foo/bar"), FPL("d:/foo/bar/baz") }, FPL("")},
+ { { FPL("c:/foo/bar"), FPL("D:/foo/bar/baz") }, FPL("")},
+ { { FPL("C:/foo/bar"), FPL("d:/foo/bar/baz") }, FPL("")},
+ { { FPL("c:/foo/bar"), FPL("c:/foo2/bar/baz") }, FPL("")},
+ { { FPL("e:/foo/bar"), FPL("E:/foo2/bar/baz") }, FPL("")},
+ { { FPL("F:/foo/bar"), FPL("f:/foo2/bar/baz") }, FPL("")},
+ { { FPL("c:/foo/bar"), FPL("c:/foo/bar2/baz") }, FPL("")},
+#endif // FILE_PATH_USES_DRIVE_LETTERS
+#if defined(FILE_PATH_USES_WIN_SEPARATORS)
+ { { FPL("\\foo\\bar"), FPL("\\foo\\bar\\baz") }, FPL("baz")},
+ { { FPL("\\foo/bar"), FPL("\\foo\\bar\\baz") }, FPL("baz")},
+ { { FPL("\\foo/bar"), FPL("\\foo/bar/baz") }, FPL("baz")},
+ { { FPL("\\"), FPL("\\foo\\bar\\baz") }, FPL("foo\\bar\\baz")},
+ { { FPL(""), FPL("\\foo\\bar\\baz") }, FPL("")},
+ { { FPL("\\foo\\bar"), FPL("\\foo2\\bar\\baz") }, FPL("")},
+ { { FPL("\\foo\\bar"), FPL("\\foo\\bar2\\baz") }, FPL("")},
+#endif // FILE_PATH_USES_WIN_SEPARATORS
+ };
+
+ const FilePath base(FPL("blah"));
+
+ for (size_t i = 0; i < arraysize(cases); ++i) {
+ FilePath parent(cases[i].inputs[0]);
+ FilePath child(cases[i].inputs[1]);
+ {
+ FilePath result;
+ bool success = parent.AppendRelativePath(child, &result);
+ EXPECT_EQ(cases[i].expected[0] != '\0', success) <<
+ "i: " << i << ", parent: " << parent.value() << ", child: " <<
+ child.value();
+ EXPECT_STREQ(cases[i].expected, result.value().c_str()) <<
+ "i: " << i << ", parent: " << parent.value() << ", child: " <<
+ child.value();
+ }
+ {
+ FilePath result(base);
+ bool success = parent.AppendRelativePath(child, &result);
+ EXPECT_EQ(cases[i].expected[0] != '\0', success) <<
+ "i: " << i << ", parent: " << parent.value() << ", child: " <<
+ child.value();
+ EXPECT_EQ(base.Append(cases[i].expected).value(), result.value()) <<
+ "i: " << i << ", parent: " << parent.value() << ", child: " <<
+ child.value();
+ }
+ }
+}
+
TEST_F(FilePathTest, EqualityTest) {
const struct BinaryBooleanTestData cases[] = {
{ { FPL("/foo/bar/baz"), FPL("/foo/bar/baz") }, true},
diff --git a/base/path_service_unittest.cc b/base/path_service_unittest.cc
index 32f49b2..cc86be0 100644
--- a/base/path_service_unittest.cc
+++ b/base/path_service_unittest.cc
@@ -47,7 +47,7 @@ TEST_F(PathServiceTest, Get) {
for (int key = base::DIR_CURRENT; key < base::PATH_END; ++key) {
EXPECT_PRED1(ReturnsValidPath, key);
}
-#ifdef OS_WIN
+#if defined(OS_WIN)
for (int key = base::PATH_WIN_START + 1; key < base::PATH_WIN_END; ++key) {
if (key == base::DIR_LOCAL_APP_DATA_LOW &&
win_util::GetWinVersion() < win_util::WINVERSION_VISTA) {
@@ -58,5 +58,9 @@ TEST_F(PathServiceTest, Get) {
EXPECT_TRUE(ReturnsValidPath(key)) << key;
}
}
+#elif defined(OS_MACOSX)
+ for (int key = base::PATH_MAC_START + 1; key < base::PATH_MAC_END; ++key) {
+ EXPECT_PRED1(ReturnsValidPath, key);
+ }
#endif
}
diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc
index 10cb6a1..c3eea76 100644
--- a/chrome/browser/profile.cc
+++ b/chrome/browser/profile.cc
@@ -6,6 +6,7 @@
#include "base/command_line.h"
#include "base/file_path.h"
+#include "base/file_util.h"
#include "base/path_service.h"
#include "base/scoped_ptr.h"
#include "base/string_util.h"
@@ -104,6 +105,19 @@ void GetCacheParameters(ContextType type, FilePath* cache_path,
}
}
+FilePath GetCachePath(const FilePath& base) {
+ return base.Append(chrome::kCacheDirname);
+}
+
+FilePath GetMediaCachePath(const FilePath& base) {
+ return base.Append(chrome::kMediaCacheDirname);
+}
+
+bool HasACacheSubdir(const FilePath &dir) {
+ return file_util::PathExists(GetCachePath(dir)) ||
+ file_util::PathExists(GetMediaCachePath(dir));
+}
+
} // namespace
// A pointer to the request context for the default profile. See comments on
@@ -585,8 +599,28 @@ ProfileImpl::ProfileImpl(const FilePath& path)
blacklist_ = new Blacklist(path);
}
+#if defined(OS_MACOSX)
+ // If the profile directory doesn't already have a cache directory and it
+ // is under ~/Library/Application Support, use a suitable cache directory
+ // under ~/Library/Caches. For example, a profile directory of
+ // ~/Library/Application Support/Google/Chrome/MyProfileName that doesn't
+ // have a "Cache" or "MediaCache" subdirectory would use the cache directory
+ // ~/Library/Caches/Google/Chrome/MyProfileName.
+ //
+ // TODO(akalin): Come up with unit tests for this.
+ // TODO(akalin): Use for Linux, too?
+ if (!HasACacheSubdir(path_)) {
+ FilePath app_data_path, user_cache_path;
+ if (PathService::Get(base::DIR_APP_DATA, &app_data_path) &&
+ PathService::Get(base::DIR_CACHE, &user_cache_path) &&
+ app_data_path.AppendRelativePath(path_, &user_cache_path)) {
+ base_cache_path_ = user_cache_path;
+ }
+ }
+#else
if (!PathService::IsOverridden(chrome::DIR_USER_DATA))
PathService::Get(chrome::DIR_USER_CACHE, &base_cache_path_);
+#endif
if (base_cache_path_.empty())
base_cache_path_ = path_;
@@ -890,7 +924,7 @@ URLRequestContext* ProfileImpl::GetRequestContext() {
int max_size;
GetCacheParameters(kNormalContext, &cache_path, &max_size);
- cache_path = cache_path.Append(chrome::kCacheDirname);
+ cache_path = GetCachePath(cache_path);
request_context_ = ChromeURLRequestContext::CreateOriginal(
this, cookie_path, cache_path, max_size);
request_context_->AddRef();
@@ -921,7 +955,7 @@ URLRequestContext* ProfileImpl::GetRequestContextForMedia() {
int max_size;
GetCacheParameters(kMediaContext, &cache_path, &max_size);
- cache_path = cache_path.Append(chrome::kMediaCacheDirname);
+ cache_path = GetMediaCachePath(cache_path);
media_request_context_ = ChromeURLRequestContext::CreateOriginalForMedia(
this, cache_path, max_size);
media_request_context_->AddRef();
diff --git a/chrome/common/chrome_paths_mac.mm b/chrome/common/chrome_paths_mac.mm
index 82dbb3c..734a0a9 100644
--- a/chrome/common/chrome_paths_mac.mm
+++ b/chrome/common/chrome_paths_mac.mm
@@ -14,19 +14,12 @@ namespace chrome {
bool GetDefaultUserDataDirectory(FilePath* result) {
bool success = false;
- NSArray* dirs =
- NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory,
- NSUserDomainMask, YES);
- if ([dirs count] && result) {
- NSString* base = [dirs objectAtIndex:0];
+ if (result && PathService::Get(base::DIR_APP_DATA, result)) {
#if defined(GOOGLE_CHROME_BUILD)
- base = [base stringByAppendingPathComponent:@"Google"];
- NSString* tail = @"Chrome";
+ *result = result->Append("Google").Append("Chrome");
#else
- NSString* tail = @"Chromium";
+ *result = result->Append("Chromium");
#endif
- NSString* path = [base stringByAppendingPathComponent:tail];
- *result = FilePath([path fileSystemRepresentation]);
success = true;
}
return success;