You've already forked android_translation_layer
mirror of
https://gitlab.com/android_translation_layer/android_translation_layer.git
synced 2025-10-27 11:48:10 -07:00
implement file sharing by file descriptor
Using custom gdbus code, as libportal doesn't expose the raw org.freedesktop.portal.OpenURI.OpenFile method.
This commit is contained in:
@@ -50,6 +50,9 @@ viewporter = wl_mod.scan_xml(xml)
|
||||
mpris = gnome.gdbus_codegen('mpris-dbus',
|
||||
'src/api-impl-jni/media/org.mpris.MediaPlayer2.xml',
|
||||
interface_prefix: 'org.mpris')
|
||||
portal_openuri = gnome.gdbus_codegen('portal-openuri',
|
||||
'src/api-impl-jni/content/org.freedesktop.portal.OpenURI.xml',
|
||||
interface_prefix: 'org.freedesktop.portal')
|
||||
|
||||
# libandroid
|
||||
libandroid_so = shared_library('android', [
|
||||
@@ -139,6 +142,7 @@ libtranslationlayer_so = shared_library('translation_layer_main', [
|
||||
linux_dmabuf,
|
||||
viewporter,
|
||||
mpris,
|
||||
portal_openuri,
|
||||
] + marshal_files,
|
||||
include_directories: ['src/sk_area/'],
|
||||
install: true,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <libportal/portal.h>
|
||||
|
||||
#include <jni.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../defines.h"
|
||||
#include "../util.h"
|
||||
@@ -261,7 +262,7 @@ JNIEXPORT void JNICALL Java_android_app_Activity_nativeFileChooser(JNIEnv *env,
|
||||
#endif
|
||||
|
||||
const char *type = type_jstring ? (*env)->GetStringUTFChars(env, type_jstring, NULL) : NULL;
|
||||
if (type) {
|
||||
if (type && !strchr(type, '*')) {
|
||||
GtkFileFilter *filter = gtk_file_filter_new();
|
||||
gtk_file_filter_add_mime_type(filter, type);
|
||||
gtk_file_filter_set_name(filter, type);
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#include <gtk/gtk.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "portal-openuri.h"
|
||||
|
||||
#include "../defines.h"
|
||||
#include "../util.h"
|
||||
|
||||
@@ -32,3 +34,16 @@ JNIEXPORT void JNICALL Java_android_content_Context_native_1updateConfig(JNIEnv
|
||||
if (!theme_name_from_env)
|
||||
g_free(theme_name);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_android_content_Context_nativeOpenFile(JNIEnv *env, jclass class, jint fd)
|
||||
{
|
||||
GDBusConnection *connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL);
|
||||
OpenURI *openuri = open_uri_proxy_new_sync(connection, 0, "org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop", NULL, NULL);
|
||||
GVariantBuilder opt_builder;
|
||||
g_variant_builder_init(&opt_builder, G_VARIANT_TYPE_VARDICT);
|
||||
GUnixFDList *fd_list = g_unix_fd_list_new_from_array(&fd, 1);
|
||||
open_uri_call_open_file_sync(openuri, "", g_variant_new("h", 0), g_variant_builder_end(&opt_builder), fd_list, NULL, NULL, NULL, NULL);
|
||||
g_object_unref(fd_list);
|
||||
g_object_unref(openuri);
|
||||
g_object_unref(connection);
|
||||
}
|
||||
|
||||
167
src/api-impl-jni/content/org.freedesktop.portal.OpenURI.xml
Normal file
167
src/api-impl-jni/content/org.freedesktop.portal.OpenURI.xml
Normal file
@@ -0,0 +1,167 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (C) 2016 Red Hat, Inc.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Author: Matthias Clasen <mclasen@redhat.com>
|
||||
-->
|
||||
|
||||
<node name="/" xmlns:doc="http://www.freedesktop.org/dbus/1.0/doc.dtd">
|
||||
<!--
|
||||
org.freedesktop.portal.OpenURI:
|
||||
@short_description: Portal for opening URIs
|
||||
|
||||
The OpenURI portal allows sandboxed applications to open
|
||||
URIs (e.g. a http: link to the applications homepage)
|
||||
under the control of the user.
|
||||
|
||||
This documentation describes version 3 of this interface.
|
||||
-->
|
||||
<interface name="org.freedesktop.portal.OpenURI">
|
||||
<!--
|
||||
OpenURI:
|
||||
@parent_window: Identifier for the application window, see <link linkend="parent_window">Common Conventions</link>
|
||||
@uri: The uri to open
|
||||
@options: Vardict with optional further onformation
|
||||
@handle: Object path for the #org.freedesktop.portal.Request object representing this call
|
||||
|
||||
Asks to open a uri.
|
||||
|
||||
Note that file:// uris are explicitly not supported by this method.
|
||||
To request opening local files, use org.freedesktop.portal.OpenURI.OpenFile().
|
||||
|
||||
Supported keys in the @options vardict include:
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>handle_token s</term>
|
||||
<listitem><para>
|
||||
A string that will be used as the last element of the @handle. Must be a valid
|
||||
object path element. See the #org.freedesktop.portal.Request documentation for
|
||||
more information about the @handle.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>writable b</term>
|
||||
<listitem><para>
|
||||
Whether to allow the chosen application to write to the file.
|
||||
</para><para>
|
||||
This key only takes effect the uri points to a local file that
|
||||
is exported in the document portal, and the chosen application
|
||||
is sandboxed itself.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>ask b</term>
|
||||
<listitem><para>
|
||||
Whether to ask the user to choose an app. If this is not passed, or false,
|
||||
the portal may use a default or pick the last choice.
|
||||
</para><para>
|
||||
The ask option was introduced in version 3 of the interface.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
-->
|
||||
<method name="OpenURI">
|
||||
<arg type="s" name="parent_window" direction="in"/>
|
||||
<arg type="s" name="uri" direction="in"/>
|
||||
<arg type="a{sv}" name="options" direction="in"/>
|
||||
<arg type="o" name="handle" direction="out"/>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
OpenFile:
|
||||
@parent_window: Identifier for the application window, see <link linkend="parent_window">Common Conventions</link>
|
||||
@fd: File descriptor for the file to open
|
||||
@options: Vardict with optional further onformation
|
||||
@handle: Object path for the #org.freedesktop.portal.Request object representing this call
|
||||
|
||||
Asks to open a local file.
|
||||
|
||||
Supported keys in the @options vardict include:
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>handle_token s</term>
|
||||
<listitem><para>
|
||||
A string that will be used as the last element of the @handle. Must be a valid
|
||||
object path element. See the #org.freedesktop.portal.Request documentation for
|
||||
more information about the @handle.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>writable b</term>
|
||||
<listitem><para>
|
||||
Whether to allow the chosen application to write to the file.
|
||||
</para><para>
|
||||
This key only takes effect the uri points to a local file that
|
||||
is exported in the document portal, and the chosen application
|
||||
is sandboxed itself.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>ask b</term>
|
||||
<listitem><para>
|
||||
Whether to ask the user to choose an app. If this is not passed, or false,
|
||||
the portal may use a default or pick the last choice.
|
||||
</para><para>
|
||||
The ask option was introduced in version 3 of the interface.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
The OpenFile method was introduced in version 2 of the OpenURI portal API.
|
||||
-->
|
||||
<method name="OpenFile">
|
||||
<annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
|
||||
<arg type="s" name="parent_window" direction="in"/>
|
||||
<arg type="h" name="fd" direction="in"/>
|
||||
<arg type="a{sv}" name="options" direction="in"/>
|
||||
<arg type="o" name="handle" direction="out"/>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
OpenDirectory:
|
||||
@parent_window: Identifier for the application window, see <link linkend="parent_window">Common Conventions</link>
|
||||
@fd: File descriptor for a file
|
||||
@options: Vardict with optional further onformation
|
||||
@handle: Object path for the #org.freedesktop.portal.Request object representing this call
|
||||
|
||||
Asks to open the directory containing a local file in the file browser.
|
||||
|
||||
Supported keys in the @options vardict include:
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term>handle_token s</term>
|
||||
<listitem><para>
|
||||
A string that will be used as the last element of the @handle. Must be a valid
|
||||
object path element. See the #org.freedesktop.portal.Request documentation for
|
||||
more information about the @handle.
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
The OpenDirectory method was introduced in version 3 of the OpenURI portal API.
|
||||
-->
|
||||
<method name="OpenDirectory">
|
||||
<annotation name="org.gtk.GDBus.C.UnixFD" value="true"/>
|
||||
<arg type="s" name="parent_window" direction="in"/>
|
||||
<arg type="h" name="fd" direction="in"/>
|
||||
<arg type="a{sv}" name="options" direction="in"/>
|
||||
<arg type="o" name="handle" direction="out"/>
|
||||
</method>
|
||||
|
||||
<property name="version" type="u" access="read"/>
|
||||
</interface>
|
||||
</node>
|
||||
@@ -25,6 +25,14 @@ JNIEXPORT jstring JNICALL Java_android_content_Context_native_1get_1apk_1path
|
||||
JNIEXPORT void JNICALL Java_android_content_Context_native_1updateConfig
|
||||
(JNIEnv *, jclass, jobject);
|
||||
|
||||
/*
|
||||
* Class: android_content_Context
|
||||
* Method: nativeOpenFile
|
||||
* Signature: (I)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_android_content_Context_nativeOpenFile
|
||||
(JNIEnv *, jclass, jint);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.Map;
|
||||
import android.content.pm.PackageParser;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
|
||||
public abstract class ContentProvider {
|
||||
|
||||
@@ -34,4 +35,8 @@ public abstract class ContentProvider {
|
||||
|
||||
public abstract int delete(Uri uri, String selection, String[] selectionArgs);
|
||||
|
||||
public abstract String getType(Uri uri);
|
||||
|
||||
public abstract ParcelFileDescriptor openFile(Uri uri, String mode);
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,15 @@ public class ContentResolver {
|
||||
}
|
||||
|
||||
public ParcelFileDescriptor openFileDescriptor(Uri uri, String mode) throws FileNotFoundException {
|
||||
if ("file".equals(uri.getScheme())) {
|
||||
return ParcelFileDescriptor.open(new File(uri.toString()), ParcelFileDescriptor.parseMode(mode));
|
||||
} else {
|
||||
ContentProvider provider = ContentProvider.providers.get(uri.getAuthority());
|
||||
if (provider != null)
|
||||
return provider.openFile(uri, mode);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
|
||||
@@ -53,4 +61,12 @@ public class ContentResolver {
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getType(Uri uri) {
|
||||
ContentProvider provider = ContentProvider.providers.get(uri.getAuthority());
|
||||
if (provider != null)
|
||||
return provider.getType(uri);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.PowerManager;
|
||||
import android.os.Vibrator;
|
||||
import android.telephony.TelephonyManager;
|
||||
@@ -116,6 +117,7 @@ public class Context extends Object {
|
||||
|
||||
private static native String native_get_apk_path();
|
||||
protected static native void native_updateConfig(Configuration config);
|
||||
private static native void nativeOpenFile(int fd);
|
||||
|
||||
static Application createApplication(long native_window) throws Exception {
|
||||
Application application;
|
||||
@@ -494,6 +496,15 @@ public class Context extends Object {
|
||||
ClipboardManager.native_set_clipboard(text);
|
||||
} else if (intent.getData() != null) {
|
||||
Slog.i(TAG, "starting extern activity with intent: " + intent);
|
||||
if (intent.getData().getScheme().equals("content")) {
|
||||
try {
|
||||
ParcelFileDescriptor fd = getContentResolver().openFileDescriptor(intent.getData(), "r");
|
||||
nativeOpenFile(fd.getFd());
|
||||
return;
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Activity.nativeOpenURI(String.valueOf(intent.getData()));
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -2,6 +2,7 @@ package android.content;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
|
||||
public class SearchRecentSuggestionsProvider extends ContentProvider {
|
||||
public void setupSuggestions(String s, int i) {}
|
||||
@@ -20,4 +21,14 @@ public class SearchRecentSuggestionsProvider extends ContentProvider {
|
||||
public int delete(Uri uri, String selection, String[] selectionArgs) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'delete'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType(Uri uri) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'getType'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParcelFileDescriptor openFile(Uri uri, String mode) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'openFile'");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user