* 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)
@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}.
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
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. */
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@
"requestStorageAccess", "()V");
FIND_METHOD (cancel_notification,
"cancelNotification", "(Ljava/lang/String;)V");
+ FIND_METHOD (relinquish_uri_rights,
+ "relinquishUriRights", "(Ljava/lang/String;)V");
#undef FIND_METHOD
}
jmethodID external_storage_available;
jmethodID request_storage_access;
jmethodID cancel_notification;
+ jmethodID relinquish_uri_rights;
};
extern JNIEnv *android_java_env;
\f
-/* Directory access requests. */
+/* SAF directory access management. */
DEFUN ("android-request-directory-access", Fandroid_request_directory_access,
Sandroid_request_directory_access, 0, 0, "",
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;
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;
\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);
}