Warning: That file was not part of the compilation database. It may have many parsing errors.

1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#include "qstandardpaths.h"
41
42#ifndef QT_NO_STANDARDPATHS
43
44#include <QtCore/private/qjni_p.h>
45#include <QtCore/private/qjnihelpers_p.h>
46#include <QtCore/qmap.h>
47#include <QDir>
48
49QT_BEGIN_NAMESPACE
50
51typedef QMap<QString, QString> AndroidDirCache;
52Q_GLOBAL_STATIC(AndroidDirCache, androidDirCache)
53
54static QString testDir()
55{
56 return QStandardPaths::isTestModeEnabled() ? QLatin1String("/qttest")
57 : QLatin1String("");
58}
59
60static QJNIObjectPrivate applicationContext()
61{
62 static QJNIObjectPrivate appCtx;
63 if (appCtx.isValid())
64 return appCtx;
65
66 QJNIObjectPrivate context(QtAndroidPrivate::activity());
67 if (!context.isValid()) {
68 context = QtAndroidPrivate::service();
69 if (!context.isValid())
70 return appCtx;
71 }
72
73 appCtx = context.callObjectMethod("getApplicationContext",
74 "()Landroid/content/Context;");
75 return appCtx;
76}
77
78static inline QString getAbsolutePath(const QJNIObjectPrivate &file)
79{
80 QJNIObjectPrivate path = file.callObjectMethod("getAbsolutePath",
81 "()Ljava/lang/String;");
82 if (!path.isValid())
83 return QString();
84
85 return path.toString();
86}
87
88/*
89 * The root of the external storage
90 *
91 */
92static QString getExternalStorageDirectory()
93{
94 QString &path = (*androidDirCache)[QStringLiteral("EXT_ROOT")];
95 if (!path.isEmpty())
96 return path;
97
98 QJNIObjectPrivate file = QJNIObjectPrivate::callStaticObjectMethod("android/os/Environment",
99 "getExternalStorageDirectory",
100 "()Ljava/io/File;");
101 if (!file.isValid())
102 return QString();
103
104 return (path = getAbsolutePath(file));
105}
106
107/*
108 * Locations where applications can place user files (public).
109 * E.g., /storage/Music
110 */
111static QString getExternalStoragePublicDirectory(const char *directoryField)
112{
113 QString &path = (*androidDirCache)[QLatin1String(directoryField)];
114 if (!path.isEmpty())
115 return path;
116
117 QJNIObjectPrivate dirField = QJNIObjectPrivate::getStaticObjectField("android/os/Environment",
118 directoryField,
119 "Ljava/lang/String;");
120 if (!dirField.isValid())
121 return QString();
122
123 QJNIObjectPrivate file = QJNIObjectPrivate::callStaticObjectMethod("android/os/Environment",
124 "getExternalStoragePublicDirectory",
125 "(Ljava/lang/String;)Ljava/io/File;",
126 dirField.object());
127 if (!file.isValid())
128 return QString();
129
130 return (path = getAbsolutePath(file));
131}
132
133/*
134 * Locations where applications can place persistent files it owns.
135 * E.g., /storage/org.app/Music
136 */
137static QString getExternalFilesDir(const char *directoryField = 0)
138{
139 QString &path = (*androidDirCache)[QLatin1String("APPNAME_%1").arg(QLatin1String(directoryField))];
140 if (!path.isEmpty())
141 return path;
142
143 QJNIObjectPrivate appCtx = applicationContext();
144 if (!appCtx.isValid())
145 return QString();
146
147 QJNIObjectPrivate dirField = QJNIObjectPrivate::fromString(QLatin1String(""));
148 if (directoryField) {
149 dirField = QJNIObjectPrivate::getStaticObjectField("android/os/Environment",
150 directoryField,
151 "Ljava/lang/String;");
152 if (!dirField.isValid())
153 return QString();
154 }
155
156 QJNIObjectPrivate file = appCtx.callObjectMethod("getExternalFilesDir",
157 "(Ljava/lang/String;)Ljava/io/File;",
158 dirField.object());
159
160 if (!file.isValid())
161 return QString();
162
163 return (path = getAbsolutePath(file));
164}
165
166/*
167 * Directory where applications can store cache files it owns (public).
168 * E.g., /storage/org.app/
169 */
170static QString getExternalCacheDir()
171{
172 QString &path = (*androidDirCache)[QStringLiteral("APPNAME_CACHE")];
173 if (!path.isEmpty())
174 return path;
175
176 QJNIObjectPrivate appCtx = applicationContext();
177 if (!appCtx.isValid())
178 return QString();
179
180 QJNIObjectPrivate file = appCtx.callObjectMethod("getExternalCacheDir",
181 "()Ljava/io/File;");
182
183 if (!file.isValid())
184 return QString();
185
186 return (path = getAbsolutePath(file));
187}
188
189/*
190 * Directory where applications can store cache files it owns (private).
191 */
192static QString getCacheDir()
193{
194 QString &path = (*androidDirCache)[QStringLiteral("APPROOT_CACHE")];
195 if (!path.isEmpty())
196 return path;
197
198 QJNIObjectPrivate appCtx = applicationContext();
199 if (!appCtx.isValid())
200 return QString();
201
202 QJNIObjectPrivate file = appCtx.callObjectMethod("getCacheDir",
203 "()Ljava/io/File;");
204 if (!file.isValid())
205 return QString();
206
207 return (path = getAbsolutePath(file));
208}
209
210/*
211 * Directory where applications can store files it owns (private).
212 * (Same location as $HOME)
213 */
214static QString getFilesDir()
215{
216 QString &path = (*androidDirCache)[QStringLiteral("APPROOT_FILES")];
217 if (!path.isEmpty())
218 return path;
219
220 QJNIObjectPrivate appCtx = applicationContext();
221 if (!appCtx.isValid())
222 return QString();
223
224 QJNIObjectPrivate file = appCtx.callObjectMethod("getFilesDir",
225 "()Ljava/io/File;");
226 if (!file.isValid())
227 return QString();
228
229 return (path = getAbsolutePath(file));
230}
231
232QString QStandardPaths::writableLocation(StandardLocation type)
233{
234 switch (type) {
235 case QStandardPaths::MusicLocation:
236 return getExternalStoragePublicDirectory("DIRECTORY_MUSIC");
237 case QStandardPaths::MoviesLocation:
238 return getExternalStoragePublicDirectory("DIRECTORY_MOVIES");
239 case QStandardPaths::PicturesLocation:
240 return getExternalStoragePublicDirectory("DIRECTORY_PICTURES");
241 case QStandardPaths::DocumentsLocation:
242 return getExternalStoragePublicDirectory("DIRECTORY_DOCUMENTS");
243 case QStandardPaths::DownloadLocation:
244 return getExternalStoragePublicDirectory("DIRECTORY_DOWNLOADS");
245 case QStandardPaths::GenericConfigLocation:
246 case QStandardPaths::ConfigLocation:
247 case QStandardPaths::AppConfigLocation:
248 return getFilesDir() + testDir() + QLatin1String("/settings");
249 case QStandardPaths::GenericDataLocation:
250 return getExternalStorageDirectory() + testDir();
251 case QStandardPaths::AppDataLocation:
252 case QStandardPaths::AppLocalDataLocation:
253 return getFilesDir() + testDir();
254 case QStandardPaths::GenericCacheLocation:
255 case QStandardPaths::RuntimeLocation:
256 case QStandardPaths::TempLocation:
257 case QStandardPaths::CacheLocation:
258 return getCacheDir() + testDir();
259 case QStandardPaths::DesktopLocation:
260 case QStandardPaths::HomeLocation:
261 return getFilesDir();
262 case QStandardPaths::ApplicationsLocation:
263 case QStandardPaths::FontsLocation:
264 default:
265 break;
266 }
267
268 return QString();
269}
270
271QStringList QStandardPaths::standardLocations(StandardLocation type)
272{
273 if (type == MusicLocation) {
274 return QStringList() << writableLocation(type)
275 << getExternalFilesDir("DIRECTORY_MUSIC")
276 << getExternalStoragePublicDirectory("DIRECTORY_PODCASTS")
277 << getExternalFilesDir("DIRECTORY_PODCASTS")
278 << getExternalStoragePublicDirectory("DIRECTORY_NOTIFICATIONS")
279 << getExternalFilesDir("DIRECTORY_NOTIFICATIONS")
280 << getExternalStoragePublicDirectory("DIRECTORY_ALARMS")
281 << getExternalFilesDir("DIRECTORY_ALARMS");
282 }
283
284 if (type == MoviesLocation) {
285 return QStringList() << writableLocation(type)
286 << getExternalFilesDir("DIRECTORY_MOVIES");
287 }
288
289 if (type == PicturesLocation) {
290 return QStringList() << writableLocation(type)
291 << getExternalFilesDir("DIRECTORY_PICTURES");
292 }
293
294 if (type == DocumentsLocation) {
295 return QStringList() << writableLocation(type)
296 << getExternalFilesDir("DIRECTORY_DOCUMENTS");
297 }
298
299 if (type == DownloadLocation) {
300 return QStringList() << writableLocation(type)
301 << getExternalFilesDir("DIRECTORY_DOWNLOADS");
302 }
303
304 if (type == AppDataLocation || type == AppLocalDataLocation) {
305 return QStringList() << writableLocation(type)
306 << getExternalFilesDir();
307 }
308
309 if (type == CacheLocation) {
310 return QStringList() << writableLocation(type)
311 << getExternalCacheDir();
312 }
313
314 if (type == FontsLocation) {
315 QString &fontLocation = (*androidDirCache)[QStringLiteral("FONT_LOCATION")];
316 if (!fontLocation.isEmpty())
317 return QStringList(fontLocation);
318
319 const QByteArray ba = qgetenv("QT_ANDROID_FONT_LOCATION");
320 if (!ba.isEmpty())
321 return QStringList((fontLocation = QDir::cleanPath(QString::fromLocal8Bit(ba))));
322
323 // Don't cache the fallback, as we might just have been called before
324 // QT_ANDROID_FONT_LOCATION has been set.
325 return QStringList(QLatin1String("/system/fonts"));
326 }
327
328 return QStringList(writableLocation(type));
329}
330
331QT_END_NAMESPACE
332
333#endif // QT_NO_STANDARDPATHS
334

Warning: That file was not part of the compilation database. It may have many parsing errors.