diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java index 626b305b8..c36547780 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java @@ -338,26 +338,34 @@ public class GBApplication extends Application { private static HashSet blacklist = null; public static boolean isBlacklisted(String packageName) { + if (blacklist == null) { + GB.log("isBlacklisted: blacklisti is null!", GB.INFO, null); + } return blacklist != null && blacklist.contains(packageName); } public static void setBlackList(Set packageNames) { if (packageNames == null) { + GB.log("Set null blacklist", GB.INFO, null); blacklist = new HashSet<>(); } else { blacklist = new HashSet<>(packageNames); } + GB.log("New blacklist has " + blacklist.size() + " entries", GB.INFO, null); saveBlackList(); } private static void loadBlackList() { + GB.log("Loading blacklist", GB.INFO, null); blacklist = (HashSet) sharedPrefs.getStringSet(GBPrefs.PACKAGE_BLACKLIST, null); if (blacklist == null) { blacklist = new HashSet<>(); } + GB.log("Loaded blacklist has " + blacklist.size() + " entries", GB.INFO, null); } private static void saveBlackList() { + GB.log("Saving blacklist with " + blacklist.size() + " entries", GB.INFO, null); SharedPreferences.Editor editor = sharedPrefs.edit(); if (blacklist.isEmpty()) { editor.putStringSet(GBPrefs.PACKAGE_BLACKLIST, null); @@ -374,6 +382,7 @@ public class GBApplication extends Application { } public static synchronized void removeFromBlacklist(String packageName) { + GB.log("Removing from blacklist: " + packageName, GB.INFO, null); blacklist.remove(packageName); saveBlackList(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java index 465895acd..78d7c9ec4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/DeviceCoordinator.java @@ -201,8 +201,6 @@ public interface DeviceCoordinator { */ boolean supportsHeartRateMeasurement(GBDevice device); - int getTapString(); - /** * Returns the readable name of the manufacturer. */ diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java index e89198fa4..51d516177 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/UnknownDeviceCoordinator.java @@ -157,11 +157,6 @@ public class UnknownDeviceCoordinator extends AbstractDeviceCoordinator { return false; } - @Override - public int getTapString() { - return 0; - } - @Override public String getManufacturer() { return "unknown"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java index b3e6a4a4f..529fb09a3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/hplus/HPlusCoordinator.java @@ -147,11 +147,6 @@ public class HPlusCoordinator extends AbstractDeviceCoordinator { return true; } - @Override - public int getTapString() { - return R.string.tap_connected_device_for_activity; - } - @Override public String getManufacturer() { return "Zeblaze"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewCoordinator.java index 5b5c19a7d..465d65823 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/liveview/LiveviewCoordinator.java @@ -99,12 +99,6 @@ public class LiveviewCoordinator extends AbstractDeviceCoordinator { return false; } - @Override - public int getTapString() { - //TODO: changeme - return R.string.tap_connected_device_for_activity; - } - @Override public String getManufacturer() { return "Sony Ericsson"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java index 6afc943b6..d4d9a1b02 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandCoordinator.java @@ -151,11 +151,6 @@ public class MiBandCoordinator extends AbstractDeviceCoordinator { return true; } - @Override - public int getTapString() { - return R.string.tap_connected_device_for_activity; - } - @Override public String getManufacturer() { return "Xiaomi"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java index 2e4da852b..9d410c63a 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PebbleCoordinator.java @@ -137,11 +137,6 @@ public class PebbleCoordinator extends AbstractDeviceCoordinator { return PebbleUtils.hasHRM(device.getModel()); } - @Override - public int getTapString() { - return R.string.tap_connected_device_for_app_mananger; - } - @Override public String getManufacturer() { return "Pebble"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vibratissimo/VibratissimoCoordinator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vibratissimo/VibratissimoCoordinator.java index ecc10de17..2b20f1a0b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vibratissimo/VibratissimoCoordinator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/vibratissimo/VibratissimoCoordinator.java @@ -100,11 +100,6 @@ public class VibratissimoCoordinator extends AbstractDeviceCoordinator { return false; } - @Override - public int getTapString() { - return R.string.tap_connected_device_for_vibration; - } - @Override public String getManufacturer() { return "Amor AG"; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btclassic/BtClassicIoThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btclassic/BtClassicIoThread.java new file mode 100644 index 000000000..750bde0fd --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btclassic/BtClassicIoThread.java @@ -0,0 +1,202 @@ +/* Copyright (C) 2016-2017 Daniele Gobbetti + + This file is part of Gadgetbridge. + + Gadgetbridge is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published + by the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Gadgetbridge is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . */ +package nodomain.freeyourgadget.gadgetbridge.service.btclassic; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothSocket; +import android.content.Context; +import android.os.ParcelUuid; +import android.support.annotation.NonNull; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.SocketTimeoutException; +import java.nio.ByteBuffer; +import java.util.UUID; + +import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; +import nodomain.freeyourgadget.gadgetbridge.devices.liveview.LiveviewConstants; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport; +import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread; +import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol; +import nodomain.freeyourgadget.gadgetbridge.util.GB; + +public abstract class BtClassicIoThread extends GBDeviceIoThread { + private static final Logger LOG = LoggerFactory.getLogger(BtClassicIoThread.class); + + private final GBDeviceProtocol mProtocol; + private final AbstractSerialDeviceSupport mDeviceSupport; + + + private BluetoothAdapter mBtAdapter = null; + private BluetoothSocket mBtSocket = null; + private InputStream mInStream = null; + private OutputStream mOutStream = null; + private boolean mQuit = false; + + @Override + public void quit() { + mQuit = true; + if (mBtSocket != null) { + try { + mBtSocket.close(); + } catch (IOException e) { + LOG.error(e.getMessage()); + } + } + } + + private boolean mIsConnected = false; + + + public BtClassicIoThread(GBDevice gbDevice, Context context, GBDeviceProtocol deviceProtocol, AbstractSerialDeviceSupport deviceSupport, BluetoothAdapter btAdapter) { + super(gbDevice, context); + mProtocol = deviceProtocol; + mDeviceSupport = deviceSupport; + mBtAdapter = btAdapter; + } + + @Override + public synchronized void write(byte[] bytes) { + if (null == bytes) + return; + LOG.debug("writing:" + GB.hexdump(bytes, 0, bytes.length)); + try { + mOutStream.write(bytes); + mOutStream.flush(); + } catch (IOException e) { + LOG.error("Error writing.", e); + } + } + + @Override + public void run() { + mIsConnected = connect(); + if (!mIsConnected) { + setUpdateState(GBDevice.State.NOT_CONNECTED); + return; + } + mQuit = false; + + while (!mQuit) { + LOG.info("Ready for a new message exchange."); + + try { + GBDeviceEvent deviceEvents[] = mProtocol.decodeResponse(parseIncoming(mInStream)); + if (deviceEvents == null) { + LOG.info("unhandled message"); + } else { + for (GBDeviceEvent deviceEvent : deviceEvents) { + if (deviceEvent == null) { + continue; + } + mDeviceSupport.evaluateGBDeviceEvent(deviceEvent); + } + } + } catch (SocketTimeoutException ignore) { + LOG.debug("socket timeout, we can't help but ignore this"); + } catch (IOException e) { + LOG.info(e.getMessage()); + mIsConnected = false; + mBtSocket = null; + mInStream = null; + mOutStream = null; + LOG.info("Bluetooth socket closed, will quit IO Thread"); + break; + } + } + + mIsConnected = false; + if (mBtSocket != null) { + try { + mBtSocket.close(); + } catch (IOException e) { + LOG.error(e.getMessage()); + } + mBtSocket = null; + } + setUpdateState(GBDevice.State.NOT_CONNECTED); + } + + @Override + protected boolean connect() { + GBDevice.State originalState = gbDevice.getState(); + setUpdateState(GBDevice.State.CONNECTING); + + try { + BluetoothDevice btDevice = mBtAdapter.getRemoteDevice(gbDevice.getAddress()); + ParcelUuid uuids[] = btDevice.getUuids(); + if (uuids == null) { + LOG.warn("Device provided no UUIDs to connect to, giving up: " + gbDevice); + return false; + } + for (ParcelUuid uuid : uuids) { + LOG.info("found service UUID " + uuid); + } + mBtSocket = btDevice.createRfcommSocketToServiceRecord(getUuidToConnect(uuids)); + mBtSocket.connect(); + mInStream = mBtSocket.getInputStream(); + mOutStream = mBtSocket.getOutputStream(); + setUpdateState(GBDevice.State.CONNECTED); + } catch (IOException e) { + LOG.error("Server socket cannot be started."); + //LOG.error(e.getMessage()); + setUpdateState(originalState); + mInStream = null; + mOutStream = null; + mBtSocket = null; + return false; + } + + write(mProtocol.encodeSetTime()); + setUpdateState(GBDevice.State.INITIALIZED); + + return true; + } + + /** + * Returns the uuid to connect to. + * Default implementation returns the first of the given uuids that were + * read from the remote device. + * @param uuids + * @return + */ + @NonNull + protected UUID getUuidToConnect(@NonNull ParcelUuid[] uuids) { + return uuids[0].getUuid(); + } + + protected void setUpdateState(GBDevice.State state) { + gbDevice.setState(state); + gbDevice.sendDeviceUpdateIntent(getContext()); + } + + /** + * Returns an incoming message for consuming by the GBDeviceProtocol + * @return + * @throws IOException + * @param inStream + */ + protected abstract byte[] parseIncoming(InputStream inStream) throws IOException; +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewIoThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewIoThread.java index 157fe87a4..a823c5d6e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewIoThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/liveview/LiveviewIoThread.java @@ -17,10 +17,7 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.liveview; import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothDevice; -import android.bluetooth.BluetoothSocket; import android.content.Context; -import android.os.ParcelUuid; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,158 +25,25 @@ import org.slf4j.LoggerFactory; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; -import java.net.SocketTimeoutException; import java.nio.ByteBuffer; import java.util.UUID; -import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent; import nodomain.freeyourgadget.gadgetbridge.devices.liveview.LiveviewConstants; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; -import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceIoThread; +import nodomain.freeyourgadget.gadgetbridge.service.btclassic.BtClassicIoThread; import nodomain.freeyourgadget.gadgetbridge.service.serial.GBDeviceProtocol; import nodomain.freeyourgadget.gadgetbridge.util.GB; -public class LiveviewIoThread extends GBDeviceIoThread { +public class LiveviewIoThread extends BtClassicIoThread { private static final Logger LOG = LoggerFactory.getLogger(LiveviewIoThread.class); private static final UUID SERIAL = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); - private final LiveviewProtocol mLiveviewProtocol; - private final LiveviewSupport mLiveviewSupport; - - - private BluetoothAdapter mBtAdapter = null; - private BluetoothSocket mBtSocket = null; - private InputStream mInStream = null; - private OutputStream mOutStream = null; - private boolean mQuit = false; - - @Override - public void quit() { - mQuit = true; - if (mBtSocket != null) { - try { - mBtSocket.close(); - } catch (IOException e) { - LOG.error(e.getMessage()); - } - } - } - - private boolean mIsConnected = false; - - public LiveviewIoThread(GBDevice gbDevice, Context context, GBDeviceProtocol lvProtocol, LiveviewSupport lvSupport, BluetoothAdapter lvBtAdapter) { - super(gbDevice, context); - mLiveviewProtocol = (LiveviewProtocol) lvProtocol; - mBtAdapter = lvBtAdapter; - mLiveviewSupport = lvSupport; + super(gbDevice, context, lvProtocol, lvSupport, lvBtAdapter); } - @Override - public synchronized void write(byte[] bytes) { - if (null == bytes) - return; - LOG.debug("writing:" + GB.hexdump(bytes, 0, bytes.length)); - try { - mOutStream.write(bytes); - mOutStream.flush(); - } catch (IOException e) { - LOG.error("Error writing.", e); - } - } - - @Override - public void run() { - mIsConnected = connect(); - if (!mIsConnected) { - setUpdateState(GBDevice.State.NOT_CONNECTED); - return; - } - mQuit = false; - - while (!mQuit) { - LOG.info("Ready for a new message exchange."); - - try { - GBDeviceEvent deviceEvents[] = mLiveviewProtocol.decodeResponse(parseIncoming()); - if (deviceEvents == null) { - LOG.info("unhandled message"); - } else { - for (GBDeviceEvent deviceEvent : deviceEvents) { - if (deviceEvent == null) { - continue; - } - mLiveviewSupport.evaluateGBDeviceEvent(deviceEvent); - } - } - } catch (SocketTimeoutException ignore) { - LOG.debug("socket timeout, we can't help but ignore this"); - } catch (IOException e) { - LOG.info(e.getMessage()); - mIsConnected = false; - mBtSocket = null; - mInStream = null; - mOutStream = null; - LOG.info("Bluetooth socket closed, will quit IO Thread"); - break; - } - } - - mIsConnected = false; - if (mBtSocket != null) { - try { - mBtSocket.close(); - } catch (IOException e) { - LOG.error(e.getMessage()); - } - mBtSocket = null; - } - setUpdateState(GBDevice.State.NOT_CONNECTED); - } - - @Override - protected boolean connect() { - GBDevice.State originalState = gbDevice.getState(); - setUpdateState(GBDevice.State.CONNECTING); - - try { - BluetoothDevice btDevice = mBtAdapter.getRemoteDevice(gbDevice.getAddress()); - ParcelUuid uuids[] = btDevice.getUuids(); - if (uuids == null) { - return false; - } - for (ParcelUuid uuid : uuids) { - LOG.info("found service UUID " + uuid); - } - mBtSocket = btDevice.createRfcommSocketToServiceRecord(uuids[0].getUuid()); - mBtSocket.connect(); - mInStream = mBtSocket.getInputStream(); - mOutStream = mBtSocket.getOutputStream(); - setUpdateState(GBDevice.State.CONNECTED); - } catch (IOException e) { - LOG.error("Server socket cannot be started."); - //LOG.error(e.getMessage()); - setUpdateState(originalState); - mInStream = null; - mOutStream = null; - mBtSocket = null; - return false; - } - - write(mLiveviewProtocol.encodeSetTime()); - setUpdateState(GBDevice.State.INITIALIZED); - - return true; - } - - private void setUpdateState(GBDevice.State state) { - gbDevice.setState(state); - gbDevice.sendDeviceUpdateIntent(getContext()); - } - - private byte[] parseIncoming() throws IOException { + protected byte[] parseIncoming(InputStream inputStream) throws IOException { ByteArrayOutputStream msgStream = new ByteArrayOutputStream(); boolean finished = false; @@ -187,7 +51,7 @@ public class LiveviewIoThread extends GBDeviceIoThread { byte[] incoming = new byte[1]; while (!finished) { - mInStream.read(incoming); + inputStream.read(incoming); msgStream.write(incoming); switch (state) {