From f258e626336fac1a691a9885e18fbd987410a1ed Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Sun, 13 Dec 2015 00:43:07 +0100 Subject: [PATCH] Refactoring: centralize GBDevice creation - created and provided by DeviceHelper - passed from UI to service - without UI, service uses DeviceHelper directly => Cleaner and less duplicated code --- .../activities/ControlCenter.java | 75 ++++--------------- .../activities/FwAppInstallerActivity.java | 2 +- .../devices/miband/MiBandPairingActivity.java | 3 +- .../gadgetbridge/impl/GBDeviceService.java | 7 ++ .../gadgetbridge/model/DeviceService.java | 3 + .../service/DeviceCommunicationService.java | 25 ++++--- .../service/DeviceSupportFactory.java | 43 +++++------ .../gadgetbridge/util/DeviceHelper.java | 59 +++++++++++++++ .../DeviceCommunicationServiceTestCase.java | 4 +- .../service/TestDeviceSupport.java | 1 - 10 files changed, 123 insertions(+), 99 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenter.java index 1bca50bbe..87ccd58ee 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenter.java @@ -136,7 +136,7 @@ public class ControlCenter extends Activity { startActivity(startIntent); } } else { - GBApplication.deviceService().connect(deviceList.get(position).getAddress()); + GBApplication.deviceService().connect(deviceList.get(position)); } } }); @@ -334,74 +334,27 @@ public class ControlCenter extends Activity { } private void refreshPairedDevices() { + Set availableDevices = DeviceHelper.getInstance().getAvailableDevices(this); + deviceList.retainAll(availableDevices); + for (GBDevice availableDevice : availableDevices) { + if (!deviceList.contains(availableDevice)) { + deviceList.add(availableDevice); + } + } boolean connected = false; - List availableDevices = new ArrayList<>(); for (GBDevice device : deviceList) { if (device.isConnected() || device.isConnecting()) { connected = true; - availableDevices.add(device); + break; } } - BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); - - if (btAdapter == null) { - Toast.makeText(this, R.string.bluetooth_is_not_supported_, Toast.LENGTH_SHORT).show(); - } else if (!btAdapter.isEnabled()) { - Toast.makeText(this, R.string.bluetooth_is_disabled_, Toast.LENGTH_SHORT).show(); - } else { - Set pairedDevices = btAdapter.getBondedDevices(); - DeviceHelper deviceHelper = DeviceHelper.getInstance(); - for (BluetoothDevice pairedDevice : pairedDevices) { - if (isDeviceContainedIn(pairedDevice, availableDevices)) { - continue; - } - GBDevice device = deviceHelper.toSupportedDevice(pairedDevice); - if (device != null) { - availableDevices.add(device); - } - } - - SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); - String miAddr = sharedPrefs.getString(MiBandConst.PREF_MIBAND_ADDRESS, ""); - if (miAddr.length() > 0) { - GBDevice miDevice = new GBDevice(miAddr, "MI", DeviceType.MIBAND); - if (!availableDevices.contains(miDevice)) { - availableDevices.add(miDevice); - } - } - - String pebbleEmuAddr = sharedPrefs.getString("pebble_emu_addr", ""); - String pebbleEmuPort = sharedPrefs.getString("pebble_emu_port", ""); - if (pebbleEmuAddr.length() >= 7 && pebbleEmuPort.length() > 0) { - GBDevice pebbleEmuDevice = new GBDevice(pebbleEmuAddr + ":" + pebbleEmuPort, "Pebble qemu", DeviceType.PEBBLE); - if (!availableDevices.contains(pebbleEmuDevice)) { - availableDevices.add(pebbleEmuDevice); - } - } - - deviceList.retainAll(availableDevices); - for (GBDevice dev : availableDevices) { - if (!deviceList.contains(dev)) { - deviceList.add(dev); - } - } - - if (connected) { - hintTextView.setText(R.string.tap_connected_device_for_app_mananger); - } else if (!deviceList.isEmpty()) { - hintTextView.setText(R.string.tap_a_device_to_connect); - } + if (connected) { + hintTextView.setText(R.string.tap_connected_device_for_app_mananger); + } else if (!deviceList.isEmpty()) { + hintTextView.setText(R.string.tap_a_device_to_connect); } + mGBDeviceAdapter.notifyDataSetChanged(); } - - private boolean isDeviceContainedIn(BluetoothDevice device, List availableDevices) { - for (GBDevice avail : availableDevices) { - if (avail.getAddress().equals(device.getAddress())) { - return true; - } - } - return false; - } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java index e3baad523..0c7b88cdf 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java @@ -89,7 +89,7 @@ public class FwAppInstallerActivity extends Activity implements InstallActivity private void connect() { mayConnect = false; // only do that once per #onCreate - GBApplication.deviceService().connect(device != null ? device.getAddress() : null); + GBApplication.deviceService().connect(device); } private void validateInstallation() { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java index 00fe76ca8..e5109e51b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/miband/MiBandPairingActivity.java @@ -22,6 +22,7 @@ import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter; import nodomain.freeyourgadget.gadgetbridge.activities.DiscoveryActivity; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; +import nodomain.freeyourgadget.gadgetbridge.util.GB; public class MiBandPairingActivity extends Activity { private static final Logger LOG = LoggerFactory.getLogger(MiBandPairingActivity.class); @@ -90,7 +91,7 @@ public class MiBandPairingActivity extends Activity { // start pairing immediately when we return from the user settings if (requestCode == REQ_CODE_USER_SETTINGS) { if (!MiBandCoordinator.hasValidUserInfo()) { - Toast.makeText(this, getString(R.string.miband_pairing_using_dummy_userdata), Toast.LENGTH_SHORT).show(); + GB.toast(this, getString(R.string.miband_pairing_using_dummy_userdata), Toast.LENGTH_LONG, GB.WARN); } startPairing(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java index 2782d6093..b1f745675 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java @@ -48,6 +48,13 @@ public class GBDeviceService implements DeviceService { connect(null, false); } + @Override + public void connect(GBDevice device) { + Intent intent = createIntent().setAction(ACTION_CONNECT) + .putExtra(GBDevice.EXTRA_DEVICE, device); + invokeService(intent); + } + @Override public void connect(@Nullable String deviceAddress) { connect(deviceAddress, false); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java index 59a09f20e..342c66d22 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java @@ -3,6 +3,7 @@ package nodomain.freeyourgadget.gadgetbridge.model; import android.support.annotation.Nullable; import nodomain.freeyourgadget.gadgetbridge.devices.EventHandler; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; /** @@ -60,6 +61,8 @@ public interface DeviceService extends EventHandler { void connect(); + void connect(GBDevice device); + void connect(@Nullable String deviceAddress); void connect(@Nullable String deviceAddress, boolean performPair); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java index 123824a54..41f7df33f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -35,6 +35,7 @@ import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.NotificationSpec; import nodomain.freeyourgadget.gadgetbridge.model.NotificationType; import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand; +import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; import nodomain.freeyourgadget.gadgetbridge.util.GB; import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CALLSTATE; @@ -162,20 +163,26 @@ public class DeviceCommunicationService extends Service { break; case ACTION_CONNECT: start(); // ensure started - String btDeviceAddress = intent.getStringExtra(EXTRA_DEVICE_ADDRESS); - SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); - if (sharedPrefs != null) { // may be null in test cases - if (btDeviceAddress == null) { - btDeviceAddress = sharedPrefs.getString("last_device_address", null); - } else { - sharedPrefs.edit().putString("last_device_address", btDeviceAddress).apply(); + GBDevice gbDevice = intent.getParcelableExtra(GBDevice.EXTRA_DEVICE); + if (gbDevice == null) { + String btDeviceAddress = intent.getStringExtra(EXTRA_DEVICE_ADDRESS); + SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this); + if (sharedPrefs != null) { // may be null in test cases + if (btDeviceAddress == null) { + btDeviceAddress = sharedPrefs.getString("last_device_address", null); + } else { + sharedPrefs.edit().putString("last_device_address", btDeviceAddress).apply(); + } + } + if (btDeviceAddress != null) { + gbDevice = DeviceHelper.getInstance().findAvailableDevice(btDeviceAddress, this); } } - if (btDeviceAddress != null && !isConnecting() && !isConnected()) { + if (gbDevice != null && !isConnecting() && !isConnected()) { setDeviceSupport(null); try { - DeviceSupport deviceSupport = mFactory.createDeviceSupport(btDeviceAddress); + DeviceSupport deviceSupport = mFactory.createDeviceSupport(gbDevice); if (deviceSupport != null) { setDeviceSupport(deviceSupport); if (pair) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java index bf170d33d..55765588d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceSupportFactory.java @@ -26,19 +26,20 @@ public class DeviceSupportFactory { mBtAdapter = BluetoothAdapter.getDefaultAdapter(); } - public synchronized DeviceSupport createDeviceSupport(String deviceAddress) throws GBException { - DeviceSupport deviceSupport; + public synchronized DeviceSupport createDeviceSupport(GBDevice device) throws GBException { + DeviceSupport deviceSupport = null; + String deviceAddress = device.getAddress(); int indexFirstColon = deviceAddress.indexOf(":"); if (indexFirstColon > 0) { if (indexFirstColon == deviceAddress.lastIndexOf(":")) { // only one colon - deviceSupport = createTCPDeviceSupport(deviceAddress); + deviceSupport = createTCPDeviceSupport(device); } else { // multiple colons -- bt? - deviceSupport = createBTDeviceSupport(deviceAddress); + deviceSupport = createBTDeviceSupport(device); } } else { // no colon at all, maybe a class name? - deviceSupport = createClassNameDeviceSupport(deviceAddress); + deviceSupport = createClassNameDeviceSupport(device); } if (deviceSupport != null) { @@ -50,13 +51,14 @@ public class DeviceSupportFactory { return null; } - private DeviceSupport createClassNameDeviceSupport(String className) throws GBException { + private DeviceSupport createClassNameDeviceSupport(GBDevice device) throws GBException { + String className = device.getAddress(); try { Class deviceSupportClass = Class.forName(className); Constructor constructor = deviceSupportClass.getConstructor(); DeviceSupport support = (DeviceSupport) constructor.newInstance(); // has to create the device itself - support.setContext(null, null, mContext); + support.setContext(device, null, mContext); return support; } catch (ClassNotFoundException e) { return null; // not a class, or not known at least @@ -73,25 +75,19 @@ public class DeviceSupportFactory { } } - private DeviceSupport createBTDeviceSupport(String deviceAddress) throws GBException { + private DeviceSupport createBTDeviceSupport(GBDevice gbDevice) throws GBException { if (mBtAdapter != null && mBtAdapter.isEnabled()) { - GBDevice gbDevice; DeviceSupport deviceSupport = null; try { - BluetoothDevice btDevice = mBtAdapter.getRemoteDevice(deviceAddress); - gbDevice = DeviceHelper.getInstance().toSupportedDevice(btDevice); - if (gbDevice != null) { - switch (gbDevice.getType()) { - case PEBBLE: - deviceSupport = new ServiceDeviceSupport(new PebbleSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); - break; - case MIBAND: - deviceSupport = new ServiceDeviceSupport(new MiBandSupport(), EnumSet.of(ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING)); - break; - } + switch (gbDevice.getType()) { + case PEBBLE: + deviceSupport = new ServiceDeviceSupport(new PebbleSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); + break; + case MIBAND: + deviceSupport = new ServiceDeviceSupport(new MiBandSupport(), EnumSet.of(ServiceDeviceSupport.Flags.THROTTLING, ServiceDeviceSupport.Flags.BUSY_CHECKING)); + break; } - if (deviceSupport != null) { deviceSupport.setContext(gbDevice, mBtAdapter, mContext); return deviceSupport; @@ -103,14 +99,13 @@ public class DeviceSupportFactory { return null; } - private DeviceSupport createTCPDeviceSupport(String deviceAddress) throws GBException { + private DeviceSupport createTCPDeviceSupport(GBDevice gbDevice) throws GBException { try { - GBDevice gbDevice = new GBDevice(deviceAddress, "Pebble qemu", DeviceType.PEBBLE); //FIXME, do not hardcode DeviceSupport deviceSupport = new ServiceDeviceSupport(new PebbleSupport(), EnumSet.of(ServiceDeviceSupport.Flags.BUSY_CHECKING)); deviceSupport.setContext(gbDevice, mBtAdapter, mContext); return deviceSupport; } catch (Exception e) { - throw new GBException("cannot connect to " + deviceAddress, e); // FIXME: localize + throw new GBException("cannot connect to " + gbDevice, e); // FIXME: localize } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java index 9f997d9e9..ae7ee58ed 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/DeviceHelper.java @@ -1,16 +1,27 @@ package nodomain.freeyourgadget.gadgetbridge.util; +import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.widget.Toast; import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; +import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.UnknownDeviceCoordinator; +import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandConst; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.pebble.PebbleCoordinator; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceCandidate; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; public class DeviceHelper { private static final DeviceHelper instance = new DeviceHelper(); @@ -36,6 +47,54 @@ public class DeviceHelper { return false; } + public GBDevice findAvailableDevice(String deviceAddress, Context context) { + Set availableDevices = getAvailableDevices(context); + for (GBDevice availableDevice : availableDevices) { + if (deviceAddress.equals(availableDevice.getAddress())) { + return availableDevice; + } + } + return null; + } + + public Set getAvailableDevices(Context context) { + BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter(); + + Set availableDevices = new LinkedHashSet(); + + if (btAdapter == null) { + GB.toast(context, context.getString(R.string.bluetooth_is_not_supported_), Toast.LENGTH_SHORT, GB.WARN); + } else if (!btAdapter.isEnabled()) { + GB.toast(context, context.getString(R.string.bluetooth_is_disabled_), Toast.LENGTH_SHORT, GB.WARN); + } else { + Set pairedDevices = btAdapter.getBondedDevices(); + DeviceHelper deviceHelper = DeviceHelper.getInstance(); + for (BluetoothDevice pairedDevice : pairedDevices) { + GBDevice device = deviceHelper.toSupportedDevice(pairedDevice); + if (device != null) { + availableDevices.add(device); + } + } + + SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context); + String miAddr = sharedPrefs.getString(MiBandConst.PREF_MIBAND_ADDRESS, ""); + if (miAddr.length() > 0) { + GBDevice miDevice = new GBDevice(miAddr, "MI", DeviceType.MIBAND); + if (!availableDevices.contains(miDevice)) { + availableDevices.add(miDevice); + } + } + + String pebbleEmuAddr = sharedPrefs.getString("pebble_emu_addr", ""); + String pebbleEmuPort = sharedPrefs.getString("pebble_emu_port", ""); + if (pebbleEmuAddr.length() >= 7 && pebbleEmuPort.length() > 0) { + GBDevice pebbleEmuDevice = new GBDevice(pebbleEmuAddr + ":" + pebbleEmuPort, "Pebble qemu", DeviceType.PEBBLE); + availableDevices.add(pebbleEmuDevice); + } + } + return availableDevices; + } + public GBDevice toSupportedDevice(BluetoothDevice device) { GBDeviceCandidate candidate = new GBDeviceCandidate(device, GBDevice.RSSI_UNKNOWN); if (coordinator != null && coordinator.supports(candidate)) { diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationServiceTestCase.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationServiceTestCase.java index 394ff8ba7..e4d1fe5b5 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationServiceTestCase.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationServiceTestCase.java @@ -27,7 +27,7 @@ public class DeviceCommunicationServiceTestCase extends AbstractServiceTestCase< } @Override - public synchronized DeviceSupport createDeviceSupport(String deviceAddress) throws GBException { + public synchronized DeviceSupport createDeviceSupport(GBDevice device) throws GBException { return mockSupport; } } @@ -62,7 +62,7 @@ public class DeviceCommunicationServiceTestCase extends AbstractServiceTestCase< @Test public void ensureConnected() { - mDeviceService.connect(TEST_DEVICE_ADDRESS); + mDeviceService.connect(realSupport.getDevice()); Mockito.verify(mockSupport, Mockito.times(1)).connect(); assertTrue(realSupport.getDevice().isInitialized()); } diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/TestDeviceSupport.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/TestDeviceSupport.java index 208af61b8..f84b6013a 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/TestDeviceSupport.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/service/TestDeviceSupport.java @@ -21,7 +21,6 @@ public class TestDeviceSupport extends AbstractDeviceSupport { @Override public void setContext(GBDevice gbDevice, BluetoothAdapter btAdapter, Context context) { - gbDevice = new GBDevice(getClass().getName(), "Test Device", DeviceType.TEST); super.setContext(gbDevice, btAdapter, context); }