]> git.eshelyaron.com Git - emacs.git/commitdiff
Allow opening more files in emacsclient on Android
authorPo Lu <luangruo@yahoo.com>
Sun, 19 Feb 2023 07:29:46 +0000 (15:29 +0800)
committerPo Lu <luangruo@yahoo.com>
Sun, 19 Feb 2023 07:29:46 +0000 (15:29 +0800)
* java/org/gnu/emacs/EmacsOpenActivity.java (EmacsOpenActivity)
(checkReadableOrCopy): New function.
(onCreate): If the file specified is not readable from C, read
it into a temporary file and ask Emacs to open that.

java/org/gnu/emacs/EmacsOpenActivity.java

index baf31039ecd22908a745e8a934cd7d0fb56ce1e1..c8501d9102523baee65d5075937ca1b11c5a346f 100644 (file)
@@ -58,8 +58,10 @@ import android.os.Bundle;
 import android.os.ParcelFileDescriptor;
 
 import java.io.File;
-import java.io.FileReader;
+import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.UnsupportedEncodingException;
@@ -176,6 +178,50 @@ public class EmacsOpenActivity extends Activity
     dialog.show ();
   }
 
+  /* Check that the specified FILE is readable.  If it is not, then
+     copy the file in FD to a location in the system cache
+     directory and return the name of that file.  */
+
+  private String
+  checkReadableOrCopy (String file, ParcelFileDescriptor fd)
+    throws IOException, FileNotFoundException
+  {
+    File inFile;
+    FileOutputStream outStream;
+    InputStream stream;
+    byte buffer[];
+    int read;
+
+    inFile = new File (file);
+
+    if (inFile.setReadable (true))
+      return file;
+
+    /* inFile is now the file being written to.  */
+    inFile = new File (getCacheDir (), inFile.getName ());
+    buffer = new byte[4098];
+    outStream = new FileOutputStream (inFile);
+    stream = new FileInputStream (fd.getFileDescriptor ());
+
+    try
+      {
+       while ((read = stream.read (buffer)) >= 0)
+         outStream.write (buffer, 0, read);
+      }
+    finally
+      {
+       /* Note that this does not close FD.
+
+          Keep in mind that execution is transferred to ``finally''
+          even if an exception happens inside the while loop
+          above.  */
+       stream.close ();
+       outStream.close ();
+      }
+
+    return inFile.getCanonicalPath ();
+  }
+
   /* Finish this activity in response to emacsclient having
      successfully opened a file.
 
@@ -340,17 +386,19 @@ public class EmacsOpenActivity extends Activity
                   opening the file and doing readlink on its file
                   descriptor in /proc/self/fd.  */
                resolver = getContentResolver ();
+               fd = null;
 
                try
                  {
                    fd = resolver.openFileDescriptor (uri, "r");
                    names = EmacsNative.getProcName (fd.getFd ());
-                   fd.close ();
 
                    /* What is the right encoding here? */
 
                    if (names != null)
                      fileName = new String (names, "UTF-8");
+
+                   fileName = checkReadableOrCopy (fileName, fd);
                  }
                catch (FileNotFoundException exception)
                  {
@@ -360,6 +408,18 @@ public class EmacsOpenActivity extends Activity
                  {
                    /* Do nothing.  */
                  }
+
+               if (fd != null)
+                 {
+                   try
+                     {
+                       fd.close ();
+                     }
+                   catch (IOException exception)
+                     {
+                       /* Do nothing.  */
+                     }
+                 }
              }
 
            if (fileName == null)