Commit c3ea0b5f290168ef1ea43e07d9701c25771b9a90

Authored by perry.werneck@gmail.com
1 parent 7eb74648

Android - Melhorando tratamento da parte de rede

android/jni/globals.h
... ... @@ -34,18 +34,6 @@
34 34  
35 35 /*--[ Defines ]--------------------------------------------------------------------------------------*/
36 36  
37   -/*
38   - #define session_request(env, obj) H3270 * session = lib3270_get_default_session_handle(); \
39   - session->widget = &jni_data;
40   -
41   - #define session_release() session->widget = 0;
42   -*/
43   -
44   -/*
45   - #define PW3270_JNI_BEGIN pw3270_env = env; pw3270_obj = obj;
46   - #define PW3270_JNI_END pw3270_env = NULL; pw3270_obj = NULL;
47   -*/
48   -
49 37 #define PW3270_JNI_BEGIN __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "%s.lock env=%p obj=%p",__FUNCTION__,env,obj); \
50 38 pw3270_jni_lock(env,obj);
51 39  
... ... @@ -74,9 +62,9 @@
74 62  
75 63 extern PW3270_JNI *pw3270_jni_active;
76 64  
77   - void pw3270_jni_lock(JNIEnv *env, jobject obj);
78   - void pw3270_jni_unlock();
79   - void pw3270_jni_post_message(int msgid, int arg1 = 0, int arg2 = 0);
  65 + int pw3270_jni_lock(JNIEnv *env, jobject obj);
  66 + void pw3270_jni_unlock();
  67 + void pw3270_jni_post_message(int msgid, int arg1 = 0, int arg2 = 0);
80 68  
81 69 jmethodID lib3270_getmethodID(const char *name, const char *sig);
82 70  
... ...
android/jni/main.cpp
... ... @@ -33,6 +33,7 @@
33 33 #include <lib3270/config.h>
34 34 #include <lib3270/popup.h>
35 35 #include <lib3270/internals.h>
  36 + #include <lib3270/html.h>
36 37  
37 38 /*--[ Structs ]--------------------------------------------------------------------------------------*/
38 39  
... ... @@ -65,7 +66,7 @@ jmethodID lib3270_getmethodID(const char *name, const char *sig)
65 66  
66 67 void pw3270_jni_post_message(int msgid, int arg1, int arg2)
67 68 {
68   - trace("%s: pw3270_env=%p pw3270_obj=%p",__FUNCTION__,PW3270_JNI_ENV,PW3270_JNI_OBJ);
  69 + trace("%s: pw3270_env=%p pw3270_obj=%p msgid=%d",__FUNCTION__,PW3270_JNI_ENV,PW3270_JNI_OBJ,msgid);
69 70  
70 71 if(pw3270_jni_active)
71 72 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)
73 74  
74 75 static void changed(H3270 *session, int offset, int len)
75 76 {
  77 + trace("%s: offset=%d len=%d",__FUNCTION__,offset,len);
  78 +
  79 + {
  80 + char *text = lib3270_get_as_html(session,(LIB3270_HTML_OPTION) (LIB3270_HTML_OPTION_ALL|LIB3270_HTML_OPTION_FORM));
  81 +
  82 + if(text)
  83 + {
  84 + trace("Screen:\n%s\n",text);
  85 + lib3270_free(text);
  86 + }
  87 + else
  88 + {
  89 + trace("%s returns NULL","lib3270_get_as_html");
  90 + }
  91 + }
  92 +
76 93 pw3270_jni_post_message(2,offset,len);
77 94 }
78 95  
... ... @@ -129,7 +146,6 @@ static void ctlr_done(H3270 *session)
129 146  
130 147 void update_status(H3270 *session, LIB3270_MESSAGE id)
131 148 {
132   -// __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "Status changed to %d",(int) id);
133 149 pw3270_jni_post_message(1,(int) id);
134 150 }
135 151  
... ... @@ -137,6 +153,8 @@ static int write_buffer(H3270 *session, unsigned const char *buf, int len)
137 153 {
138 154 int rc = -1;
139 155  
  156 + __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "%s: Writing %d bytes",__FUNCTION__,len);
  157 +
140 158 if(PW3270_JNI_ENV)
141 159 {
142 160 jbyteArray buffer = pw3270_jni_new_byte_array(len);
... ... @@ -147,35 +165,26 @@ static int write_buffer(H3270 *session, unsigned const char *buf, int len)
147 165 }
148 166 else
149 167 {
150   - __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "Can't send %d bytes, no jni env for active session",len);
  168 + __android_log_print(ANDROID_LOG_ERROR, PACKAGE_NAME, "Can't send %d bytes, no jni env for active session",len);
151 169 }
152 170  
153 171 trace("%s exits with rc=%d",__FUNCTION__,rc);
  172 +
154 173 return rc;
155 174 }
156 175  
157 176 static void * add_timer(unsigned long interval_ms, H3270 *session, void (*proc)(H3270 *session))
158 177 {
159   - TIMER * timer = NULL;
  178 + TIMER * timer = (TIMER *) lib3270_malloc(sizeof(TIMER));
160 179  
161   - if(PW3270_JNI_ENV)
162   - {
163   -
164   - timer = (TIMER *) lib3270_malloc(sizeof(TIMER));
165   - timer->sz = sizeof(timer);
166   - timer->enabled = true;
167   - timer->session = session;
168   - timer->proc = proc;
  180 + timer->sz = sizeof(timer);
  181 + timer->enabled = true;
  182 + timer->session = session;
  183 + timer->proc = proc;
169 184  
170   - trace("Timer %08lx created",(unsigned long) timer);
  185 + trace("Timer %08lx created",(unsigned long) timer);
171 186  
172   - pw3270_jni_call_void("newTimer", "(JI)V", (jlong) timer, (jint) interval_ms);
173   -
174   - }
175   - else
176   - {
177   - __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "Can't set timer, no jni env for active session");
178   - }
  187 + pw3270_jni_call_void("newTimer", "(JI)V", (jlong) timer, (jint) interval_ms);
179 188  
180 189 return timer;
181 190 }
... ... @@ -185,10 +194,7 @@ static void remove_timer(void *id)
185 194 TIMER *timer = (TIMER *) id;
186 195  
187 196 if(timer == NULL)
188   - {
189   -// __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "Invalid timer ID %08lx",(unsigned long) timer);
190 197 return;
191   - }
192 198  
193 199 __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "Disabling timer %08lx",(unsigned long) timer);
194 200  
... ... @@ -258,18 +264,17 @@ static void tracehandler(H3270 *session, const char *fmt, va_list args)
258 264 }
259 265  
260 266 *dst = 0;
  267 +
261 268 }
262 269 #endif // X3270_TRACE
263 270  
264   -JNIEXPORT jint JNICALL Java_br_com_bb_pw3270_lib3270_init(JNIEnv *env, jclass obj)
  271 +jint JNI_OnLoad(JavaVM *vm, void *reserved)
265 272 {
266 273 H3270 * session = lib3270_session_new("");
267 274  
268   - pthread_mutex_init(&mutex,NULL);
269   -
270   - PW3270_JNI_BEGIN
  275 + __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "Initializing %s",PACKAGE_NAME);
271 276  
272   - __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "Initializing session %p",session);
  277 + pthread_mutex_init(&mutex,NULL);
273 278  
274 279 #ifdef X3270_TRACE
275 280 lib3270_set_trace_handler(tracehandler);
... ... @@ -284,13 +289,12 @@ JNIEXPORT jint JNICALL Java_br_com_bb_pw3270_lib3270_init(JNIEnv *env, jclass ob
284 289 session->ctlr_done = ctlr_done;
285 290 session->update_status = update_status;
286 291  
287   - PW3270_JNI_END
288   -
289   - return 0;
  292 + return JNI_VERSION_1_4;
290 293 }
291 294  
292   -JNIEXPORT jint JNICALL Java_br_com_bb_pw3270_lib3270_deinit(JNIEnv *env, jclass obj)
  295 +void JNI_OnUnload(JavaVM *vm, void *reserved)
293 296 {
  297 + __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "Deinitializing %s",PACKAGE_NAME);
294 298 pthread_mutex_destroy(&mutex);
295 299 }
296 300  
... ... @@ -352,38 +356,60 @@ JNIEXPORT void JNICALL Java_br_com_bb_pw3270_lib3270_set_1connection_1status(JNI
352 356  
353 357 JNIEXPORT void JNICALL Java_br_com_bb_pw3270_lib3270_procRecvdata(JNIEnv *env, jobject obj, jbyteArray buffer, jint sz)
354 358 {
355   - unsigned char *netrbuf = (unsigned char *) env->GetByteArrayElements(buffer,NULL);
  359 + unsigned char *netrbuf;
356 360  
357 361 PW3270_JNI_BEGIN
358 362  
359   - trace("Processando %d bytes",(size_t) sz);
360   -
  363 + netrbuf = (unsigned char *) env->GetByteArrayElements(buffer,NULL);
361 364 lib3270_data_recv(PW3270_SESSION, (size_t) sz, netrbuf);
362   -
363   - trace("Liberando %d bytes",(size_t) sz);
364   -
365 365 PW3270_JNI_ENV->ReleaseByteArrayElements(buffer, (signed char *) netrbuf, 0);
366 366  
367 367 PW3270_JNI_END
368 368  
369 369 }
370 370  
371   -void pw3270_jni_lock(JNIEnv *env, jobject obj)
  371 +int pw3270_jni_lock(JNIEnv *env, jobject obj)
372 372 {
  373 + int status;
  374 +
373 375 PW3270_JNI *datablock = (PW3270_JNI *) lib3270_malloc(sizeof(PW3270_JNI));
374 376  
375 377 datablock->parent = pw3270_jni_active;
376 378 datablock->env = env;
377 379 datablock->obj = obj;
378 380  
  381 +// __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "%s",__FUNCTION__);
  382 +
  383 + status = pthread_mutex_trylock(&mutex);
  384 + if(status)
  385 + {
  386 + __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "Error %s when trying mutex semaphore (rc=%d)",strerror(status),status);
  387 + status = pthread_mutex_lock(&mutex);
  388 + if(status)
  389 + {
  390 + __android_log_print(ANDROID_LOG_VERBOSE, PACKAGE_NAME, "Error %s acquiring mutex semaphore (rc=%d)",strerror(status),status);
  391 + }
  392 + }
  393 +
  394 +/*
379 395 if(!pw3270_jni_active || pw3270_jni_active->env != env)
380 396 {
381 397 // Environment change, lock
  398 + if(!pthread_mutex_trylock(&mutex))
  399 + {
  400 + __android_log_print(ANDROID_LOG_DEBUG, PACKAGE_NAME, "Recursive access");
  401 + }
  402 +
382 403 trace("%s: Environment has changed",__FUNCTION__);
383 404 pthread_mutex_lock(&mutex);
384 405 }
385 406  
  407 + */
  408 +
386 409 pw3270_jni_active = datablock;
  410 +
  411 + return status;
  412 +
387 413 }
388 414  
389 415 void pw3270_jni_unlock(void)
... ... @@ -391,12 +417,16 @@ void pw3270_jni_unlock(void)
391 417 PW3270_JNI *datablock = pw3270_jni_active;
392 418 pw3270_jni_active = datablock->parent;
393 419  
  420 + pthread_mutex_unlock(&mutex);
  421 +
  422 +/*
394 423 if(!pw3270_jni_active || pw3270_jni_active->env != datablock->env)
395 424 {
396 425 // Environment change, unlock
397 426 trace("%s: Environment has changed",__FUNCTION__);
398 427 pthread_mutex_unlock(&mutex);
399 428 }
  429 +*/
400 430  
401 431 lib3270_free(datablock);
402 432 }
... ...
android/jni/text.cpp
... ... @@ -46,12 +46,13 @@ JNIEXPORT jbyteArray JNICALL Java_br_com_bb_pw3270_lib3270_getHTML(JNIEnv *env,
46 46  
47 47 PW3270_JNI_BEGIN
48 48  
49   - trace("%s starts, session=%p",__FUNCTION__,PW3270_SESSION);
  49 +// trace("%s starts, session=%p",__FUNCTION__,PW3270_SESSION);
50 50  
51 51 char *text = lib3270_get_as_html(PW3270_SESSION,(LIB3270_HTML_OPTION) (LIB3270_HTML_OPTION_ALL|LIB3270_HTML_OPTION_FORM));
52 52  
53 53 if(text)
54 54 {
  55 +// trace("Retornar:\n%s\n",text);
55 56 ret = retString(text);
56 57 lib3270_free(text);
57 58 }
... ... @@ -60,7 +61,7 @@ JNIEXPORT jbyteArray JNICALL Java_br_com_bb_pw3270_lib3270_getHTML(JNIEnv *env,
60 61 ret = retString("<b>Empty session</b>");
61 62 }
62 63  
63   - trace("%s ends",__FUNCTION__);
  64 +// trace("%s ends",__FUNCTION__);
64 65  
65 66 PW3270_JNI_END
66 67  
... ...
android/src/br/com/bb/pw3270/PW3270Activity.java
... ... @@ -86,6 +86,10 @@ public class PW3270Activity extends Activity
86 86  
87 87 protected void popupMessage(int type, String title, String text, String info)
88 88 {
  89 + Log.v(TAG,title);
  90 + Log.v(TAG,text);
  91 + Log.v(TAG,info);
  92 + /*
89 93 AlertDialog d = new AlertDialog.Builder(mainact).create();
90 94  
91 95 d.setTitle(title);
... ... @@ -94,6 +98,7 @@ public class PW3270Activity extends Activity
94 98 d.setCancelable(true);
95 99 hideProgressDialog();
96 100 d.show();
  101 + */
97 102 }
98 103  
99 104 @SuppressWarnings("unused")
... ... @@ -104,7 +109,12 @@ public class PW3270Activity extends Activity
104 109 try
105 110 {
106 111 text = new String(getHTML(),getEncoding());
107   - } catch(Exception e) { text = ""; }
  112 + }
  113 + catch(Exception e)
  114 + {
  115 + Log.e(TAG,e.getLocalizedMessage());
  116 + return "";
  117 + }
108 118  
109 119 return text;
110 120 }
... ... @@ -128,12 +138,16 @@ public class PW3270Activity extends Activity
128 138 // http://developer.android.com/reference/android/webkit/WebView.html
129 139 view = new WebView(this);
130 140  
  141 + host = new terminal();
  142 + view.addJavascriptInterface(host, "pw3270");
  143 +
131 144 view.setWebChromeClient(new WebChromeClient());
132 145  
133 146 view.getSettings().setBuiltInZoomControls(true);
134 147 view.getSettings().setSupportZoom(true);
135 148 view.getSettings().setUseWideViewPort(true);
136 149 view.getSettings().setLoadWithOverviewMode(true);
  150 + view.getSettings().setJavaScriptEnabled(true);
137 151  
138 152 view.setWebViewClient(new WebViewClient()
139 153 {
... ... @@ -167,15 +181,10 @@ public class PW3270Activity extends Activity
167 181  
168 182 });
169 183  
170   - view.getSettings().setJavaScriptEnabled(true);
171   -
172 184 setContentView(view);
173 185 view.loadUrl("file:index.html");
174 186  
175   - host = new terminal();
176   - view.addJavascriptInterface(host, "pw3270");
177   - host.connect();
178   -
  187 + // host.connect();
179 188  
180 189 }
181 190  
... ...
android/src/br/com/bb/pw3270/lib3270.java
... ... @@ -50,6 +50,7 @@ public class lib3270
50 50 private boolean connected = false;
51 51 private boolean refresh = true;
52 52 private Socket sock = null;
  53 + private lib3270 hSession = this;
53 54  
54 55 DataOutputStream outData = null;
55 56 DataInputStream inData = null;
... ... @@ -65,9 +66,10 @@ public class lib3270
65 66 {
66 67 switch (msg.what)
67 68 {
  69 +/*
68 70 case 0: // Connected/Disconnected
69   - set_connection_status(connected);
70 71 break;
  72 +*/
71 73  
72 74 case 1: // OIA message has changed
73 75 showProgramMessage(msg.arg1);
... ... @@ -95,9 +97,11 @@ public class lib3270
95 97 Log.d(TAG, "ctlr_done");
96 98 break;
97 99  
  100 +/*
98 101 case 6: // recv_data
99 102 procRecvdata(((byteMessage) msg.obj).getMessage(),((byteMessage) msg.obj).getLength());
100 103 break;
  104 +*/
101 105  
102 106 case 7: // ready
103 107 hideProgressDialog();
... ... @@ -106,6 +110,11 @@ public class lib3270
106 110 case 8: // busy
107 111 showProgressDialog("Aguarde...");
108 112 break;
  113 +
  114 + case 9: // Create timer
  115 + new timer(((Long) msg.obj).longValue(), msg.arg1);
  116 + break;
  117 +
109 118 }
110 119 }
111 120 };
... ... @@ -114,7 +123,6 @@ public class lib3270
114 123 static
115 124 {
116 125 System.loadLibrary("3270");
117   - init();
118 126 }
119 127  
120 128 lib3270()
... ... @@ -128,11 +136,12 @@ public class lib3270
128 136 private long id;
129 137 private lib3270 terminal;
130 138  
131   - timer(lib3270 session, long timer_id, int msec) {
  139 + timer(long timer_id, int msec)
  140 + {
132 141 super(msec, msec);
133 142  
134   - terminal = session;
135   - id = timer_id;
  143 + terminal = hSession;
  144 + id = timer_id;
136 145  
137 146 Log.d(TAG, "Timer " + id + " set to " + msec + " ms");
138 147  
... ... @@ -157,7 +166,8 @@ public class lib3270
157 166 public String text;
158 167 public String info;
159 168  
160   - popupMessageInfo(String title, String text, String info) {
  169 + popupMessageInfo(String title, String text, String info)
  170 + {
161 171 this.title = title;
162 172 this.text = text;
163 173 this.info = info;
... ... @@ -169,16 +179,19 @@ public class lib3270
169 179 byte[] msg;
170 180 int sz;
171 181  
172   - byteMessage(byte[] contents, int len) {
  182 + byteMessage(byte[] contents, int len)
  183 + {
173 184 msg = contents;
174 185 sz = len;
175 186 }
176 187  
177   - byte[] getMessage() {
  188 + byte[] getMessage()
  189 + {
178 190 return msg;
179 191 }
180 192  
181   - int getLength() {
  193 + int getLength()
  194 + {
182 195 return sz;
183 196 }
184 197 }
... ... @@ -187,7 +200,7 @@ public class lib3270
187 200 {
188 201 Log.i(TAG, "Bytes a enviar: " + len);
189 202  
190   - try
  203 + try
191 204 {
192 205 outData.write(data, 0, len);
193 206 outData.flush();
... ... @@ -207,6 +220,8 @@ public class lib3270
207 220  
208 221 postPopup(0, "Erro na comunicação", "Não foi possível enviar dados", msg);
209 222  
  223 + connected = false;
  224 +
210 225 }
211 226 return -1;
212 227 }
... ... @@ -224,18 +239,21 @@ public class lib3270
224 239  
225 240 postMessage(1, 14, 0);
226 241  
227   - if (ssl)
  242 + if (ssl)
228 243 {
229 244 // Host é SSL
230 245 socketFactory = SSLSocketFactory.getDefault();
231   - }
232   - else
  246 + Log.v(TAG,"Conecting with SSLSocketFactory");
  247 + }
  248 + else
233 249 {
  250 + Log.v(TAG,"Conecting with SocketFactory");
234 251 socketFactory = SocketFactory.getDefault();
235 252 }
236 253  
237   - try
  254 + try
238 255 {
  256 + Log.v(TAG,"Getting socket for " + hostname + ":" + Integer.toString(port));
239 257 sock = socketFactory.createSocket(hostname, port);
240 258 outData = new DataOutputStream(sock.getOutputStream());
241 259 inData = new DataInputStream(sock.getInputStream());
... ... @@ -272,32 +290,42 @@ public class lib3270
272 290  
273 291 if (connected)
274 292 {
275   - postMessage(0, 0, 0);
  293 + set_connection_status(true);
276 294  
277 295 while (connected)
278 296 {
279 297 byte[] in = new byte[4096];
280 298 int sz = -1;
281 299  
282   - try
  300 + try
283 301 {
  302 + Log.v(TAG,"Aguardando dados...");
284 303 sz = inData.read(in, 0, 4096);
285 304  
286   - Log.i(TAG, Integer.toString(sz) + " bytes recebidos");
287   -
288   - if (sz > 0)
289   - {
290   - Message msg = mHandler.obtainMessage();
291   - msg.what = 6;
292   - msg.obj = new byteMessage(in, sz);
293   - mHandler.sendMessage(msg);
294   - }
295   -
296   - } catch (Exception e)
  305 + } catch (Exception e)
297 306 {
298 307 Log.i(TAG, "Erro ao receber dados do host: " + e.getLocalizedMessage());
299 308 connected = false;
  309 + sz = -1;
300 310 }
  311 +
  312 + if (sz > 0)
  313 + {
  314 + try
  315 + {
  316 + Log.i(TAG, Integer.toString(sz) + " bytes recebidos");
  317 + procRecvdata(in,sz);
  318 + // Message msg = mHandler.obtainMessage();
  319 + // msg.what = 6;
  320 + // msg.obj = new byteMessage(in, sz);
  321 + // mHandler.sendMessage(msg);
  322 + } catch (Exception e)
  323 + {
  324 + Log.i(TAG, "Erro ao processar dados recebidos: " + e.getLocalizedMessage());
  325 + connected = false;
  326 + }
  327 + }
  328 +
301 329 }
302 330 }
303 331  
... ... @@ -313,23 +341,12 @@ public class lib3270
313 341 outData = null;
314 342 inData = null;
315 343  
316   - postMessage(0, 0, 0);
  344 + set_connection_status(false);
317 345  
318 346 mainloop = null;
319 347 info(TAG, "Network thread stopped");
320 348 }
321 349  
322   - /*
323   - public void postMessage(int what, int arg1, int arg2)
324   - {
325   - Message msg = mHandler.obtainMessage();
326   - msg.what = what;
327   - msg.arg1 = arg1;
328   - msg.arg2 = arg2;
329   - mHandler.sendMessage(msg);
330   - }
331   - */
332   -
333 350 public void postPopup(int type, String title, String text, String info)
334 351 {
335 352 Message msg = mHandler.obtainMessage();
... ... @@ -499,10 +516,6 @@ public class lib3270
499 516 }
500 517  
501 518 /*---[ Native calls ]----------------------------------------------------*/
502   - static private native int init();
503   -
504   - static private native int deinit();
505   -
506 519 private native int processEvents();
507 520  
508 521 // private native int do_connect();
... ... @@ -530,9 +543,16 @@ public class lib3270
530 543 public native boolean isTerminalReady();
531 544  
532 545 // Timers
533   - protected void newTimer(long id, int msec)
  546 + protected void newTimer(long id, int msec)
534 547 {
535   - new timer(this, id, msec);
  548 + Message msg = mHandler.obtainMessage();
  549 +
  550 + msg.what = 9; // MSG_CREATETIMER
  551 + msg.arg1 = msec;
  552 + msg.obj = new Long(id);
  553 +
  554 + mHandler.sendMessage(msg);
  555 +
536 556 }
537 557  
538 558 private native void timerFinish(long id);
... ...