aboutsummaryrefslogtreecommitdiffstats
path: root/java/org/gnu
diff options
context:
space:
mode:
authorPo Lu2023-10-15 13:10:34 +0800
committerPo Lu2023-10-15 13:11:37 +0800
commit93104cff532f932bcea65d02a59c916767a31645 (patch)
tree20070ee4cb8500824fceef285bd4b104ada3748b /java/org/gnu
parenta3fd382f3fe803e0b61c5353e9b5bdaf4d1e564e (diff)
downloademacs-93104cff532f932bcea65d02a59c916767a31645.tar.gz
emacs-93104cff532f932bcea65d02a59c916767a31645.zip
Correctly receive files through Android DND
* java/org/gnu/emacs/EmacsService.java (getUsefulContentResolver) (getContentResolverContext): New functions which return a content resolver from an EmacsActivity, if at all possible. (openContentUri, checkContentUri): Probe or open URIs through such content resolvers. Probe URIs by opening them if merely testing permissions fails, for DND URIs do not make checkCallingUriPermission return true. * java/org/gnu/emacs/EmacsWindow.java (onDragEvent): Address potential crash. * src/androidvfs.c (android_check_content_access): Circumvent JNI dynamic method dispatch. (android_authority_name): Guarantee NAME is never a directory.
Diffstat (limited to 'java/org/gnu')
-rw-r--r--java/org/gnu/emacs/EmacsService.java89
-rw-r--r--java/org/gnu/emacs/EmacsWindow.java9
2 files changed, 93 insertions, 5 deletions
diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java
index 6fa2ebb3fdb..1325cd85e9b 100644
--- a/java/org/gnu/emacs/EmacsService.java
+++ b/java/org/gnu/emacs/EmacsService.java
@@ -921,6 +921,48 @@ public final class EmacsService extends Service
921 921
922 /* Content provider functions. */ 922 /* Content provider functions. */
923 923
924 /* Return a ContentResolver capable of accessing as many files as
925 possible, namely the content resolver of the last selected
926 activity if available: only they posses the rights to access drag
927 and drop files. */
928
929 public ContentResolver
930 getUsefulContentResolver ()
931 {
932 EmacsActivity activity;
933
934 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
935 /* Since the system predates drag and drop, return this resolver
936 to avoid any unforseen difficulties. */
937 return resolver;
938
939 activity = EmacsActivity.lastFocusedActivity;
940 if (activity == null)
941 return resolver;
942
943 return activity.getContentResolver ();
944 }
945
946 /* Return a context whose ContentResolver is granted access to most
947 files, as in `getUsefulContentResolver'. */
948
949 public Context
950 getContentResolverContext ()
951 {
952 EmacsActivity activity;
953
954 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
955 /* Since the system predates drag and drop, return this resolver
956 to avoid any unforseen difficulties. */
957 return this;
958
959 activity = EmacsActivity.lastFocusedActivity;
960 if (activity == null)
961 return this;
962
963 return activity;
964 }
965
924 /* Open a content URI described by the bytes BYTES, a non-terminated 966 /* Open a content URI described by the bytes BYTES, a non-terminated
925 string; make it writable if WRITABLE, and readable if READABLE. 967 string; make it writable if WRITABLE, and readable if READABLE.
926 Truncate the file if TRUNCATE. 968 Truncate the file if TRUNCATE.
@@ -934,6 +976,9 @@ public final class EmacsService extends Service
934 String name, mode; 976 String name, mode;
935 ParcelFileDescriptor fd; 977 ParcelFileDescriptor fd;
936 int i; 978 int i;
979 ContentResolver resolver;
980
981 resolver = getUsefulContentResolver ();
937 982
938 /* Figure out the file access mode. */ 983 /* Figure out the file access mode. */
939 984
@@ -978,6 +1023,7 @@ public final class EmacsService extends Service
978 } 1023 }
979 catch (Exception exception) 1024 catch (Exception exception)
980 { 1025 {
1026 exception.printStackTrace ();
981 return -1; 1027 return -1;
982 } 1028 }
983 } 1029 }
@@ -994,6 +1040,11 @@ public final class EmacsService extends Service
994 ParcelFileDescriptor fd; 1040 ParcelFileDescriptor fd;
995 Uri uri; 1041 Uri uri;
996 int rc, flags; 1042 int rc, flags;
1043 Context context;
1044 ContentResolver resolver;
1045 ParcelFileDescriptor descriptor;
1046
1047 context = getContentResolverContext ();
997 1048
998 uri = Uri.parse (name); 1049 uri = Uri.parse (name);
999 flags = 0; 1050 flags = 0;
@@ -1004,8 +1055,42 @@ public final class EmacsService extends Service
1004 if (writable) 1055 if (writable)
1005 flags |= Intent.FLAG_GRANT_WRITE_URI_PERMISSION; 1056 flags |= Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
1006 1057
1007 rc = checkCallingUriPermission (uri, flags); 1058 rc = context.checkCallingUriPermission (uri, flags);
1008 return rc == PackageManager.PERMISSION_GRANTED; 1059
1060 if (rc == PackageManager.PERMISSION_GRANTED)
1061 return true;
1062
1063 /* In the event checkCallingUriPermission fails and only read
1064 permissions are being verified, attempt to query the URI. This
1065 enables ascertaining whether drag and drop URIs can be
1066 accessed, something otherwise not provided for. */
1067
1068 descriptor = null;
1069
1070 try
1071 {
1072 resolver = context.getContentResolver ();
1073 descriptor = resolver.openFileDescriptor (uri, "r");
1074 return true;
1075 }
1076 catch (Exception exception)
1077 {
1078 /* Ignored. */
1079 }
1080 finally
1081 {
1082 try
1083 {
1084 if (descriptor != null)
1085 descriptor.close ();
1086 }
1087 catch (IOException exception)
1088 {
1089 /* Ignored. */
1090 }
1091 }
1092
1093 return false;
1009 } 1094 }
1010 1095
1011 /* Build a content file name for URI. 1096 /* Build a content file name for URI.
diff --git a/java/org/gnu/emacs/EmacsWindow.java b/java/org/gnu/emacs/EmacsWindow.java
index 3d2d86624a7..386eaca8c41 100644
--- a/java/org/gnu/emacs/EmacsWindow.java
+++ b/java/org/gnu/emacs/EmacsWindow.java
@@ -1601,7 +1601,7 @@ public final class EmacsWindow extends EmacsHandleObject
1601 { 1601 {
1602 ClipData data; 1602 ClipData data;
1603 ClipDescription description; 1603 ClipDescription description;
1604 int i, x, y; 1604 int i, j, x, y, itemCount;
1605 String type; 1605 String type;
1606 Uri uri; 1606 Uri uri;
1607 EmacsActivity activity; 1607 EmacsActivity activity;
@@ -1626,11 +1626,12 @@ public final class EmacsWindow extends EmacsHandleObject
1626 1626
1627 data = event.getClipData (); 1627 data = event.getClipData ();
1628 description = data.getDescription (); 1628 description = data.getDescription ();
1629 itemCount = data.getItemCount ();
1629 1630
1630 /* If there are insufficient items within the clip data, 1631 /* If there are insufficient items within the clip data,
1631 return false. */ 1632 return false. */
1632 1633
1633 if (data.getItemCount () < 1) 1634 if (itemCount < 1)
1634 return false; 1635 return false;
1635 1636
1636 /* Search for plain text data within the clipboard. */ 1637 /* Search for plain text data within the clipboard. */
@@ -1662,12 +1663,14 @@ public final class EmacsWindow extends EmacsHandleObject
1662 { 1663 {
1663 /* If the item dropped is a URI, send it to the main 1664 /* If the item dropped is a URI, send it to the main
1664 thread. */ 1665 thread. */
1666
1665 uri = data.getItemAt (0).getUri (); 1667 uri = data.getItemAt (0).getUri ();
1666 1668
1667 /* Attempt to acquire permissions for this URI; 1669 /* Attempt to acquire permissions for this URI;
1668 failing which, insert it as text instead. */ 1670 failing which, insert it as text instead. */
1669 1671
1670 if (uri.getScheme () != null 1672 if (uri != null
1673 && uri.getScheme () != null
1671 && uri.getScheme ().equals ("content") 1674 && uri.getScheme ().equals ("content")
1672 && (activity = EmacsActivity.lastFocusedActivity) != null) 1675 && (activity = EmacsActivity.lastFocusedActivity) != null)
1673 { 1676 {