diff options
| author | Po Lu | 2023-07-31 10:50:12 +0800 |
|---|---|---|
| committer | Po Lu | 2023-07-31 10:50:12 +0800 |
| commit | 5a8130ab967cb296d028539d10c749ee35f62e6a (patch) | |
| tree | 65095973fc4084f628f205f99857280e6d18b83f /java | |
| parent | 2ad50c7ff5093e7a1d3a5a06f042430e7d46c117 (diff) | |
| download | emacs-5a8130ab967cb296d028539d10c749ee35f62e6a.tar.gz emacs-5a8130ab967cb296d028539d10c749ee35f62e6a.zip | |
Implement cross-directory SAF rename operations
* java/org/gnu/emacs/EmacsService.java (renameDocument): Don't
catch UnsupportedOperationException; handle ENOSYS in
android_saf_rename_document instead.
(moveDocument): New function.
* lisp/subr.el (y-or-n-p): Always change the text conversion
style.
* src/android.c (android_init_emacs_service)
(android_exception_check_4): New function.
* src/android.h: Update Java function table.
* src/androidvfs.c (android_saf_rename_document): Handle ENOSYS
here by setting errno to EXDEV.
(android_saf_move_document): New function.
(android_document_id_from_name): Take const `dir_name'.
(android_saf_tree_rename): Use delete-move-rename to implement
cross-directory renames.
Diffstat (limited to 'java')
| -rw-r--r-- | java/org/gnu/emacs/EmacsService.java | 67 |
1 files changed, 50 insertions, 17 deletions
diff --git a/java/org/gnu/emacs/EmacsService.java b/java/org/gnu/emacs/EmacsService.java index 07e585ad37c..e714f75fdf2 100644 --- a/java/org/gnu/emacs/EmacsService.java +++ b/java/org/gnu/emacs/EmacsService.java | |||
| @@ -1713,26 +1713,59 @@ public final class EmacsService extends Service | |||
| 1713 | tree = Uri.parse (uri); | 1713 | tree = Uri.parse (uri); |
| 1714 | uriObject = DocumentsContract.buildDocumentUriUsingTree (tree, docId); | 1714 | uriObject = DocumentsContract.buildDocumentUriUsingTree (tree, docId); |
| 1715 | 1715 | ||
| 1716 | try | 1716 | if (DocumentsContract.renameDocument (resolver, uriObject, |
| 1717 | { | 1717 | name) |
| 1718 | if (DocumentsContract.renameDocument (resolver, uriObject, | 1718 | != null) |
| 1719 | name) | ||
| 1720 | != null) | ||
| 1721 | { | ||
| 1722 | /* Invalidate the cache. */ | ||
| 1723 | if (storageThread != null) | ||
| 1724 | storageThread.postInvalidateCacheDir (tree, docId, | ||
| 1725 | name); | ||
| 1726 | return 0; | ||
| 1727 | } | ||
| 1728 | } | ||
| 1729 | catch (UnsupportedOperationException e) | ||
| 1730 | { | 1719 | { |
| 1731 | ;; | 1720 | /* Invalidate the cache. */ |
| 1721 | if (storageThread != null) | ||
| 1722 | storageThread.postInvalidateCacheDir (tree, docId, | ||
| 1723 | name); | ||
| 1724 | return 0; | ||
| 1732 | } | 1725 | } |
| 1733 | 1726 | ||
| 1734 | /* Handle unsupported operation exceptions specially, so | 1727 | /* Handle errors specially, so `android_saf_rename_document' can |
| 1735 | `android_rename' can return ENXDEV. */ | 1728 | return ENXDEV. */ |
| 1736 | return -1; | 1729 | return -1; |
| 1737 | } | 1730 | } |
| 1731 | |||
| 1732 | /* Move the document designated by DOCID from the directory under | ||
| 1733 | DIR_NAME designated by SRCID to the directory designated by | ||
| 1734 | DSTID. If the ID of the document being moved changes as a | ||
| 1735 | consequence of the movement, return the new ID, else NULL. | ||
| 1736 | |||
| 1737 | URI is the document tree containing all three documents. */ | ||
| 1738 | |||
| 1739 | public String | ||
| 1740 | moveDocument (String uri, String docId, String dirName, | ||
| 1741 | String dstId, String srcId) | ||
| 1742 | throws FileNotFoundException | ||
| 1743 | { | ||
| 1744 | Uri uri1, docId1, dstId1, srcId1; | ||
| 1745 | Uri name; | ||
| 1746 | |||
| 1747 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) | ||
| 1748 | throw new UnsupportedOperationException ("Documents aren't capable" | ||
| 1749 | + " of being moved on Android" | ||
| 1750 | + " versions before 7.0."); | ||
| 1751 | |||
| 1752 | uri1 = Uri.parse (uri); | ||
| 1753 | docId1 = DocumentsContract.buildDocumentUriUsingTree (uri1, docId); | ||
| 1754 | dstId1 = DocumentsContract.buildDocumentUriUsingTree (uri1, dstId); | ||
| 1755 | srcId1 = DocumentsContract.buildDocumentUriUsingTree (uri1, srcId); | ||
| 1756 | |||
| 1757 | /* Move the document; this function returns the new ID of the | ||
| 1758 | document should it change. */ | ||
| 1759 | name = DocumentsContract.moveDocument (resolver, docId1, | ||
| 1760 | srcId1, dstId1); | ||
| 1761 | |||
| 1762 | /* Now invalidate the caches for both DIRNAME and DOCID. */ | ||
| 1763 | |||
| 1764 | if (storageThread != null) | ||
| 1765 | storageThread.postInvalidateCacheDir (uri1, docId, dirName); | ||
| 1766 | |||
| 1767 | return (name != null | ||
| 1768 | ? DocumentsContract.getDocumentId (name) | ||
| 1769 | : null); | ||
| 1770 | } | ||
| 1738 | }; | 1771 | }; |