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.cpp165
1 files changed, 75 insertions, 90 deletions
diff --git a/src/plugins/platforms/android/androidcontentfileengine.cpp b/src/plugins/platforms/android/androidcontentfileengine.cpp
index c86bbeae77..f4afb3789a 100644
--- a/src/plugins/platforms/android/androidcontentfileengine.cpp
+++ b/src/plugins/platforms/android/androidcontentfileengine.cpp
@@ -16,19 +16,15 @@ 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(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()
{
static QJniObject contentResolver;
if (!contentResolver.isValid()) {
contentResolver = QJniObject(QNativeInterface::QAndroidApplication::context())
- .callMethod<QtJniTypes::ContentResolverType>("getContentResolver");
+ .callMethod<QtJniTypes::ContentResolver>("getContentResolver");
}
return contentResolver;
@@ -80,7 +76,7 @@ bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode,
}
m_pfd = contentResolverInstance().callMethod<
- QtJniTypes::ParcelFileDescriptorType, QtJniTypes::UriType, jstring>(
+ QtJniTypes::ParcelFileDescriptorType, QtJniTypes::Uri, jstring>(
"openFileDescriptor",
m_documentFile->uri().object(),
QJniObject::fromString(openModeStr).object<jstring>());
@@ -194,10 +190,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 +244,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 +285,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
@@ -375,12 +370,10 @@ public:
{
auto cursor = contentResolverInstance().callMethod<QtJniTypes::CursorType>(
"query",
- uri.object<QtJniTypes::UriType>(),
- projection.isEmpty() ?
- nullptr : fromStringList(projection).object<QtJniTypes::StringArray>(),
+ uri.object<QtJniTypes::Uri>(),
+ 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 +407,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;
};
@@ -464,64 +448,64 @@ const QLatin1String MIME_TYPE_DIR("vnd.android.document/directory");
QString documentId(const QJniObject &uri)
{
- return QJniObject::callStaticMethod<jstring, QtJniTypes::UriType>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ return QJniObject::callStaticMethod<jstring, QtJniTypes::Uri>(
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"getDocumentId",
uri.object()).toString();
}
QString treeDocumentId(const QJniObject &uri)
{
- return QJniObject::callStaticMethod<jstring, QtJniTypes::UriType>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ return QJniObject::callStaticMethod<jstring, QtJniTypes::Uri>(
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"getTreeDocumentId",
uri.object()).toString();
}
QJniObject buildChildDocumentsUriUsingTree(const QJniObject &uri, const QString &parentDocumentId)
{
- return QJniObject::callStaticMethod<QtJniTypes::UriType>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ return QJniObject::callStaticMethod<QtJniTypes::Uri>(
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"buildChildDocumentsUriUsingTree",
- uri.object<QtJniTypes::UriType>(),
+ uri.object<QtJniTypes::Uri>(),
QJniObject::fromString(parentDocumentId).object<jstring>());
}
QJniObject buildDocumentUriUsingTree(const QJniObject &treeUri, const QString &documentId)
{
- return QJniObject::callStaticMethod<QtJniTypes::UriType>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ return QJniObject::callStaticMethod<QtJniTypes::Uri>(
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"buildDocumentUriUsingTree",
- treeUri.object<QtJniTypes::UriType>(),
+ treeUri.object<QtJniTypes::Uri>(),
QJniObject::fromString(documentId).object<jstring>());
}
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>());
+ uri.object<QtJniTypes::Uri>());
}
bool isTreeUri(const QJniObject &uri)
{
return QJniObject::callStaticMethod<jboolean>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"isTreeUri",
- uri.object<QtJniTypes::UriType>());
+ uri.object<QtJniTypes::Uri>());
}
QJniObject createDocument(const QJniObject &parentDocumentUri, const QString &mimeType,
const QString &displayName)
{
- return QJniObject::callStaticMethod<QtJniTypes::UriType>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ return QJniObject::callStaticMethod<QtJniTypes::Uri>(
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"createDocument",
- contentResolverInstance().object<QtJniTypes::ContentResolverType>(),
- parentDocumentUri.object<QtJniTypes::UriType>(),
+ contentResolverInstance().object<QtJniTypes::ContentResolver>(),
+ parentDocumentUri.object<QtJniTypes::Uri>(),
QJniObject::fromString(mimeType).object<jstring>(),
QJniObject::fromString(displayName).object<jstring>());
}
@@ -533,10 +517,10 @@ 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>());
+ contentResolverInstance().object<QtJniTypes::ContentResolver>(),
+ documentUri.object<QtJniTypes::Uri>());
}
QJniObject moveDocument(const QJniObject &sourceDocumentUri,
@@ -547,13 +531,13 @@ QJniObject moveDocument(const QJniObject &sourceDocumentUri,
if (!(flags & Document::FLAG_SUPPORTS_MOVE))
return {};
- return QJniObject::callStaticMethod<QtJniTypes::UriType>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ return QJniObject::callStaticMethod<QtJniTypes::Uri>(
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"moveDocument",
- contentResolverInstance().object<QtJniTypes::ContentResolverType>(),
- sourceDocumentUri.object<QtJniTypes::UriType>(),
- sourceParentDocumentUri.object<QtJniTypes::UriType>(),
- targetParentDocumentUri.object<QtJniTypes::UriType>());
+ contentResolverInstance().object<QtJniTypes::ContentResolver>(),
+ sourceDocumentUri.object<QtJniTypes::Uri>(),
+ sourceParentDocumentUri.object<QtJniTypes::Uri>(),
+ targetParentDocumentUri.object<QtJniTypes::Uri>());
}
QJniObject renameDocument(const QJniObject &documentUri, const QString &displayName)
@@ -562,11 +546,11 @@ QJniObject renameDocument(const QJniObject &documentUri, const QString &displayN
if (!(flags & Document::FLAG_SUPPORTS_RENAME))
return {};
- return QJniObject::callStaticMethod<QtJniTypes::UriType>(
- QtJniTypes::className<QtJniTypes::DocumentsContract>(),
+ return QJniObject::callStaticMethod<QtJniTypes::Uri>(
+ QtJniTypes::Traits<QtJniTypes::DocumentsContract>::className(),
"renameDocument",
- contentResolverInstance().object<QtJniTypes::ContentResolverType>(),
- documentUri.object<QtJniTypes::UriType>(),
+ contentResolverInstance().object<QtJniTypes::ContentResolver>(),
+ documentUri.object<QtJniTypes::Uri>(),
QJniObject::fromString(displayName).object<jstring>());
}
} // End DocumentsContract namespace
@@ -597,33 +581,34 @@ QJniObject parseUri(const QString &uri)
if (uriToParse.contains(' '))
uriToParse.replace(' ', QUrl::toPercentEncoding(" "));
- return QJniObject::callStaticMethod<QtJniTypes::UriType>(
- QtJniTypes::className<QtJniTypes::Uri>(),
+ return QJniObject::callStaticMethod<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));
@@ -733,7 +718,7 @@ bool DocumentFile::canRead() const
{
const auto context = QJniObject(QNativeInterface::QAndroidApplication::context());
const bool selfUriPermission = context.callMethod<jint>("checkCallingOrSelfUriPermission",
- m_uri.object<QtJniTypes::UriType>(),
+ m_uri.object<QtJniTypes::Uri>(),
FLAG_GRANT_READ_URI_PERMISSION);
if (selfUriPermission != 0)
return false;
@@ -745,7 +730,7 @@ bool DocumentFile::canWrite() const
{
const auto context = QJniObject(QNativeInterface::QAndroidApplication::context());
const bool selfUriPermission = context.callMethod<jint>("checkCallingOrSelfUriPermission",
- m_uri.object<QtJniTypes::UriType>(),
+ m_uri.object<QtJniTypes::Uri>(),
FLAG_GRANT_WRITE_URI_PERMISSION);
if (selfUriPermission != 0)
return false;