diff --git a/chromium_src/chrome/common/chrome_constants.cc b/chromium_src/chrome/common/chrome_constants.cc new file mode 100644 index 000000000000..1e7bd33a9658 --- /dev/null +++ b/chromium_src/chrome/common/chrome_constants.cc @@ -0,0 +1,68 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_version.h" + +namespace chrome { + +// filenames +const base::FilePath::CharType kCacheDirname[] = FPL("Cache"); +const base::FilePath::CharType kChannelIDFilename[] = FPL("Origin Bound Certs"); +const base::FilePath::CharType kCookieFilename[] = FPL("Cookies"); +const base::FilePath::CharType kCRLSetFilename[] = + FPL("Certificate Revocation Lists"); +const base::FilePath::CharType kCustomDictionaryFileName[] = + FPL("Custom Dictionary.txt"); +const base::FilePath::CharType kExtensionActivityLogFilename[] = + FPL("Extension Activity"); +const base::FilePath::CharType kExtensionsCookieFilename[] = + FPL("Extension Cookies"); +const base::FilePath::CharType kFirstRunSentinel[] = FPL("First Run"); +const base::FilePath::CharType kGCMStoreDirname[] = FPL("GCM Store"); +const base::FilePath::CharType kLocalStateFilename[] = FPL("Local State"); +const base::FilePath::CharType kLocalStorePoolName[] = FPL("LocalStorePool"); +const base::FilePath::CharType kMediaCacheDirname[] = FPL("Media Cache"); +const base::FilePath::CharType kNetworkPersistentStateFilename[] = + FPL("Network Persistent State"); +const base::FilePath::CharType kOfflinePageArchviesDirname[] = + FPL("Offline Pages/archives"); +const base::FilePath::CharType kOfflinePageMetadataDirname[] = + FPL("Offline Pages/metadata"); +const base::FilePath::CharType kPreferencesFilename[] = FPL("Preferences"); +const base::FilePath::CharType kProtectedPreferencesFilenameDeprecated[] = + FPL("Protected Preferences"); +const base::FilePath::CharType kReadmeFilename[] = FPL("README"); +const base::FilePath::CharType kResetPromptMementoFilename[] = + FPL("Reset Prompt Memento"); +const base::FilePath::CharType kSafeBrowsingBaseFilename[] = + FPL("Safe Browsing"); +const base::FilePath::CharType kSecurePreferencesFilename[] = + FPL("Secure Preferences"); +const base::FilePath::CharType kServiceStateFileName[] = FPL("Service State"); +const base::FilePath::CharType kSingletonCookieFilename[] = + FPL("SingletonCookie"); +const base::FilePath::CharType kSingletonLockFilename[] = FPL("SingletonLock"); +const base::FilePath::CharType kSingletonSocketFilename[] = + FPL("SingletonSocket"); +const base::FilePath::CharType kSupervisedUserSettingsFilename[] = + FPL("Managed Mode Settings"); +const base::FilePath::CharType kThemePackFilename[] = FPL("Cached Theme.pak"); +const base::FilePath::CharType kThemePackMaterialDesignFilename[] = + FPL("Cached Theme Material Design.pak"); +const base::FilePath::CharType kWebAppDirname[] = FPL("Web Applications"); + +// File name of the Pepper Flash plugin on different platforms. +const base::FilePath::CharType kPepperFlashPluginFilename[] = +#if defined(OS_MACOSX) + FPL("PepperFlashPlayer.plugin"); +#elif defined(OS_WIN) + FPL("pepflashplayer.dll"); +#else // OS_LINUX, etc. + FPL("libpepflashplayer.so"); +#endif + +} // namespace chrome + +#undef FPL diff --git a/chromium_src/chrome/common/chrome_constants.h b/chromium_src/chrome/common/chrome_constants.h new file mode 100644 index 000000000000..e36eeeeff413 --- /dev/null +++ b/chromium_src/chrome/common/chrome_constants.h @@ -0,0 +1,50 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// A handful of resource-like constants related to the Chrome application. + +#ifndef CHROME_COMMON_CHROME_CONSTANTS_H_ +#define CHROME_COMMON_CHROME_CONSTANTS_H_ + +#include "base/files/file_path.h" + +namespace chrome { + +// filenames +extern const base::FilePath::CharType kCacheDirname[]; +extern const base::FilePath::CharType kChannelIDFilename[]; +extern const base::FilePath::CharType kCookieFilename[]; +extern const base::FilePath::CharType kCRLSetFilename[]; +extern const base::FilePath::CharType kCustomDictionaryFileName[]; +extern const base::FilePath::CharType kExtensionActivityLogFilename[]; +extern const base::FilePath::CharType kExtensionsCookieFilename[]; +extern const base::FilePath::CharType kFirstRunSentinel[]; +extern const base::FilePath::CharType kGCMStoreDirname[]; +extern const base::FilePath::CharType kLocalStateFilename[]; +extern const base::FilePath::CharType kLocalStorePoolName[]; +extern const base::FilePath::CharType kMediaCacheDirname[]; +extern const base::FilePath::CharType kNetworkPersistentStateFilename[]; +extern const base::FilePath::CharType kOfflinePageArchviesDirname[]; +extern const base::FilePath::CharType kOfflinePageMetadataDirname[]; +extern const base::FilePath::CharType kPreferencesFilename[]; +extern const base::FilePath::CharType kProtectedPreferencesFilenameDeprecated[]; +extern const base::FilePath::CharType kReadmeFilename[]; +extern const base::FilePath::CharType kResetPromptMementoFilename[]; +extern const base::FilePath::CharType kSafeBrowsingBaseFilename[]; +extern const base::FilePath::CharType kSecurePreferencesFilename[]; +extern const base::FilePath::CharType kServiceStateFileName[]; +extern const base::FilePath::CharType kSingletonCookieFilename[]; +extern const base::FilePath::CharType kSingletonLockFilename[]; +extern const base::FilePath::CharType kSingletonSocketFilename[]; +extern const base::FilePath::CharType kSupervisedUserSettingsFilename[]; +extern const base::FilePath::CharType kThemePackFilename[]; +extern const base::FilePath::CharType kThemePackMaterialDesignFilename[]; +extern const base::FilePath::CharType kWebAppDirname[]; + +// File name of the Pepper Flash plugin on different platforms. +extern const base::FilePath::CharType kPepperFlashPluginFilename[]; + +} // namespace chrome + +#endif // CHROME_COMMON_CHROME_CONSTANTS_H_ diff --git a/chromium_src/chrome/common/chrome_paths.cc b/chromium_src/chrome/common/chrome_paths.cc new file mode 100644 index 000000000000..d8a32446fe9e --- /dev/null +++ b/chromium_src/chrome/common/chrome_paths.cc @@ -0,0 +1,610 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/common/chrome_paths.h" + +#include "base/files/file_util.h" +#include "base/lazy_instance.h" +#include "base/logging.h" +#include "base/mac/bundle_locations.h" +#include "base/path_service.h" +#include "base/strings/string_util.h" +#include "base/sys_info.h" +#include "base/threading/thread_restrictions.h" +#include "base/version.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_paths_internal.h" + +#if defined(OS_ANDROID) +#include "base/android/path_utils.h" +#include "base/base_paths_android.h" +// ui/base must only be used on Android. See BUILD.gn for dependency info. +#include "ui/base/ui_base_paths.h" // nogncheck +#endif + +#if defined(OS_MACOSX) +#include "base/mac/foundation_util.h" +#endif + +#if defined(OS_WIN) +#include "base/win/registry.h" +#endif + +namespace { + +// The Pepper Flash plugins are in a directory with this name. +const base::FilePath::CharType kPepperFlashBaseDirectory[] = + FILE_PATH_LITERAL("PepperFlash"); + +#if defined(OS_MACOSX) && !defined(OS_IOS) +const base::FilePath::CharType kPepperFlashSystemBaseDirectory[] = + FILE_PATH_LITERAL("Internet Plug-Ins/PepperFlashPlayer"); +const base::FilePath::CharType kFlashSystemBaseDirectory[] = + FILE_PATH_LITERAL("Internet Plug-Ins"); +const base::FilePath::CharType kFlashSystemPluginName[] = + FILE_PATH_LITERAL("Flash Player.plugin"); +#endif + +const base::FilePath::CharType kInternalNaClPluginFileName[] = + FILE_PATH_LITERAL("internal-nacl-plugin"); + +#if defined(OS_LINUX) +// The path to the external extension .json files. +// /usr/share seems like a good choice, see: http://www.pathname.com/fhs/ +const base::FilePath::CharType kFilepathSinglePrefExtensions[] = +#if defined(GOOGLE_CHROME_BUILD) + FILE_PATH_LITERAL("/usr/share/google-chrome/extensions"); +#else + FILE_PATH_LITERAL("/usr/share/chromium/extensions"); +#endif // defined(GOOGLE_CHROME_BUILD) + +// The path to the hint file that tells the pepper plugin loader +// where it can find the latest component updated flash. +const base::FilePath::CharType kComponentUpdatedFlashHint[] = + FILE_PATH_LITERAL("latest-component-updated-flash"); +#endif // defined(OS_LINUX) + +static base::LazyInstance + g_invalid_specified_user_data_dir = LAZY_INSTANCE_INITIALIZER; + +// Gets the path for internal plugins. +bool GetInternalPluginsDirectory(base::FilePath* result) { +#if defined(OS_MACOSX) && !defined(OS_IOS) + // If called from Chrome, get internal plugins from a subdirectory of the + // framework. + if (base::mac::AmIBundled()) { + *result = chrome::GetFrameworkBundlePath(); + DCHECK(!result->empty()); + *result = result->Append("Internet Plug-Ins"); + return true; + } + // In tests, just look in the module directory (below). +#endif + + // The rest of the world expects plugins in the module directory. + return PathService::Get(base::DIR_MODULE, result); +} + +#if defined(OS_WIN) +// Gets the Flash path if installed on the system. |is_npapi| determines whether +// to return the NPAPI of the PPAPI version of the system plugin. +bool GetSystemFlashFilename(base::FilePath* out_path, bool is_npapi) { + const wchar_t kNpapiFlashRegistryRoot[] = + L"SOFTWARE\\Macromedia\\FlashPlayerPlugin"; + const wchar_t kPepperFlashRegistryRoot[] = + L"SOFTWARE\\Macromedia\\FlashPlayerPepper"; + const wchar_t kFlashPlayerPathValueName[] = L"PlayerPath"; + + base::win::RegKey path_key( + HKEY_LOCAL_MACHINE, + is_npapi ? kNpapiFlashRegistryRoot : kPepperFlashRegistryRoot, KEY_READ); + base::string16 path_str; + if (FAILED(path_key.ReadValue(kFlashPlayerPathValueName, &path_str))) + return false; + + *out_path = base::FilePath(path_str); + return true; +} +#endif + +} // namespace + +namespace chrome { + +bool PathProvider(int key, base::FilePath* result) { + // Some keys are just aliases... + switch (key) { + case chrome::DIR_APP: + return PathService::Get(base::DIR_MODULE, result); + case chrome::DIR_LOGS: +#ifdef NDEBUG + // Release builds write to the data dir + return PathService::Get(chrome::DIR_USER_DATA, result); +#else + // Debug builds write next to the binary (in the build tree) +#if defined(OS_MACOSX) + if (!PathService::Get(base::DIR_EXE, result)) + return false; + if (base::mac::AmIBundled()) { + // If we're called from chrome, dump it beside the app (outside the + // app bundle), if we're called from a unittest, we'll already + // outside the bundle so use the exe dir. + // exe_dir gave us .../Chromium.app/Contents/MacOS/Chromium. + *result = result->DirName(); + *result = result->DirName(); + *result = result->DirName(); + } + return true; +#else + return PathService::Get(base::DIR_EXE, result); +#endif // defined(OS_MACOSX) +#endif // NDEBUG + case chrome::FILE_RESOURCE_MODULE: + return PathService::Get(base::FILE_MODULE, result); + } + + // Assume that we will not need to create the directory if it does not exist. + // This flag can be set to true for the cases where we want to create it. + bool create_dir = false; + + base::FilePath cur; + switch (key) { + case chrome::DIR_USER_DATA: + if (!GetDefaultUserDataDirectory(&cur)) { + NOTREACHED(); + return false; + } + create_dir = true; + break; + case chrome::DIR_USER_DOCUMENTS: + if (!GetUserDocumentsDirectory(&cur)) + return false; + create_dir = true; + break; + case chrome::DIR_USER_MUSIC: + if (!GetUserMusicDirectory(&cur)) + return false; + break; + case chrome::DIR_USER_PICTURES: + if (!GetUserPicturesDirectory(&cur)) + return false; + break; + case chrome::DIR_USER_VIDEOS: + if (!GetUserVideosDirectory(&cur)) + return false; + break; + case chrome::DIR_DEFAULT_DOWNLOADS_SAFE: +#if defined(OS_WIN) || defined(OS_LINUX) + if (!GetUserDownloadsDirectorySafe(&cur)) + return false; + break; +#else + // Fall through for all other platforms. +#endif + case chrome::DIR_DEFAULT_DOWNLOADS: +#if defined(OS_ANDROID) + if (!base::android::GetDownloadsDirectory(&cur)) + return false; +#else + if (!GetUserDownloadsDirectory(&cur)) + return false; + // Do not create the download directory here, we have done it twice now + // and annoyed a lot of users. +#endif + break; + case chrome::DIR_CRASH_DUMPS: +#if defined(OS_CHROMEOS) + // ChromeOS uses a separate directory. See http://crosbug.com/25089 + cur = base::FilePath("/var/log/chrome"); +#elif defined(OS_ANDROID) + if (!base::android::GetCacheDirectory(&cur)) + return false; +#else + // The crash reports are always stored relative to the default user data + // directory. This avoids the problem of having to re-initialize the + // exception handler after parsing command line options, which may + // override the location of the app's profile directory. + if (!GetDefaultUserDataDirectory(&cur)) + return false; +#endif +#if defined(OS_MACOSX) + cur = cur.Append(FILE_PATH_LITERAL("Crashpad")); +#else + cur = cur.Append(FILE_PATH_LITERAL("Crash Reports")); +#endif + create_dir = true; + break; +#if defined(OS_WIN) + case chrome::DIR_WATCHER_DATA: + // The watcher data is always stored relative to the default user data + // directory. This allows the watcher to be initialized before + // command-line options have been parsed. + if (!GetDefaultUserDataDirectory(&cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("Diagnostics")); + break; +#endif + case chrome::DIR_RESOURCES: +#if defined(OS_MACOSX) + cur = base::mac::FrameworkBundlePath(); + cur = cur.Append(FILE_PATH_LITERAL("Resources")); +#else + if (!PathService::Get(chrome::DIR_APP, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("resources")); +#endif + break; + case chrome::DIR_INSPECTOR: + if (!PathService::Get(chrome::DIR_RESOURCES, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("inspector")); + break; + case chrome::DIR_APP_DICTIONARIES: +#if defined(OS_POSIX) + // We can't write into the EXE dir on Linux, so keep dictionaries + // alongside the safe browsing database in the user data dir. + // And we don't want to write into the bundle on the Mac, so push + // it to the user data dir there also. + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; +#else + if (!PathService::Get(base::DIR_EXE, &cur)) + return false; +#endif + cur = cur.Append(FILE_PATH_LITERAL("Dictionaries")); + create_dir = true; + break; + case chrome::DIR_INTERNAL_PLUGINS: + if (!GetInternalPluginsDirectory(&cur)) + return false; + break; + case chrome::DIR_PEPPER_FLASH_PLUGIN: + if (!GetInternalPluginsDirectory(&cur)) + return false; + cur = cur.Append(kPepperFlashBaseDirectory); + break; + case chrome::DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(kPepperFlashBaseDirectory); + break; + case chrome::FILE_PEPPER_FLASH_SYSTEM_PLUGIN: +#if defined(OS_WIN) + if (!GetSystemFlashFilename(&cur, false)) + return false; +#elif defined(OS_MACOSX) && !defined(OS_IOS) + if (!GetLocalLibraryDirectory(&cur)) + return false; + cur = cur.Append(kPepperFlashSystemBaseDirectory); + cur = cur.Append(chrome::kPepperFlashPluginFilename); +#else + // Chrome on iOS does not supports PPAPI binaries, return false. + // TODO(wfh): If Adobe release PPAPI binaries for Linux, add support here. + return false; +#endif + break; + case chrome::FILE_FLASH_SYSTEM_PLUGIN: +#if defined(OS_WIN) + if (!GetSystemFlashFilename(&cur, true)) + return false; +#elif defined(OS_MACOSX) && !defined(OS_IOS) + if (!GetLocalLibraryDirectory(&cur)) + return false; + cur = cur.Append(kFlashSystemBaseDirectory); + cur = cur.Append(kFlashSystemPluginName); +#else + // Chrome on other platforms does not supports system NPAPI binaries. + return false; +#endif + break; + case chrome::FILE_LOCAL_STATE: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(chrome::kLocalStateFilename); + break; + case chrome::FILE_RECORDED_SCRIPT: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("script.log")); + break; + case chrome::FILE_PEPPER_FLASH_PLUGIN: + if (!PathService::Get(chrome::DIR_PEPPER_FLASH_PLUGIN, &cur)) + return false; + cur = cur.Append(chrome::kPepperFlashPluginFilename); + break; + // TODO(teravest): Remove this case once the internal NaCl plugin is gone. + // We currently need a path here to look up whether the plugin is disabled + // and what its permissions are. + case chrome::FILE_NACL_PLUGIN: + if (!GetInternalPluginsDirectory(&cur)) + return false; + cur = cur.Append(kInternalNaClPluginFileName); + break; + // PNaCl is currenly installable via the component updater or by being + // simply built-in. DIR_PNACL_BASE is used as the base directory for + // installation via component updater. DIR_PNACL_COMPONENT will be + // the final location of pnacl, which is a subdir of DIR_PNACL_BASE. + case chrome::DIR_PNACL_BASE: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("pnacl")); + break; + // Where PNaCl files are ultimately located. The default finds the files + // inside the InternalPluginsDirectory / build directory, as if it + // was shipped along with chrome. The value can be overridden + // if it is installed via component updater. + case chrome::DIR_PNACL_COMPONENT: +#if defined(OS_MACOSX) + // PNaCl really belongs in the InternalPluginsDirectory but actually + // copying it there would result in the files also being shipped, which + // we don't want yet. So for now, just find them in the directory where + // they get built. + if (!PathService::Get(base::DIR_EXE, &cur)) + return false; + if (base::mac::AmIBundled()) { + // If we're called from chrome, it's beside the app (outside the + // app bundle), if we're called from a unittest, we'll already be + // outside the bundle so use the exe dir. + // exe_dir gave us .../Chromium.app/Contents/MacOS/Chromium. + cur = cur.DirName(); + cur = cur.DirName(); + cur = cur.DirName(); + } +#else + if (!GetInternalPluginsDirectory(&cur)) + return false; +#endif + cur = cur.Append(FILE_PATH_LITERAL("pnacl")); + break; +#if defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS) +#if defined(WIDEVINE_CDM_IS_COMPONENT) + case chrome::DIR_COMPONENT_WIDEVINE_CDM: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("WidevineCDM")); + break; +#endif // defined(WIDEVINE_CDM_IS_COMPONENT) + // TODO(xhwang): FILE_WIDEVINE_CDM_ADAPTER has different meanings. + // In the component case, this is the source adapter. Otherwise, it is the + // actual Pepper module that gets loaded. + case chrome::FILE_WIDEVINE_CDM_ADAPTER: + if (!GetInternalPluginsDirectory(&cur)) + return false; + cur = cur.AppendASCII(kWidevineCdmAdapterFileName); + break; +#endif // defined(WIDEVINE_CDM_AVAILABLE) && defined(ENABLE_PEPPER_CDMS) + case chrome::FILE_RESOURCES_PACK: +#if defined(OS_MACOSX) && !defined(OS_IOS) + if (base::mac::AmIBundled()) { + cur = base::mac::FrameworkBundlePath(); + cur = cur.Append(FILE_PATH_LITERAL("Resources")) + .Append(FILE_PATH_LITERAL("resources.pak")); + break; + } +#elif defined(OS_ANDROID) + if (!PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &cur)) + return false; +#else + // If we're not bundled on mac or Android, resources.pak should be next + // to the binary (e.g., for unit tests). + if (!PathService::Get(base::DIR_MODULE, &cur)) + return false; +#endif + cur = cur.Append(FILE_PATH_LITERAL("resources.pak")); + break; + case chrome::DIR_RESOURCES_EXTENSION: + if (!PathService::Get(base::DIR_MODULE, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("resources")) + .Append(FILE_PATH_LITERAL("extension")); + break; +#if defined(OS_CHROMEOS) + case chrome::DIR_CHROMEOS_WALLPAPERS: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("wallpapers")); + break; + case chrome::DIR_CHROMEOS_WALLPAPER_THUMBNAILS: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("wallpaper_thumbnails")); + break; + case chrome::DIR_CHROMEOS_CUSTOM_WALLPAPERS: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("custom_wallpapers")); + break; +#endif +#if defined(ENABLE_SUPERVISED_USERS) +#if defined(OS_LINUX) + case chrome::DIR_SUPERVISED_USERS_DEFAULT_APPS: + if (!PathService::Get(chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("managed_users")); + break; +#endif + case chrome::DIR_SUPERVISED_USER_INSTALLED_WHITELISTS: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("SupervisedUserInstalledWhitelists")); + break; +#endif + // The following are only valid in the development environment, and + // will fail if executed from an installed executable (because the + // generated path won't exist). + case chrome::DIR_GEN_TEST_DATA: +#if defined(OS_ANDROID) + // On Android, our tests don't have permission to write to DIR_MODULE. + // gtest/test_runner.py pushes data to external storage. + if (!PathService::Get(base::DIR_ANDROID_EXTERNAL_STORAGE, &cur)) + return false; +#else + if (!PathService::Get(base::DIR_MODULE, &cur)) + return false; +#endif + cur = cur.Append(FILE_PATH_LITERAL("test_data")); + if (!base::PathExists(cur)) // We don't want to create this. + return false; + break; + case chrome::DIR_TEST_DATA: + if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("chrome")); + 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. + return false; + break; + case chrome::DIR_TEST_TOOLS: + if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("chrome")); + cur = cur.Append(FILE_PATH_LITERAL("tools")); + cur = cur.Append(FILE_PATH_LITERAL("test")); + if (!base::PathExists(cur)) // We don't want to create this + return false; + break; +#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_OPENBSD) + case chrome::DIR_POLICY_FILES: { +#if defined(GOOGLE_CHROME_BUILD) + cur = base::FilePath(FILE_PATH_LITERAL("/etc/opt/chrome/policies")); +#else + cur = base::FilePath(FILE_PATH_LITERAL("/etc/chromium/policies")); +#endif + break; + } +#endif +#if defined(OS_MACOSX) && !defined(OS_IOS) + case chrome::DIR_USER_LIBRARY: { + if (!GetUserLibraryDirectory(&cur)) + return false; + if (!base::PathExists(cur)) // We don't want to create this. + return false; + break; + } + case chrome::DIR_USER_APPLICATIONS: { + if (!GetUserApplicationsDirectory(&cur)) + return false; + if (!base::PathExists(cur)) // We don't want to create this. + return false; + break; + } +#endif +#if defined(OS_CHROMEOS) || (defined(OS_LINUX) && defined(CHROMIUM_BUILD)) || \ + (defined(OS_MACOSX) && !defined(OS_IOS)) + case chrome::DIR_USER_EXTERNAL_EXTENSIONS: { + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("External Extensions")); + break; + } +#endif +#if defined(OS_LINUX) + case chrome::DIR_STANDALONE_EXTERNAL_EXTENSIONS: { + cur = base::FilePath(kFilepathSinglePrefExtensions); + break; + } +#endif + case chrome::DIR_EXTERNAL_EXTENSIONS: +#if defined(OS_MACOSX) && !defined(OS_IOS) + if (!chrome::GetGlobalApplicationSupportDirectory(&cur)) + return false; + + cur = cur.Append(FILE_PATH_LITERAL("Google")) + .Append(FILE_PATH_LITERAL("Chrome")) + .Append(FILE_PATH_LITERAL("External Extensions")); + create_dir = false; +#else + if (!PathService::Get(base::DIR_MODULE, &cur)) + return false; + + cur = cur.Append(FILE_PATH_LITERAL("extensions")); + create_dir = true; +#endif + break; + + case chrome::DIR_DEFAULT_APPS: +#if defined(OS_MACOSX) + cur = base::mac::FrameworkBundlePath(); + cur = cur.Append(FILE_PATH_LITERAL("Default Apps")); +#else + if (!PathService::Get(chrome::DIR_APP, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("default_apps")); +#endif + break; + +#if defined(OS_LINUX) || (defined(OS_MACOSX) && !defined(OS_IOS)) + case chrome::DIR_NATIVE_MESSAGING: +#if defined(OS_MACOSX) +#if defined(GOOGLE_CHROME_BUILD) + cur = base::FilePath(FILE_PATH_LITERAL( + "/Library/Google/Chrome/NativeMessagingHosts")); +#else + cur = base::FilePath(FILE_PATH_LITERAL( + "/Library/Application Support/Chromium/NativeMessagingHosts")); +#endif +#else // defined(OS_MACOSX) +#if defined(GOOGLE_CHROME_BUILD) + cur = base::FilePath(FILE_PATH_LITERAL( + "/etc/opt/chrome/native-messaging-hosts")); +#else + cur = base::FilePath(FILE_PATH_LITERAL( + "/etc/chromium/native-messaging-hosts")); +#endif +#endif // !defined(OS_MACOSX) + break; + + case chrome::DIR_USER_NATIVE_MESSAGING: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("NativeMessagingHosts")); + break; +#endif // defined(OS_LINUX) || (defined(OS_MACOSX) && !defined(OS_IOS)) +#if !defined(OS_ANDROID) + case chrome::DIR_GLOBAL_GCM_STORE: + if (!PathService::Get(chrome::DIR_USER_DATA, &cur)) + return false; + cur = cur.Append(kGCMStoreDirname); + break; +#endif // !defined(OS_ANDROID) +#if defined(OS_LINUX) + case chrome::FILE_COMPONENT_FLASH_HINT: + if (!PathService::Get(chrome::DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN, + &cur)) { + return false; + } + cur = cur.Append(kComponentUpdatedFlashHint); + break; +#endif // defined(OS_LINUX) + + default: + return false; + } + + // TODO(bauerb): http://crbug.com/259796 + base::ThreadRestrictions::ScopedAllowIO allow_io; + if (create_dir && !base::PathExists(cur) && + !base::CreateDirectory(cur)) + return false; + + *result = cur; + return true; +} + +// This cannot be done as a static initializer sadly since Visual Studio will +// eliminate this object file if there is no direct entry point into it. +void RegisterPathProvider() { + PathService::RegisterProvider(PathProvider, PATH_START, PATH_END); +} + +void SetInvalidSpecifiedUserDataDir(const base::FilePath& user_data_dir) { + g_invalid_specified_user_data_dir.Get() = user_data_dir; +} + +const base::FilePath& GetInvalidSpecifiedUserDataDir() { + return g_invalid_specified_user_data_dir.Get(); +} + +} // namespace chrome diff --git a/chromium_src/chrome/common/chrome_paths.h b/chromium_src/chrome/common/chrome_paths.h new file mode 100644 index 000000000000..581fdc06f7c1 --- /dev/null +++ b/chromium_src/chrome/common/chrome_paths.h @@ -0,0 +1,152 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_COMMON_CHROME_PATHS_H__ +#define CHROME_COMMON_CHROME_PATHS_H__ + +#include "build/build_config.h" + +namespace base { +class FilePath; +} + +// This file declares path keys for the chrome module. These can be used with +// the PathService to access various special directories and files. + +namespace chrome { + +enum { + PATH_START = 1000, + + DIR_APP = PATH_START, // Directory where dlls and data reside. + DIR_LOGS, // Directory where logs should be written. + DIR_USER_DATA, // Directory where user data can be written. + DIR_CRASH_DUMPS, // Directory where crash dumps are written. +#if defined(OS_WIN) + DIR_WATCHER_DATA, // Directory where the Chrome watcher stores + // data. +#endif + DIR_RESOURCES, // Directory containing separate file resources + // used by Chrome at runtime. + DIR_INSPECTOR, // Directory where web inspector is located. + DIR_APP_DICTIONARIES, // Directory where the global dictionaries are. + DIR_USER_DOCUMENTS, // Directory for a user's "My Documents". + DIR_USER_MUSIC, // Directory for a user's music. + DIR_USER_PICTURES, // Directory for a user's pictures. + DIR_USER_VIDEOS, // Directory for a user's videos. + DIR_DEFAULT_DOWNLOADS_SAFE, // Directory for a user's + // "My Documents/Downloads", (Windows) or + // "Downloads". (Linux) + DIR_DEFAULT_DOWNLOADS, // Directory for a user's downloads. + DIR_INTERNAL_PLUGINS, // Directory where internal plugins reside. +#if defined(OS_POSIX) && !defined(OS_MACOSX) + DIR_POLICY_FILES, // Directory for system-wide read-only + // policy files that allow sys-admins + // to set policies for chrome. This directory + // contains subdirectories. +#endif +#if defined(OS_MACOSX) && !defined(OS_IOS) + DIR_USER_APPLICATIONS, // ~/Applications + DIR_USER_LIBRARY, // ~/Library +#endif +#if defined(OS_CHROMEOS) || (defined(OS_LINUX) && defined(CHROMIUM_BUILD)) || \ + (defined(OS_MACOSX) && !defined(OS_IOS)) + DIR_USER_EXTERNAL_EXTENSIONS, // Directory for per-user external extensions + // on Chrome Mac and Chromium Linux. + // On Chrome OS, this path is used for OEM + // customization. Getting this path does not + // create it. +#endif + +#if defined(OS_LINUX) + DIR_STANDALONE_EXTERNAL_EXTENSIONS, // Directory for 'per-extension' + // definition manifest files that + // describe extensions which are to be + // installed when chrome is run. +#endif + DIR_EXTERNAL_EXTENSIONS, // Directory where installer places .crx files. + + DIR_DEFAULT_APPS, // Directory where installer places .crx files + // to be installed when chrome is first run. + DIR_PEPPER_FLASH_PLUGIN, // Directory to the bundled Pepper Flash plugin, + // containing the plugin and the manifest. + DIR_COMPONENT_UPDATED_PEPPER_FLASH_PLUGIN, // Base directory of the Pepper + // Flash plugins downloaded by the + // component updater. + FILE_RESOURCE_MODULE, // Full path and filename of the module that + // contains embedded resources (version, + // strings, images, etc.). + FILE_LOCAL_STATE, // Path and filename to the file in which + // machine/installation-specific state is saved. + FILE_RECORDED_SCRIPT, // Full path to the script.log file that + // contains recorded browser events for + // playback. + FILE_PEPPER_FLASH_PLUGIN, // Full path to the bundled Pepper Flash plugin + // file. + FILE_PEPPER_FLASH_SYSTEM_PLUGIN, // Full path to the system version of the + // Pepper Flash plugin, downloadable from + // Adobe website. Querying this path might + // succeed no matter the file exists or not. + FILE_FLASH_SYSTEM_PLUGIN, // Full path to the system version of NPAPI + // Flash plugin, downloadable from Adobe + // website. Querying this path might succeed no + // matter the file exists or not. + FILE_NACL_PLUGIN, // Full path to the internal NaCl plugin file. + DIR_PNACL_BASE, // Full path to the base dir for PNaCl. + DIR_PNACL_COMPONENT, // Full path to the latest PNaCl version + // (subdir of DIR_PNACL_BASE). + DIR_COMPONENT_WIDEVINE_CDM, // Directory that contains component-updated + // Widevine CDM files. + FILE_WIDEVINE_CDM_ADAPTER, // Full path to the Widevine CDM adapter file. + FILE_RESOURCES_PACK, // Full path to the .pak file containing + // binary data (e.g., html files and images + // used by internal pages). + DIR_RESOURCES_EXTENSION, // Full path to extension resources. +#if defined(OS_CHROMEOS) + DIR_CHROMEOS_WALLPAPERS, // Directory where downloaded chromeos + // wallpapers reside. + DIR_CHROMEOS_WALLPAPER_THUMBNAILS, // Directory where downloaded chromeos + // wallpaper thumbnails reside. + DIR_CHROMEOS_CUSTOM_WALLPAPERS, // Directory where custom wallpapers + // reside. +#endif + DIR_SUPERVISED_USERS_DEFAULT_APPS, // Directory where installer places .crx + // files to be installed when managed user + // session starts. + DIR_SUPERVISED_USER_INSTALLED_WHITELISTS, // Directory where sanitized + // supervised user whitelists are + // installed. +#if defined(OS_LINUX) || (defined(OS_MACOSX) && !defined(OS_IOS)) + DIR_NATIVE_MESSAGING, // System directory where native messaging host + // manifest files are stored. + DIR_USER_NATIVE_MESSAGING, // Directory with Native Messaging Hosts + // installed per-user. +#endif +#if !defined(OS_ANDROID) + DIR_GLOBAL_GCM_STORE, // Directory where the global GCM instance + // stores its data. +#endif + + // Valid only in development environment; TODO(darin): move these + DIR_GEN_TEST_DATA, // Directory where generated test data resides. + DIR_TEST_DATA, // Directory where unit test data resides. + DIR_TEST_TOOLS, // Directory where unit test tools reside. +#if defined(OS_LINUX) + FILE_COMPONENT_FLASH_HINT, // A file in a known location that points to + // the component updated flash plugin. +#endif // defined(OS_LINUX) + + PATH_END +}; + +// Call once to register the provider for the path keys defined above. +void RegisterPathProvider(); + +// Get or set the invalid user data dir that was originally specified. +void SetInvalidSpecifiedUserDataDir(const base::FilePath& user_data_dir); +const base::FilePath& GetInvalidSpecifiedUserDataDir(); + +} // namespace chrome + +#endif // CHROME_COMMON_CHROME_PATHS_H__ diff --git a/chromium_src/chrome/common/chrome_paths_internal.h b/chromium_src/chrome/common/chrome_paths_internal.h new file mode 100644 index 000000000000..ae1cd623d773 --- /dev/null +++ b/chromium_src/chrome/common/chrome_paths_internal.h @@ -0,0 +1,112 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_COMMON_CHROME_PATHS_INTERNAL_H_ +#define CHROME_COMMON_CHROME_PATHS_INTERNAL_H_ + +#include + +#include "build/build_config.h" + +#if defined(OS_MACOSX) +#if defined(__OBJC__) +@class NSBundle; +#else +class NSBundle; +#endif +#endif + +namespace base { +class FilePath; +} + +namespace chrome { + +// Get the path to the user's data directory, regardless of whether +// DIR_USER_DATA has been overridden by a command-line option. +bool GetDefaultUserDataDirectory(base::FilePath* result); + +// Get the path to the user's cache directory. This is normally the +// same as the profile directory, but on Linux it can also be +// $XDG_CACHE_HOME and on Mac it can be under ~/Library/Caches. +// Note that the Chrome cache directories are actually subdirectories +// of this directory, with names like "Cache" and "Media Cache". +// This will always fill in |result| with a directory, sometimes +// just |profile_dir|. +void GetUserCacheDirectory(const base::FilePath& profile_dir, base::FilePath* result); + +// Get the path to the user's documents directory. +bool GetUserDocumentsDirectory(base::FilePath* result); + +#if defined(OS_WIN) || defined(OS_LINUX) +// Gets the path to a safe default download directory for a user. +bool GetUserDownloadsDirectorySafe(base::FilePath* result); +#endif + +// Get the path to the user's downloads directory. +bool GetUserDownloadsDirectory(base::FilePath* result); + +// Gets the path to the user's music directory. +bool GetUserMusicDirectory(base::FilePath* result); + +// Gets the path to the user's pictures directory. +bool GetUserPicturesDirectory(base::FilePath* result); + +// Gets the path to the user's videos directory. +bool GetUserVideosDirectory(base::FilePath* result); + +#if defined(OS_MACOSX) && !defined(OS_IOS) +// The "versioned directory" is a directory in the browser .app bundle. It +// contains the bulk of the application, except for the things that the system +// requires be located at spepcific locations. The versioned directory is +// in the .app at Contents/Versions/w.x.y.z. +base::FilePath GetVersionedDirectory(); + +// This overrides the directory returned by |GetVersionedDirectory()|, to be +// used when |GetVersionedDirectory()| can't automatically determine the proper +// location. This is the case when the browser didn't load itself but by, e.g., +// the app mode loader. This should be called before |ChromeMain()|. This takes +// ownership of the object |path| and the caller must not delete it. +void SetOverrideVersionedDirectory(const base::FilePath* path); + +// Most of the application is further contained within the framework. The +// framework bundle is located within the versioned directory at a specific +// path. The only components in the versioned directory not included in the +// framework are things that also depend on the framework, such as the helper +// app bundle. +base::FilePath GetFrameworkBundlePath(); + +// Get the local library directory. +bool GetLocalLibraryDirectory(base::FilePath* result); + +// Get the user library directory. +bool GetUserLibraryDirectory(base::FilePath* result); + +// Get the user applications directory. +bool GetUserApplicationsDirectory(base::FilePath* result); + +// Get the global Application Support directory (under /Library/). +bool GetGlobalApplicationSupportDirectory(base::FilePath* result); + +// Returns the NSBundle for the outer browser application, even when running +// inside the helper. In unbundled applications, such as tests, returns nil. +NSBundle* OuterAppBundle(); + +// Get the user data directory for the Chrome browser bundle at |bundle|. +// |bundle| should be the same value that would be returned from +[NSBundle +// mainBundle] if Chrome were launched normaly. This is used by app shims, +// which run from a bundle which isn't Chrome itself, but which need access to +// the user data directory to connect to a UNIX-domain socket therein. +// Returns false if there was a problem fetching the app data directory. +bool GetUserDataDirectoryForBrowserBundle(NSBundle* bundle, + base::FilePath* result); + +#endif // OS_MACOSX && !OS_IOS + +// Checks if the |process_type| has the rights to access the profile. +bool ProcessNeedsProfileDir(const std::string& process_type); + +} // namespace chrome + +#endif // CHROME_COMMON_CHROME_PATHS_INTERNAL_H_ diff --git a/chromium_src/chrome/common/chrome_paths_linux.cc b/chromium_src/chrome/common/chrome_paths_linux.cc new file mode 100644 index 000000000000..91348fec4808 --- /dev/null +++ b/chromium_src/chrome/common/chrome_paths_linux.cc @@ -0,0 +1,145 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/common/chrome_paths_internal.h" + +#include "base/base_paths.h" +#include "base/environment.h" +#include "base/files/file_util.h" +#include "base/memory/scoped_ptr.h" +#include "base/nix/xdg_util.h" +#include "base/path_service.h" +#include "chrome/common/chrome_paths.h" + +namespace chrome { + +using base::nix::GetXDGDirectory; +using base::nix::GetXDGUserDirectory; +using base::nix::kDotConfigDir; +using base::nix::kXdgConfigHomeEnvVar; + +namespace { + +const char kDownloadsDir[] = "Downloads"; +const char kMusicDir[] = "Music"; +const char kPicturesDir[] = "Pictures"; +const char kVideosDir[] = "Videos"; + +// Generic function for GetUser{Music,Pictures,Video}Directory. +bool GetUserMediaDirectory(const std::string& xdg_name, + const std::string& fallback_name, + base::FilePath* result) { +#if defined(OS_CHROMEOS) + // No local media directories on CrOS. + return false; +#else + *result = GetXDGUserDirectory(xdg_name.c_str(), fallback_name.c_str()); + + base::FilePath home; + PathService::Get(base::DIR_HOME, &home); + if (*result != home) { + base::FilePath desktop; + if (!PathService::Get(base::DIR_USER_DESKTOP, &desktop)) + return false; + if (*result != desktop) { + return true; + } + } + + *result = home.Append(fallback_name); + return true; +#endif +} + +} // namespace + +// See http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html +// for a spec on where config files go. The net effect for most +// systems is we use ~/.config/chromium/ for Chromium and +// ~/.config/google-chrome/ for official builds. +// (This also helps us sidestep issues with other apps grabbing ~/.chromium .) +bool GetDefaultUserDataDirectory(base::FilePath* result) { + scoped_ptr env(base::Environment::Create()); + base::FilePath config_dir(GetXDGDirectory(env.get(), + kXdgConfigHomeEnvVar, + kDotConfigDir)); +#if defined(GOOGLE_CHROME_BUILD) + *result = config_dir.Append("google-chrome"); +#else + *result = config_dir.Append("chromium"); +#endif + return true; +} + +void GetUserCacheDirectory(const base::FilePath& profile_dir, + base::FilePath* result) { + // See http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html + // for a spec on where cache files go. Our rule is: + // - if the user-data-dir in the standard place, + // use same subdirectory of the cache directory. + // (this maps ~/.config/google-chrome to ~/.cache/google-chrome as well + // as the same thing for ~/.config/chromium) + // - otherwise, use the profile dir directly. + + // Default value in cases where any of the following fails. + *result = profile_dir; + + scoped_ptr env(base::Environment::Create()); + + base::FilePath cache_dir; + if (!PathService::Get(base::DIR_CACHE, &cache_dir)) + return; + base::FilePath config_dir(GetXDGDirectory(env.get(), + kXdgConfigHomeEnvVar, + kDotConfigDir)); + + if (!config_dir.AppendRelativePath(profile_dir, &cache_dir)) + return; + + *result = cache_dir; +} + +bool GetUserDocumentsDirectory(base::FilePath* result) { + *result = GetXDGUserDirectory("DOCUMENTS", "Documents"); + return true; +} + +bool GetUserDownloadsDirectorySafe(base::FilePath* result) { + base::FilePath home; + PathService::Get(base::DIR_HOME, &home); + *result = home.Append(kDownloadsDir); + return true; +} + +bool GetUserDownloadsDirectory(base::FilePath* result) { + *result = GetXDGUserDirectory("DOWNLOAD", kDownloadsDir); + return true; +} + +// We respect the user's preferred pictures location, unless it is +// ~ or their desktop directory, in which case we default to ~/Music. +bool GetUserMusicDirectory(base::FilePath* result) { + return GetUserMediaDirectory("MUSIC", kMusicDir, result); +} + +// We respect the user's preferred pictures location, unless it is +// ~ or their desktop directory, in which case we default to ~/Pictures. +bool GetUserPicturesDirectory(base::FilePath* result) { + return GetUserMediaDirectory("PICTURES", kPicturesDir, result); +} + +// We respect the user's preferred pictures location, unless it is +// ~ or their desktop directory, in which case we default to ~/Videos. +bool GetUserVideosDirectory(base::FilePath* result) { + return GetUserMediaDirectory("VIDEOS", kVideosDir, result); +} + +bool ProcessNeedsProfileDir(const std::string& process_type) { + // For now we have no reason to forbid this on Linux as we don't + // have the roaming profile troubles there. Moreover the Linux breakpad needs + // profile dir access in all process if enabled on Linux. + return true; +} + +} // namespace chrome diff --git a/chromium_src/chrome/common/chrome_paths_mac.mm b/chromium_src/chrome/common/chrome_paths_mac.mm new file mode 100644 index 000000000000..09cf13bfe122 --- /dev/null +++ b/chromium_src/chrome/common/chrome_paths_mac.mm @@ -0,0 +1,252 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/common/chrome_paths_internal.h" + +#import +#include + +#include + +#include "base/base_paths.h" +#include "base/logging.h" +#import "base/mac/foundation_util.h" +#import "base/mac/scoped_nsautorelease_pool.h" +#include "base/memory/scoped_ptr.h" +#include "base/path_service.h" +#include "chrome/common/chrome_constants.h" + +namespace { + +#if !defined(OS_IOS) +const base::FilePath* g_override_versioned_directory = NULL; + +// Return a retained (NOT autoreleased) NSBundle* as the internal +// implementation of chrome::OuterAppBundle(), which should be the only +// caller. +NSBundle* OuterAppBundleInternal() { + base::mac::ScopedNSAutoreleasePool pool; + + if (!base::mac::AmIBundled()) { + // If unbundled (as in a test), there's no app bundle. + return nil; + } + + if (!base::mac::IsBackgroundOnlyProcess()) { + // Shortcut: in the browser process, just return the main app bundle. + return [[NSBundle mainBundle] retain]; + } + + // From C.app/Contents/Versions/1.2.3.4, go up three steps to get to C.app. + base::FilePath versioned_dir = chrome::GetVersionedDirectory(); + base::FilePath outer_app_dir = versioned_dir.DirName().DirName().DirName(); + const char* outer_app_dir_c = outer_app_dir.value().c_str(); + NSString* outer_app_dir_ns = [NSString stringWithUTF8String:outer_app_dir_c]; + + return [[NSBundle bundleWithPath:outer_app_dir_ns] retain]; +} +#endif // !defined(OS_IOS) + +char* ProductDirNameForBundle(NSBundle* chrome_bundle) { + const char* product_dir_name = NULL; +#if !defined(OS_IOS) + base::mac::ScopedNSAutoreleasePool pool; + + NSString* product_dir_name_ns = + [chrome_bundle objectForInfoDictionaryKey:@"CrProductDirName"]; + product_dir_name = [product_dir_name_ns fileSystemRepresentation]; +#else + DCHECK(!chrome_bundle); +#endif + + if (!product_dir_name) { +#if defined(GOOGLE_CHROME_BUILD) + product_dir_name = "Google/Chrome"; +#else + product_dir_name = "Chromium"; +#endif + } + + // Leaked, but the only caller initializes a static with this result, so it + // only happens once, and that's OK. + return strdup(product_dir_name); +} + +// ProductDirName returns the name of the directory inside +// ~/Library/Application Support that should hold the product application +// data. This can be overridden by setting the CrProductDirName key in the +// outer browser .app's Info.plist. The default is "Google/Chrome" for +// officially-branded builds, and "Chromium" for unbranded builds. For the +// official canary channel, the Info.plist will have CrProductDirName set +// to "Google/Chrome Canary". +std::string ProductDirName() { +#if defined(OS_IOS) + static const char* product_dir_name = ProductDirNameForBundle(nil); +#else + // Use OuterAppBundle() to get the main app's bundle. This key needs to live + // in the main app's bundle because it will be set differently on the canary + // channel, and the autoupdate system dictates that there can be no + // differences between channels within the versioned directory. This would + // normally use base::mac::FrameworkBundle(), but that references the + // framework bundle within the versioned directory. Ordinarily, the profile + // should not be accessed from non-browser processes, but those processes do + // attempt to get the profile directory, so direct them to look in the outer + // browser .app's Info.plist for the CrProductDirName key. + static const char* product_dir_name = + ProductDirNameForBundle(chrome::OuterAppBundle()); +#endif + return std::string(product_dir_name); +} + +bool GetDefaultUserDataDirectoryForProduct(const std::string& product_dir, + base::FilePath* result) { + bool success = false; + if (result && PathService::Get(base::DIR_APP_DATA, result)) { + *result = result->Append(product_dir); + success = true; + } + return success; +} + +} // namespace + +namespace chrome { + +bool GetDefaultUserDataDirectory(base::FilePath* result) { + return GetDefaultUserDataDirectoryForProduct(ProductDirName(), result); +} + +bool GetUserDocumentsDirectory(base::FilePath* result) { + return base::mac::GetUserDirectory(NSDocumentDirectory, result); +} + +void GetUserCacheDirectory(const base::FilePath& profile_dir, + base::FilePath* result) { + // If the profile directory 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 would use the cache directory + // ~/Library/Caches/Google/Chrome/MyProfileName. + + // Default value in cases where any of the following fails. + *result = profile_dir; + + base::FilePath app_data_dir; + if (!PathService::Get(base::DIR_APP_DATA, &app_data_dir)) + return; + base::FilePath cache_dir; + if (!PathService::Get(base::DIR_CACHE, &cache_dir)) + return; + if (!app_data_dir.AppendRelativePath(profile_dir, &cache_dir)) + return; + + *result = cache_dir; +} + +bool GetUserDownloadsDirectory(base::FilePath* result) { + return base::mac::GetUserDirectory(NSDownloadsDirectory, result); +} + +bool GetUserMusicDirectory(base::FilePath* result) { + return base::mac::GetUserDirectory(NSMusicDirectory, result); +} + +bool GetUserPicturesDirectory(base::FilePath* result) { + return base::mac::GetUserDirectory(NSPicturesDirectory, result); +} + +bool GetUserVideosDirectory(base::FilePath* result) { + return base::mac::GetUserDirectory(NSMoviesDirectory, result); +} + +#if !defined(OS_IOS) + +base::FilePath GetVersionedDirectory() { + if (g_override_versioned_directory) + return *g_override_versioned_directory; + + // Start out with the path to the running executable. + base::FilePath path; + PathService::Get(base::FILE_EXE, &path); + + // One step up to MacOS, another to Contents. + path = path.DirName().DirName(); + DCHECK_EQ(path.BaseName().value(), "Contents"); + + if (base::mac::IsBackgroundOnlyProcess()) { + // path identifies the helper .app's Contents directory in the browser + // .app's versioned directory. Go up two steps to get to the browser + // .app's versioned directory. + path = path.DirName().DirName(); + DCHECK_EQ(path.BaseName().value(), kChromeVersion); + } else { + // Go into the versioned directory. + path = path.Append("Versions").Append(kChromeVersion); + } + + return path; +} + +void SetOverrideVersionedDirectory(const base::FilePath* path) { + if (path != g_override_versioned_directory) { + delete g_override_versioned_directory; + g_override_versioned_directory = path; + } +} + +base::FilePath GetFrameworkBundlePath() { + // It's tempting to use +[NSBundle bundleWithIdentifier:], but it's really + // slow (about 30ms on 10.5 and 10.6), despite Apple's documentation stating + // that it may be more efficient than +bundleForClass:. +bundleForClass: + // itself takes 1-2ms. Getting an NSBundle from a path, on the other hand, + // essentially takes no time at all, at least when the bundle has already + // been loaded as it will have been in this case. The FilePath operations + // needed to compute the framework's path are also effectively free, so that + // is the approach that is used here. NSBundle is also documented as being + // not thread-safe, and thread safety may be a concern here. + + // The framework bundle is at a known path and name from the browser .app's + // versioned directory. + return GetVersionedDirectory().Append(kFrameworkName); +} + +bool GetLocalLibraryDirectory(base::FilePath* result) { + return base::mac::GetLocalDirectory(NSLibraryDirectory, result); +} + +bool GetUserLibraryDirectory(base::FilePath* result) { + return base::mac::GetUserDirectory(NSLibraryDirectory, result); +} + +bool GetUserApplicationsDirectory(base::FilePath* result) { + return base::mac::GetUserDirectory(NSApplicationDirectory, result); +} + +bool GetGlobalApplicationSupportDirectory(base::FilePath* result) { + return base::mac::GetLocalDirectory(NSApplicationSupportDirectory, result); +} + +NSBundle* OuterAppBundle() { + // Cache this. Foundation leaks it anyway, and this should be the only call + // to OuterAppBundleInternal(). + static NSBundle* bundle = OuterAppBundleInternal(); + return bundle; +} + +bool GetUserDataDirectoryForBrowserBundle(NSBundle* bundle, + base::FilePath* result) { + scoped_ptr + product_dir_name(ProductDirNameForBundle(bundle)); + return GetDefaultUserDataDirectoryForProduct(product_dir_name.get(), result); +} + +#endif // !defined(OS_IOS) + +bool ProcessNeedsProfileDir(const std::string& process_type) { + // For now we have no reason to forbid this on other MacOS as we don't + // have the roaming profile troubles there. + return true; +} + +} // namespace chrome diff --git a/chromium_src/chrome/common/chrome_paths_win.cc b/chromium_src/chrome/common/chrome_paths_win.cc new file mode 100644 index 000000000000..18073ca04759 --- /dev/null +++ b/chromium_src/chrome/common/chrome_paths_win.cc @@ -0,0 +1,122 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/common/chrome_paths_internal.h" + +#include +#include +#include +#include +#include + +#include "base/files/file_path.h" +#include "base/path_service.h" +#include "base/win/metro.h" +#include "base/win/scoped_co_mem.h" +#include "chrome/common/chrome_constants.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/installer/util/browser_distribution.h" +#include "components/nacl/common/nacl_switches.h" + +namespace chrome { + +namespace { + +// Generic function to call SHGetFolderPath(). +bool GetUserDirectory(int csidl_folder, base::FilePath* result) { + // We need to go compute the value. It would be nice to support paths + // with names longer than MAX_PATH, but the system functions don't seem + // to be designed for it either, with the exception of GetTempPath + // (but other things will surely break if the temp path is too long, + // so we don't bother handling it. + wchar_t path_buf[MAX_PATH]; + path_buf[0] = 0; + if (FAILED(SHGetFolderPath(NULL, csidl_folder, NULL, + SHGFP_TYPE_CURRENT, path_buf))) { + return false; + } + *result = base::FilePath(path_buf); + return true; +} + +} // namespace + +bool GetDefaultUserDataDirectory(base::FilePath* result) { + if (!PathService::Get(base::DIR_LOCAL_APP_DATA, result)) + return false; + BrowserDistribution* dist = BrowserDistribution::GetDistribution(); + *result = result->Append(dist->GetInstallSubDir()); + *result = result->Append(chrome::kUserDataDirname); + return true; +} + +void GetUserCacheDirectory(const base::FilePath& profile_dir, + base::FilePath* result) { + // This function does more complicated things on Mac/Linux. + *result = profile_dir; +} + +bool GetUserDocumentsDirectory(base::FilePath* result) { + return GetUserDirectory(CSIDL_MYDOCUMENTS, result); +} + +// Return a default path for downloads that is safe. +// We just use 'Downloads' under DIR_USER_DOCUMENTS. Localizing +// 'downloads' is not a good idea because Chrome's UI language +// can be changed. +bool GetUserDownloadsDirectorySafe(base::FilePath* result) { + if (!GetUserDocumentsDirectory(result)) + return false; + + *result = result->Append(L"Downloads"); + return true; +} + +// On Vista and higher, use the downloads known folder. Since it can be +// relocated to point to a "dangerous" folder, callers should validate that the +// returned path is not dangerous before using it. +bool GetUserDownloadsDirectory(base::FilePath* result) { + typedef HRESULT (WINAPI *GetKnownFolderPath)( + REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR*); + GetKnownFolderPath f = reinterpret_cast( + GetProcAddress(GetModuleHandle(L"shell32.dll"), "SHGetKnownFolderPath")); + base::win::ScopedCoMem path_buf; + if (f && SUCCEEDED(f(FOLDERID_Downloads, 0, NULL, &path_buf))) { + *result = base::FilePath(std::wstring(path_buf)); + return true; + } + return GetUserDownloadsDirectorySafe(result); +} + +bool GetUserMusicDirectory(base::FilePath* result) { + return GetUserDirectory(CSIDL_MYMUSIC, result); +} + +bool GetUserPicturesDirectory(base::FilePath* result) { + return GetUserDirectory(CSIDL_MYPICTURES, result); +} + +bool GetUserVideosDirectory(base::FilePath* result) { + return GetUserDirectory(CSIDL_MYVIDEO, result); +} + +bool ProcessNeedsProfileDir(const std::string& process_type) { + // On windows we don't want subprocesses other than the browser process and + // service processes to be able to use the profile directory because if it + // lies on a network share the sandbox will prevent us from accessing it. + + if (process_type.empty() || process_type == switches::kServiceProcess) + return true; + +#if !defined(DISABLE_NACL) + if (process_type == switches::kNaClBrokerProcess || + process_type == switches::kNaClLoaderProcess) { + return true; + } +#endif + + return false; +} + +} // namespace chrome diff --git a/filenames.gypi b/filenames.gypi index 658c8e76b6b0..0e91dd21e16d 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -419,6 +419,14 @@ 'chromium_src/chrome/browser/ui/views/color_chooser_aura.h', 'chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.cc', 'chromium_src/chrome/browser/ui/views/frame/global_menu_bar_registrar_x11.h', + 'chromium_src/chrome/common/chrome_constants.cc', + 'chromium_src/chrome/common/chrome_constants.h', + 'chromium_src/chrome/common/chrome_paths.cc', + 'chromium_src/chrome/common/chrome_paths.h', + 'chromium_src/chrome/common/chrome_paths_internal.h', + 'chromium_src/chrome/common/chrome_paths_linux.cc', + 'chromium_src/chrome/common/chrome_paths_mac.mm', + 'chromium_src/chrome/common/chrome_paths_win.cc', 'chromium_src/chrome/common/chrome_utility_messages.h', 'chromium_src/chrome/common/pref_names.cc', 'chromium_src/chrome/common/pref_names.h',