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