From e8da301da3e9c72dbfbf4b734ac121181409f5ec Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Sun, 20 Nov 2016 22:04:49 +0100 Subject: [PATCH] Pebble 2: fix a few crashes with disconnect/ reconnect --- .../devices/pebble/PebbleIoThread.java | 22 +++++++++++++------ .../devices/pebble/ble/PebbleLESupport.java | 14 ++++++------ 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java index 27fa3587..01b43168 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java @@ -157,6 +157,14 @@ class PebbleIoThread extends GBDeviceIoThread { mEnablePebblekit = prefs.getBoolean("pebble_enable_pebblekit", false); } + private int readWithException(InputStream inputStream, byte[] buffer, int byteOffset, int byteCount) throws IOException { + int ret = inputStream.read(buffer, byteOffset, byteCount); + if (ret == -1) { + throw new IOException("broken pipe"); + } + return ret; + } + private void sendAppMessageAck(int transactionId) { Intent intent = new Intent(); intent.setAction(PEBBLEKIT_ACTION_APP_RECEIVE_ACK); @@ -323,10 +331,10 @@ class PebbleIoThread extends GBDeviceIoThread { if (mIsTCP) { mInStream.skip(6); } - int bytes = mInStream.read(buffer, 0, 4); + int bytes = readWithException(mInStream, buffer, 0, 4); while (bytes < 4) { - bytes += mInStream.read(buffer, bytes, 4 - bytes); + bytes += readWithException(mInStream, buffer, bytes, 4 - bytes); } ByteBuffer buf = ByteBuffer.wrap(buffer); @@ -336,14 +344,14 @@ class PebbleIoThread extends GBDeviceIoThread { if (length < 0 || length > 8192) { LOG.info("invalid length " + length); while (mInStream.available() > 0) { - mInStream.read(buffer); // read all + readWithException(mInStream, buffer, 0, buffer.length); // read all } continue; } - bytes = mInStream.read(buffer, 4, length); + bytes = readWithException(mInStream, buffer, 4, length); while (bytes < length) { - bytes += mInStream.read(buffer, bytes + 4, length - bytes); + bytes += readWithException(mInStream, buffer, bytes + 4, length - bytes); } if (mIsTCP) { @@ -368,8 +376,8 @@ class PebbleIoThread extends GBDeviceIoThread { } catch (InterruptedException e) { e.printStackTrace(); } - } catch (IOException | ArrayIndexOutOfBoundsException e) { - if (e.getMessage() != null && (e instanceof ArrayIndexOutOfBoundsException || e.getMessage().contains("socket closed"))) { //FIXME: this does not feel right + } catch (IOException e) { + if (e.getMessage() != null && (e.getMessage().equals("broken pipe") || e.getMessage().contains("socket closed"))) { //FIXME: this does not feel right LOG.info(e.getMessage()); mIsConnected = false; int reconnectAttempts = prefs.getInt("pebble_reconnect_attempts", 10); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleLESupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleLESupport.java index ff1dafcb..449b76d9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleLESupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/ble/PebbleLESupport.java @@ -60,14 +60,9 @@ public class PebbleLESupport { mPebbleGATTClient.close(); mPebbleGATTClient = null; } - try { - mPipedInputStream.close(); - mPipedOutputStream.close(); - } catch (IOException ignore) { - } } - void createPipedInputReader() { + synchronized void createPipedInputReader() { if (mPipeReader == null) { mPipeReader = new PipeReader(); } @@ -76,7 +71,7 @@ public class PebbleLESupport { } } - private void destroyPipedInputReader() { + synchronized private void destroyPipedInputReader() { if (mPipeReader != null) { mPipeReader.quit(); mPipeReader.interrupt(); @@ -137,6 +132,11 @@ public class PebbleLESupport { break; } } + try { + mPipedOutputStream.close(); + mPipedInputStream.close(); + } catch (IOException ignore) { + } } void quit() {