summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/android/androidcontentfileengine.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/android/androidcontentfileengine.cpp')
-rw-r--r--src/plugins/platforms/android/androidcontentfileengine.cpp112
1 files changed, 50 insertions, 62 deletions
diff --git a/src/plugins/platforms/android/androidcontentfileengine.cpp b/src/plugins/platforms/android/androidcontentfileengine.cpp
index c86bbeae77..5757f5d8cc 100644
--- a/src/plugins/platforms/android/androidcontentfileengine.cpp
+++ b/src/plugins/platforms/android/androidcontentfileengine.cpp
@@ -16,12 +16,11 @@ QT_BEGIN_NAMESPACE
using namespace QNativeInterface;
using namespace Qt::StringLiterals;
-Q_DECLARE_JNI_TYPE(ContentResolverType, "Landroid/content/ContentResolver;");
-Q_DECLARE_JNI_TYPE(UriType, "Landroid/net/Uri;");
+Q_DECLARE_JNI_CLASS(ContentResolverType, "android/content/ContentResolver");
+Q_DECLARE_JNI_CLASS(UriType, "android/net/Uri");
Q_DECLARE_JNI_CLASS(Uri, "android/net/Uri");
-Q_DECLARE_JNI_TYPE(ParcelFileDescriptorType, "Landroid/os/ParcelFileDescriptor;");
-Q_DECLARE_JNI_TYPE(CursorType, "Landroid/database/Cursor;");
-Q_DECLARE_JNI_TYPE(StringArray, "[Ljava/lang/String;");
+Q_DECLARE_JNI_CLASS(ParcelFileDescriptorType, "android/os/ParcelFileDescriptor");
+Q_DECLARE_JNI_CLASS(CursorType, "android/database/Cursor");
static QJniObject &contentResolverInstance()
{
@@ -194,10 +193,10 @@ QByteArray AndroidContentFileEngine::id() const
return m_documentFile->id().toUtf8();
}
-QDateTime AndroidContentFileEngine::fileTime(FileTime time) const
+QDateTime AndroidContentFileEngine::fileTime(QFile::FileTime time) const
{
switch (time) {
- case FileTime::ModificationTime:
+ case QFile::FileModificationTime:
return m_documentFile->lastModified();
break;
default:
@@ -248,47 +247,37 @@ QString AndroidContentFileEngine::fileName(FileName f) const
return QString();
}
-QAbstractFileEngine::Iterator *AndroidContentFileEngine::beginEntryList(QDir::Filters filters,
- const QStringList &filterNames)
+QAbstractFileEngine::IteratorUniquePtr
+AndroidContentFileEngine::beginEntryList(const QString &path, QDir::Filters filters,
+ const QStringList &filterNames)
{
- return new AndroidContentFileEngineIterator(filters, filterNames);
-}
-
-QAbstractFileEngine::Iterator *AndroidContentFileEngine::endEntryList()
-{
- return nullptr;
+ return std::make_unique<AndroidContentFileEngineIterator>(path, filters, filterNames);
}
AndroidContentFileEngineHandler::AndroidContentFileEngineHandler() = default;
AndroidContentFileEngineHandler::~AndroidContentFileEngineHandler() = default;
-QAbstractFileEngine* AndroidContentFileEngineHandler::create(const QString &fileName) const
+std::unique_ptr<QAbstractFileEngine>
+AndroidContentFileEngineHandler::create(const QString &fileName) const
{
- if (!fileName.startsWith("content"_L1))
- return nullptr;
+ if (fileName.startsWith("content"_L1))
+ return std::make_unique<AndroidContentFileEngine>(fileName);
- return new AndroidContentFileEngine(fileName);
-}
+ return {};
-AndroidContentFileEngineIterator::AndroidContentFileEngineIterator(QDir::Filters filters,
- const QStringList &filterNames)
- : QAbstractFileEngineIterator(filters, filterNames)
-{
}
-AndroidContentFileEngineIterator::~AndroidContentFileEngineIterator()
+AndroidContentFileEngineIterator::AndroidContentFileEngineIterator(
+ const QString &path, QDir::Filters filters, const QStringList &filterNames)
+ : QAbstractFileEngineIterator(path, filters, filterNames)
{
}
-QString AndroidContentFileEngineIterator::next()
+AndroidContentFileEngineIterator::~AndroidContentFileEngineIterator()
{
- if (!hasNext())
- return QString();
- ++m_index;
- return currentFilePath();
}
-bool AndroidContentFileEngineIterator::hasNext() const
+bool AndroidContentFileEngineIterator::advance()
{
if (m_index == -1 && m_files.isEmpty()) {
const auto currentPath = path();
@@ -299,9 +288,18 @@ bool AndroidContentFileEngineIterator::hasNext() const
if (iterDoc->isDirectory())
for (const auto &doc : iterDoc->listFiles())
m_files.append(doc);
+ if (m_files.isEmpty())
+ return false;
+ m_index = 0;
+ return true;
+ }
+
+ if (m_index < m_files.size() - 1) {
+ ++m_index;
+ return true;
}
- return m_index < (m_files.size() - 1);
+ return false;
}
QString AndroidContentFileEngineIterator::currentFileName() const
@@ -376,11 +374,9 @@ public:
auto cursor = contentResolverInstance().callMethod<QtJniTypes::CursorType>(
"query",
uri.object<QtJniTypes::UriType>(),
- projection.isEmpty() ?
- nullptr : fromStringList(projection).object<QtJniTypes::StringArray>(),
+ QJniArray(projection),
selection.isEmpty() ? nullptr : QJniObject::fromString(selection).object<jstring>(),
- selectionArgs.isEmpty() ?
- nullptr : fromStringList(selectionArgs).object<QtJniTypes::StringArray>(),
+ QJniArray(selectionArgs),
sortOrder.isEmpty() ? nullptr : QJniObject::fromString(sortOrder).object<jstring>());
if (!cursor.isValid())
return {};
@@ -414,15 +410,6 @@ public:
bool moveToNext() { return m_object.callMethod<jboolean>("moveToNext"); }
private:
- static QJniObject fromStringList(const QStringList &list)
- {
- QJniEnvironment env;
- auto array = env->NewObjectArray(list.size(), env.findClass("java/lang/String"), nullptr);
- for (int i = 0; i < list.size(); ++i)
- env->SetObjectArrayElement(array, i, QJniObject::fromString(list[i]).object());
- return QJniObject::fromLocalRef(array);
- }
-
QJniObject m_object;
};
@@ -465,7 +452,7 @@ const QLatin1String MIME_TYPE_DIR("vnd.android.document/directory");
QString documentId(const QJniObject &uri)
{
return QJniObject::callStaticMethod<jstring, QtJniTypes::UriType>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"getDocumentId",
uri.object()).toString();
}
@@ -473,7 +460,7 @@ QString documentId(const QJniObject &uri)
QString treeDocumentId(const QJniObject &uri)
{
return QJniObject::callStaticMethod<jstring, QtJniTypes::UriType>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"getTreeDocumentId",
uri.object()).toString();
}
@@ -481,7 +468,7 @@ QString treeDocumentId(const QJniObject &uri)
QJniObject buildChildDocumentsUriUsingTree(const QJniObject &uri, const QString &parentDocumentId)
{
return QJniObject::callStaticMethod<QtJniTypes::UriType>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"buildChildDocumentsUriUsingTree",
uri.object<QtJniTypes::UriType>(),
QJniObject::fromString(parentDocumentId).object<jstring>());
@@ -491,7 +478,7 @@ QJniObject buildChildDocumentsUriUsingTree(const QJniObject &uri, const QString
QJniObject buildDocumentUriUsingTree(const QJniObject &treeUri, const QString &documentId)
{
return QJniObject::callStaticMethod<QtJniTypes::UriType>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"buildDocumentUriUsingTree",
treeUri.object<QtJniTypes::UriType>(),
QJniObject::fromString(documentId).object<jstring>());
@@ -500,7 +487,7 @@ QJniObject buildDocumentUriUsingTree(const QJniObject &treeUri, const QString &d
bool isDocumentUri(const QJniObject &uri)
{
return QJniObject::callStaticMethod<jboolean>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"isDocumentUri",
QNativeInterface::QAndroidApplication::context(),
uri.object<QtJniTypes::UriType>());
@@ -509,7 +496,7 @@ bool isDocumentUri(const QJniObject &uri)
bool isTreeUri(const QJniObject &uri)
{
return QJniObject::callStaticMethod<jboolean>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"isTreeUri",
uri.object<QtJniTypes::UriType>());
}
@@ -518,7 +505,7 @@ QJniObject createDocument(const QJniObject &parentDocumentUri, const QString &mi
const QString &displayName)
{
return QJniObject::callStaticMethod<QtJniTypes::UriType>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"createDocument",
contentResolverInstance().object<QtJniTypes::ContentResolverType>(),
parentDocumentUri.object<QtJniTypes::UriType>(),
@@ -533,7 +520,7 @@ bool deleteDocument(const QJniObject &documentUri)
return {};
return QJniObject::callStaticMethod<jboolean>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"deleteDocument",
contentResolverInstance().object<QtJniTypes::ContentResolverType>(),
documentUri.object<QtJniTypes::UriType>());
@@ -548,7 +535,7 @@ QJniObject moveDocument(const QJniObject &sourceDocumentUri,
return {};
return QJniObject::callStaticMethod<QtJniTypes::UriType>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"moveDocument",
contentResolverInstance().object<QtJniTypes::ContentResolverType>(),
sourceDocumentUri.object<QtJniTypes::UriType>(),
@@ -563,7 +550,7 @@ QJniObject renameDocument(const QJniObject &documentUri, const QString &displayN
return {};
return QJniObject::callStaticMethod<QtJniTypes::UriType>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"renameDocument",
contentResolverInstance().object<QtJniTypes::ContentResolverType>(),
documentUri.object<QtJniTypes::UriType>(),
@@ -598,32 +585,33 @@ QJniObject parseUri(const QString &uri)
uriToParse.replace(' ', QUrl::toPercentEncoding(" "));
return QJniObject::callStaticMethod<QtJniTypes::UriType>(
- QtJniTypes::className<QtJniTypes::Uri>(),
+ QtJniTypes::Traits<QtJniTypes::Uri>::className(),
"parse",
QJniObject::fromString(uriToParse).object<jstring>());
}
DocumentFilePtr DocumentFile::parseFromAnyUri(const QString &fileName)
{
- const QJniObject uri = parseUri(fileName);
+ const QString encodedUri = QUrl(fileName).toEncoded();
+ const QJniObject uri = parseUri(encodedUri);
- if (DocumentsContract::isDocumentUri(uri))
+ if (DocumentsContract::isDocumentUri(uri) || !DocumentsContract::isTreeUri(uri))
return fromSingleUri(uri);
const QString documentType = "/document/"_L1;
const QString treeType = "/tree/"_L1;
- const int treeIndex = fileName.indexOf(treeType);
- const int documentIndex = fileName.indexOf(documentType);
+ const int treeIndex = encodedUri.indexOf(treeType);
+ const int documentIndex = encodedUri.indexOf(documentType);
const int index = fileName.lastIndexOf("/");
if (index <= treeIndex + treeType.size() || index <= documentIndex + documentType.size())
return fromTreeUri(uri);
- const QString parentUrl = fileName.left(index);
+ const QString parentUrl = encodedUri.left(index);
DocumentFilePtr parentDocFile = fromTreeUri(parseUri(parentUrl));
- const QString baseName = fileName.mid(index);
+ const QString baseName = encodedUri.mid(index);
const QString fileUrl = parentUrl + QUrl::toPercentEncoding(baseName);
DocumentFilePtr docFile = std::make_shared<MakeableDocumentFile>(parseUri(fileUrl));