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
here
cpfeiffer 2015-12-13 00:43:07 +01:00
parent 7cf1e0e004
commit f258e62633
10 changed files with 123 additions and 99 deletions

View File

@ -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<GBDevice> availableDevices = DeviceHelper.getInstance().getAvailableDevices(this);
deviceList.retainAll(availableDevices);
for (GBDevice availableDevice : availableDevices) {
if (!deviceList.contains(availableDevice)) {
deviceList.add(availableDevice);
}
}
boolean connected = false;
List<GBDevice> 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<BluetoothDevice> 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<GBDevice> availableDevices) {
for (GBDevice avail : availableDevices) {
if (avail.getAddress().equals(device.getAddress())) {
return true;
}
}
return false;
}
}

View File

@ -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() {

View File

@ -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();
}

View File

@ -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);

View File

@ -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);

View File

@ -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) {

View File

@ -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
}
}

View File

@ -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<GBDevice> availableDevices = getAvailableDevices(context);
for (GBDevice availableDevice : availableDevices) {
if (deviceAddress.equals(availableDevice.getAddress())) {
return availableDevice;
}
}
return null;
}
public Set<GBDevice> getAvailableDevices(Context context) {
BluetoothAdapter btAdapter = BluetoothAdapter.getDefaultAdapter();
Set<GBDevice> availableDevices = new LinkedHashSet<GBDevice>();
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<BluetoothDevice> 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)) {

View File

@ -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());
}

View File

@ -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);
}