1From da96bead3af1bfc9c808ac4774597be0bbe2fb9e Mon Sep 17 00:00:00 2001
2From: Sharaf Zaman <sharafzaz121@gmail.com>
3Date: Mon, 1 Jun 2020 00:05:25 +0530
4Subject: [PATCH 2/2] Android: return the actual file name the URI is pointing
5 to
6
7This only manages QFileInfo::filename() and QFileInfo::suffix().
8
9Change-Id: Iec527e2a6808f04dca25fd17e82e8d2aa7e45cfc
10---
11 .../org/qtproject/qt5/android/QtNative.java   | 24 +++++++++++
12 src/corelib/io/qfileinfo.cpp                  | 11 +++++
13 .../android/androidcontentfileengine.cpp      | 42 ++++++++++++++-----
14 .../android/androidcontentfileengine.h        |  5 ++-
15 4 files changed, 70 insertions(+), 12 deletions(-)
16
17diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
18index b5d2b9e6a6..4282f73638 100644
19--- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
20+++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
21@@ -290,6 +290,30 @@ public class QtNative
22         }
23     }
24
25+    public static String getFileNameFromUri(Context context, String contentUrl)
26+    {
27+        Uri uri = getUriWithValidPermission(context, contentUrl, "r");
28+        if (uri == null) {
29+            Log.e(QtTAG, "getFileNameFromUri(): No permissions to open Uri");
30+            return null;
31+        }
32+
33+        String filename = null;
34+        try {
35+            Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
36+            if (cursor != null) {
37+                if (cursor.moveToFirst()) {
38+                    filename = cursor.getString(cursor.getColumnIndexOrThrow(OpenableColumns.DISPLAY_NAME));
39+                }
40+                cursor.close();
41+            }
42+        } catch (IllegalArgumentException e) {
43+            Log.e(QtTAG, "getFileNameFromUri(): Couldn't get filename");
44+        }
45+
46+        return filename;
47+    }
48+
49     // this method loads full path libs
50     public static void loadQtLibraries(final ArrayList<String> libraries)
51     {
52diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
53index 185e061d8f..189b704b51 100644
54--- a/src/corelib/io/qfileinfo.cpp
55+++ b/src/corelib/io/qfileinfo.cpp
56@@ -757,6 +757,12 @@ QString QFileInfo::fileName() const
57     Q_D(const QFileInfo);
58     if (d->isDefaultConstructed)
59         return QLatin1String("");
60+#ifdef Q_OS_ANDROID
61+    if (d->fileEntry.filePath().startsWith("content:") && d->fileEngine) {
62+        QString fname = d->fileEngine->fileName();
63+        return fname;
64+    }
65+#endif
66     return d->fileEntry.fileName();
67 }
68
69@@ -862,6 +868,11 @@ QString QFileInfo::suffix() const
70     Q_D(const QFileInfo);
71     if (d->isDefaultConstructed)
72         return QLatin1String("");
73+
74+#ifdef Q_OS_ANDROID
75+    QString fname = fileName();
76+    return fname.split(".").last();
77+#endif
78     return d->fileEntry.suffix();
79 }
80
81diff --git a/src/plugins/platforms/android/androidcontentfileengine.cpp b/src/plugins/platforms/android/androidcontentfileengine.cpp
82index 6351b642ae..31f68780df 100644
83--- a/src/plugins/platforms/android/androidcontentfileengine.cpp
84+++ b/src/plugins/platforms/android/androidcontentfileengine.cpp
85@@ -45,9 +45,10 @@
86 #include <QDebug>
87
88 AndroidContentFileEngine::AndroidContentFileEngine(const QString &f)
89-    : m_file(f)
90+    : m_file(f), m_resolvedName(QString())
91 {
92     setFileName(f);
93+    setResolvedFileName(f);
94 }
95
96 bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode)
97@@ -69,7 +70,7 @@ bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode)
98         "openFdForContentUrl",
99         "(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)I",
100         QtAndroidPrivate::context(),
101-        QJNIObjectPrivate::fromString(fileName(DefaultName)).object(),
102+        QJNIObjectPrivate::fromString(m_file).object(),
103         QJNIObjectPrivate::fromString(openModeStr).object());
104
105     if (fd < 0) {
106@@ -84,7 +85,7 @@ qint64 AndroidContentFileEngine::size() const
107     const jlong size = QJNIObjectPrivate::callStaticMethod<jlong>(
108             "org/qtproject/qt5/android/QtNative", "getSize",
109             "(Landroid/content/Context;Ljava/lang/String;)J", QtAndroidPrivate::context(),
110-            QJNIObjectPrivate::fromString(fileName(DefaultName)).object());
111+            QJNIObjectPrivate::fromString(m_file).object());
112     return (qint64)size;
113 }
114
115@@ -95,7 +96,7 @@ AndroidContentFileEngine::FileFlags AndroidContentFileEngine::fileFlags(FileFlag
116     const bool exists = QJNIObjectPrivate::callStaticMethod<jboolean>(
117             "org/qtproject/qt5/android/QtNative", "checkFileExists",
118             "(Landroid/content/Context;Ljava/lang/String;)Z", QtAndroidPrivate::context(),
119-            QJNIObjectPrivate::fromString(fileName(DefaultName)).object());
120+            QJNIObjectPrivate::fromString(m_file).object());
121     if (!exists)
122         return flags;
123     flags = FileType | commonFlags;
124@@ -105,23 +106,42 @@ AndroidContentFileEngine::FileFlags AndroidContentFileEngine::fileFlags(FileFlag
125 QString AndroidContentFileEngine::fileName(FileName f) const
126 {
127     switch (f) {
128+        case DefaultName: {
129+            return m_resolvedName;
130+        }
131         case PathName:
132-        case AbsolutePathName:
133-        case CanonicalPathName:
134-        case DefaultName:
135         case AbsoluteName:
136+        case AbsolutePathName:
137         case CanonicalName:
138+        case CanonicalPathName:
139             return m_file;
140-        case BaseName:
141-        {
142-            const int pos = m_file.lastIndexOf(QChar(QLatin1Char('/')));
143-            return m_file.mid(pos);
144+
145+        case BaseName: {
146+            const int pos = m_resolvedName.lastIndexOf(QChar(QLatin1Char('/')));
147+            return m_resolvedName.mid(pos);
148         }
149         default:
150             return QString();
151     }
152 }
153
154+void AndroidContentFileEngine::setResolvedFileName(const QString& uri)
155+{
156+    QJNIObjectPrivate resolvedName = QJNIObjectPrivate::callStaticObjectMethod(
157+        "org/qtproject/qt5/android/QtNative",
158+        "getFileNameFromUri",
159+        "(Landroid/content/Context;Ljava/lang/String;)Ljava/lang/String;",
160+        QtAndroidPrivate::context(),
161+        QJNIObjectPrivate::fromString(uri).object());
162+
163+    if (resolvedName.isValid()) {
164+        m_resolvedName = resolvedName.toString();
165+    } else {
166+        qWarning("setResolvedFileName: Couldn't resolve the URI");
167+    }
168+}
169+
170+
171 AndroidContentFileEngineHandler::AndroidContentFileEngineHandler() = default;
172 AndroidContentFileEngineHandler::~AndroidContentFileEngineHandler() = default;
173
174diff --git a/src/plugins/platforms/android/androidcontentfileengine.h b/src/plugins/platforms/android/androidcontentfileengine.h
175index 09e5d77553..bb97bd6975 100644
176--- a/src/plugins/platforms/android/androidcontentfileengine.h
177+++ b/src/plugins/platforms/android/androidcontentfileengine.h
178@@ -50,9 +50,12 @@ public:
179     qint64 size() const override;
180     FileFlags fileFlags(FileFlags type = FileInfoAll) const override;
181     QString fileName(FileName file = DefaultName) const override;
182+
183+    /// Resolves the URI to the actual filename
184+    void setResolvedFileName(const QString& uri);
185 private:
186     QString m_file;
187-
188+    QString m_resolvedName;
189 };
190
191 class AndroidContentFileEngineHandler : public QAbstractFileEngineHandler
192--
1932.26.2
194
195