From c3ea0b5f290168ef1ea43e07d9701c25771b9a90 Mon Sep 17 00:00:00 2001 From: perry.werneck@gmail.com Date: Tue, 31 Jul 2012 17:25:42 +0000 Subject: [PATCH] Android - Melhorando tratamento da parte de rede --- android/jni/globals.h | 18 +++--------------- android/jni/main.cpp | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------- android/jni/text.cpp | 5 +++-- android/src/br/com/bb/pw3270/PW3270Activity.java | 23 ++++++++++++++++------- android/src/br/com/bb/pw3270/lib3270.java | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------- 5 files changed, 156 insertions(+), 108 deletions(-) diff --git a/android/jni/globals.h b/android/jni/globals.h index 8d4b117..0d1a3c8 100644 --- a/android/jni/globals.h +++ b/android/jni/globals.h @@ -34,18 +34,6 @@ /*--[ Defines ]--------------------------------------------------------------------------------------*/ -/* - #define session_request(env, obj) H3270 * session = lib3270_get_default_session_handle(); \ - session->widget = &jni_data; - - #define session_release() session->widget = 0; -*/ - -/* - #define PW3270_JNI_BEGIN pw3270_env = env; pw3270_obj = obj; - #define PW3270_JNI_END pw3270_env = NULL; pw3270_obj = NULL; -*/ - #define PW3270_JNI_BEGIN __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "%s.lock env=%p obj=%p",__FUNCTION__,env,obj); \ pw3270_jni_lock(env,obj); @@ -74,9 +62,9 @@ extern PW3270_JNI *pw3270_jni_active; - void pw3270_jni_lock(JNIEnv *env, jobject obj); - void pw3270_jni_unlock(); - void pw3270_jni_post_message(int msgid, int arg1 = 0, int arg2 = 0); + int pw3270_jni_lock(JNIEnv *env, jobject obj); + void pw3270_jni_unlock(); + void pw3270_jni_post_message(int msgid, int arg1 = 0, int arg2 = 0); jmethodID lib3270_getmethodID(const char *name, const char *sig); diff --git a/android/jni/main.cpp b/android/jni/main.cpp index 0c59fb5..617ce13 100644 --- a/android/jni/main.cpp +++ b/android/jni/main.cpp @@ -33,6 +33,7 @@ #include #include #include + #include /*--[ Structs ]--------------------------------------------------------------------------------------*/ @@ -65,7 +66,7 @@ jmethodID lib3270_getmethodID(const char *name, const char *sig) void pw3270_jni_post_message(int msgid, int arg1, int arg2) { - trace("%s: pw3270_env=%p pw3270_obj=%p",__FUNCTION__,PW3270_JNI_ENV,PW3270_JNI_OBJ); + trace("%s: pw3270_env=%p pw3270_obj=%p msgid=%d",__FUNCTION__,PW3270_JNI_ENV,PW3270_JNI_OBJ,msgid); if(pw3270_jni_active) pw3270_jni_call_void("postMessage", "(III)V",(jint) msgid, (jint) arg1, (jint) arg2); @@ -73,6 +74,22 @@ void pw3270_jni_post_message(int msgid, int arg1, int arg2) static void changed(H3270 *session, int offset, int len) { + trace("%s: offset=%d len=%d",__FUNCTION__,offset,len); + + { + char *text = lib3270_get_as_html(session,(LIB3270_HTML_OPTION) (LIB3270_HTML_OPTION_ALL|LIB3270_HTML_OPTION_FORM)); + + if(text) + { + trace("Screen:\n%s\n",text); + lib3270_free(text); + } + else + { + trace("%s returns NULL","lib3270_get_as_html"); + } + } + pw3270_jni_post_message(2,offset,len); } @@ -129,7 +146,6 @@ static void ctlr_done(H3270 *session) void update_status(H3270 *session, LIB3270_MESSAGE id) { -// __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "Status changed to %d",(int) id); pw3270_jni_post_message(1,(int) id); } @@ -137,6 +153,8 @@ static int write_buffer(H3270 *session, unsigned const char *buf, int len) { int rc = -1; + __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "%s: Writing %d bytes",__FUNCTION__,len); + if(PW3270_JNI_ENV) { jbyteArray buffer = pw3270_jni_new_byte_array(len); @@ -147,35 +165,26 @@ static int write_buffer(H3270 *session, unsigned const char *buf, int len) } else { - __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "Can't send %d bytes, no jni env for active session",len); + __android_log_print(ANDROID_LOG_ERROR, PACKAGE_NAME, "Can't send %d bytes, no jni env for active session",len); } trace("%s exits with rc=%d",__FUNCTION__,rc); + return rc; } static void * add_timer(unsigned long interval_ms, H3270 *session, void (*proc)(H3270 *session)) { - TIMER * timer = NULL; + TIMER * timer = (TIMER *) lib3270_malloc(sizeof(TIMER)); - if(PW3270_JNI_ENV) - { - - timer = (TIMER *) lib3270_malloc(sizeof(TIMER)); - timer->sz = sizeof(timer); - timer->enabled = true; - timer->session = session; - timer->proc = proc; + timer->sz = sizeof(timer); + timer->enabled = true; + timer->session = session; + timer->proc = proc; - trace("Timer %08lx created",(unsigned long) timer); + trace("Timer %08lx created",(unsigned long) timer); - pw3270_jni_call_void("newTimer", "(JI)V", (jlong) timer, (jint) interval_ms); - - } - else - { - __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "Can't set timer, no jni env for active session"); - } + pw3270_jni_call_void("newTimer", "(JI)V", (jlong) timer, (jint) interval_ms); return timer; } @@ -185,10 +194,7 @@ static void remove_timer(void *id) TIMER *timer = (TIMER *) id; if(timer == NULL) - { -// __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "Invalid timer ID %08lx",(unsigned long) timer); return; - } __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "Disabling timer %08lx",(unsigned long) timer); @@ -258,18 +264,17 @@ static void tracehandler(H3270 *session, const char *fmt, va_list args) } *dst = 0; + } #endif // X3270_TRACE -JNIEXPORT jint JNICALL Java_br_com_bb_pw3270_lib3270_init(JNIEnv *env, jclass obj) +jint JNI_OnLoad(JavaVM *vm, void *reserved) { H3270 * session = lib3270_session_new(""); - pthread_mutex_init(&mutex,NULL); - - PW3270_JNI_BEGIN + __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "Initializing %s",PACKAGE_NAME); - __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "Initializing session %p",session); + pthread_mutex_init(&mutex,NULL); #ifdef X3270_TRACE lib3270_set_trace_handler(tracehandler); @@ -284,13 +289,12 @@ JNIEXPORT jint JNICALL Java_br_com_bb_pw3270_lib3270_init(JNIEnv *env, jclass ob session->ctlr_done = ctlr_done; session->update_status = update_status; - PW3270_JNI_END - - return 0; + return JNI_VERSION_1_4; } -JNIEXPORT jint JNICALL Java_br_com_bb_pw3270_lib3270_deinit(JNIEnv *env, jclass obj) +void JNI_OnUnload(JavaVM *vm, void *reserved) { + __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "Deinitializing %s",PACKAGE_NAME); pthread_mutex_destroy(&mutex); } @@ -352,38 +356,60 @@ JNIEXPORT void JNICALL Java_br_com_bb_pw3270_lib3270_set_1connection_1status(JNI JNIEXPORT void JNICALL Java_br_com_bb_pw3270_lib3270_procRecvdata(JNIEnv *env, jobject obj, jbyteArray buffer, jint sz) { - unsigned char *netrbuf = (unsigned char *) env->GetByteArrayElements(buffer,NULL); + unsigned char *netrbuf; PW3270_JNI_BEGIN - trace("Processando %d bytes",(size_t) sz); - + netrbuf = (unsigned char *) env->GetByteArrayElements(buffer,NULL); lib3270_data_recv(PW3270_SESSION, (size_t) sz, netrbuf); - - trace("Liberando %d bytes",(size_t) sz); - PW3270_JNI_ENV->ReleaseByteArrayElements(buffer, (signed char *) netrbuf, 0); PW3270_JNI_END } -void pw3270_jni_lock(JNIEnv *env, jobject obj) +int pw3270_jni_lock(JNIEnv *env, jobject obj) { + int status; + PW3270_JNI *datablock = (PW3270_JNI *) lib3270_malloc(sizeof(PW3270_JNI)); datablock->parent = pw3270_jni_active; datablock->env = env; datablock->obj = obj; +// __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "%s",__FUNCTION__); + + status = pthread_mutex_trylock(&mutex); + if(status) + { + __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "Error %s when trying mutex semaphore (rc=%d)",strerror(status),status); + status = pthread_mutex_lock(&mutex); + if(status) + { + __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "Error %s acquiring mutex semaphore (rc=%d)",strerror(status),status); + } + } + +/* if(!pw3270_jni_active || pw3270_jni_active->env != env) { // Environment change, lock + if(!pthread_mutex_trylock(&mutex)) + { + __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "Recursive access"); + } + trace("%s: Environment has changed",__FUNCTION__); pthread_mutex_lock(&mutex); } + */ + pw3270_jni_active = datablock; + + return status; + } void pw3270_jni_unlock(void) @@ -391,12 +417,16 @@ void pw3270_jni_unlock(void) PW3270_JNI *datablock = pw3270_jni_active; pw3270_jni_active = datablock->parent; + pthread_mutex_unlock(&mutex); + +/* if(!pw3270_jni_active || pw3270_jni_active->env != datablock->env) { // Environment change, unlock trace("%s: Environment has changed",__FUNCTION__); pthread_mutex_unlock(&mutex); } +*/ lib3270_free(datablock); } diff --git a/android/jni/text.cpp b/android/jni/text.cpp index 6167cf8..8275d65 100644 --- a/android/jni/text.cpp +++ b/android/jni/text.cpp @@ -46,12 +46,13 @@ JNIEXPORT jbyteArray JNICALL Java_br_com_bb_pw3270_lib3270_getHTML(JNIEnv *env, PW3270_JNI_BEGIN - trace("%s starts, session=%p",__FUNCTION__,PW3270_SESSION); +// trace("%s starts, session=%p",__FUNCTION__,PW3270_SESSION); char *text = lib3270_get_as_html(PW3270_SESSION,(LIB3270_HTML_OPTION) (LIB3270_HTML_OPTION_ALL|LIB3270_HTML_OPTION_FORM)); if(text) { +// trace("Retornar:\n%s\n",text); ret = retString(text); lib3270_free(text); } @@ -60,7 +61,7 @@ JNIEXPORT jbyteArray JNICALL Java_br_com_bb_pw3270_lib3270_getHTML(JNIEnv *env, ret = retString("Empty session"); } - trace("%s ends",__FUNCTION__); +// trace("%s ends",__FUNCTION__); PW3270_JNI_END diff --git a/android/src/br/com/bb/pw3270/PW3270Activity.java b/android/src/br/com/bb/pw3270/PW3270Activity.java index 37ac819..0901bcc 100644 --- a/android/src/br/com/bb/pw3270/PW3270Activity.java +++ b/android/src/br/com/bb/pw3270/PW3270Activity.java @@ -86,6 +86,10 @@ public class PW3270Activity extends Activity protected void popupMessage(int type, String title, String text, String info) { + Log.v(TAG,title); + Log.v(TAG,text); + Log.v(TAG,info); + /* AlertDialog d = new AlertDialog.Builder(mainact).create(); d.setTitle(title); @@ -94,6 +98,7 @@ public class PW3270Activity extends Activity d.setCancelable(true); hideProgressDialog(); d.show(); + */ } @SuppressWarnings("unused") @@ -104,7 +109,12 @@ public class PW3270Activity extends Activity try { text = new String(getHTML(),getEncoding()); - } catch(Exception e) { text = ""; } + } + catch(Exception e) + { + Log.e(TAG,e.getLocalizedMessage()); + return ""; + } return text; } @@ -128,12 +138,16 @@ public class PW3270Activity extends Activity // http://developer.android.com/reference/android/webkit/WebView.html view = new WebView(this); + host = new terminal(); + view.addJavascriptInterface(host, "pw3270"); + view.setWebChromeClient(new WebChromeClient()); view.getSettings().setBuiltInZoomControls(true); view.getSettings().setSupportZoom(true); view.getSettings().setUseWideViewPort(true); view.getSettings().setLoadWithOverviewMode(true); + view.getSettings().setJavaScriptEnabled(true); view.setWebViewClient(new WebViewClient() { @@ -167,15 +181,10 @@ public class PW3270Activity extends Activity }); - view.getSettings().setJavaScriptEnabled(true); - setContentView(view); view.loadUrl("file:index.html"); - host = new terminal(); - view.addJavascriptInterface(host, "pw3270"); - host.connect(); - + // host.connect(); } diff --git a/android/src/br/com/bb/pw3270/lib3270.java b/android/src/br/com/bb/pw3270/lib3270.java index 1b65d96..702c0cf 100644 --- a/android/src/br/com/bb/pw3270/lib3270.java +++ b/android/src/br/com/bb/pw3270/lib3270.java @@ -50,6 +50,7 @@ public class lib3270 private boolean connected = false; private boolean refresh = true; private Socket sock = null; + private lib3270 hSession = this; DataOutputStream outData = null; DataInputStream inData = null; @@ -65,9 +66,10 @@ public class lib3270 { switch (msg.what) { +/* case 0: // Connected/Disconnected - set_connection_status(connected); break; +*/ case 1: // OIA message has changed showProgramMessage(msg.arg1); @@ -95,9 +97,11 @@ public class lib3270 Log.d(TAG, "ctlr_done"); break; +/* case 6: // recv_data procRecvdata(((byteMessage) msg.obj).getMessage(),((byteMessage) msg.obj).getLength()); break; +*/ case 7: // ready hideProgressDialog(); @@ -106,6 +110,11 @@ public class lib3270 case 8: // busy showProgressDialog("Aguarde..."); break; + + case 9: // Create timer + new timer(((Long) msg.obj).longValue(), msg.arg1); + break; + } } }; @@ -114,7 +123,6 @@ public class lib3270 static { System.loadLibrary("3270"); - init(); } lib3270() @@ -128,11 +136,12 @@ public class lib3270 private long id; private lib3270 terminal; - timer(lib3270 session, long timer_id, int msec) { + timer(long timer_id, int msec) + { super(msec, msec); - terminal = session; - id = timer_id; + terminal = hSession; + id = timer_id; Log.d(TAG, "Timer " + id + " set to " + msec + " ms"); @@ -157,7 +166,8 @@ public class lib3270 public String text; public String info; - popupMessageInfo(String title, String text, String info) { + popupMessageInfo(String title, String text, String info) + { this.title = title; this.text = text; this.info = info; @@ -169,16 +179,19 @@ public class lib3270 byte[] msg; int sz; - byteMessage(byte[] contents, int len) { + byteMessage(byte[] contents, int len) + { msg = contents; sz = len; } - byte[] getMessage() { + byte[] getMessage() + { return msg; } - int getLength() { + int getLength() + { return sz; } } @@ -187,7 +200,7 @@ public class lib3270 { Log.i(TAG, "Bytes a enviar: " + len); - try + try { outData.write(data, 0, len); outData.flush(); @@ -207,6 +220,8 @@ public class lib3270 postPopup(0, "Erro na comunicação", "Não foi possível enviar dados", msg); + connected = false; + } return -1; } @@ -224,18 +239,21 @@ public class lib3270 postMessage(1, 14, 0); - if (ssl) + if (ssl) { // Host é SSL socketFactory = SSLSocketFactory.getDefault(); - } - else + Log.v(TAG,"Conecting with SSLSocketFactory"); + } + else { + Log.v(TAG,"Conecting with SocketFactory"); socketFactory = SocketFactory.getDefault(); } - try + try { + Log.v(TAG,"Getting socket for " + hostname + ":" + Integer.toString(port)); sock = socketFactory.createSocket(hostname, port); outData = new DataOutputStream(sock.getOutputStream()); inData = new DataInputStream(sock.getInputStream()); @@ -272,32 +290,42 @@ public class lib3270 if (connected) { - postMessage(0, 0, 0); + set_connection_status(true); while (connected) { byte[] in = new byte[4096]; int sz = -1; - try + try { + Log.v(TAG,"Aguardando dados..."); sz = inData.read(in, 0, 4096); - Log.i(TAG, Integer.toString(sz) + " bytes recebidos"); - - if (sz > 0) - { - Message msg = mHandler.obtainMessage(); - msg.what = 6; - msg.obj = new byteMessage(in, sz); - mHandler.sendMessage(msg); - } - - } catch (Exception e) + } catch (Exception e) { Log.i(TAG, "Erro ao receber dados do host: " + e.getLocalizedMessage()); connected = false; + sz = -1; } + + if (sz > 0) + { + try + { + Log.i(TAG, Integer.toString(sz) + " bytes recebidos"); + procRecvdata(in,sz); + // Message msg = mHandler.obtainMessage(); + // msg.what = 6; + // msg.obj = new byteMessage(in, sz); + // mHandler.sendMessage(msg); + } catch (Exception e) + { + Log.i(TAG, "Erro ao processar dados recebidos: " + e.getLocalizedMessage()); + connected = false; + } + } + } } @@ -313,23 +341,12 @@ public class lib3270 outData = null; inData = null; - postMessage(0, 0, 0); + set_connection_status(false); mainloop = null; info(TAG, "Network thread stopped"); } - /* - public void postMessage(int what, int arg1, int arg2) - { - Message msg = mHandler.obtainMessage(); - msg.what = what; - msg.arg1 = arg1; - msg.arg2 = arg2; - mHandler.sendMessage(msg); - } - */ - public void postPopup(int type, String title, String text, String info) { Message msg = mHandler.obtainMessage(); @@ -499,10 +516,6 @@ public class lib3270 } /*---[ Native calls ]----------------------------------------------------*/ - static private native int init(); - - static private native int deinit(); - private native int processEvents(); // private native int do_connect(); @@ -530,9 +543,16 @@ public class lib3270 public native boolean isTerminalReady(); // Timers - protected void newTimer(long id, int msec) + protected void newTimer(long id, int msec) { - new timer(this, id, msec); + Message msg = mHandler.obtainMessage(); + + msg.what = 9; // MSG_CREATETIMER + msg.arg1 = msec; + msg.obj = new Long(id); + + mHandler.sendMessage(msg); + } private native void timerFinish(long id); -- libgit2 0.21.2