From 1e041d19522292597b51ca5d16df6a80893968ec Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 30 Sep 2013 16:33:45 +0200 Subject: [PATCH 1/3] Added new advanced configuration options for async. --- client/Android/FreeRDPCore/.classpath | 3 +- .../Android/FreeRDPCore/jni/android_freerdp.c | 21 ++++-- .../Android/FreeRDPCore/jni/android_freerdp.h | 5 +- .../jni/generated/android_freerdp_jni.c | 9 ++- ..._freerdp_freerdpcore_services_LibFreeRDP.h | 4 +- .../FreeRDPCore/res/values-es/strings.xml | 4 ++ .../FreeRDPCore/res/values-fr/strings.xml | 4 ++ .../FreeRDPCore/res/values-nl/strings.xml | 4 ++ .../FreeRDPCore/res/values/strings.xml | 4 ++ .../FreeRDPCore/res/xml/advanced_settings.xml | 4 ++ .../freerdpcore/domain/BookmarkBase.java | 68 ++++++++++++++++++- .../services/BookmarkBaseGateway.java | 20 ++++++ .../freerdpcore/services/BookmarkDB.java | 10 ++- .../freerdpcore/services/LibFreeRDP.java | 9 ++- .../freerdpcore/utils/RDPFileParser.java | 4 ++ 15 files changed, 158 insertions(+), 15 deletions(-) diff --git a/client/Android/FreeRDPCore/.classpath b/client/Android/FreeRDPCore/.classpath index a4763d1ee..7bc01d9a9 100644 --- a/client/Android/FreeRDPCore/.classpath +++ b/client/Android/FreeRDPCore/.classpath @@ -3,6 +3,7 @@ - + + diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index f0046dcc5..43734eab7 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -134,7 +134,9 @@ BOOL android_post_connect(freerdp* instance) { DEBUG_ANDROID("android_post_connect"); - freerdp_callback("OnSettingsChanged", "(IIII)V", instance, instance->settings->DesktopWidth, instance->settings->DesktopHeight, instance->settings->ColorDepth); + freerdp_callback("OnSettingsChanged", "(IIII)V", instance, + instance->settings->DesktopWidth, instance->settings->DesktopHeight, + instance->settings->ColorDepth); instance->context->cache = cache_new(instance->settings); @@ -553,8 +555,10 @@ JNIEXPORT void JNICALL jni_freerdp_set_connection_info(JNIEnv *env, jclass cls, } JNIEXPORT void JNICALL jni_freerdp_set_performance_flags( - JNIEnv *env, jclass cls, jint instance, jboolean remotefx, jboolean disableWallpaper, jboolean disableFullWindowDrag, - jboolean disableMenuAnimations, jboolean disableTheming, jboolean enableFontSmoothing, jboolean enableDesktopComposition) + JNIEnv *env, jclass cls, jint instance, jboolean remotefx, + jboolean disableWallpaper, jboolean disableFullWindowDrag, + jboolean disableMenuAnimations, jboolean disableTheming, + jboolean enableFontSmoothing, jboolean enableDesktopComposition) { freerdp* inst = (freerdp*)instance; rdpSettings * settings = inst->settings; @@ -617,7 +621,10 @@ JNIEXPORT void JNICALL jni_freerdp_set_performance_flags( DEBUG_ANDROID("performance_flags: %04X", settings->PerformanceFlags); } -JNIEXPORT void JNICALL jni_freerdp_set_advanced_settings(JNIEnv *env, jclass cls, jint instance, jstring jRemoteProgram, jstring jWorkDir) +JNIEXPORT void JNICALL jni_freerdp_set_advanced_settings(JNIEnv *env, jclass cls, + jint instance, jstring jRemoteProgram, jstring jWorkDir, + jboolean async_channel, jboolean async_transport, jboolean async_input, + jboolean async_update) { freerdp* inst = (freerdp*)instance; rdpSettings * settings = inst->settings; @@ -628,6 +635,12 @@ JNIEXPORT void JNICALL jni_freerdp_set_advanced_settings(JNIEnv *env, jclass cls DEBUG_ANDROID("Remote Program: %s", (char*) remote_program); DEBUG_ANDROID("Work Dir: %s", (char*) work_dir); + /* Enable async mode. */ + settings->AsyncUpdate = async_update; + settings->AsyncChannels = async_channel; + settings->AsyncTransport = async_transport; + settings->AsyncInput = async_input; + if(remote_program && strlen(remote_program) > 0) settings->AlternateShell = strdup(remote_program); diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.h b/client/Android/FreeRDPCore/jni/android_freerdp.h index ad96bc398..a06ab0cc4 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.h +++ b/client/Android/FreeRDPCore/jni/android_freerdp.h @@ -43,7 +43,10 @@ JNIEXPORT void JNICALL jni_freerdp_set_connection_info(JNIEnv *env, jclass cls, jint height, jint color_depth, jint port, jboolean console, jint security, jstring jcertname); JNIEXPORT void JNICALL jni_freerdp_set_performance_flags(JNIEnv *env, jclass cls, jint instance, jboolean remotefx, jboolean disableWallpaper, jboolean disableFullWindowDrag, jboolean disableMenuAnimations, jboolean disableTheming, jboolean enableFontSmoothing, jboolean enableDesktopComposition); -JNIEXPORT void JNICALL jni_freerdp_set_advanced_settings(JNIEnv *env, jclass cls, jint instance, jstring jRemoteProgram, jstring jWorkDir); +JNIEXPORT void JNICALL jni_freerdp_set_advanced_settings(JNIEnv *env, jclass cls, + jint instance, jstring jRemoteProgram, jstring jWorkDir, + jboolean async_channel, jboolean async_transport, jboolean async_input, + jboolean async_update); JNIEXPORT void JNICALL jni_freerdp_set_drive_redirection(JNIEnv *env, jclass cls, jint instance, jstring jpath); JNIEXPORT void JNICALL jni_freerdp_set_clipboard_redirection(JNIEnv *env, jclass cls, jint instance, jboolean enable); JNIEXPORT void JNICALL jni_freerdp_set_gateway_info(JNIEnv *env, jclass cls, jint instance, jstring jgatewayhostname, jint port, jstring jgatewayusername, jstring jgatewaypassword, jstring jgatewaydomain); diff --git a/client/Android/FreeRDPCore/jni/generated/android_freerdp_jni.c b/client/Android/FreeRDPCore/jni/generated/android_freerdp_jni.c index 1aa889abe..9a80fcd2a 100644 --- a/client/Android/FreeRDPCore/jni/generated/android_freerdp_jni.c +++ b/client/Android/FreeRDPCore/jni/generated/android_freerdp_jni.c @@ -53,9 +53,14 @@ JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_ width, height, color_depth, port, console, security, certname); } -JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1advanced_1settings(JNIEnv *env, jclass cls, jint instance, jstring remote_program, jstring work_dir) +JNIEXPORT void JNICALL +Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1advanced_1settings( + JNIEnv *env, jclass cls, jint instance, jstring remote_program, jstring work_dir, + jboolean async_channel, jboolean async_transport, jboolean async_input, + jboolean async_update) { - jni_freerdp_set_advanced_settings(env, cls, instance, remote_program, work_dir); + jni_freerdp_set_advanced_settings(env, cls, instance, remote_program, work_dir, + async_channel, async_transport, async_input, async_update); } JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1data_1directory(JNIEnv *env, jclass cls, jint instance, jstring directory) diff --git a/client/Android/FreeRDPCore/jni/generated/com_freerdp_freerdpcore_services_LibFreeRDP.h b/client/Android/FreeRDPCore/jni/generated/com_freerdp_freerdpcore_services_LibFreeRDP.h index 1e6be8dff..591919f3a 100644 --- a/client/Android/FreeRDPCore/jni/generated/com_freerdp_freerdpcore_services_LibFreeRDP.h +++ b/client/Android/FreeRDPCore/jni/generated/com_freerdp_freerdpcore_services_LibFreeRDP.h @@ -66,10 +66,10 @@ JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_ /* * Class: com_freerdp_freerdpcore_services_LibFreeRDP * Method: freerdp_set_advanced_settings - * Signature: (ILjava/lang/String;Ljava/lang/String;)V + * Signature: (ILjava/lang/String;Ljava/lang/String;ZZZZ)V */ JNIEXPORT void JNICALL Java_com_freerdp_freerdpcore_services_LibFreeRDP_freerdp_1set_1advanced_1settings - (JNIEnv *, jclass, jint, jstring, jstring); + (JNIEnv *, jclass, jint, jstring, jstring, jboolean, jboolean, jboolean, jboolean); /* * Class: com_freerdp_freerdpcore_services_LibFreeRDP diff --git a/client/Android/FreeRDPCore/res/values-es/strings.xml b/client/Android/FreeRDPCore/res/values-es/strings.xml index e539660de..88cd0db32 100644 --- a/client/Android/FreeRDPCore/res/values-es/strings.xml +++ b/client/Android/FreeRDPCore/res/values-es/strings.xml @@ -130,6 +130,10 @@ Programa Remoto Directorio de trabajo + Async channel + Async transport + Async input + Async update Modo Consola ******* diff --git a/client/Android/FreeRDPCore/res/values-fr/strings.xml b/client/Android/FreeRDPCore/res/values-fr/strings.xml index ffd74bf32..b851843c6 100644 --- a/client/Android/FreeRDPCore/res/values-fr/strings.xml +++ b/client/Android/FreeRDPCore/res/values-fr/strings.xml @@ -129,6 +129,10 @@ "Lancement de programme" "Répertoire de travail" + Async channel + Async transport + Async input + Async update "Mode console" "*******" diff --git a/client/Android/FreeRDPCore/res/values-nl/strings.xml b/client/Android/FreeRDPCore/res/values-nl/strings.xml index 03c694aa5..9092b07b3 100644 --- a/client/Android/FreeRDPCore/res/values-nl/strings.xml +++ b/client/Android/FreeRDPCore/res/values-nl/strings.xml @@ -130,6 +130,10 @@ Extern programma Werkmap + Async channel + Async transport + Async input + Async update Console modus ******* diff --git a/client/Android/FreeRDPCore/res/values/strings.xml b/client/Android/FreeRDPCore/res/values/strings.xml index 0f6aacded..1fdd5fa84 100644 --- a/client/Android/FreeRDPCore/res/values/strings.xml +++ b/client/Android/FreeRDPCore/res/values/strings.xml @@ -127,6 +127,10 @@ Remote Program Working Directory + Async channel + Async transport + Async input + Async update Console Mode ******* diff --git a/client/Android/FreeRDPCore/res/xml/advanced_settings.xml b/client/Android/FreeRDPCore/res/xml/advanced_settings.xml index 61cd61d19..b5d010170 100644 --- a/client/Android/FreeRDPCore/res/xml/advanced_settings.xml +++ b/client/Android/FreeRDPCore/res/xml/advanced_settings.xml @@ -39,6 +39,10 @@ + + + + diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java index 8db15b864..efd80b38f 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/domain/BookmarkBase.java @@ -299,6 +299,10 @@ public class BookmarkBase implements Parcelable, Cloneable private boolean consoleMode; private String remoteProgram; private String workDir; + private boolean asyncChannel; + private boolean asyncTransport; + private boolean asyncInput; + private boolean asyncUpdate; public AdvancedSettings() { init(); @@ -312,7 +316,11 @@ public class BookmarkBase implements Parcelable, Cloneable security = parcel.readInt(); consoleMode = (parcel.readInt() == 1) ? true : false; remoteProgram = parcel.readString(); - workDir = parcel.readString(); + workDir = parcel.readString(); + asyncChannel = (parcel.readInt() == 1) ? true : false; + asyncTransport = (parcel.readInt() == 1) ? true : false; + asyncInput = (parcel.readInt() == 1) ? true : false; + asyncUpdate = (parcel.readInt() == 1) ? true : false; } private void init() { @@ -324,6 +332,10 @@ public class BookmarkBase implements Parcelable, Cloneable consoleMode = false; remoteProgram = ""; workDir = ""; + asyncChannel = true; + asyncTransport = true; + asyncInput = true; + asyncUpdate = true; } public void setEnable3GSettings(boolean enable3GSettings) { @@ -393,7 +405,47 @@ public class BookmarkBase implements Parcelable, Cloneable { return workDir; } - + + public boolean getAsyncTransport() + { + return asyncTransport; + } + + public void setAsyncTransport(boolean enabled) + { + asyncTransport = enabled; + } + + public boolean getAsyncUpdate() + { + return asyncUpdate; + } + + public void setAsyncUpdate(boolean enabled) + { + asyncUpdate = enabled; + } + + public boolean getAsyncInput() + { + return asyncInput; + } + + public void setAsyncInput(boolean enabled) + { + asyncInput = enabled; + } + + public void setAsyncChannel(boolean enabled) + { + asyncChannel = enabled; + } + + public boolean getAsyncChannel() + { + return asyncChannel; + } + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { public AdvancedSettings createFromParcel(Parcel in) { @@ -422,6 +474,10 @@ public class BookmarkBase implements Parcelable, Cloneable out.writeInt(consoleMode ? 1 : 0); out.writeString(remoteProgram); out.writeString(workDir); + out.writeInt(asyncChannel ? 1 : 0); + out.writeInt(asyncTransport ? 1 : 0); + out.writeInt(asyncInput ? 1 : 0); + out.writeInt(asyncUpdate ? 1 : 0); } } @@ -623,6 +679,10 @@ public class BookmarkBase implements Parcelable, Cloneable editor.putInt("bookmark.security", advancedSettings.getSecurity()); editor.putString("bookmark.remote_program", advancedSettings.getRemoteProgram()); editor.putString("bookmark.work_dir", advancedSettings.getWorkDir()); + editor.putBoolean("bookmark.async_channel", advancedSettings.getAsyncChannel()); + editor.putBoolean("bookmark.async_transport", advancedSettings.getAsyncTransport()); + editor.putBoolean("bookmark.async_input", advancedSettings.getAsyncInput()); + editor.putBoolean("bookmark.async_update", advancedSettings.getAsyncUpdate()); editor.putBoolean("bookmark.console_mode", advancedSettings.getConsoleMode()); editor.commit(); @@ -665,6 +725,10 @@ public class BookmarkBase implements Parcelable, Cloneable advancedSettings.setSecurity(sharedPrefs.getInt("bookmark.security", 0)); advancedSettings.setRemoteProgram(sharedPrefs.getString("bookmark.remote_program", "")); advancedSettings.setWorkDir(sharedPrefs.getString("bookmark.work_dir", "")); + advancedSettings.setAsyncChannel(sharedPrefs.getBoolean("bookmark.async_channel", true)); + advancedSettings.setAsyncTransport(sharedPrefs.getBoolean("bookmark.async_transport", true)); + advancedSettings.setAsyncInput(sharedPrefs.getBoolean("bookmark.async_input", true)); + advancedSettings.setAsyncUpdate(sharedPrefs.getBoolean("bookmark.async_update", true)); advancedSettings.setConsoleMode(sharedPrefs.getBoolean("bookmark.console_mode", false)); } diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/BookmarkBaseGateway.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/BookmarkBaseGateway.java index 7f6a939b1..22c728a2f 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/BookmarkBaseGateway.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/BookmarkBaseGateway.java @@ -68,6 +68,10 @@ public abstract class BookmarkBaseGateway values.put("console_mode", bookmark.getAdvancedSettings().getConsoleMode()); values.put("remote_program", bookmark.getAdvancedSettings().getRemoteProgram()); values.put("work_dir", bookmark.getAdvancedSettings().getWorkDir()); + values.put("async_channel", bookmark.getAdvancedSettings().getAsyncChannel()); + values.put("async_transport", bookmark.getAdvancedSettings().getAsyncTransport()); + values.put("async_input", bookmark.getAdvancedSettings().getAsyncInput()); + values.put("async_update", bookmark.getAdvancedSettings().getAsyncUpdate()); // add any special columns addBookmarkSpecificColumns(bookmark, values); @@ -104,6 +108,10 @@ public abstract class BookmarkBaseGateway values.put("console_mode", bookmark.getAdvancedSettings().getConsoleMode()); values.put("remote_program", bookmark.getAdvancedSettings().getRemoteProgram()); values.put("work_dir", bookmark.getAdvancedSettings().getWorkDir()); + values.put("async_channel", bookmark.getAdvancedSettings().getAsyncChannel()); + values.put("async_transport", bookmark.getAdvancedSettings().getAsyncTransport()); + values.put("async_input", bookmark.getAdvancedSettings().getAsyncInput()); + values.put("async_update", bookmark.getAdvancedSettings().getAsyncUpdate()); addBookmarkSpecificColumns(bookmark, values); @@ -223,6 +231,10 @@ public abstract class BookmarkBaseGateway columns.add("console_mode"); columns.add("remote_program"); columns.add("work_dir"); + columns.add("async_channel"); + columns.add("async_transport"); + columns.add("async_input"); + columns.add("async_update"); addBookmarkSpecificColumns(columns); } @@ -281,6 +293,14 @@ public abstract class BookmarkBaseGateway bookmark.getAdvancedSettings().setConsoleMode(cursor.getInt(cursor.getColumnIndex("console_mode")) == 0 ? false : true); bookmark.getAdvancedSettings().setRemoteProgram(cursor.getString(cursor.getColumnIndex("remote_program"))); bookmark.getAdvancedSettings().setWorkDir(cursor.getString(cursor.getColumnIndex("work_dir"))); + bookmark.getAdvancedSettings().setAsyncChannel( + cursor.getInt(cursor.getColumnIndex("async_channel")) == 1 ? true : false); + bookmark.getAdvancedSettings().setAsyncTransport( + cursor.getInt(cursor.getColumnIndex("async_transport")) == 1 ? true : false); + bookmark.getAdvancedSettings().setAsyncInput( + cursor.getInt(cursor.getColumnIndex("async_input")) == 1 ? true : false); + bookmark.getAdvancedSettings().setAsyncUpdate( + cursor.getInt(cursor.getColumnIndex("async_update")) == 1 ? true : false); readBookmarkSpecificColumns(bookmark, cursor); diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/BookmarkDB.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/BookmarkDB.java index e54cc1502..9aa06202e 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/BookmarkDB.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/BookmarkDB.java @@ -22,7 +22,7 @@ import android.database.sqlite.SQLiteOpenHelper; public class BookmarkDB extends SQLiteOpenHelper { - private static final int DB_VERSION = 3; + private static final int DB_VERSION = 5; private static final String DB_NAME = "bookmarks.db"; public static final String ID = BaseColumns._ID; @@ -104,6 +104,10 @@ public class BookmarkDB extends SQLiteOpenHelper + "security, " + "remote_program, " + "work_dir, " + + "async_channel, " + + "async_transport, " + + "async_input, " + + "async_update, " + "console_mode) " + "VALUES ( " + "'Test Server', " @@ -144,6 +148,10 @@ public class BookmarkDB extends SQLiteOpenHelper + "security INTEGER, " + "remote_program TEXT, " + "work_dir TEXT, " + + "async_channel INTEGER DEFAULT 0, " + + "async_transport INTEGER DEFAULT 0, " + + "async_input INTEGER DEFAULT 0, " + + "async_update INTEGER DEFAULT 0, " + "console_mode INTEGER, " + "FOREIGN KEY(screen_settings) REFERENCES tbl_screen_settings(" + ID + "), " diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/LibFreeRDP.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/LibFreeRDP.java index 54de217c9..331b47285 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/LibFreeRDP.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/services/LibFreeRDP.java @@ -35,7 +35,9 @@ public class LibFreeRDP boolean disableMenuAnimations, boolean disableTheming, boolean enableFontSmoothing, boolean enableDesktopComposition); - private static native void freerdp_set_advanced_settings(int inst, String remoteProgram, String workDir); + private static native void freerdp_set_advanced_settings(int inst, + String remoteProgram, String workDir, boolean async_channel, + boolean async_transport, boolean async_input, boolean async_update); private static native void freerdp_set_data_directory(int inst, String directory); @@ -149,7 +151,10 @@ public class LibFreeRDP flags.getDesktopComposition()); BookmarkBase.AdvancedSettings advancedSettings = bookmark.getAdvancedSettings(); - freerdp_set_advanced_settings(inst, advancedSettings.getRemoteProgram(), advancedSettings.getWorkDir()); + freerdp_set_advanced_settings(inst, advancedSettings.getRemoteProgram(), + advancedSettings.getWorkDir(), advancedSettings.getAsyncChannel(), + advancedSettings.getAsyncTransport(), advancedSettings.getAsyncInput(), + advancedSettings.getAsyncUpdate()); // drive redirection enabled? if (advancedSettings.getRedirectSDCard()) diff --git a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/utils/RDPFileParser.java b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/utils/RDPFileParser.java index a903ed2eb..3ce52ff8d 100644 --- a/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/utils/RDPFileParser.java +++ b/client/Android/FreeRDPCore/src/com/freerdp/freerdpcore/utils/RDPFileParser.java @@ -52,7 +52,10 @@ public class RDPFileParser { lines++; ok = false; if (errors > MAX_ERRORS || lines > MAX_LINES) + { + br.close(); throw new IOException("Parsing limits exceeded"); + } String[] fields = line.split(":", 3); @@ -81,6 +84,7 @@ public class RDPFileParser { if (!ok) errors++; } + br.close(); } public String getString(String optionName) From 2fec8ad4c84c7f86387a33d5169587e246197f30 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Mon, 30 Sep 2013 17:52:13 +0200 Subject: [PATCH 2/3] Implemented async_channels, async_transport and async_update. --- .../Android/FreeRDPCore/jni/android_freerdp.c | 217 ++++++++++++++++-- 1 file changed, 198 insertions(+), 19 deletions(-) diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index 43734eab7..b51f38526 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -3,6 +3,7 @@ Copyright 2010-2012 Marc-Andre Moreau Copyright 2013 Thinstuff Technologies GmbH, Author: Martin Fleisz + Copyright 2013 Thinstuff Technologies GmbH, Author: Armin Novak This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. @@ -12,6 +13,7 @@ #include "config.h" #endif +#include #include #include #include @@ -228,7 +230,7 @@ int android_receive_channel_data(freerdp* instance, int channelId, UINT8* data, return freerdp_channels_data(instance, channelId, data, size, flags, total_size); } -void android_process_channel_event(rdpChannels* channels, freerdp* instance) +static void android_process_channel_event(rdpChannels* channels, freerdp* instance) { wMessage* event; @@ -243,6 +245,7 @@ void android_process_channel_event(rdpChannels* channels, freerdp* instance) break; default: + DEBUG_ANDROID("Unsupported channel event %08X", event); break; } @@ -250,7 +253,111 @@ void android_process_channel_event(rdpChannels* channels, freerdp* instance) } } -int android_freerdp_run(freerdp* instance) +static void *jni_update_thread(void *arg) +{ + int status; + wMessage message; + wMessageQueue* queue; + freerdp* instance = (freerdp*) arg; + + assert( NULL != instance); + + status = 1; + queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE); + + while (MessageQueue_Wait(queue)) + { + while (MessageQueue_Peek(queue, &message, TRUE)) + { + status = freerdp_message_queue_process_message(instance, FREERDP_UPDATE_MESSAGE_QUEUE, &message); + + if (!status) + break; + } + + if (!status) + break; + } + + ExitThread(0); + return NULL; +} + +static void* jni_input_thread(void* arg) +{ + HANDLE event; + wMessageQueue* queue; + int pending_status = 1; + int process_status = 1; + freerdp* instance = (freerdp*) arg; + + assert(NULL != instance); + + queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); + //event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds); + + while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0) + { + do + { +#if 0 + xf_lock_x11(xfc, FALSE); + + pending_status = XPending(xfc->display); + + xf_unlock_x11(xfc, FALSE); + + if (pending_status) + { + xf_lock_x11(xfc, FALSE); + + ZeroMemory(&xevent, sizeof(xevent)); + XNextEvent(xfc->display, &xevent); + process_status = xf_event_process(instance, &xevent); + + xf_unlock_x11(xfc, FALSE); + if (!process_status) + break; + } +#endif + } + while (pending_status); + + if (!process_status) + break; + } + + MessageQueue_PostQuit(queue, 0); + ExitThread(0); + return NULL; +} + +static void* jni_channels_thread(void* arg) +{ + int status; + HANDLE event; + rdpChannels* channels; + freerdp* instance = (freerdp*) arg; + + assert(NULL != instance); + + channels = instance->context->channels; + event = freerdp_channels_get_event_handle(instance); + + while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0) + { + status = freerdp_channels_process_pending_messages(instance); + if (!status) + break; + + android_process_channel_event(channels, instance); + } + + ExitThread(0); + return NULL; +} + +static int android_freerdp_run(freerdp* instance) { int i; int fds; @@ -264,6 +371,17 @@ int android_freerdp_run(freerdp* instance) int select_status; struct timeval timeout; + const rdpSettings* settings = instance->context->settings; + + HANDLE update_thread; + HANDLE input_thread; + HANDLE channels_thread; + + BOOL async_update = settings->AsyncUpdate; + BOOL async_input = settings->AsyncInput; + BOOL async_channels = settings->AsyncChannels; + BOOL async_transport = settings->AsyncTransport; + memset(rfds, 0, sizeof(rfds)); memset(wfds, 0, sizeof(wfds)); @@ -272,27 +390,56 @@ int android_freerdp_run(freerdp* instance) freerdp_callback("OnConnectionFailure", "(I)V", instance); return 0; } - + + if (async_update) + { + update_thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) jni_update_thread, instance, 0, NULL); + } + + if (async_input) + { + input_thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) jni_input_thread, instance, 0, NULL); + } + + if (async_channels) + { + channels_thread = CreateThread(NULL, 0, + (LPTHREAD_START_ROUTINE) jni_channels_thread, instance, 0, NULL); + } + ((androidContext*)instance->context)->is_connected = TRUE; while (!freerdp_shall_disconnect(instance)) { rcount = 0; wcount = 0; - if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) + if (!async_transport) { - DEBUG_ANDROID("Failed to get FreeRDP file descriptor\n"); - break; + if (freerdp_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) + { + DEBUG_ANDROID("Failed to get FreeRDP file descriptor\n"); + break; + } } - if (freerdp_channels_get_fds(instance->context->channels, instance, rfds, &rcount, wfds, &wcount) != TRUE) + + if (!async_channels) { - DEBUG_ANDROID("Failed to get channel manager file descriptor\n"); - break; + if (freerdp_channels_get_fds(instance->context->channels, instance, rfds, &rcount, wfds, &wcount) != TRUE) + { + DEBUG_ANDROID("Failed to get channel manager file descriptor\n"); + break; + } } - if (android_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) + + if (!async_input) { - DEBUG_ANDROID("Failed to get android file descriptor\n"); - break; + if (android_get_fds(instance, rfds, &rcount, wfds, &wcount) != TRUE) + { + DEBUG_ANDROID("Failed to get android file descriptor\n"); + break; + } } max_fds = 0; @@ -332,27 +479,59 @@ int android_freerdp_run(freerdp* instance) } } - if (freerdp_check_fds(instance) != TRUE) + if (!async_transport) { - DEBUG_ANDROID("Failed to check FreeRDP file descriptor\n"); - break; + if (freerdp_check_fds(instance) != TRUE) + { + DEBUG_ANDROID("Failed to check FreeRDP file descriptor\n"); + break; + } } + if (android_check_fds(instance) != TRUE) { DEBUG_ANDROID("Failed to check android file descriptor\n"); break; } - if (freerdp_channels_check_fds(instance->context->channels, instance) != TRUE) + + if (!async_channels) { - DEBUG_ANDROID("Failed to check channel manager file descriptor\n"); - break; + if (freerdp_channels_check_fds(instance->context->channels, instance) != TRUE) + { + DEBUG_ANDROID("Failed to check channel manager file descriptor\n"); + break; + } + + android_process_channel_event(instance->context->channels, instance); } - android_process_channel_event(instance->context->channels, instance); } // issue another OnDisconnecting here in case the disconnect was initiated by the sever and not our client freerdp_callback("OnDisconnecting", "(I)V", instance); freerdp_channels_close(instance->context->channels, instance); + + if (async_update) + { + wMessageQueue* update_queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE); + MessageQueue_PostQuit(update_queue, 0); + WaitForSingleObject(update_thread, INFINITE); + CloseHandle(update_thread); + } + + if (async_input) + { + wMessageQueue* input_queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); + MessageQueue_PostQuit(input_queue, 0); + WaitForSingleObject(input_thread, INFINITE); + CloseHandle(input_thread); + } + + if (async_channels) + { + WaitForSingleObject(channels_thread, INFINITE); + CloseHandle(channels_thread); + } + freerdp_disconnect(instance); gdi_free(instance); cache_free(instance->context->cache); From fe336da721edaf0aea51d22680aa48d7fb1dbc9e Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 1 Oct 2013 10:33:28 +0200 Subject: [PATCH 3/3] Implemented async_input handling. --- .../Android/FreeRDPCore/jni/android_freerdp.c | 115 ++++++++++++------ 1 file changed, 79 insertions(+), 36 deletions(-) diff --git a/client/Android/FreeRDPCore/jni/android_freerdp.c b/client/Android/FreeRDPCore/jni/android_freerdp.c index b51f38526..51b23450a 100644 --- a/client/Android/FreeRDPCore/jni/android_freerdp.c +++ b/client/Android/FreeRDPCore/jni/android_freerdp.c @@ -238,14 +238,15 @@ static void android_process_channel_event(rdpChannels* channels, freerdp* instan if (event) { - switch(GetMessageClass(event->id)) + int ev = GetMessageClass(event->id); + switch(ev) { case CliprdrChannel_Class: android_process_cliprdr_event(instance, event); break; default: - DEBUG_ANDROID("Unsupported channel event %08X", event); + DEBUG_ANDROID("Unsupported channel event %08X", ev); break; } @@ -262,6 +263,8 @@ static void *jni_update_thread(void *arg) assert( NULL != instance); + DEBUG_ANDROID("Start."); + status = 1; queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE); @@ -279,53 +282,49 @@ static void *jni_update_thread(void *arg) break; } + DEBUG_ANDROID("Quit."); + ExitThread(0); return NULL; } static void* jni_input_thread(void* arg) { - HANDLE event; + HANDLE event[3]; wMessageQueue* queue; - int pending_status = 1; - int process_status = 1; freerdp* instance = (freerdp*) arg; + androidContext *aCtx = (androidContext*)instance->context; assert(NULL != instance); + assert(NULL != aCtx); + DEBUG_ANDROID("Start."); + queue = freerdp_get_message_queue(instance, FREERDP_INPUT_MESSAGE_QUEUE); - //event = CreateFileDescriptorEvent(NULL, FALSE, FALSE, xfc->xfds); - - while (WaitForSingleObject(event, INFINITE) == WAIT_OBJECT_0) - { - do - { -#if 0 - xf_lock_x11(xfc, FALSE); + event[0] = CreateFileDescriptorEvent(NULL, FALSE, FALSE, aCtx->event_queue->pipe_fd[0]); + event[1] = CreateFileDescriptorEvent(NULL, FALSE, FALSE, aCtx->event_queue->pipe_fd[1]); + event[2] = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE); - pending_status = XPending(xfc->display); - - xf_unlock_x11(xfc, FALSE); - - if (pending_status) - { - xf_lock_x11(xfc, FALSE); - - ZeroMemory(&xevent, sizeof(xevent)); - XNextEvent(xfc->display, &xevent); - process_status = xf_event_process(instance, &xevent); - - xf_unlock_x11(xfc, FALSE); - if (!process_status) - break; - } -#endif + do + { + DWORD rc = WaitForMultipleObjects(3, event, FALSE, INFINITE); + if (rc == WAIT_OBJECT_0 + 2) + { + wMessage msg; + + MessageQueue_Peek(queue, &msg, FALSE); + if (msg.id == WMQ_QUIT) + break; } - while (pending_status); + if ((rc < WAIT_OBJECT_0) && (rc > WAIT_OBJECT_0 + 1)) + break; - if (!process_status) + if (android_check_fds(instance) != TRUE) break; } + while(1); + + DEBUG_ANDROID("Quit."); MessageQueue_PostQuit(queue, 0); ExitThread(0); @@ -341,6 +340,8 @@ static void* jni_channels_thread(void* arg) assert(NULL != instance); + DEBUG_ANDROID("Start."); + channels = instance->context->channels; event = freerdp_channels_get_event_handle(instance); @@ -353,6 +354,8 @@ static void* jni_channels_thread(void* arg) android_process_channel_event(channels, instance); } + DEBUG_ANDROID("Quit."); + ExitThread(0); return NULL; } @@ -364,6 +367,8 @@ static int android_freerdp_run(freerdp* instance) int max_fds; int rcount; int wcount; + int fd_input_event; + HANDLE input_event; void* rfds[32]; void* wfds[32]; fd_set rfds_set; @@ -382,6 +387,11 @@ static int android_freerdp_run(freerdp* instance) BOOL async_channels = settings->AsyncChannels; BOOL async_transport = settings->AsyncTransport; + DEBUG_ANDROID("AsyncUpdate=%d", settings->AsyncUpdate); + DEBUG_ANDROID("AsyncInput=%d", settings->AsyncInput); + DEBUG_ANDROID("AsyncChannels=%d", settings->AsyncChannels); + DEBUG_ANDROID("AsyncTransport=%d", settings->AsyncTransport); + memset(rfds, 0, sizeof(rfds)); memset(wfds, 0, sizeof(wfds)); @@ -441,6 +451,12 @@ static int android_freerdp_run(freerdp* instance) break; } } + else + { + input_event = freerdp_get_message_queue_event_handle(instance, FREERDP_INPUT_MESSAGE_QUEUE); + fd_input_event = GetEventFileDescriptor(input_event); + rfds[rcount++] = (void*) (long) fd_input_event; + } max_fds = 0; FD_ZERO(&rfds_set); @@ -488,10 +504,25 @@ static int android_freerdp_run(freerdp* instance) } } - if (android_check_fds(instance) != TRUE) + if (!async_input) { - DEBUG_ANDROID("Failed to check android file descriptor\n"); - break; + if (android_check_fds(instance) != TRUE) + { + DEBUG_ANDROID("Failed to check android file descriptor\n"); + break; + } + } + else + { + if (WaitForSingleObject(input_event, 0) == WAIT_OBJECT_0) + { + if (!freerdp_message_queue_process_pending_messages(instance, + FREERDP_INPUT_MESSAGE_QUEUE)) + { + DEBUG_ANDROID("User Disconnect"); + break; + } + } } if (!async_channels) @@ -506,10 +537,15 @@ static int android_freerdp_run(freerdp* instance) } } + DEBUG_ANDROID("Prepare shutdown..."); + // issue another OnDisconnecting here in case the disconnect was initiated by the sever and not our client freerdp_callback("OnDisconnecting", "(I)V", instance); + + DEBUG_ANDROID("Close channels..."); freerdp_channels_close(instance->context->channels, instance); + DEBUG_ANDROID("Cleanup threads..."); if (async_update) { wMessageQueue* update_queue = freerdp_get_message_queue(instance, FREERDP_UPDATE_MESSAGE_QUEUE); @@ -532,12 +568,16 @@ static int android_freerdp_run(freerdp* instance) CloseHandle(channels_thread); } + DEBUG_ANDROID("Disconnecting..."); + freerdp_channels_free(instance->context->channels); freerdp_disconnect(instance); gdi_free(instance); cache_free(instance->context->cache); android_cliprdr_uninit(instance); freerdp_callback("OnDisconnected", "(I)V", instance); + DEBUG_ANDROID("Quit."); + return 0; } @@ -546,12 +586,15 @@ void* android_thread_func(void* param) struct thread_data* data; data = (struct thread_data*) param; + DEBUG_ANDROID("Start."); + freerdp* instance = data->instance; android_freerdp_run(instance); free(data); - pthread_detach(pthread_self()); + DEBUG_ANDROID("Quit."); + ExitThread(0); return NULL; }