diff options
Diffstat (limited to 'src/plugins/platforms/android/androidcontentfileengine.cpp')
-rw-r--r-- | src/plugins/platforms/android/androidcontentfileengine.cpp | 112 |
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)); |