Warning: That file was not part of the compilation database. It may have many parsing errors.
1 | /**************************************************************************** |
---|---|
2 | ** |
3 | ** Copyright (C) 2013 BlackBerry Limited. All rights reserved. |
4 | ** Copyright (C) 2016 The Qt Company Ltd. |
5 | ** Contact: https://www.qt.io/licensing/ |
6 | ** |
7 | ** This file is part of the QtWebEngine module of the Qt Toolkit. |
8 | ** |
9 | ** $QT_BEGIN_LICENSE:LGPL$ |
10 | ** Commercial License Usage |
11 | ** Licensees holding valid commercial Qt licenses may use this file in |
12 | ** accordance with the commercial license agreement provided with the |
13 | ** Software or, alternatively, in accordance with the terms contained in |
14 | ** a written agreement between you and The Qt Company. For licensing terms |
15 | ** and conditions see https://www.qt.io/terms-conditions. For further |
16 | ** information use the contact form at https://www.qt.io/contact-us. |
17 | ** |
18 | ** GNU Lesser General Public License Usage |
19 | ** Alternatively, this file may be used under the terms of the GNU Lesser |
20 | ** General Public License version 3 as published by the Free Software |
21 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |
22 | ** packaging of this file. Please review the following information to |
23 | ** ensure the GNU Lesser General Public License version 3 requirements |
24 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |
25 | ** |
26 | ** GNU General Public License Usage |
27 | ** Alternatively, this file may be used under the terms of the GNU |
28 | ** General Public License version 2.0 or (at your option) the GNU General |
29 | ** Public license version 3 or any later version approved by the KDE Free |
30 | ** Qt Foundation. The licenses are as published by the Free Software |
31 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |
32 | ** included in the packaging of this file. Please review the following |
33 | ** information to ensure the GNU General Public License requirements will |
34 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |
35 | ** https://www.gnu.org/licenses/gpl-3.0.html. |
36 | ** |
37 | ** $QT_END_LICENSE$ |
38 | ** |
39 | ****************************************************************************/ |
40 | |
41 | #include "web_engine_library_info.h" |
42 | |
43 | #include "base/base_paths.h" |
44 | #include "base/command_line.h" |
45 | #include "base/files/file_util.h" |
46 | #include "components/spellcheck/spellcheck_buildflags.h" |
47 | #include "content/public/common/content_paths.h" |
48 | #include "ui/base/ui_base_paths.h" |
49 | #include "ui/base/ui_base_switches.h" |
50 | #include "type_conversion.h" |
51 | |
52 | #include <QByteArray> |
53 | #include <QCoreApplication> |
54 | #include <QDir> |
55 | #include <QFileInfo> |
56 | #include <QLibraryInfo> |
57 | #include <QLocale> |
58 | #include <QStandardPaths> |
59 | #include <QString> |
60 | |
61 | #ifndef QTWEBENGINEPROCESS_NAME |
62 | #error "No name defined for QtWebEngine's process" |
63 | #endif |
64 | |
65 | using namespace QtWebEngineCore; |
66 | |
67 | namespace { |
68 | |
69 | QString fallbackDir() { |
70 | static QString directory = QDir::homePath() % QLatin1String("/.") % QCoreApplication::applicationName(); |
71 | return directory; |
72 | } |
73 | |
74 | #if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD) |
75 | static inline CFBundleRef frameworkBundle() |
76 | { |
77 | return CFBundleGetBundleWithIdentifier(CFSTR("org.qt-project.Qt.QtWebEngineCore")); |
78 | } |
79 | |
80 | static QString getPath(CFBundleRef frameworkBundle) |
81 | { |
82 | QString path; |
83 | // The following is a fix for QtWebEngineProcess crashes on OS X 10.7 and before. |
84 | // We use it for the other OS X versions as well to make sure it works and because |
85 | // the directory structure should be the same. |
86 | if (qApp->applicationName() == QLatin1String(QTWEBENGINEPROCESS_NAME)) { |
87 | path = QDir::cleanPath(qApp->applicationDirPath() % QLatin1String("/../../../..")); |
88 | } else if (frameworkBundle) { |
89 | CFURLRef bundleUrl = CFBundleCopyBundleURL(frameworkBundle); |
90 | CFStringRef bundlePath = CFURLCopyFileSystemPath(bundleUrl, kCFURLPOSIXPathStyle); |
91 | path = QString::fromCFString(bundlePath); |
92 | CFRelease(bundlePath); |
93 | CFRelease(bundleUrl); |
94 | } |
95 | return path; |
96 | } |
97 | |
98 | static QString getResourcesPath(CFBundleRef frameworkBundle) |
99 | { |
100 | QString path; |
101 | // The following is a fix for QtWebEngineProcess crashes on OS X 10.7 and before. |
102 | // We use it for the other OS X versions as well to make sure it works and because |
103 | // the directory structure should be the same. |
104 | if (qApp->applicationName() == QLatin1String(QTWEBENGINEPROCESS_NAME)) { |
105 | path = getPath(frameworkBundle) % QLatin1String("/Resources"); |
106 | } else if (frameworkBundle) { |
107 | CFURLRef resourcesRelativeUrl = CFBundleCopyResourcesDirectoryURL(frameworkBundle); |
108 | CFStringRef resourcesRelativePath = CFURLCopyFileSystemPath(resourcesRelativeUrl, kCFURLPOSIXPathStyle); |
109 | path = getPath(frameworkBundle) % QLatin1Char('/') % QString::fromCFString(resourcesRelativePath); |
110 | CFRelease(resourcesRelativePath); |
111 | CFRelease(resourcesRelativeUrl); |
112 | } |
113 | return path; |
114 | } |
115 | #endif |
116 | |
117 | #if defined(OS_MACOSX) |
118 | static QString getMainApplicationResourcesPath() |
119 | { |
120 | QString resourcesPath; |
121 | CFBundleRef mainBundle = CFBundleGetMainBundle(); |
122 | if (!mainBundle) |
123 | return resourcesPath; |
124 | |
125 | // Will point to Resources inside an app bundle, or in case if the application is not packaged |
126 | // as a bundle, will point to the application directory, where the resources are assumed to be |
127 | // found. |
128 | CFURLRef resourcesRelativeUrl = CFBundleCopyResourcesDirectoryURL(mainBundle); |
129 | if (!resourcesRelativeUrl) |
130 | return resourcesPath; |
131 | |
132 | CFURLRef resourcesAbsoluteUrl = CFURLCopyAbsoluteURL(resourcesRelativeUrl); |
133 | CFStringRef resourcesAbolutePath = CFURLCopyFileSystemPath(resourcesAbsoluteUrl, |
134 | kCFURLPOSIXPathStyle); |
135 | resourcesPath = QString::fromCFString(resourcesAbolutePath); |
136 | CFRelease(resourcesAbolutePath); |
137 | CFRelease(resourcesAbsoluteUrl); |
138 | CFRelease(resourcesRelativeUrl); |
139 | |
140 | return resourcesPath; |
141 | } |
142 | |
143 | #endif |
144 | |
145 | QString subProcessPath() |
146 | { |
147 | static QString processPath; |
148 | if (processPath.isEmpty()) { |
149 | #if defined(OS_WIN) |
150 | const QString processBinary = QLatin1String(QTWEBENGINEPROCESS_NAME) % QLatin1String(".exe"); |
151 | #else |
152 | const QString processBinary = QLatin1String(QTWEBENGINEPROCESS_NAME); |
153 | #endif |
154 | |
155 | QStringList candidatePaths; |
156 | const QByteArray fromEnv = qgetenv("QTWEBENGINEPROCESS_PATH"); |
157 | if (!fromEnv.isEmpty()) { |
158 | // Only search in QTWEBENGINEPROCESS_PATH if set |
159 | candidatePaths << QString::fromLocal8Bit(fromEnv); |
160 | } else { |
161 | #if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD) |
162 | candidatePaths << getPath(frameworkBundle()) |
163 | % QStringLiteral("/Helpers/"QTWEBENGINEPROCESS_NAME ".app/Contents/MacOS/"QTWEBENGINEPROCESS_NAME); |
164 | #else |
165 | candidatePaths << QLibraryInfo::location(QLibraryInfo::LibraryExecutablesPath) |
166 | % QLatin1Char('/') % processBinary; |
167 | #endif |
168 | candidatePaths << QCoreApplication::applicationDirPath() |
169 | % QLatin1Char('/') % processBinary; |
170 | } |
171 | |
172 | for (const QString &candidate : qAsConst(candidatePaths)) { |
173 | if (QFileInfo::exists(candidate)) { |
174 | processPath = candidate; |
175 | break; |
176 | } |
177 | } |
178 | if (processPath.isEmpty()) |
179 | qFatal("Could not find %s", processBinary.toUtf8().constData()); |
180 | |
181 | } |
182 | |
183 | |
184 | return processPath; |
185 | } |
186 | |
187 | QString localesPath() |
188 | { |
189 | static bool initialized = false; |
190 | static QString potentialLocalesPath = |
191 | #if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD) |
192 | getResourcesPath(frameworkBundle()) % QLatin1String("/qtwebengine_locales"); |
193 | #else |
194 | QLibraryInfo::location(QLibraryInfo::TranslationsPath) % QDir::separator() % QLatin1String("qtwebengine_locales"); |
195 | #endif |
196 | |
197 | if (!initialized) { |
198 | initialized = true; |
199 | if (!QFileInfo::exists(potentialLocalesPath)) { |
200 | qWarning("Installed Qt WebEngine locales directory not found at location %s. Trying application directory...", qPrintable(potentialLocalesPath)); |
201 | potentialLocalesPath = QCoreApplication::applicationDirPath() % QDir::separator() % QLatin1String("qtwebengine_locales"); |
202 | } |
203 | if (!QFileInfo::exists(potentialLocalesPath)) { |
204 | qWarning("Qt WebEngine locales directory not found at location %s. Trying fallback directory... Translations MAY NOT not be correct.", qPrintable(potentialLocalesPath)); |
205 | potentialLocalesPath = fallbackDir(); |
206 | } |
207 | } |
208 | |
209 | return potentialLocalesPath; |
210 | } |
211 | |
212 | #if QT_CONFIG(webengine_spellchecker) |
213 | QString dictionariesPath() |
214 | { |
215 | static QString potentialDictionariesPath; |
216 | static bool initialized = false; |
217 | QStringList candidatePaths; |
218 | if (!initialized) { |
219 | initialized = true; |
220 | |
221 | const QByteArray fromEnv = qgetenv("QTWEBENGINE_DICTIONARIES_PATH"); |
222 | if (!fromEnv.isEmpty()) { |
223 | // Only search in QTWEBENGINE_DICTIONARIES_PATH if set |
224 | candidatePaths << QString::fromLocal8Bit(fromEnv); |
225 | } else { |
226 | // First try to find dictionaries near the application. |
227 | #ifdef OS_MACOSX |
228 | QString resourcesDictionariesPath = getMainApplicationResourcesPath() |
229 | % QDir::separator() % QLatin1String("qtwebengine_dictionaries"); |
230 | candidatePaths << resourcesDictionariesPath; |
231 | #endif |
232 | QString applicationDictionariesPath = QCoreApplication::applicationDirPath() |
233 | % QDir::separator() % QLatin1String("qtwebengine_dictionaries"); |
234 | candidatePaths << applicationDictionariesPath; |
235 | |
236 | // Then try to find dictionaries near the installed library. |
237 | #if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD) |
238 | QString frameworkDictionariesPath = getResourcesPath(frameworkBundle()) |
239 | % QLatin1String("/qtwebengine_dictionaries"); |
240 | candidatePaths << frameworkDictionariesPath; |
241 | #endif |
242 | |
243 | QString libraryDictionariesPath = QLibraryInfo::location(QLibraryInfo::DataPath) |
244 | % QDir::separator() % QLatin1String("qtwebengine_dictionaries"); |
245 | candidatePaths << libraryDictionariesPath; |
246 | } |
247 | |
248 | for (const QString &candidate : qAsConst(candidatePaths)) { |
249 | if (QFileInfo::exists(candidate)) { |
250 | potentialDictionariesPath = candidate; |
251 | break; |
252 | } |
253 | } |
254 | } |
255 | |
256 | return potentialDictionariesPath; |
257 | } |
258 | #endif // QT_CONFIG(webengine_spellchecker) |
259 | |
260 | QString resourcesDataPath() |
261 | { |
262 | static bool initialized = false; |
263 | static QString potentialResourcesPath = |
264 | #if defined(OS_MACOSX) && defined(QT_MAC_FRAMEWORK_BUILD) |
265 | getResourcesPath(frameworkBundle()); |
266 | #else |
267 | QLibraryInfo::location(QLibraryInfo::DataPath) % QLatin1String("/resources"); |
268 | #endif |
269 | if (!initialized) { |
270 | initialized = true; |
271 | if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/qtwebengine_resources.pak"))) { |
272 | qWarning("Qt WebEngine resources not found at %s. Trying parent directory...", qPrintable(potentialResourcesPath)); |
273 | potentialResourcesPath = QLibraryInfo::location(QLibraryInfo::DataPath); |
274 | } |
275 | if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/qtwebengine_resources.pak"))) { |
276 | qWarning("Qt WebEngine resources not found at %s. Trying application directory...", qPrintable(potentialResourcesPath)); |
277 | potentialResourcesPath = QCoreApplication::applicationDirPath(); |
278 | } |
279 | if (!QFileInfo::exists(potentialResourcesPath % QLatin1String("/qtwebengine_resources.pak"))) { |
280 | qWarning("Qt WebEngine resources not found at %s. Trying fallback directory... The application MAY NOT work.", qPrintable(potentialResourcesPath)); |
281 | potentialResourcesPath = fallbackDir(); |
282 | } |
283 | } |
284 | |
285 | return potentialResourcesPath; |
286 | } |
287 | } // namespace |
288 | |
289 | base::FilePath WebEngineLibraryInfo::getPath(int key) |
290 | { |
291 | QString directory; |
292 | switch (key) { |
293 | case QT_RESOURCES_PAK: |
294 | return toFilePath(resourcesDataPath() % QLatin1String("/qtwebengine_resources.pak")); |
295 | case QT_RESOURCES_100P_PAK: |
296 | return toFilePath(resourcesDataPath() % QLatin1String("/qtwebengine_resources_100p.pak")); |
297 | case QT_RESOURCES_200P_PAK: |
298 | return toFilePath(resourcesDataPath() % QLatin1String("/qtwebengine_resources_200p.pak")); |
299 | case QT_RESOURCES_DEVTOOLS_PAK: |
300 | return toFilePath(resourcesDataPath() % QLatin1String("/qtwebengine_devtools_resources.pak")); |
301 | case base::FILE_EXE: |
302 | case content::CHILD_PROCESS_EXE: |
303 | return toFilePath(subProcessPath()); |
304 | #if defined(OS_POSIX) |
305 | case base::DIR_CACHE: |
306 | directory = QStandardPaths::writableLocation(QStandardPaths::CacheLocation); |
307 | break; |
308 | case base::DIR_HOME: |
309 | directory = QDir::homePath(); |
310 | break; |
311 | #endif |
312 | case base::DIR_USER_DESKTOP: |
313 | directory = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); |
314 | break; |
315 | case base::DIR_QT_LIBRARY_DATA: |
316 | return toFilePath(resourcesDataPath()); |
317 | case ui::DIR_LOCALES: |
318 | return toFilePath(localesPath()); |
319 | #if QT_CONFIG(webengine_spellchecker) |
320 | case base::DIR_APP_DICTIONARIES: |
321 | return toFilePath(dictionariesPath()); |
322 | #endif |
323 | default: |
324 | // Note: the path system expects this function to override the default |
325 | // behavior. So no need to log an error if we don't support a given |
326 | // path. The system will just use the default. |
327 | return base::FilePath(); |
328 | } |
329 | |
330 | return toFilePath(directory.isEmpty() ? fallbackDir() : directory); |
331 | } |
332 | |
333 | base::string16 WebEngineLibraryInfo::getApplicationName() |
334 | { |
335 | return toString16(qApp->applicationName()); |
336 | } |
337 | |
338 | std::string WebEngineLibraryInfo::getApplicationLocale() |
339 | { |
340 | base::CommandLine *parsedCommandLine = base::CommandLine::ForCurrentProcess(); |
341 | if (!parsedCommandLine->HasSwitch(switches::kLang)) { |
342 | const QString &locale = QLocale().bcp47Name(); |
343 | |
344 | // QLocale::bcp47Name returns "en" for American English locale. Chromium requires the "US" suffix |
345 | // to clarify the dialect and ignores the shorter version. |
346 | if (locale == "en") |
347 | return "en-US"; |
348 | |
349 | return locale.toStdString(); |
350 | } |
351 | |
352 | return parsedCommandLine->GetSwitchValueASCII(switches::kLang); |
353 | } |
354 |
Warning: That file was not part of the compilation database. It may have many parsing errors.