comparison app/src/main/java/com/five_ten_sg/connectbot/monitor/MonitorService.java @ 31:0bc0b4798d9e

fix saystring(12) command for proper unicode and document it
author Carl Byington <carl@five-ten-sg.com>
date Sun, 28 Apr 2019 14:45:56 -0700
parents 807f7e4eaebe
children
comparison
equal deleted inserted replaced
30:89b6389aa5b2 31:0bc0b4798d9e
43 public static final char MONITOR_CMD_SCREENWATCH = 7; 43 public static final char MONITOR_CMD_SCREENWATCH = 7;
44 public static final char MONITOR_CMD_DEPRESS = 8; 44 public static final char MONITOR_CMD_DEPRESS = 8;
45 public static final char MONITOR_CMD_SHOWURL = 9; 45 public static final char MONITOR_CMD_SHOWURL = 9;
46 public static final char MONITOR_CMD_SWITCHSESSION = 10; 46 public static final char MONITOR_CMD_SWITCHSESSION = 10;
47 public static final char MONITOR_CMD_CURSORREQUEST = 11; 47 public static final char MONITOR_CMD_CURSORREQUEST = 11;
48 public static final char MONITOR_CMD_SAYSTRING = 12;
48 49
49 public static final char CURSOR_REQUESTED = 0; 50 public static final char CURSOR_REQUESTED = 0;
50 public static final char CURSOR_SCREEN_CHANGE = 1; 51 public static final char CURSOR_SCREEN_CHANGE = 1;
51 public static final char CURSOR_USER_KEY = 2; 52 public static final char CURSOR_USER_KEY = 2;
52 53
197 public synchronized void abandon() { 198 public synchronized void abandon() {
198 value_queue.offer(new triple(0, 0, new char[0])); 199 value_queue.offer(new triple(0, 0, new char[0]));
199 } 200 }
200 201
201 public void speak(byte [] msg, boolean flush, boolean synchronous) { 202 public void speak(byte [] msg, boolean flush, boolean synchronous) {
203 speak(utf8BytesToString(msg), flush, synchronous);
204 }
205
206 public void speak(char [] msg, boolean flush, boolean synchronous) {
207 speak(new String(msg), flush, synchronous);
208 }
209
210 public void speak(String msg, boolean flush, boolean synchronous) {
202 if (speech) { 211 if (speech) {
203 String smsg = bytesToString(msg);
204 if (synchronous) { 212 if (synchronous) {
205 HashMap<String, String> myHashParms = new HashMap(); 213 HashMap<String, String> myHashParms = new HashMap();
206 myHashParms.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, String.format("connection %d", connection)); 214 myHashParms.put(TextToSpeech.Engine.KEY_PARAM_UTTERANCE_ID, String.format("connection %d", connection));
207 talker.speak(smsg, (flush) ? TextToSpeech.QUEUE_FLUSH : TextToSpeech.QUEUE_ADD, myHashParms); 215 talker.speak(msg, (flush) ? TextToSpeech.QUEUE_FLUSH : TextToSpeech.QUEUE_ADD, myHashParms);
208 try { 216 try {
209 String x = talkerQueue.take(); // wait for completion 217 String x = talkerQueue.take(); // wait for completion
210 } catch (InterruptedException e) { 218 } catch (InterruptedException e) {
211 Log.e(TAG, "exception in cm.speak()", e); 219 Log.e(TAG, "exception in cm.speak()", e);
212 } 220 }
213 } 221 }
214 else { 222 else {
215 talker.speak(smsg, (flush) ? TextToSpeech.QUEUE_FLUSH : TextToSpeech.QUEUE_ADD, null); 223 talker.speak(msg, (flush) ? TextToSpeech.QUEUE_FLUSH : TextToSpeech.QUEUE_ADD, null);
216 } 224 }
217 } 225 }
218 } 226 }
219 227
220 public String bytesToString(byte[] b) { 228 public String utf8BytesToString(byte[] b) {
221 char[] c = new char[b.length]; 229 try {
222 int bp = 0; 230 return new String(b, "UTF-8");
223 for(int i = 0; i < c.length; i++) { 231 }
224 byte b1 = 0; 232 catch (Exception e) {
225 byte b2 = b[bp++]; 233 return "invalid utf-8";
226 c[i] = (char) (((b1 & 0x00FF) << 8) + (b2 & 0x00FF)); 234 }
227 }
228 return new String(c);
229 } 235 }
230 236
231 public char[] bytesToChars(byte[] b, int len) { 237 public char[] bytesToChars(byte[] b, int len) {
232 char[] c = new char[len >> 1]; 238 char[] c = new char[len >> 1];
233 int bp = 0; 239 int bp = 0;
285 catch (IOException ee) { 291 catch (IOException ee) {
286 Log.e(TAG, "exception in monitorWrite() closing socket", ee); 292 Log.e(TAG, "exception in monitorWrite() closing socket", ee);
287 } 293 }
288 client_out = null; 294 client_out = null;
289 } 295 }
290 }; 296 }
291 297
292 private char[] forceRead(int len) throws IOException { 298 private char[] forceRead(int len) throws IOException {
293 int len2 = len*2; 299 int len2 = len*2;
294 int off = 0; 300 int off = 0;
295 byte[] b = new byte[len2]; 301 byte[] b = new byte[len2];
396 break; 402 break;
397 case MONITOR_CMD_FIELDVALUE: 403 case MONITOR_CMD_FIELDVALUE:
398 value_queue.clear(); 404 value_queue.clear();
399 value_queue.put(reformatValue(packet)); 405 value_queue.put(reformatValue(packet));
400 break; 406 break;
407 case MONITOR_CMD_SAYSTRING:
408 buf = new char[plen-3];
409 System.arraycopy(packet, 3, buf, 0, plen-3);
410 cleanup(buf);
411 speak(buf, (packet[1] != 0), (packet[2] != 0));
401 default: 412 default:
402 break; 413 break;
403 } 414 }
404 } catch (IOException e) { 415 } catch (IOException e) {
405 if (!is_closing) Log.e(TAG, "exception in CommunicationThread.run()", e); 416 if (!is_closing) Log.e(TAG, "exception in CommunicationThread.run()", e);
409 break; 420 break;
410 } 421 }
411 } 422 }
412 Log.i(TAG, String.format("shutting down connection %d", connection)); 423 Log.i(TAG, String.format("shutting down connection %d", connection));
413 try { 424 try {
425 teClose(connection);
414 if (client_in != null) client_in.close(); 426 if (client_in != null) client_in.close();
415 if (client_out != null) client_out.close(); 427 if (client_out != null) client_out.close();
416 if (client_socket != null) client_socket.close(); 428 if (client_socket != null) client_socket.close();
417 } catch (IOException e) { 429 } catch (IOException e) {
418 Log.e(TAG, "exception in CommunicationThread.run() closing sockets", e); 430 Log.e(TAG, "exception in CommunicationThread.run() closing sockets", e);
455 Log.i(TAG, String.format("teActivate %d", connection)); 467 Log.i(TAG, String.format("teActivate %d", connection));
456 printer(String.format("activate %d lines %d columns %d b.len %d", connection, lines, columns, buf.length)); 468 printer(String.format("activate %d lines %d columns %d b.len %d", connection, lines, columns, buf.length));
457 boolean sameinit = false; 469 boolean sameinit = false;
458 CommunicationThread cm = clients.get(currentConnection); 470 CommunicationThread cm = clients.get(currentConnection);
459 if (cm != null) { 471 if (cm != null) {
460 sameinit = (cm.initString == fn); 472 sameinit = (cm.initString.equals(fn));
461 } 473 }
462 setCurrentConnection(connection); 474 setCurrentConnection(connection);
463 } 475 }
464 476
465 public void teKeyState(int connection, boolean down) { 477 public void teKeyState(int connection, boolean down) {
533 if (cm != null) { 545 if (cm != null) {
534 char[] arg = new char[5]; 546 char[] arg = new char[5];
535 arg[2] = (char) (l & 0x0000ffff); 547 arg[2] = (char) (l & 0x0000ffff);
536 arg[3] = (char) (c & 0x0000ffff); 548 arg[3] = (char) (c & 0x0000ffff);
537 arg[4] = (char) (len & 0x0000ffff); 549 arg[4] = (char) (len & 0x0000ffff);
538 cm.clientWrite(MONITOR_CMD_GETFIELD, arg); 550 cm.clientWrite(MONITOR_CMD_SCREENWATCH, arg);
539 } 551 }
540 } 552 }
541 553
542 public static void teSpeak(int connection, byte [] msg, boolean flush, boolean synchronous) { 554 public static void teSpeak(int connection, byte [] msg, boolean flush, boolean synchronous) {
543 CommunicationThread cm = clients.get(connection); 555 CommunicationThread cm = clients.get(connection);