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
178 lines
7.8 KiB
C
178 lines
7.8 KiB
C
#define _GNU_SOURCE
|
|
|
|
#include <gtk/gtk.h>
|
|
#include <string.h>
|
|
#include <libportal/portal.h>
|
|
#ifdef XDP_TYPE_INPUT_CAPTURE_SESSION // libportal >= 0.8
|
|
#include <libportal/settings.h>
|
|
#endif
|
|
|
|
#include "portal-openuri.h"
|
|
#include "unifiedpush-distributor.h"
|
|
#include "unifiedpush-connector.h"
|
|
|
|
#include "../defines.h"
|
|
#include "../util.h"
|
|
|
|
#include "../generated_headers/android_content_Context.h"
|
|
|
|
extern char *apk_path;
|
|
|
|
JNIEXPORT jstring JNICALL Java_android_content_Context_native_1get_1apk_1path(JNIEnv *env, jclass this) {
|
|
return _JSTRING(apk_path);
|
|
}
|
|
|
|
#ifdef XDP_TYPE_INPUT_CAPTURE_SESSION // libportal >= 0.8
|
|
static void settings_changed_cb(XdpSettings *xdp_settings, gchar *namestpace, gchar *key, GVariant* value, jobject configuration)
|
|
{
|
|
JNIEnv *env;
|
|
if (!strcmp(namestpace, "org.freedesktop.appearance") && !strcmp(key, "color-scheme")) {
|
|
int color_sheme = g_variant_get_uint32(value);
|
|
g_object_set(gtk_settings_get_default(), "gtk-application-prefer-dark-theme", color_sheme == 1, NULL);
|
|
env = get_jni_env();
|
|
if (!configuration) {
|
|
jobject resources = _GET_STATIC_OBJ_FIELD(handle_cache.context.class, "r", "Landroid/content/res/Resources;");
|
|
configuration = _GET_OBJ_FIELD(resources, "mConfiguration", "Landroid/content/res/Configuration;");
|
|
}
|
|
if (color_sheme == 1) // Prefer dark appearance
|
|
_SET_INT_FIELD(configuration, "uiMode", /*UI_MODE_NIGHT_YES*/ 0x20);
|
|
else if (color_sheme == 2) // Prefer light appearance
|
|
_SET_INT_FIELD(configuration, "uiMode", /*UI_MODE_NIGHT_NO*/ 0x10);
|
|
else // No preference
|
|
_SET_INT_FIELD(configuration, "uiMode", /*UI_MODE_NIGHT_UNDEFINED*/ 0x00);
|
|
}
|
|
}
|
|
|
|
static XdpSettings *xdp_settings = NULL;
|
|
#endif
|
|
|
|
JNIEXPORT void JNICALL Java_android_content_Context_native_1updateConfig(JNIEnv *env, jclass this, jobject config)
|
|
{
|
|
GdkDisplay *display = gdk_display_get_default();
|
|
GdkMonitor *monitor = g_list_model_get_item(gdk_display_get_monitors(display), 0);
|
|
GdkRectangle geometry;
|
|
gdk_monitor_get_geometry(monitor, &geometry);
|
|
|
|
_SET_INT_FIELD(config, "screenWidthDp", geometry.width);
|
|
_SET_INT_FIELD(config, "screenHeightDp", geometry.height);
|
|
#ifdef XDP_TYPE_INPUT_CAPTURE_SESSION // libportal >= 0.8
|
|
if (!xdp_settings) {
|
|
GError *error = NULL;
|
|
XdpPortal *portal = xdp_portal_initable_new(&error);
|
|
if (!portal) {
|
|
printf("xdp_portal_initable_new failed: %s\n", error->message);
|
|
g_error_free(error);
|
|
return;
|
|
}
|
|
xdp_settings = xdp_portal_get_settings(portal);
|
|
g_object_unref(portal);
|
|
g_signal_connect(xdp_settings, "changed", G_CALLBACK(settings_changed_cb), NULL);
|
|
}
|
|
GVariant *color_sheme = xdp_settings_read_value(xdp_settings, "org.freedesktop.appearance", "color-scheme", NULL, NULL);
|
|
if (color_sheme) {
|
|
settings_changed_cb(xdp_settings, "org.freedesktop.appearance", "color-scheme", color_sheme, config);
|
|
g_variant_unref(color_sheme);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
static void on_bus_acquired(GDBusConnection *connection, const char *name, gpointer user_data)
|
|
{
|
|
Connector1 *connector1 = user_data;
|
|
g_dbus_interface_skeleton_export(G_DBUS_INTERFACE_SKELETON(connector1),
|
|
connection, "/org/unifiedpush/Connector", NULL);
|
|
}
|
|
|
|
static gboolean on_new_endpoint(Connector1 *connector, GDBusMethodInvocation *invocation, gpointer user_data)
|
|
{
|
|
GVariant *parameters = g_dbus_method_invocation_get_parameters(invocation);
|
|
const char *token;
|
|
g_variant_get_child(parameters, 0, "s", &token);
|
|
const char *endpoint;
|
|
g_variant_get_child(parameters, 1, "s", &endpoint);
|
|
connector1_complete_new_endpoint(connector, invocation);
|
|
|
|
JNIEnv *env = get_jni_env();
|
|
jobject intent = (*env)->NewObject(env, handle_cache.intent.class, handle_cache.intent.constructor);
|
|
_SET_OBJ_FIELD(intent, "action", "Ljava/lang/String;", _JSTRING("org.unifiedpush.android.connector.NEW_ENDPOINT"));
|
|
(*env)->CallObjectMethod(env, intent, handle_cache.intent.putExtraCharSequence, _JSTRING("token"), _JSTRING(token));
|
|
(*env)->CallObjectMethod(env, intent, handle_cache.intent.putExtraCharSequence, _JSTRING("endpoint"), _JSTRING(endpoint));
|
|
|
|
jobject context = _GET_STATIC_OBJ_FIELD(handle_cache.context.class, "this_application", "Landroid/app/Application;");
|
|
(*env)->CallVoidMethod(env, context, handle_cache.context.sendBroadcast, intent);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
(*env)->ExceptionDescribe(env);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean on_message(Connector1 *connector, GDBusMethodInvocation *invocation, gpointer user_data)
|
|
{
|
|
GVariant *parameters = g_dbus_method_invocation_get_parameters(invocation);
|
|
const char *token;
|
|
g_variant_get_child(parameters, 0, "s", &token);
|
|
gsize size;
|
|
const int8_t *message = g_variant_get_fixed_array(g_variant_get_child_value(parameters, 1), &size, 1);
|
|
connector1_complete_message(connector, invocation);
|
|
|
|
JNIEnv *env = get_jni_env();
|
|
jobject intent = (*env)->NewObject(env, handle_cache.intent.class, handle_cache.intent.constructor);
|
|
_SET_OBJ_FIELD(intent, "action", "Ljava/lang/String;", _JSTRING("org.unifiedpush.android.connector.MESSAGE"));
|
|
(*env)->CallObjectMethod(env, intent, handle_cache.intent.putExtraCharSequence, _JSTRING("token"), _JSTRING(token));
|
|
jbyteArray bytesMessage = (*env)->NewByteArray(env, size);
|
|
(*env)->SetByteArrayRegion(env, bytesMessage, 0, size, message);
|
|
(*env)->CallObjectMethod(env, intent, handle_cache.intent.putExtraByteArray, _JSTRING("bytesMessage"), bytesMessage);
|
|
|
|
jobject context = _GET_STATIC_OBJ_FIELD(handle_cache.context.class, "this_application", "Landroid/app/Application;");
|
|
(*env)->CallVoidMethod(env, context, handle_cache.context.sendBroadcast, intent);
|
|
if ((*env)->ExceptionCheck(env)) {
|
|
(*env)->ExceptionDescribe(env);
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_android_content_Context_nativeExportUnifiedPush(JNIEnv *env, jclass this, jstring application_jstr)
|
|
{
|
|
const char *application = (*env)->GetStringUTFChars(env, application_jstr, NULL);
|
|
|
|
Connector1 *connector1 = connector1_skeleton_new();
|
|
g_signal_connect(connector1, "handle-new-endpoint", G_CALLBACK(on_new_endpoint), NULL);
|
|
g_signal_connect(connector1, "handle-message", G_CALLBACK(on_message), NULL);
|
|
g_bus_own_name(G_BUS_TYPE_SESSION, application, G_BUS_NAME_OWNER_FLAGS_NONE,
|
|
on_bus_acquired, NULL, NULL, connector1, NULL);
|
|
(*env)->ReleaseStringUTFChars(env, application_jstr, application);
|
|
}
|
|
|
|
JNIEXPORT void JNICALL Java_android_content_Context_nativeRegisterUnifiedPush(JNIEnv *env, jclass this, jstring token_jstr, jstring application_jstr)
|
|
{
|
|
const char *token = (*env)->GetStringUTFChars(env, token_jstr, NULL);
|
|
const char *application = (*env)->GetStringUTFChars(env, application_jstr, NULL);
|
|
|
|
GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
|
|
Distributor1 *distributor1 = distributor1_proxy_new_sync(connection, 0, "org.unifiedpush.Distributor.kde", "/org/unifiedpush/Distributor", NULL, NULL);
|
|
GError *error = NULL;
|
|
distributor1_call_register(distributor1, application, token, "", NULL, NULL, &error);
|
|
if (error) {
|
|
printf("nativeRegisterUnifiedPush: error=%s\n", error->message);
|
|
g_error_free(error);
|
|
}
|
|
g_object_unref(distributor1);
|
|
g_object_unref(connection);
|
|
|
|
(*env)->ReleaseStringUTFChars(env, token_jstr, token);
|
|
(*env)->ReleaseStringUTFChars(env, application_jstr, application);
|
|
}
|