100 lines
3.9 KiB
Diff
100 lines
3.9 KiB
Diff
From: uazo <uazo@users.noreply.github.com>
|
|
Date: Tue, 12 Apr 2022 15:58:01 +0000
|
|
Subject: Add support for writing URIs
|
|
|
|
Allows native-side URI file writing
|
|
|
|
Original License: GPL-2.0-or-later - https://spdx.org/licenses/GPL-2.0-or-later.html
|
|
License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html
|
|
---
|
|
base/android/content_uri_utils.cc | 10 ++++++
|
|
base/android/content_uri_utils.h | 4 +++
|
|
.../org/chromium/base/ContentUriUtils.java | 33 +++++++++++++++++++
|
|
3 files changed, 47 insertions(+)
|
|
|
|
diff --git a/base/android/content_uri_utils.cc b/base/android/content_uri_utils.cc
|
|
--- a/base/android/content_uri_utils.cc
|
|
+++ b/base/android/content_uri_utils.cc
|
|
@@ -140,6 +140,16 @@ static void JNI_ContentUriUtils_AddFileInfoToVector(
|
|
Time::FromMillisecondsSinceUnixEpoch(last_modified));
|
|
}
|
|
|
|
+File OpenContentUriForWrite(const FilePath& content_uri) {
|
|
+ JNIEnv* env = base::android::AttachCurrentThread();
|
|
+ ScopedJavaLocalRef<jstring> j_uri =
|
|
+ ConvertUTF8ToJavaString(env, content_uri.value());
|
|
+ jint fd = Java_ContentUriUtils_openContentUriForWrite(env, j_uri);
|
|
+ if (fd < 0)
|
|
+ return File();
|
|
+ return File(fd);
|
|
+}
|
|
+
|
|
std::string GetContentUriMimeType(const FilePath& content_uri) {
|
|
JNIEnv* env = android::AttachCurrentThread();
|
|
return Java_ContentUriUtils_getMimeType(env, content_uri.value());
|
|
diff --git a/base/android/content_uri_utils.h b/base/android/content_uri_utils.h
|
|
--- a/base/android/content_uri_utils.h
|
|
+++ b/base/android/content_uri_utils.h
|
|
@@ -46,6 +46,10 @@ int ContentUriGetFd(
|
|
void ContentUriClose(
|
|
const base::android::JavaRef<jobject>& java_parcel_file_descriptor);
|
|
|
|
+// Opens a content URI for write and returns the file descriptor to the caller.
|
|
+// Returns -1 if the URI is invalid.
|
|
+BASE_EXPORT File OpenContentUriForWrite(const FilePath& content_uri);
|
|
+
|
|
// Returns true if file exists and results are populated, else returns false.
|
|
bool ContentUriGetFileInfo(const FilePath& content_uri,
|
|
FileEnumerator::FileInfo* results);
|
|
diff --git a/base/android/java/src/org/chromium/base/ContentUriUtils.java b/base/android/java/src/org/chromium/base/ContentUriUtils.java
|
|
--- a/base/android/java/src/org/chromium/base/ContentUriUtils.java
|
|
+++ b/base/android/java/src/org/chromium/base/ContentUriUtils.java
|
|
@@ -31,6 +31,9 @@ import org.chromium.build.annotations.Nullable;
|
|
import java.io.IOException;
|
|
import java.util.List;
|
|
|
|
+import android.system.Os;
|
|
+import android.content.ContentProviderClient;
|
|
+
|
|
/** This class provides methods to access content URI schemes. */
|
|
@JNINamespace("base")
|
|
@NullMarked
|
|
@@ -72,6 +75,36 @@ public abstract class ContentUriUtils {
|
|
StreamUtil.closeQuietly(parcelFileDescriptor);
|
|
}
|
|
|
|
+ @CalledByNative
|
|
+ public static int openContentUriForWrite(String uriString) {
|
|
+ try {
|
|
+ Uri uri = Uri.parse(uriString);
|
|
+ ContentResolver resolver = ContextUtils.getApplicationContext().getContentResolver();
|
|
+ ContentProviderClient client = resolver.acquireContentProviderClient(
|
|
+ uri.getAuthority());
|
|
+ ParcelFileDescriptor pfd = client.openFile(uri, "wt");
|
|
+ int fd = pfd.detachFd();
|
|
+ client.close();
|
|
+ return fd;
|
|
+ } catch (Exception e) {
|
|
+ Log.e(TAG, "Cannot open intermediate URI", e);
|
|
+ }
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ public static String getFilePathFromContentUri(Uri uri) {
|
|
+ String path = null;
|
|
+ try {
|
|
+ ContentResolver resolver = ContextUtils.getApplicationContext().getContentResolver();
|
|
+ ParcelFileDescriptor pfd = resolver.openFileDescriptor(uri, "r");
|
|
+ path = Os.readlink("/proc/self/fd/" + pfd.getFd());
|
|
+ pfd.close();
|
|
+ } catch (Exception e) {
|
|
+ Log.e(TAG, "Cannot get file path from content URI", e);
|
|
+ }
|
|
+ return path;
|
|
+ }
|
|
+
|
|
/**
|
|
* Check whether a content URI exists.
|
|
*
|
|
--
|