Warning, /graphics/krita/3rdparty/ext_qt/0022-Android-Properly-close-the-File-Descriptor.patch is written in an unsupported language. File is not indexed.

0001 From b6be4ece264a95314eb04f88dfcefe7359adba62 Mon Sep 17 00:00:00 2001
0002 From: Sharaf Zaman <sharafzaz121@gmail.com>
0003 Date: Mon, 21 Sep 2020 11:06:37 +0000
0004 Subject: [PATCH 22/46] Android: Properly close the File Descriptor
0005 
0006 In some we are not supposed to detach the file
0007 descriptor from the original object that created it.
0008 With this patch, we save the don't detach, but
0009 save the ParcelFileDescriptor in a Map and close it
0010 when we receive close() from C++.
0011 
0012 Direct effect of this can be seen in Krita, where some
0013 content providers would not allow writing to some detached
0014 FD.
0015 ---
0016  .../org/qtproject/qt5/android/QtNative.java   | 29 +++++++++++++++++--
0017  .../android/androidcontentfileengine.cpp      | 17 +++++++++--
0018  .../android/androidcontentfileengine.h        |  6 ++++
0019  3 files changed, 47 insertions(+), 5 deletions(-)
0020 
0021 diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
0022 index b838720213..5e9749f264 100644
0023 --- a/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
0024 +++ b/src/android/jar/src/org/qtproject/qt5/android/QtNative.java
0025 @@ -43,6 +43,7 @@ package org.qtproject.qt5.android;
0026  import java.io.File;
0027  import java.io.FileNotFoundException;
0028  import java.util.ArrayList;
0029 +import java.util.HashMap;
0030  import java.util.concurrent.Semaphore;
0031  import java.io.IOException;
0032  
0033 @@ -112,6 +113,9 @@ public class QtNative
0034      private static boolean m_usePrimaryClip = false;
0035      public static QtThread m_qtThread = new QtThread();
0036      private static Method m_addItemMethod = null;
0037 +
0038 +    private static HashMap<Integer, ParcelFileDescriptor> m_parcelFileDescriptors = new HashMap<Integer, ParcelFileDescriptor>();
0039 +
0040      private static final Runnable runPendingCppRunnablesRunnable = new Runnable() {
0041          @Override
0042          public void run() {
0043 @@ -177,8 +181,9 @@ public class QtNative
0044                  if (!openMode.equals("r"))
0045                     isRightPermission = permissions.get(i).isWritePermission();
0046  
0047 -                if (iterUri.getPath().equals(uriStr) && isRightPermission)
0048 +                if (iterUri.getPath().equals(uriStr) && isRightPermission) {
0049                      return iterUri;
0050 +                }
0051              }
0052  
0053              return null;
0054 @@ -235,7 +240,8 @@ public class QtNative
0055          try {
0056              ContentResolver resolver = context.getContentResolver();
0057              ParcelFileDescriptor fdDesc = resolver.openFileDescriptor(uri, openMode);
0058 -            return fdDesc.detachFd();
0059 +            m_parcelFileDescriptors.put(fdDesc.getFd(), fdDesc);
0060 +            return fdDesc.getFd();
0061          } catch (FileNotFoundException e) {
0062              return error;
0063          } catch (IllegalArgumentException e) {
0064 @@ -244,6 +250,23 @@ public class QtNative
0065          }
0066      }
0067  
0068 +    public static boolean closeFd(int fd)
0069 +    {
0070 +        ParcelFileDescriptor pfd = m_parcelFileDescriptors.get(fd);
0071 +        if (pfd == null) {
0072 +            Log.wtf(QtTAG, "File descriptor doesn't exist in cache");
0073 +            return false;
0074 +        }
0075 +
0076 +        try {
0077 +            pfd.close();
0078 +            return true;
0079 +        } catch (IOException e) {
0080 +            Log.e(QtTAG, "closeFd(): Failed to close the FD", e);
0081 +            return false;
0082 +        }
0083 +    }
0084 +
0085      public static long getSize(Context context, String contentUrl)
0086      {
0087          Uri uri = getUriWithValidPermission(context, contentUrl, "r");
0088 @@ -304,7 +327,7 @@ public class QtNative
0089      {
0090          Uri uri = getUriWithValidPermission(context, contentUrl, "r");
0091          if (uri == null) {
0092 -            Log.e(QtTAG, "getFileNameFromUri(): No permissions to open Uri");
0093 +            Log.e(QtTAG, "getFileNameFromUri(): No permissions to open Uri:" + contentUrl);
0094              return null;
0095          }
0096  
0097 diff --git a/src/plugins/platforms/android/androidcontentfileengine.cpp b/src/plugins/platforms/android/androidcontentfileengine.cpp
0098 index c15352d60e..2c11f5f14a 100644
0099 --- a/src/plugins/platforms/android/androidcontentfileengine.cpp
0100 +++ b/src/plugins/platforms/android/androidcontentfileengine.cpp
0101 @@ -45,7 +45,7 @@
0102  #include <QDebug>
0103  
0104  AndroidContentFileEngine::AndroidContentFileEngine(const QString &f)
0105 -    : m_file(f), m_resolvedName(QString())
0106 +    : m_fd(-1), m_file(f), m_resolvedName(QString())
0107  {
0108      setFileName(f);
0109      setResolvedFileName(f);
0110 @@ -77,7 +77,15 @@ bool AndroidContentFileEngine::open(QIODevice::OpenMode openMode)
0111          return false;
0112      }
0113  
0114 -    return QFSFileEngine::open(openMode, fd, QFile::AutoCloseHandle);
0115 +    setFileDescriptor(fd);
0116 +    return QFSFileEngine::open(openMode, m_fd, QFile::AutoCloseHandle);
0117 +}
0118 +
0119 +bool AndroidContentFileEngine::close()
0120 +{
0121 +    return QJNIObjectPrivate::callStaticMethod<jboolean>(
0122 +        "org/qtproject/qt5/android/QtNative", "closeFd",
0123 +        "(I)Z", m_fd);
0124  }
0125  
0126  qint64 AndroidContentFileEngine::size() const
0127 @@ -141,6 +149,11 @@ void AndroidContentFileEngine::setResolvedFileName(const QString& uri)
0128      }
0129  }
0130  
0131 +void AndroidContentFileEngine::setFileDescriptor(const int fd)
0132 +{
0133 +    m_fd = fd;
0134 +}
0135 +
0136  
0137  AndroidContentFileEngineHandler::AndroidContentFileEngineHandler() = default;
0138  AndroidContentFileEngineHandler::~AndroidContentFileEngineHandler() = default;
0139 diff --git a/src/plugins/platforms/android/androidcontentfileengine.h b/src/plugins/platforms/android/androidcontentfileengine.h
0140 index bb97bd6975..abf969ba20 100644
0141 --- a/src/plugins/platforms/android/androidcontentfileengine.h
0142 +++ b/src/plugins/platforms/android/androidcontentfileengine.h
0143 @@ -47,13 +47,19 @@ class AndroidContentFileEngine : public QFSFileEngine
0144  public:
0145      AndroidContentFileEngine(const QString &fileName);
0146      bool open(QIODevice::OpenMode openMode) override;
0147 +    bool close() override;
0148      qint64 size() const override;
0149      FileFlags fileFlags(FileFlags type = FileInfoAll) const override;
0150      QString fileName(FileName file = DefaultName) const override;
0151  
0152      /// Resolves the URI to the actual filename
0153      void setResolvedFileName(const QString& uri);
0154 +
0155 +private:
0156 +    void setFileDescriptor(const int fd);
0157 +
0158  private:
0159 +    int m_fd;
0160      QString m_file;
0161      QString m_resolvedName;
0162  };
0163 -- 
0164 2.33.0
0165