mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-12-25 01:55:50 +01:00
Next refactoring: the road to support BT and BT LE
This commit is contained in:
parent
fad59e218d
commit
1f31c1d79c
@ -0,0 +1,87 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceProtocol;
|
||||||
|
|
||||||
|
public abstract class AbstractBTDeviceSupport extends AbstractDeviceSupport {
|
||||||
|
|
||||||
|
private GBDeviceProtocol gbDeviceProtocol;
|
||||||
|
private GBDeviceIoThread gbDeviceIOThread;
|
||||||
|
|
||||||
|
protected abstract GBDeviceProtocol createDeviceProtocol();
|
||||||
|
|
||||||
|
protected abstract GBDeviceIoThread createDeviceIOThread();
|
||||||
|
|
||||||
|
public synchronized GBDeviceProtocol getDeviceProtocol() {
|
||||||
|
if (gbDeviceProtocol == null) {
|
||||||
|
gbDeviceProtocol = createDeviceProtocol();
|
||||||
|
}
|
||||||
|
return gbDeviceProtocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized GBDeviceIoThread getDeviceIOThread() {
|
||||||
|
if (gbDeviceIOThread == null) {
|
||||||
|
gbDeviceIOThread = createDeviceIOThread();
|
||||||
|
}
|
||||||
|
return gbDeviceIOThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void sendToDevice(byte[] bytes) {
|
||||||
|
if (bytes != null) {
|
||||||
|
gbDeviceIOThread.write(bytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSMS(String from, String body) {
|
||||||
|
byte[] bytes = gbDeviceProtocol.encodeSMS(from, body);
|
||||||
|
sendToDevice(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEmail(String from, String subject, String body) {
|
||||||
|
byte[] bytes = gbDeviceProtocol.encodeEmail(from, subject, body);
|
||||||
|
sendToDevice(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSetTime(long ts) {
|
||||||
|
byte[] bytes = gbDeviceProtocol.encodeSetTime(ts);
|
||||||
|
sendToDevice(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSetCallState(String number, String name, GBCommand command) {
|
||||||
|
byte[] bytes = gbDeviceProtocol.encodeSetCallState(number, name, command);
|
||||||
|
sendToDevice(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSetMusicInfo(String artist, String album, String track) {
|
||||||
|
byte[] bytes = gbDeviceProtocol.encodeSetMusicInfo(artist, album, track);
|
||||||
|
sendToDevice(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFirmwareVersionReq() {
|
||||||
|
byte[] bytes = gbDeviceProtocol.encodeFirmwareVersionReq();
|
||||||
|
sendToDevice(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAppInfoReq() {
|
||||||
|
byte[] bytes = gbDeviceProtocol.encodeAppInfoReq();
|
||||||
|
sendToDevice(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAppDelete(int id, int index) {
|
||||||
|
byte[] bytes = gbDeviceProtocol.encodeAppDelete(id, index);
|
||||||
|
sendToDevice(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPhoneVersion(byte os) {
|
||||||
|
byte[] bytes = gbDeviceProtocol.encodePhoneVersion(os);
|
||||||
|
sendToDevice(bytes);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public abstract class AbstractBTLEDeviceSupport extends AbstractDeviceSupport {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
public abstract class AbstractDeviceSupport implements DeviceSupport {
|
||||||
|
private GBDevice gbDevice;
|
||||||
|
private BluetoothAdapter btAdapter;
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
public void initialize(GBDevice gbDevice, BluetoothAdapter btAdapter, Context context) {
|
||||||
|
this.gbDevice = gbDevice;
|
||||||
|
this.btAdapter = btAdapter;
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public GBDevice getDevice() {
|
||||||
|
return gbDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BluetoothAdapter getBluetoothAdapter() {
|
||||||
|
return btAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Context getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,9 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge;
|
package nodomain.freeyourgadget.gadgetbridge;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.GBDevice.State;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.miband.MiBandSupport;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.pebble.PebbleIoThread;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.pebble.PebbleSupport;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.Service;
|
import android.app.Service;
|
||||||
import android.bluetooth.BluetoothAdapter;
|
import android.bluetooth.BluetoothAdapter;
|
||||||
@ -16,12 +20,6 @@ import android.provider.ContactsContract;
|
|||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.GBDevice.State;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.pebble.PebbleIoThread;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceProtocol;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.protocol.MibandProtocol;
|
|
||||||
import nodomain.freeyourgadget.gadgetbridge.protocol.PebbleProtocol;
|
|
||||||
|
|
||||||
public class BluetoothCommunicationService extends Service {
|
public class BluetoothCommunicationService extends Service {
|
||||||
public static final String ACTION_START
|
public static final String ACTION_START
|
||||||
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.start";
|
= "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.start";
|
||||||
@ -55,7 +53,7 @@ public class BluetoothCommunicationService extends Service {
|
|||||||
private boolean mStarted = false;
|
private boolean mStarted = false;
|
||||||
|
|
||||||
private GBDevice mGBDevice = null;
|
private GBDevice mGBDevice = null;
|
||||||
private GBDeviceProtocol mGBDeviceProtocol = null;
|
private DeviceSupport mDeviceSupport;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
@ -119,18 +117,17 @@ public class BluetoothCommunicationService extends Service {
|
|||||||
if (btDevice != null) {
|
if (btDevice != null) {
|
||||||
if (btDevice.getName() == null || btDevice.getName().equals("MI")) { //FIXME: workaround for Miband not being paired
|
if (btDevice.getName() == null || btDevice.getName().equals("MI")) { //FIXME: workaround for Miband not being paired
|
||||||
mGBDevice = new GBDevice(btDeviceAddress, btDevice.getName(), GBDevice.Type.MIBAND);
|
mGBDevice = new GBDevice(btDeviceAddress, btDevice.getName(), GBDevice.Type.MIBAND);
|
||||||
mGBDeviceProtocol = new MibandProtocol();
|
mDeviceSupport = new MiBandSupport();
|
||||||
mGBDeviceIoThread = new MibandIoThread(mGBDevice, this);
|
|
||||||
} else if (btDevice.getName().indexOf("Pebble") == 0) {
|
} else if (btDevice.getName().indexOf("Pebble") == 0) {
|
||||||
mGBDevice = new GBDevice(btDeviceAddress, btDevice.getName(), GBDevice.Type.PEBBLE);
|
mGBDevice = new GBDevice(btDeviceAddress, btDevice.getName(), GBDevice.Type.PEBBLE);
|
||||||
mGBDeviceProtocol = new PebbleProtocol();
|
mDeviceSupport = new PebbleSupport();
|
||||||
mGBDeviceIoThread = new PebbleIoThread(mGBDevice, mGBDeviceProtocol, mBtAdapter, this);
|
|
||||||
}
|
}
|
||||||
if (mGBDeviceProtocol != null) {
|
if (mDeviceSupport != null) {
|
||||||
mGBDevice.setState(GBDevice.State.CONNECTING);
|
mDeviceSupport.initialize(mGBDevice, mBtAdapter, this);
|
||||||
mGBDevice.sendDeviceUpdateIntent(this);
|
mDeviceSupport.connect();
|
||||||
|
if (mDeviceSupport instanceof AbstractBTDeviceSupport) {
|
||||||
mGBDeviceIoThread.start();
|
mGBDeviceIoThread = ((AbstractBTDeviceSupport) mDeviceSupport).getDeviceIOThread();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,20 +135,17 @@ public class BluetoothCommunicationService extends Service {
|
|||||||
} else if (action.equals(ACTION_NOTIFICATION_GENERIC)) {
|
} else if (action.equals(ACTION_NOTIFICATION_GENERIC)) {
|
||||||
String title = intent.getStringExtra("notification_title");
|
String title = intent.getStringExtra("notification_title");
|
||||||
String body = intent.getStringExtra("notification_body");
|
String body = intent.getStringExtra("notification_body");
|
||||||
byte[] msg = mGBDeviceProtocol.encodeSMS(title, body);
|
mDeviceSupport.onSMS(title, body);
|
||||||
mGBDeviceIoThread.write(msg);
|
|
||||||
} else if (action.equals(ACTION_NOTIFICATION_SMS)) {
|
} else if (action.equals(ACTION_NOTIFICATION_SMS)) {
|
||||||
String sender = intent.getStringExtra("notification_sender");
|
String sender = intent.getStringExtra("notification_sender");
|
||||||
String body = intent.getStringExtra("notification_body");
|
String body = intent.getStringExtra("notification_body");
|
||||||
String senderName = getContactDisplayNameByNumber(sender);
|
String senderName = getContactDisplayNameByNumber(sender);
|
||||||
byte[] msg = mGBDeviceProtocol.encodeSMS(senderName, body);
|
mDeviceSupport.onSMS(senderName, body);
|
||||||
mGBDeviceIoThread.write(msg);
|
|
||||||
} else if (action.equals(ACTION_NOTIFICATION_EMAIL)) {
|
} else if (action.equals(ACTION_NOTIFICATION_EMAIL)) {
|
||||||
String sender = intent.getStringExtra("notification_sender");
|
String sender = intent.getStringExtra("notification_sender");
|
||||||
String subject = intent.getStringExtra("notification_subject");
|
String subject = intent.getStringExtra("notification_subject");
|
||||||
String body = intent.getStringExtra("notification_body");
|
String body = intent.getStringExtra("notification_body");
|
||||||
byte[] msg = mGBDeviceProtocol.encodeEmail(sender, subject, body);
|
mDeviceSupport.onEmail(sender, subject, body);
|
||||||
mGBDeviceIoThread.write(msg);
|
|
||||||
} else if (action.equals(ACTION_CALLSTATE)) {
|
} else if (action.equals(ACTION_CALLSTATE)) {
|
||||||
GBCommand command = GBCommand.values()[intent.getIntExtra("call_command", 0)]; // UGLY
|
GBCommand command = GBCommand.values()[intent.getIntExtra("call_command", 0)]; // UGLY
|
||||||
String phoneNumber = intent.getStringExtra("call_phonenumber");
|
String phoneNumber = intent.getStringExtra("call_phonenumber");
|
||||||
@ -159,30 +153,26 @@ public class BluetoothCommunicationService extends Service {
|
|||||||
if (phoneNumber != null) {
|
if (phoneNumber != null) {
|
||||||
callerName = getContactDisplayNameByNumber(phoneNumber);
|
callerName = getContactDisplayNameByNumber(phoneNumber);
|
||||||
}
|
}
|
||||||
byte[] msg = mGBDeviceProtocol.encodeSetCallState(phoneNumber, callerName, command);
|
mDeviceSupport.onSetCallState(phoneNumber, callerName, command);
|
||||||
mGBDeviceIoThread.write(msg);
|
|
||||||
} else if (action.equals(ACTION_SETTIME)) {
|
} else if (action.equals(ACTION_SETTIME)) {
|
||||||
byte[] msg = mGBDeviceProtocol.encodeSetTime(-1);
|
mDeviceSupport.onSetTime(-1);
|
||||||
mGBDeviceIoThread.write(msg);
|
|
||||||
} else if (action.equals(ACTION_SETMUSICINFO)) {
|
} else if (action.equals(ACTION_SETMUSICINFO)) {
|
||||||
String artist = intent.getStringExtra("music_artist");
|
String artist = intent.getStringExtra("music_artist");
|
||||||
String album = intent.getStringExtra("music_album");
|
String album = intent.getStringExtra("music_album");
|
||||||
String track = intent.getStringExtra("music_track");
|
String track = intent.getStringExtra("music_track");
|
||||||
byte[] msg = mGBDeviceProtocol.encodeSetMusicInfo(artist, album, track);
|
mDeviceSupport.onSetMusicInfo(artist, album, track);
|
||||||
mGBDeviceIoThread.write(msg);
|
|
||||||
} else if (action.equals(ACTION_REQUEST_VERSIONINFO)) {
|
} else if (action.equals(ACTION_REQUEST_VERSIONINFO)) {
|
||||||
if (mGBDevice != null && mGBDevice.getFirmwareVersion() == null) {
|
if (mGBDevice != null && mGBDevice.getFirmwareVersion() == null) {
|
||||||
byte[] msg = mGBDeviceProtocol.encodeFirmwareVersionReq();
|
mDeviceSupport.onFirmwareVersionReq();
|
||||||
mGBDeviceIoThread.write(msg);
|
|
||||||
} else {
|
} else {
|
||||||
mGBDevice.sendDeviceUpdateIntent(this);
|
mGBDevice.sendDeviceUpdateIntent(this);
|
||||||
}
|
}
|
||||||
} else if (action.equals(ACTION_REQUEST_APPINFO)) {
|
} else if (action.equals(ACTION_REQUEST_APPINFO)) {
|
||||||
mGBDeviceIoThread.write(mGBDeviceProtocol.encodeAppInfoReq());
|
mDeviceSupport.onAppInfoReq();
|
||||||
} else if (action.equals(ACTION_DELETEAPP)) {
|
} else if (action.equals(ACTION_DELETEAPP)) {
|
||||||
int id = intent.getIntExtra("app_id", -1);
|
int id = intent.getIntExtra("app_id", -1);
|
||||||
int index = intent.getIntExtra("app_index", -1);
|
int index = intent.getIntExtra("app_index", -1);
|
||||||
mGBDeviceIoThread.write(mGBDeviceProtocol.encodeAppDelete(id, index));
|
mDeviceSupport.onAppDelete(id, index);
|
||||||
} else if (action.equals(ACTION_INSTALL_PEBBLEAPP)) {
|
} else if (action.equals(ACTION_INSTALL_PEBBLEAPP)) {
|
||||||
String uriString = intent.getStringExtra("app_uri");
|
String uriString = intent.getStringExtra("app_uri");
|
||||||
if (uriString != null) {
|
if (uriString != null) {
|
||||||
|
@ -0,0 +1,16 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge;
|
||||||
|
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
public interface DeviceSupport extends EventHandler {
|
||||||
|
public void initialize(GBDevice gbDevice, BluetoothAdapter btAdapter, Context context);
|
||||||
|
|
||||||
|
public boolean connect();
|
||||||
|
|
||||||
|
public GBDevice getDevice();
|
||||||
|
|
||||||
|
public BluetoothAdapter getBluetoothAdapter();
|
||||||
|
|
||||||
|
public Context getContext();
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge;
|
||||||
|
|
||||||
|
public interface EventHandler {
|
||||||
|
public void onSMS(String from, String body);
|
||||||
|
|
||||||
|
public void onEmail(String from, String subject, String body);
|
||||||
|
|
||||||
|
public void onSetTime(long ts);
|
||||||
|
|
||||||
|
public void onSetCallState(String number, String name, GBCommand command);
|
||||||
|
|
||||||
|
public void onSetMusicInfo(String artist, String album, String track);
|
||||||
|
|
||||||
|
public void onFirmwareVersionReq();
|
||||||
|
|
||||||
|
public void onAppInfoReq();
|
||||||
|
|
||||||
|
public void onAppDelete(int id, int index);
|
||||||
|
|
||||||
|
public void onPhoneVersion(byte os);
|
||||||
|
}
|
@ -1,11 +0,0 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
class MibandIoThread extends GBDeviceIoThread {
|
|
||||||
public MibandIoThread(GBDevice gbDevice, Context context) {
|
|
||||||
super(gbDevice, context);
|
|
||||||
}
|
|
||||||
|
|
||||||
// implement connect() run() write() and quit() here
|
|
||||||
}
|
|
@ -0,0 +1,68 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.miband;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.AbstractBTLEDeviceSupport;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.GBCommand;
|
||||||
|
|
||||||
|
public class MiBandSupport extends AbstractBTLEDeviceSupport {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean connect() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSMS(String from, String body) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEmail(String from, String subject, String body) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSetTime(long ts) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSetCallState(String number, String name, GBCommand command) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSetMusicInfo(String artist, String album, String track) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onFirmwareVersionReq() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAppInfoReq() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAppDelete(int id, int index) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPhoneVersion(byte os) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package nodomain.freeyourgadget.gadgetbridge.pebble;
|
||||||
|
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.AbstractBTDeviceSupport;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.GBDevice;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.GBDeviceIoThread;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceProtocol;
|
||||||
|
import nodomain.freeyourgadget.gadgetbridge.protocol.PebbleProtocol;
|
||||||
|
import android.bluetooth.BluetoothAdapter;
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
public class PebbleSupport extends AbstractBTDeviceSupport {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean connect() {
|
||||||
|
// TODO: state and notification handling should move to IO thread
|
||||||
|
getDevice().setState(GBDevice.State.CONNECTING);
|
||||||
|
getDevice().sendDeviceUpdateIntent(getContext());
|
||||||
|
getDeviceIOThread().start();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected GBDeviceProtocol createDeviceProtocol() {
|
||||||
|
return new PebbleProtocol();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected GBDeviceIoThread createDeviceIOThread() {
|
||||||
|
return new PebbleIoThread(getDevice(), getDeviceProtocol(), getBluetoothAdapter(), getContext());
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +0,0 @@
|
|||||||
package nodomain.freeyourgadget.gadgetbridge.protocol;
|
|
||||||
|
|
||||||
public class MibandProtocol extends GBDeviceProtocol {
|
|
||||||
/* implement methonds from GBDeviceProtocol here which make sense on the MiBand*/
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user