From: Po Lu <luangruo@yahoo.com>
Date: Sun, 19 Feb 2023 07:29:46 +0000 (+0800)
Subject: Allow opening more files in emacsclient on Android
X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=efc46330aa1e3c433246b8a008ffc7f2675369c2;p=emacs.git

Allow opening more files in emacsclient on Android

* 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.
---

diff --git a/java/org/gnu/emacs/EmacsOpenActivity.java b/java/org/gnu/emacs/EmacsOpenActivity.java
index baf31039ecd..c8501d91025 100644
--- a/java/org/gnu/emacs/EmacsOpenActivity.java
+++ b/java/org/gnu/emacs/EmacsOpenActivity.java
@@ -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)