soc.2012.android: f104cf83: Added uiops for startup (but has a segfa...
michael at soc.pidgin.im
michael at soc.pidgin.im
Sat Jun 9 06:57:12 EDT 2012
----------------------------------------------------------------------
Revision: f104cf83b14b159ff205dfea79a0cddc75124cab
Parent: 126f826cddbc3f9020d99e4d1e3aab70396ac975
Author: michael at soc.pidgin.im
Date: 06/08/12 12:41:34
Branch: im.pidgin.soc.2012.android
URL: http://d.pidgin.im/viewmtn/revision/info/f104cf83b14b159ff205dfea79a0cddc75124cab
Changelog:
Added uiops for startup (but has a segfault) and a first attempt to add debug support (not working yet)
Changes against parent 126f826cddbc3f9020d99e4d1e3aab70396ac975
added android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/exceptions
added android/workspace/im.pidgin.libpurple/native/CoreManager.c
added android/workspace/im.pidgin.libpurple/native/EventLoop.c
added android/workspace/im.pidgin.libpurple/native/EventLoop.h
added android/workspace/im.pidgin.libpurple/native/gdb.setup
added android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/exceptions/PurpleRuntimeException.java
added android/workspace/im.pidgin.libpurple/startDebugger.sh
patched android/workspace/im.pidgin.libpurple/.cproject
patched android/workspace/im.pidgin.libpurple/.project
patched android/workspace/im.pidgin.libpurple/native/PurpleInstance.c
patched android/workspace/im.pidgin.libpurple/native/build.ant
patched android/workspace/im.pidgin.libpurple/native/generateheaders.ant
patched android/workspace/im.pidgin.libpurple/native/helpers.c
patched android/workspace/im.pidgin.libpurple/native/helpers.h
patched android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/CoreManager.java
patched android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/EventLoop.java
patched android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/PurpleInstance.java
patched android/workspace/im.pidgin.libpurple.testclient/AndroidManifest.xml
attr on android/workspace/im.pidgin.libpurple/startDebugger.sh
set mtn:execute
to true
-------------- next part --------------
============================================================
--- android/workspace/im.pidgin.libpurple/native/build.ant 27927631a7ff925c42a53d18d97b36fa4aa3a29f
+++ android/workspace/im.pidgin.libpurple/native/build.ant 6af6e45c33846f9b16eb943400e023ba02c985a9
@@ -42,8 +42,9 @@
<javah classdefinition="im.pidgin.libpurple.buddy.PurpleBuddy" to="${javah.out}" />
- <javah classdefinition="im.pidgin.libpurple.core.EventLoop" to="${javah.out}" />
+ <javah classdefinition="im.pidgin.libpurple.core.EventLoop" to="${javah.out}" headerfilename="EventLoop_jni.h"/>
<javah classdefinition="im.pidgin.libpurple.core.PurpleInstance" to="${javah.out}" />
+ <javah classdefinition="im.pidgin.libpurple.core.CoreManager" to="${javah.out}" />
<javah classdefinition="im.pidgin.libpurple.core.dns.DnsQueryData" to="${javah.out}" />
<javah classdefinition="im.pidgin.libpurple.core.dns.DnsQueryFailedCallback" to="${javah.out}" />
============================================================
--- android/workspace/im.pidgin.libpurple/native/generateheaders.ant d3635bcabcd67bbefd8e3b7f5221ae68337c42f3
+++ android/workspace/im.pidgin.libpurple/native/generateheaders.ant 3dc695dff66ce83730b41dfd3ea9092bdab7a751
@@ -13,17 +13,19 @@
</description>
<property name="javah.src" location="../src" />
-
+
<!-- = = = = = = = = = = = = = = = = =
macrodef: javah
= = = = = = = = = = = = = = = = = -->
<macrodef name="javah">
<attribute name="classdefinition" default="" />
<attribute name="to" default="." />
+ <attribute name="headerfilename" default="" />
<sequential>
<antcall target="javah">
<param name="classpath" value="@{classdefinition}" />
<param name="to" location="@{to}" />
+ <param name="headerfilename" value="@{headerfilename}" />
</antcall>
</sequential>
</macrodef>
@@ -59,7 +61,13 @@
<propertyregex property="classpath_with_slash" input="${classpath}" regexp="\." replace="/" global="true" />
<propertyregex property="classpath_with__" input="${classpath}" regexp="\." replace="_" global="true" />
- <propertyregex property="headerfilename" input="${classpath}" regexp="^(\w*\.)*(\w+)$" replace="\2.h" />
+ <if>
+ <equals arg1="${headerfilename}" arg2="" trim="true"/>
+ <then>
+ <propertyregex override="true" property="headerfilename" input="${classpath}" regexp="^(\w*\.)*(\w+)$" replace="\2.h" />
+ <echo message="Header file name defaulting to ${headerfilename} for class ${classpath}"/>
+ </then>
+ </if>
<property name="headerfile" location="${to}/${headerfilename}" />
</target>
============================================================
--- android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/CoreManager.java 02b4f22413e116cecfcb2b1b1ba603ea5e949e5e
+++ android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/CoreManager.java c8fa4f197de0c1910799e8d4d5fc8c540acd9b3a
@@ -1,11 +1,43 @@ package im.pidgin.libpurple.core;
package im.pidgin.libpurple.core;
+import im.pidgin.libpurple.account.PurpleAccountList;
+
/**
* This is the core purple manager, that provides access to all functionality.
- *
+ * <p>
+ * It also implements the core UI ops.
* @author michaelz
*
*/
-public class CoreManager {
+public class CoreManager{
+ private final PurpleAccountList accountList = new PurpleAccountList();
+ private final EventLoop eventloop = new EventLoop();
+
+ /**
+ * Initializes libpurple by setting all the ui ops and calling
+ * purple_core_init().
+ *
+ * @param uiName The name of the UI.
+ */
+ public boolean startCore(String uiName) {
+ eventloop.register();
+ return startCore_native(uiName);
+ }
+
+ private native boolean startCore_native(String uiName);
+
+ public EventLoop getEventloop() {
+ return eventloop;
+ }
+
+ /**
+ * Register all the ui ops for the child objects and sets up jni.
+ * <p>
+ * Do not register the eventloop, since it is alredy registered.
+ */
+ protected void coreInitUI() {
+
+ }
+
}
============================================================
--- android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/EventLoop.java ab4b859d0155bf197e00053cf7733f2a095ef357
+++ android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/EventLoop.java 97b3555c7822b801f3d8a3450f9b6a6f5b1127ea
@@ -8,5 +8,26 @@ public class EventLoop {
*
*/
public class EventLoop {
+ public EventLoop() {
+ }
+ private native void init_native();
+
+ /**
+ * Registers the eventloop for the ui ops.
+ * <p>
+ * Only called once from main thread.
+ */
+ public void register() {
+ init_native();
+ }
+
+ public boolean eventloopRemoveTimeout(int handle) {
+ return false;
+ }
+
+ public int eventloopAddTimeout(int interval, long function, long data) {
+ return 0;
+ }
+
}
============================================================
--- android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/PurpleInstance.java ade1bafb6bb06ab816a9f891a2fc87793e5645da
+++ android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/core/PurpleInstance.java 593b0895fc26f3798d8f57f45e9baefbb746a007
@@ -18,7 +18,14 @@ public class PurpleInstance {
public class PurpleInstance {
private static Object instanceActiveMutex = new Object();
private static boolean instanceActive = false;
+
+ private final CoreManager coreManager = new CoreManager();
+ /**
+ * Creates a new instance and loads libpurple. This might take some time.
+ * @param uiName
+ * @param baseDirectory
+ */
private PurpleInstance(String uiName, File baseDirectory) {
PurpleLibraryLoader.load();
@@ -30,7 +37,7 @@ public class PurpleInstance {
}
addPluginSearchpath(pluginDirectory);
- if (!init_native(uiName)) {
+ if (!coreManager.startCore(uiName)) {
throw new PurpleRuntimeException(
"Initialization of the libpurple core failed.");
}
@@ -48,13 +55,6 @@ public class PurpleInstance {
private native void addPluginSearchpath_native(String absolutePath);
- /**
- * Initializes libpurple by setting the core ui ops and calling
- * purple_core_init(). To be called after eventloop was set up.
- *
- * @param uiName
- */
- private native boolean init_native(String uiName);
public static PurpleInstance createInstance(String uiName,
File baseDirectory) {
============================================================
--- android/workspace/im.pidgin.libpurple/.cproject b6da4f37e901a98d1c3372408fe1a042d23711f4
+++ android/workspace/im.pidgin.libpurple/.cproject 43c54e3f12083f1681fd53c0ecc6c6d4aced718c
@@ -103,7 +103,7 @@
<option id="gnu.cpp.compiler.exe.debug.option.optimization.level.1520803778" name="Optimization Level" superClass="gnu.cpp.compiler.exe.debug.option.optimization.level" value="gnu.cpp.compiler.optimization.level.none" valueType="enumerated"/>
<option id="gnu.cpp.compiler.exe.debug.option.debugging.level.507664491" name="Debug Level" superClass="gnu.cpp.compiler.exe.debug.option.debugging.level" value="gnu.cpp.compiler.debugging.level.max" valueType="enumerated"/>
</tool>
- <tool id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.58653906" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
+ <tool command="${ndk.root}/bin/${ndk.host}-gcc" id="cdt.managedbuild.tool.gnu.c.compiler.exe.debug.58653906" name="GCC C Compiler" superClass="cdt.managedbuild.tool.gnu.c.compiler.exe.debug">
<option defaultValue="gnu.c.optimization.level.none" id="gnu.c.compiler.exe.debug.option.optimization.level.289472638" name="Optimization Level" superClass="gnu.c.compiler.exe.debug.option.optimization.level" valueType="enumerated"/>
<option id="gnu.c.compiler.exe.debug.option.debugging.level.1051527660" name="Debug Level" superClass="gnu.c.compiler.exe.debug.option.debugging.level" value="gnu.c.debugging.level.max" valueType="enumerated"/>
<option id="gnu.c.compiler.option.include.paths.1831007009" name="Include paths (-I)" superClass="gnu.c.compiler.option.include.paths" valueType="includePath">
@@ -117,7 +117,7 @@
<option id="gnu.c.compiler.option.misc.other.1967504557" name="Other flags" superClass="gnu.c.compiler.option.misc.other" value="-c -fmessage-length=0" valueType="string"/>
<inputType id="cdt.managedbuild.tool.gnu.c.compiler.input.793154500" superClass="cdt.managedbuild.tool.gnu.c.compiler.input"/>
</tool>
- <tool id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.137759764" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug">
+ <tool command="${ndk.root}/bin/${ndk.host}-gcc" id="cdt.managedbuild.tool.gnu.c.linker.exe.debug.137759764" name="GCC C Linker" superClass="cdt.managedbuild.tool.gnu.c.linker.exe.debug">
<option id="gnu.c.link.option.libs.1999672232" name="Libraries (-l)" superClass="gnu.c.link.option.libs" valueType="libs">
<listOptionValue builtIn="false" value="purple"/>
<listOptionValue builtIn="false" value="log"/>
@@ -126,13 +126,14 @@
<option id="gnu.c.link.option.paths.727652150" name="Library search path (-L)" superClass="gnu.c.link.option.paths" valueType="libPaths">
<listOptionValue builtIn="false" value=""${workspace_loc:/im.pidgin.libpurple.build/build/prefix/lib}""/>
</option>
+ <option id="gnu.c.link.option.shared.1562332002" superClass="gnu.c.link.option.shared" value="true" valueType="boolean"/>
<inputType id="cdt.managedbuild.tool.gnu.c.linker.input.425224706" superClass="cdt.managedbuild.tool.gnu.c.linker.input">
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
</inputType>
</tool>
<tool id="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug.1506438485" name="GCC C++ Linker" superClass="cdt.managedbuild.tool.gnu.cpp.linker.exe.debug"/>
- <tool id="cdt.managedbuild.tool.gnu.assembler.exe.debug.336892324" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
+ <tool command="${ndk.root}/bin/${ndk.host}-as" id="cdt.managedbuild.tool.gnu.assembler.exe.debug.336892324" name="GCC Assembler" superClass="cdt.managedbuild.tool.gnu.assembler.exe.debug">
<option id="gnu.both.asm.option.include.paths.281739864" name="Include paths (-I)" superClass="gnu.both.asm.option.include.paths" valueType="includePath">
<listOptionValue builtIn="false" value=""${ndk.root}/sysroot/usr/include""/>
<listOptionValue builtIn="false" value=""${ndk.root}/sysroot/usr/include/glib-2.0""/>
============================================================
--- android/workspace/im.pidgin.libpurple/.project c98e549547abeca157c10a02528edee50803c8a6
+++ android/workspace/im.pidgin.libpurple/.project 1a7549fd76216b82a23b06b256e3fd4c56e0df7e
@@ -33,7 +33,7 @@
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildArguments</key>
- <value>-j</value>
+ <value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildCommand</key>
@@ -41,7 +41,7 @@
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildLocation</key>
- <value>${workspace_loc:/im.pidgin.libpurple/Android}</value>
+ <value>${workspace_loc:/im.pidgin.libpurple/Android Debug}</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
============================================================
--- android/workspace/im.pidgin.libpurple/native/PurpleInstance.c 723071418aace3a5ace72a8de22d4f4b77fbe3a6
+++ android/workspace/im.pidgin.libpurple/native/PurpleInstance.c dbf457f0d7e65f75f7a81bb7f86b1d6dd37e49a9
@@ -7,25 +7,9 @@
#include "PurpleInstance.h"
#include "helpers.h"
#include "logging.h"
+#include "EventLoop.h"
-JavaObjectReference instanceReference;
-void initUi();
-
-PurpleCoreUiOps coreUiOps = {
- NULL,
- initLogging,
- initUi,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-void initUi() {
- //TODO...
-}
-
/*
* Class: im_pidgin_libpurple_core_PurpleInstance
* Method: setDebugEnabled_native
@@ -55,38 +39,6 @@ Java_im_pidgin_libpurple_core_PurpleInst
/*
* Class: im_pidgin_libpurple_core_PurpleInstance
- * Method: init_native
- * Signature: ()V
- */JNIEXPORT jboolean JNICALL
-Java_im_pidgin_libpurple_core_PurpleInstance_init_1native(JNIEnv *env,
- jobject obj, jstring uiName)
-{
- jboolean success;
- const char* uiNameNative;
-
- setJavaObject(&instanceReference, env, obj);
-
- purple_core_set_ui_ops(&coreUiOps);
-
- uiNameNative = (*env)->GetStringUTFChars(env, uiName, NULL);
- g_return_val_if_fail(uiNameNative != NULL, JNI_FALSE);
-
- success = purple_core_init(uiNameNative) ? JNI_TRUE : JNI_FALSE;
- (*env)->ReleaseStringUTFChars(env, uiName, uiNameNative);
-
- if (success) {
- purple_set_blist(purple_blist_new());
- purple_blist_load();
- purple_plugins_load_saved("/plugins/loaded");
- purple_pounces_load();
-
- }
-
- return success;
-}
-
-/*
- * Class: im_pidgin_libpurple_core_PurpleInstance
* Method: getVersion_native
* Signature: ()Ljava/lang/String;
*/JNIEXPORT jstring JNICALL
============================================================
--- android/workspace/im.pidgin.libpurple.testclient/AndroidManifest.xml be8c8728a23d259e9d515e7060e08f430a6aefa2
+++ android/workspace/im.pidgin.libpurple.testclient/AndroidManifest.xml 3be12f182ab67a503c9674b7acfd8b73e1d82c7b
@@ -7,8 +7,10 @@
<uses-sdk android:minSdkVersion="10" />
<application
+ android:debuggable="true"
android:icon="@drawable/pidgin"
android:label="@string/app_name" >
+
<activity
android:name=".PurpleTestClient"
android:label="@string/app_name" >
============================================================
--- android/workspace/im.pidgin.libpurple/native/helpers.c c1dc99a68d168d1466e477595ea135683a96bbd8
+++ android/workspace/im.pidgin.libpurple/native/helpers.c 0fad24fe2b49a81da5d993f14c7504152f01cea3
@@ -11,7 +11,9 @@
#include "helpers.h"
-gboolean setJavaObject(JavaObjectReference *ref, JNIEnv *env, jobject object) {
+gboolean
+setJavaObject(JavaObjectReference *ref, JNIEnv *env, jobject object)
+{
g_return_val_if_fail(env != NULL, FALSE);
g_return_val_if_fail(object != NULL, FALSE);
@@ -37,7 +39,9 @@ gboolean setJavaObject(JavaObjectReferen
/**
* Gets the peer field of an object of the peer class.
*/
-void *getNativePointer(JNIEnv *env, jobject peered) {
+void *
+getNativePointer(JNIEnv *env, jobject peered)
+{
static jfieldID peerField = NULL;
if (peerField == NULL) {
@@ -54,3 +58,14 @@ void *getNativePointer(JNIEnv *env, jobj
return longToP((*env)->GetLongField(env, peered, peerField));
}
+
+jmethodID
+getMethodIDCachedReferenced(JNIEnv *env, jclass *class,
+ JavaMethodIDCache *cache)
+{
+ if (cache->mid == NULL) {
+ cache->mid = (*env)->GetMethodID(env, class, cache->name,
+ cache->signature);
+ }
+ return cache->mid;
+}
============================================================
--- android/workspace/im.pidgin.libpurple/native/helpers.h da8cd3d604a44e4eb7258380b02a8bf8ef1cc1f8
+++ android/workspace/im.pidgin.libpurple/native/helpers.h 3f97d6b4fa5b7739529ae45a2536b0cc280f33a4
@@ -33,8 +33,14 @@ typedef struct {
JavaVM *jvm;
jclass class;
} JavaObjectReference;
+#define JAVA_NULL_OBJECT_REF { NULL, NULL, NULL }
-#define JAVA_NULL_OBJECT_REF { NULL, NULL, NULL }
+typedef struct {
+ const char *name;
+ const char *signature;
+ jmethodID mid;
+} JavaMethodIDCache;
+#define METHOD_CACHE(name, signature) { name, signature, NULL }
/**
* Checks the jvm context, adds the *env-Variable that points to the java enviroment.
@@ -58,4 +64,8 @@ void *getNativePointer(JNIEnv *env, jobj
void *getNativePointer(JNIEnv *env, jobject peered);
+jmethodID getMethodIDCachedReferenced(JNIEnv *env, jclass *class, JavaMethodIDCache *cache);
+
+//jmethodID getMethodIDCached(JNIEnv env, jclass class, const char *name, const char *signature, JavaMethodIDCache cache);
+
#endif /* HELPERS_H_ */
============================================================
--- /dev/null
+++ android/workspace/im.pidgin.libpurple/native/CoreManager.c 409e090faa2bc21553d49a8f68b867ff7987e0dd
@@ -0,0 +1,76 @@
+/*
+ * CoreManager.c
+ *
+ * Created on: 07.06.2012
+ * Author: michaelz
+ */
+
+#include <libpurple/core.h>
+#include <libpurple/plugin.h>
+#include <libpurple/blist.h>
+#include <libpurple/pounce.h>
+
+#include "CoreManager.h"
+#include "EventLoop.h"
+#include "helpers.h"
+#include "logging.h"
+
+void
+initUi();
+
+PurpleCoreUiOps coreUiOps =
+ { NULL, initLogging, initUi, NULL, NULL, NULL, NULL };
+
+JavaObjectReference coreManagerInstance;
+
+/**
+ * Called on a ui init event from the core.
+ */
+void
+initUi()
+{
+ static JavaMethodIDCache methodCache = METHOD_CACHE("coreInitUI", "()V");
+
+ jmethodID mid;
+
+ CALLBACK_START_VOID(coreManagerInstance);
+
+ mid = getMethodIDCachedReferenced(env, coreManagerInstance.class,
+ &methodCache);
+ if (mid != NULL) {
+ (*env)->CallVoidMethod(env, coreManagerInstance.handlerObject, mid);
+ }
+}
+
+/*
+ * Class: im_pidgin_libpurple_core_CoreManager
+ * Method: startCore_native
+ * Signature: (Ljava/lang/String;)Z
+ */JNIEXPORT jboolean JNICALL
+ Java_im_pidgin_libpurple_core_CoreManager_startCore_1native(JNIEnv *env,
+ jobject obj, jstring uiName)
+{
+ jboolean success;
+ const char* uiNameNative;
+
+ setJavaObject(&coreManagerInstance, env, obj);
+
+ purple_core_set_ui_ops(&coreUiOps);
+ purple_eventloop_set_ui_ops(getEventloopUiOps());
+
+ uiNameNative = (*env)->GetStringUTFChars(env, uiName, NULL);
+ g_return_val_if_fail(uiNameNative != NULL, JNI_FALSE);
+
+ success = purple_core_init(uiNameNative) ? JNI_TRUE : JNI_FALSE;
+ (*env)->ReleaseStringUTFChars(env, uiName, uiNameNative);
+
+ if (success) {
+ purple_set_blist(purple_blist_new());
+ purple_blist_load();
+ purple_plugins_load_saved("/plugins/loaded");
+ purple_pounces_load();
+ }
+
+ return success;
+}
+
============================================================
--- /dev/null
+++ android/workspace/im.pidgin.libpurple/native/EventLoop.c 8bb800ca3cf58195849fcb90896362142af1ddd5
@@ -0,0 +1,142 @@
+/*
+ * EventLoop.c
+ *
+ * Created on: 07.06.2012
+ * Author: michaelz
+ */
+
+#include "EventLoop.h"
+#include <libpurple/eventloop.h>
+#include <libpurple/debug.h>
+
+static guint
+eventloopAddTimeout(guint interval, GSourceFunc function, gpointer data);
+static gboolean
+eventloopRemoveTimeout(guint handle);
+static guint
+eventloopAddInput(int fd, PurpleInputCondition cond, PurpleInputFunction func,
+ gpointer user_data);
+static gboolean
+eventloopRemoveInput(guint handle);
+
+JavaObjectReference eventloop;
+
+PurpleEventLoopUiOps eventloopUiOps = { eventloopAddTimeout,
+ eventloopRemoveTimeout, eventloopAddInput, eventloopRemoveInput, NULL,
+ NULL, NULL, NULL, NULL };
+
+JNIEXPORT void JNICALL
+Java_im_pidgin_libpurple_core_EventLoop_init_1native(JNIEnv *env, jobject obj)
+{
+ setJavaObject(&eventloop, env, obj);
+}
+
+PurpleEventLoopUiOps *
+getEventloopUiOps()
+{
+ return &eventloopUiOps;
+}
+
+guint
+eventloopAddTimeout(guint interval, GSourceFunc function, gpointer data)
+{
+ static JavaMethodIDCache methodCache =
+ METHOD_CACHE("eventloopAddTimeout", "(IJJ)I");
+
+ jmethodID mid;
+ jlong function_ptr;
+ jlong data_ptr;
+ jint result = 0;
+
+ CALLBACK_START(eventloop, 0);
+
+ function_ptr = pToLong(function);
+ data_ptr = pToLong(data);
+
+ mid = getMethodIDCachedReferenced(env, eventloop.class, &methodCache);
+ if (mid != NULL) {
+ result = (*env)->CallIntMethod(env, eventloop.handlerObject, mid,
+ (jint) interval, function_ptr, data_ptr);
+ }
+ return (guint) result;
+}
+
+gboolean
+eventloopRemoveTimeout(guint handle)
+{
+ static JavaMethodIDCache methodCache =
+ METHOD_CACHE("eventloopRemoveTimeout", "(I)Z");
+
+ jmethodID mid;
+ jboolean result = FALSE;
+
+ CALLBACK_START(eventloop, FALSE);
+
+ mid = getMethodIDCachedReferenced(env, eventloop.class, &methodCache);
+ if (mid != NULL) {
+ result = (*env)->CallBooleanMethod(env, eventloop.handlerObject, mid,
+ (jint) handle);
+ }
+ return (gboolean) result;
+
+}
+
+#define PIDGIN_READ_COND (G_IO_IN | G_IO_HUP | G_IO_ERR)
+#define PIDGIN_WRITE_COND (G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL)
+
+typedef struct _PidginIOClosure {
+ PurpleInputFunction function;
+ guint result;
+ gpointer data;
+} PidginIOClosure;
+
+static gboolean
+pidgin_io_invoke(GIOChannel *source, GIOCondition condition, gpointer data)
+{
+ PidginIOClosure *closure = data;
+ PurpleInputCondition purple_cond = 0;
+
+ if (condition & PIDGIN_READ_COND)
+ purple_cond |= PURPLE_INPUT_READ;
+ if (condition & PIDGIN_WRITE_COND)
+ purple_cond |= PURPLE_INPUT_WRITE;
+
+ purple_debug_misc("eventloop", "CLOSURE: callback for %d, fd is %d\n",
+ closure->result, g_io_channel_unix_get_fd(source));
+
+ closure->function(closure->data, g_io_channel_unix_get_fd(source),
+ purple_cond);
+
+ return TRUE;
+}
+static guint
+eventloopAddInput(gint fd, PurpleInputCondition condition,
+ PurpleInputFunction function, gpointer data)
+{
+ purple_debug_info("eventloop", "called input add");
+ PidginIOClosure *closure = g_new0(PidginIOClosure, 1);
+ GIOChannel *channel;
+ GIOCondition cond = 0;
+
+ closure->function = function;
+ closure->data = data;
+
+ if (condition & PURPLE_INPUT_READ)
+ cond |= PIDGIN_READ_COND;
+ if (condition & PURPLE_INPUT_WRITE)
+ cond |= PIDGIN_WRITE_COND;
+
+ channel = g_io_channel_unix_new(fd);
+
+ closure->result = g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond,
+ pidgin_io_invoke, closure, g_free);
+
+ g_io_channel_unref(channel);
+ return closure->result;
+}
+
+gboolean
+eventloopRemoveInput(guint handle)
+{
+ return g_source_remove(handle);
+}
============================================================
--- /dev/null
+++ android/workspace/im.pidgin.libpurple/native/EventLoop.h 5daef4dd2c6a5d7ca2ef78eec9190c068a5c3809
@@ -0,0 +1,17 @@
+/*
+ * EventLoop.h
+ *
+ * Created on: 07.06.2012
+ * Author: michaelz
+ */
+
+#ifndef EVENTLOOP_H_
+#define EVENTLOOP_H_
+
+#include "EventLoop_jni.h"
+#include "helpers.h"
+#include <libpurple/eventloop.h>
+
+PurpleEventLoopUiOps *getEventloopUiOps();
+
+#endif /* EVENTLOOP_H_ */
============================================================
--- /dev/null
+++ android/workspace/im.pidgin.libpurple/native/gdb.setup a33ec21112991a0dc06a313bd0ae4fe36f1592a8
@@ -0,0 +1 @@
+set solib-search-path ../deploy
============================================================
--- /dev/null
+++ android/workspace/im.pidgin.libpurple/src/im/pidgin/libpurple/exceptions/PurpleRuntimeException.java c7314beb77dbdf1f4e3df625b7e6944439c66c7b
@@ -0,0 +1,25 @@
+package im.pidgin.libpurple.exceptions;
+
+public class PurpleRuntimeException extends RuntimeException {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5538645079481500371L;
+
+ public PurpleRuntimeException() {
+ }
+
+ public PurpleRuntimeException(String detailMessage) {
+ super(detailMessage);
+ }
+
+ public PurpleRuntimeException(Throwable throwable) {
+ super(throwable);
+ }
+
+ public PurpleRuntimeException(String detailMessage, Throwable throwable) {
+ super(detailMessage, throwable);
+ }
+
+}
============================================================
--- /dev/null
+++ android/workspace/im.pidgin.libpurple/startDebugger.sh bcfde6bb86e6086d7dadf64922b51de00c38bb07
@@ -0,0 +1,177 @@
+#!/bin/bash
+# Sets up debugging on the device.
+# This script is a shortened Version of Androids gdb script. It may or may not work.
+# It is licenced under GPL2 or later, or Apache Licence 2.0 at your choice.
+
+
+ADB_CMD=adb
+AWK_CMD=awk
+PACKAGE_NAME=
+DEBUG_PORT=5039
+
+while [ -n "$1" ]; do
+ opt="$1"
+ optarg=`expr "x$opt" : 'x[^=]*=\(.*\)'`
+ case $opt in
+ --adb=*)
+ ADB_CMD="$optarg"
+ ;;
+ --awk=*)
+ AWK_CMD="$optarg"
+ ;;
+ --ndk=*)
+ ANDROID_NDK_ROOT="$optarg"
+ ;;
+ --package=*)
+ PACKAGE_NAME="$optarg"
+ ;;
+ --port=*)
+ DEBUG_PORT="$optarg"
+ ;;
+ esac
+ shift
+done
+
+AWK_SCRIPTS=$ANDROID_NDK_ROOT/build/awk
+
+if ! [ "$PACKAGE_NAME" ]; then
+ echo "Please use --package=... to specify your android package name."
+ exit 1;
+fi
+
+if ! [ -d "libs/armeabi" ]; then
+ echo "Run this script from your target application project directory."
+ exit 1;
+fi
+
+if ! [ -d "$AWK_SCRIPTS" ]; then
+ echo "$AWK_SCRIPTS does not exists."
+ echo "Please use the --ndk=... parameter to give a valid ndk path."
+ exit 1;
+fi
+if ! "$ADB_CMD" version; then
+ echo "Could not run adb using the command $ADB_COMMAND"
+ echo "Use --adb=... to specify an adb command"
+ exit 1;
+fi
+
+get_pid_of ()
+{
+ "$ADB_CMD" shell ps | $AWK_CMD -f $AWK_SCRIPTS/extract-pid.awk -v PACKAGE="$1"
+}
+
+# Used internally by adb_var_shell and adb_var_shell2.
+# $1: 1 to redirect stderr to $1, 0 otherwise.
+# $2: Variable name that will contain the result
+# $3+: Command options
+_adb_var_shell ()
+{
+ # We need a temporary file to store the output of our command
+ local CMD_OUT RET OUTPUT VARNAME REDIRECT_STDERR
+ REDIRECT_STDERR=$1
+ VARNAME=$2
+ shift; shift;
+ CMD_OUT=`mktemp /tmp/ndk-gdb-cmdout-XXXXXX`
+ # Run the command, while storing the standard output to CMD_OUT
+ # and appending the exit code as the last line.
+ if [ "$REDIRECT_STDERR" != 0 ]; then
+ "$ADB_CMD" $ADB_FLAGS shell "$@" ";" echo \$? | sed -e 's![[:cntrl:]]!!g' > $CMD_OUT 2>&1
+ else
+ "$ADB_CMD" $ADB_FLAGS shell "$@" ";" echo \$? | sed -e 's![[:cntrl:]]!!g' > $CMD_OUT
+ fi
+ # Get last line in log, which contains the exit code from the command
+ RET=`sed -e '$!d' $CMD_OUT`
+ # Get output, which corresponds to everything except the last line
+ OUT=`sed -e '$d' $CMD_OUT`
+ rm -f $CMD_OUT
+ eval $VARNAME=\"\$OUT\"
+ return $RET
+}
+
+# Run a command through 'adb shell' and captures its standard output
+# into a variable. The function's exit code is the same than the command's.
+#
+# This is required because there is a bug where "adb shell" always returns
+# 0 on the host, even if the command fails on the device.
+#
+# $1: Variable name (e.g. FOO)
+# On exit, $FOO is set to the command's standard output
+#
+# The return status will be 0 (success) if the command succeeded
+# or 1 (failure) otherwise.
+adb_var_shell ()
+{
+ _adb_var_shell 0 "$@"
+}
+
+# A variant of adb_var_shell that stores both stdout and stderr in the output
+# $1: Variable name
+adb_var_shell2 ()
+{
+ _adb_var_shell 1 "$@"
+}
+
+# Test adb
+if ! "$ADB_CMD" shell ls >> /dev/null; then
+ echo "Could not run adb test command"
+ echo "There may be two devices/emulators running."
+ exit 1;
+fi
+
+PID=$(get_pid_of "$PACKAGE_NAME")
+echo "PID of running application: $PID"
+if [ "$PID" == "0" ]; then
+ echo "Application process not found. Are you sure it is running?"
+ exit 1;
+fi
+
+# Let's check that 'gdbserver' is properly installed on the device too. If this
+# is not the case, the user didn't install the proper package after rebuilding.
+#
+adb_var_shell2 DEVICE_GDBSERVER ls /data/data/$PACKAGE_NAME/lib/gdbserver
+if [ $? != 0 ]; then
+ echo "ERROR: Non-debuggable application installed on the target device."
+ echo " Please re-install the debuggable version!"
+ exit 1
+fi
+echo "Found device gdbserver: $DEVICE_GDBSERVER"
+
+GDBSERVER_PID=$(get_pid_of lib/gdbserver)
+if [ "$GDBSERVER_PID" != "0" ]; then
+ echo "There is already a debug server running. Killing it."
+
+ "$ADB_CMD" shell kill -9 $GDBSERVER_PID
+fi
+
+DEBUG_SOCKET=debug-socket
+"$ADB_CMD" shell run-as $PACKAGE_NAME lib/gdbserver +$DEBUG_SOCKET --attach $PID &
+if [ $? != 0 ] ; then
+ echo "ERROR: Could not launch gdbserver on the device?"
+ exit 1
+fi
+echo "Launched gdbserver succesfully."
+
+# Find the <dataDir> of the package on the device
+adb_var_shell2 DATA_DIR run-as $PACKAGE_NAME /system/bin/sh -c pwd
+if [ $? != 0 -o -z "$DATA_DIR" ] ; then
+ echo "ERROR: Could not extract package's data directory. Are you sure that"
+ echo " your installed application is debuggable?"
+ exit 1
+fi
+echo "Found data directory: '$DATA_DIR'"
+
+# Setup network redirection
+echo "Setup network redirection"
+"$ADB_CMD" forward tcp:$DEBUG_PORT localfilesystem:$DATA_DIR/$DEBUG_SOCKET
+if [ $? != 0 ] ; then
+ echo "ERROR: Could not setup network redirection to gdbserver?"
+ echo " Maybe using --port=<port> to use a different TCP port might help?"
+ exit 1
+fi
+
+"$ADB_CMD" pull /system/bin/app_process libs/armeabi/app_process
+"$ADB_CMD" pull /system/lib/libc.so libs/armeabi/libc.so
+
+GDB_SETUP=libs/armeabi/gdb.setup
+echo "file `realpath libs/armeabi/app_process`" > $GDB_SETUP
+echo "set solib-absolute-prefix `realpath libs/armeabi`" >> $GDB_SETUP
More information about the Commits
mailing list