1 // Copyright (c) 2013 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "xwalk/runtime/common/xwalk_paths.h"
7 #include "base/file_util.h"
8 #include "base/files/file_path.h"
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/path_service.h"
12 #include "xwalk/runtime/browser/xwalk_runner.h"
15 #include "base/base_paths_win.h"
16 #elif defined(OS_LINUX)
17 #include "base/environment.h"
18 #include "base/nix/xdg_util.h"
19 #elif defined(OS_MACOSX) && !defined(OS_IOS)
20 #import "base/mac/mac_util.h"
27 #if defined(OS_MACOSX) && !defined(OS_IOS)
29 base::FilePath GetVersionedDirectory() {
30 // Start out with the path to the running executable.
32 PathService::Get(base::FILE_EXE, &path);
34 // One step up to MacOS, another to Contents.
35 path = path.DirName().DirName();
36 DCHECK_EQ(path.BaseName().value(), "Contents");
38 if (base::mac::IsBackgroundOnlyProcess()) {
39 // path identifies the helper .app's Contents directory in the browser
40 // .app's versioned directory. Go up two steps to get to the browser
41 // .app's versioned directory.
42 path = path.DirName().DirName();
48 base::FilePath GetFrameworkBundlePath() {
49 // It's tempting to use +[NSBundle bundleWithIdentifier:], but it's really
50 // slow (about 30ms on 10.5 and 10.6), despite Apple's documentation stating
51 // that it may be more efficient than +bundleForClass:. +bundleForClass:
52 // itself takes 1-2ms. Getting an NSBundle from a path, on the other hand,
53 // essentially takes no time at all, at least when the bundle has already
54 // been loaded as it will have been in this case. The FilePath operations
55 // needed to compute the framework's path are also effectively free, so that
56 // is the approach that is used here. NSBundle is also documented as being
57 // not thread-safe, and thread safety may be a concern here.
59 // The framework bundle is at a known path and name from the browser .app's
60 // versioned directory.
61 return GetVersionedDirectory().Append("XWalk");
65 // File name of the internal NaCl plugin on different platforms.
66 const base::FilePath::CharType kInternalNaClPluginFileName[] =
68 FILE_PATH_LITERAL("ppGoogleNaClPluginChrome.dll");
69 #elif defined(OS_MACOSX)
70 // TODO(noelallen) Please verify this extention name is correct.
71 FILE_PATH_LITERAL("ppGoogleNaClPluginChrome.plugin");
72 #else // Linux and Chrome OS
73 FILE_PATH_LITERAL("libppGoogleNaClPluginChrome.so");
77 base::FilePath GetConfigPath() {
78 scoped_ptr<base::Environment> env(base::Environment::Create());
79 return base::nix::GetXDGDirectory(
80 env.get(), base::nix::kXdgConfigHomeEnvVar, base::nix::kDotConfigDir);
84 bool GetXWalkDataPath(base::FilePath* path) {
85 base::FilePath::StringType xwalk_suffix;
86 if (XWalkRunner::GetInstance()->is_running_as_service())
87 xwalk_suffix = FILE_PATH_LITERAL("xwalk-service");
89 xwalk_suffix = FILE_PATH_LITERAL("xwalk");
93 CHECK(PathService::Get(base::DIR_LOCAL_APP_DATA, &cur));
94 cur = cur.Append(xwalk_suffix);
96 #elif defined(OS_TIZEN)
97 if (XWalkRunner::GetInstance()->is_running_as_service())
98 cur = GetConfigPath().Append(xwalk_suffix);
100 cur = base::FilePath("/opt/usr/apps");
102 #elif defined(OS_LINUX)
103 cur = GetConfigPath().Append(xwalk_suffix);
105 #elif defined(OS_MACOSX)
106 CHECK(PathService::Get(base::DIR_APP_DATA, &cur));
107 cur = cur.Append(xwalk_suffix);
110 NOTIMPLEMENTED() << "Unsupported OS platform.";
118 bool GetInternalPluginsDirectory(base::FilePath* result) {
119 #if defined(OS_MACOSX) && !defined(OS_IOS)
120 // If called from Chrome, get internal plugins from a subdirectory of the
122 if (base::mac::AmIBundled()) {
123 *result = xwalk::GetFrameworkBundlePath();
124 DCHECK(!result->empty());
125 *result = result->Append("Internet Plug-Ins");
128 // In tests, just look in the module directory (below).
131 // The rest of the world expects plugins in the module directory.
132 return PathService::Get(base::DIR_MODULE, result);
137 bool PathProvider(int key, base::FilePath* path) {
140 case xwalk::DIR_DATA_PATH:
141 return GetXWalkDataPath(path);
143 case xwalk::DIR_INTERNAL_PLUGINS:
144 if (!GetInternalPluginsDirectory(&cur))
147 case xwalk::FILE_NACL_PLUGIN:
148 if (!GetInternalPluginsDirectory(&cur))
150 cur = cur.Append(kInternalNaClPluginFileName);
152 // Where PNaCl files are ultimately located. The default finds the files
153 // inside the InternalPluginsDirectory / build directory, as if it
154 // was shipped along with xwalk. The value can be overridden
155 // if it is installed via component updater.
156 case xwalk::DIR_PNACL_COMPONENT:
157 #if defined(OS_MACOSX)
158 // PNaCl really belongs in the InternalPluginsDirectory but actually
159 // copying it there would result in the files also being shipped, which
160 // we don't want yet. So for now, just find them in the directory where
162 if (!PathService::Get(base::DIR_EXE, &cur))
164 if (base::mac::AmIBundled()) {
165 // If we're called from xwalk, it's beside the app (outside the
166 // app bundle), if we're called from a unittest, we'll already be
167 // outside the bundle so use the exe dir.
168 // exe_dir gave us .../Chromium.app/Contents/MacOS/Chromium.
174 if (!GetInternalPluginsDirectory(&cur))
177 cur = cur.Append(FILE_PATH_LITERAL("pnacl"));
179 case xwalk::DIR_TEST_DATA:
180 if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
182 cur = cur.Append(FILE_PATH_LITERAL("xwalk"));
183 cur = cur.Append(FILE_PATH_LITERAL("test"));
184 cur = cur.Append(FILE_PATH_LITERAL("data"));
186 case xwalk::DIR_WGT_STORAGE_PATH:
187 if (!GetXWalkDataPath(&cur))
189 cur = cur.Append(FILE_PATH_LITERAL("Widget Storage"));
198 void RegisterPathProvider() {
199 PathService::RegisterProvider(PathProvider, PATH_START, PATH_END);