]> git.eshelyaron.com Git - emacs.git/commitdiff
Enable relinquishing access to Android content directories
authorPo Lu <luangruo@yahoo.com>
Fri, 5 Apr 2024 07:04:09 +0000 (15:04 +0800)
committerEshel Yaron <me@eshelyaron.com>
Fri, 5 Apr 2024 12:12:42 +0000 (14:12 +0200)
* doc/emacs/android.texi (Android Document Providers): Document
new command.

* java/org/gnu/emacs/EmacsService.java (relinquishUriRights):
New function.

* src/Makefile.in (SOME_MACHINE_OBJECTS): Add androidvfs.c.

* src/android.c (android_init_emacs_service): Link to new
function.

* src/android.h (struct android_emacs_service)
<relinquish_uri_rights>: New field.

* src/androidfns.c:

* src/androidvfs.c (android_saf_tree_name)
(android_saf_tree_opendir): Minor adjustments to commentary.
(Fandroid_relinquish_directory_access): New function.
(syms_of_androidvfs): Define new subr.

(cherry picked from commit aad63f935f8737598835612b53bc3b53c124661f)

doc/emacs/android.texi
java/org/gnu/emacs/EmacsService.java
src/Makefile.in
src/android.c
src/android.h
src/androidfns.c
src/androidvfs.c

index c9f93429deb31698445bfa109e11497c2ffc3557..ebc00c74ede66f5ce644a520c02211afd8b4044b 100644 (file)
@@ -299,8 +299,8 @@ on some proprietary versions of Android.
 @cindex /content/storage directory, Android
 
   Android 5.0 introduces a new sort of program, the ``document
-provider'': these programs are small programs that provide access to
-their own files outside both the asset manager and the Unix
+provider'': these programs are small services that provide access to
+their own files independently of the asset manager and the Unix
 filesystem.  Emacs supports accessing files and directories they
 provide, placing their files within the directory
 @file{/content/storage}.
@@ -311,12 +311,15 @@ first request the right to access it.  This is done by running the
 command (@pxref{M-x}) @code{android-request-directory-access}, which
 displays a file selection dialog.
 
-  If a directory is selected within this dialog, its contents are
+  If a directory is selected from this dialog, its contents are
 subsequently made available within a new directory named
-@file{/content/storage/@var{authority}/@var{id}}, where
-@var{authority} is the name of the document provider, and @var{id} is
-a unique identifier assigned to the directory by the document
-provider.
+@file{/content/storage/@var{authority}/@var{id}}, where @var{authority}
+is the name of the document provider, and @var{id} is a unique
+identifier assigned to the directory by the document provider.
+
+@findex android-relinquish-directory-access
+  Such a directory can be deleted once no longer required by providing
+its name to the command @code{android-relinquish-directory-access}.
 
   The same limitations applied to the @file{/assets} directory
 (@pxref{Android File System}) are applied when creating sub-processes
index 171b427b05bbce02f5e6f8e1e562b6ef2884f622..34682feeedb7ab86cc3644f7486f9829a17229e5 100644 (file)
@@ -1973,6 +1973,21 @@ public final class EmacsService extends Service
     return false;
   }
 
+  /* Relinquish authorization for read and write access to the provided
+     URI, which is generally a reference to a directory tree.  */
+
+  public void
+  relinquishUriRights (String uri)
+  {
+    Uri uri1;
+    int flags;
+
+    uri1 = Uri.parse (uri);
+    flags = (Intent.FLAG_GRANT_READ_URI_PERMISSION
+            | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+    resolver.releasePersistableUriPermission (uri1, flags);
+  }
+
 \f
 
   /* Functions for detecting and requesting storage permissions.  */
index 9dd88895d27b60393d366915559a4224ce360047..747ec7d406ff8c6e563065f3506c4753c9806f61 100644 (file)
@@ -494,7 +494,7 @@ SOME_MACHINE_OBJECTS = dosfns.o msdos.o \
   w16select.o widget.o xfont.o ftfont.o xftfont.o gtkutil.o \
   xsettings.o xgselect.o termcap.o hbfont.o \
   haikuterm.o haikufns.o haikumenu.o haikufont.o androidterm.o androidfns.o \
-  androidfont.o androidselect.c sfntfont-android.c sfntfont.c
+  androidfont.o androidselect.c androidvfs.c sfntfont-android.c sfntfont.c
 
 ## gmalloc.o if !SYSTEM_MALLOC && !DOUG_LEA_MALLOC, else empty.
 GMALLOC_OBJ=@GMALLOC_OBJ@
index dcd5c6d99c7688bf8d2af299e3c59026e8cc2095..507ffc458d846d23c86ea46c738904bea0e896c3 100644 (file)
@@ -1690,6 +1690,8 @@ android_init_emacs_service (void)
               "requestStorageAccess", "()V");
   FIND_METHOD (cancel_notification,
               "cancelNotification", "(Ljava/lang/String;)V");
+  FIND_METHOD (relinquish_uri_rights,
+              "relinquishUriRights", "(Ljava/lang/String;)V");
 #undef FIND_METHOD
 }
 
index 2ca3d7e14469b32df04413cc53a2193223092fa5..19adfa38087ec429ba4b3c79d1e54dfa38a08107 100644 (file)
@@ -303,6 +303,7 @@ struct android_emacs_service
   jmethodID external_storage_available;
   jmethodID request_storage_access;
   jmethodID cancel_notification;
+  jmethodID relinquish_uri_rights;
 };
 
 extern JNIEnv *android_java_env;
index 83cf81c1f07a373c8181b07fae091cf59ba86161..9f7ac8b69b263a94a87cfacbc25452b886dc5094 100644 (file)
@@ -3146,7 +3146,7 @@ for more details about these values.  */)
 
 \f
 
-/* Directory access requests.  */
+/* SAF directory access management.  */
 
 DEFUN ("android-request-directory-access", Fandroid_request_directory_access,
        Sandroid_request_directory_access, 0, 0, "",
index 2e23ed40cf5b46c78258996162edeb97c203ebfc..88ea345a298d204d03caaa22530eba47d78830fc 100644 (file)
@@ -4997,7 +4997,7 @@ android_saf_tree_name (struct android_vnode *vnode, char *name,
       root.vnode.type = ANDROID_VNODE_SAF_ROOT;
       root.vnode.flags = 0;
 
-      /* Find the authority from the URI.  */
+      /* Derive the authority from the URI.  */
 
       fill = (char *) vp->tree_uri;
 
@@ -5647,7 +5647,7 @@ android_saf_tree_opendir (struct android_vnode *vnode)
   dir->vdir.closedir = android_saf_tree_closedir;
   dir->vdir.dirfd = android_saf_tree_dirfd;
 
-  /* Find the authority from the URI.  */
+  /* Derive the authority from the URI.  */
 
   fill = (char *) vp->tree_uri;
 
@@ -7816,8 +7816,58 @@ android_closedir (struct android_vdir *dirp)
 
 \f
 
+DEFUN ("android-relinquish-directory-access",
+       Fandroid_relinquish_directory_access,
+       Sandroid_relinquish_directory_access, 1, 1,
+       "DDirectory: ",
+       doc: /* Relinquish access to the provided directory.
+DIRECTORY must be an inferior directory to a subdirectory of
+/content/storage.  Once the command completes, the parent of DIRECTORY
+below that subdirectory from will cease to appear there, but no files
+will be removed.  */)
+  (Lisp_Object file)
+{
+  struct android_vnode *vp;
+  struct android_saf_tree_vnode *saf_tree;
+  jstring string;
+  jmethodID method;
+
+  if (android_get_current_api_level () < 21)
+    error ("Emacs can only access or relinquish application storage on"
+          " Android 5.0 and later");
+
+  if (!android_init_gui)
+    return Qnil;
+
+  file = ENCODE_FILE (Fexpand_file_name (file, Qnil));
+  vp   = android_name_file (SSDATA (file));
+
+  if (vp->type != ANDROID_VNODE_SAF_TREE)
+    {
+      (*vp->ops->close) (vp);
+      signal_error ("Access to this directory cannot be relinquished",
+                   file);
+    }
+
+  saf_tree = (struct android_saf_tree_vnode *) vp;
+  string   = android_build_jstring (saf_tree->tree_uri);
+  method   = service_class.relinquish_uri_rights;
+  (*android_java_env)->CallNonvirtualVoidMethod (android_java_env,
+                                                emacs_service,
+                                                service_class.class,
+                                                method, string);
+  (*vp->ops->close) (vp);
+  android_exception_check_1 (string);
+  ANDROID_DELETE_LOCAL_REF (string);
+  return Qnil;
+}
+
+\f
+
 void
 syms_of_androidvfs (void)
 {
   DEFSYM (Qandroid_jni, "android-jni");
+
+  defsubr (&Sandroid_relinquish_directory_access);
 }