From 67a59175973bc411bf4ae4162b8e089e5879b43a Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 26 Mar 2015 12:06:26 +0100 Subject: [PATCH] Change the way how device commands or replys to information requests are passed back to the App This was necessary to pack more complex and more specific information regarding apps etc. --- .../BluetoothCommunicationService.java | 33 +++++++---- .../gadgetbridge/GBCallControlReceiver.java | 16 +++--- .../gadgetbridge/GBCommandBundle.java | 8 --- .../gadgetbridge/GBCommandClass.java | 8 --- .../gadgetbridge/GBMusicControlReceiver.java | 16 +++--- .../protocol/GBDeviceCommand.java | 15 +++++ .../protocol/GBDeviceCommandAppInfo.java | 11 ++++ .../protocol/GBDeviceCommandCallControl.java | 20 +++++++ .../protocol/GBDeviceCommandMusicControl.java | 19 +++++++ .../protocol/GBDeviceCommandVersionInfo.java | 10 ++++ .../{ => protocol}/PebbleProtocol.java | 56 ++++++++++--------- 11 files changed, 143 insertions(+), 69 deletions(-) delete mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommandBundle.java delete mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommandClass.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommand.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommandAppInfo.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommandCallControl.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommandMusicControl.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommandVersionInfo.java rename app/src/main/java/nodomain/freeyourgadget/gadgetbridge/{ => protocol}/PebbleProtocol.java (86%) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java index 1095b78ef..39b0e5cea 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/BluetoothCommunicationService.java @@ -29,6 +29,13 @@ import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommand; +import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandAppInfo; +import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandCallControl; +import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandMusicControl; +import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandVersionInfo; +import nodomain.freeyourgadget.gadgetbridge.protocol.PebbleProtocol; + public class BluetoothCommunicationService extends Service { public static final String ACTION_START = "nodomain.freeyourgadget.gadgetbride.bluetoothcommunicationservice.action.start"; @@ -117,18 +124,20 @@ public class BluetoothCommunicationService extends Service { nm.notify(NOTIFICATION_ID, notification); } - private void evaluateGBCommandBundle(GBCommandBundle cmdBundle) { - switch (cmdBundle.commandClass) { + private void evaluateGBCommandBundle(GBDeviceCommand deviceCmd) { + switch (deviceCmd.commandClass) { case MUSIC_CONTROL: Log.i(TAG, "Got command for MUSIC_CONTROL"); + GBDeviceCommandMusicControl musicCmd = (GBDeviceCommandMusicControl)deviceCmd; Intent musicIntent = new Intent(GBMusicControlReceiver.ACTION_MUSICCONTROL); - musicIntent.putExtra("command", cmdBundle.command.ordinal()); + musicIntent.putExtra("command", musicCmd.command.ordinal()); sendBroadcast(musicIntent); break; case CALL_CONTROL: Log.i(TAG, "Got command for CALL_CONTROL"); + GBDeviceCommandCallControl callCmd = (GBDeviceCommandCallControl)deviceCmd; Intent callIntent = new Intent(GBCallControlReceiver.ACTION_CALLCONTROL); - callIntent.putExtra("command", cmdBundle.command.ordinal()); + callIntent.putExtra("command", callCmd.command.ordinal()); sendBroadcast(callIntent); break; case VERSION_INFO: @@ -136,17 +145,19 @@ public class BluetoothCommunicationService extends Service { if (gbdevice == null) { return; } - gbdevice.setFirmwareVersion(cmdBundle.info[0]); + GBDeviceCommandVersionInfo infoCmd = (GBDeviceCommandVersionInfo)deviceCmd; + gbdevice.setFirmwareVersion(infoCmd.fwVersion); sendDeviceUpdateIntent(); break; case APP_INFO: Log.i(TAG, "Got command for APP_INFO"); + GBDeviceCommandAppInfo appInfoCmd = (GBDeviceCommandAppInfo)deviceCmd; Intent appInfoIntent = new Intent(AppManagerActivity.ACTION_REFRESH_APPLIST); - int appCount = cmdBundle.info.length / 2; + int appCount = appInfoCmd.apps.length; appInfoIntent.putExtra("app_count", appCount); for (Integer i = 0; i < appCount; i++) { - appInfoIntent.putExtra("app_name" + i.toString(), cmdBundle.info[i * 2]); - appInfoIntent.putExtra("app_creator" + i.toString(), cmdBundle.info[i * 2 + 1]); + appInfoIntent.putExtra("app_name" + i.toString(), appInfoCmd.apps[i].getName()); + appInfoIntent.putExtra("app_creator" + i.toString(), appInfoCmd.apps[i].getCreator()); } sendBroadcast(appInfoIntent); break; @@ -399,11 +410,11 @@ public class BluetoothCommunicationService extends Service { write(PebbleProtocol.encodePhoneVersion(PebbleProtocol.PHONEVERSION_REMOTE_OS_ANDROID)); write(PebbleProtocol.encodeFirmwareVersionReq()); } else if (endpoint != PebbleProtocol.ENDPOINT_DATALOG) { - GBCommandBundle cmdBundle = PebbleProtocol.decodeResponse(buffer); - if (cmdBundle == null) { + GBDeviceCommand deviceCmd = PebbleProtocol.decodeResponse(buffer); + if (deviceCmd == null) { Log.i(TAG, "unhandled message to endpoint " + endpoint + " (" + bytes + " bytes)"); } else { - evaluateGBCommandBundle(cmdBundle); + evaluateGBCommandBundle(deviceCmd); } } try { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCallControlReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCallControlReceiver.java index 22264dc3f..802253664 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCallControlReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCallControlReceiver.java @@ -10,25 +10,25 @@ import com.android.internal.telephony.ITelephony; import java.lang.reflect.Method; -public class GBCallControlReceiver extends BroadcastReceiver { - private final String TAG = this.getClass().getSimpleName(); +import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandCallControl; +public class GBCallControlReceiver extends BroadcastReceiver { public static final String ACTION_CALLCONTROL = "nodomain.freeyourgadget.gadgetbridge.callcontrol"; + private final String TAG = this.getClass().getSimpleName(); @Override public void onReceive(Context context, Intent intent) { - GBCommand command = GBCommand.values()[intent.getIntExtra("command", 0)]; - int keyCode; - switch (command) { - case CALL_END: - case CALL_START: + GBDeviceCommandCallControl.Command callCmd = GBDeviceCommandCallControl.Command.values()[intent.getIntExtra("command", 0)]; + switch (callCmd) { + case END: + case START: try { TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); Class clazz = Class.forName(telephonyManager.getClass().getName()); Method method = clazz.getDeclaredMethod("getITelephony"); method.setAccessible(true); ITelephony telephonyService = (ITelephony) method.invoke(telephonyManager); - if (command == GBCommand.CALL_END) { + if (callCmd == GBDeviceCommandCallControl.Command.END) { telephonyService.endCall(); } else { telephonyService.answerRingingCall(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommandBundle.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommandBundle.java deleted file mode 100644 index a0c9eaef2..000000000 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommandBundle.java +++ /dev/null @@ -1,8 +0,0 @@ -package nodomain.freeyourgadget.gadgetbridge; - - -public class GBCommandBundle { - public GBCommandClass commandClass; - public GBCommand command; - public String[] info; -} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommandClass.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommandClass.java deleted file mode 100644 index 8faa4657b..000000000 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBCommandClass.java +++ /dev/null @@ -1,8 +0,0 @@ -package nodomain.freeyourgadget.gadgetbridge; - -public enum GBCommandClass { - MUSIC_CONTROL, - CALL_CONTROL, - APP_INFO, - VERSION_INFO -} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBMusicControlReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBMusicControlReceiver.java index 298f621e6..150aa8b0b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBMusicControlReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBMusicControlReceiver.java @@ -6,6 +6,8 @@ import android.content.Intent; import android.os.SystemClock; import android.view.KeyEvent; +import nodomain.freeyourgadget.gadgetbridge.protocol.GBDeviceCommandMusicControl; + public class GBMusicControlReceiver extends BroadcastReceiver { private final String TAG = this.getClass().getSimpleName(); @@ -13,22 +15,22 @@ public class GBMusicControlReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { - GBCommand command = GBCommand.values()[intent.getIntExtra("command", 0)]; + GBDeviceCommandMusicControl.Command musicCmd = GBDeviceCommandMusicControl.Command.values()[intent.getIntExtra("command", 0)]; int keyCode; - switch (command) { - case MUSIC_NEXT: + switch (musicCmd) { + case NEXT: keyCode = KeyEvent.KEYCODE_MEDIA_NEXT; break; - case MUSIC_PREVIOUS: + case PREVIOUS: keyCode = KeyEvent.KEYCODE_MEDIA_PREVIOUS; break; - case MUSIC_PLAY: + case PLAY: keyCode = KeyEvent.KEYCODE_MEDIA_PLAY; break; - case MUSIC_PAUSE: + case PAUSE: keyCode = KeyEvent.KEYCODE_MEDIA_PAUSE; break; - case MUSIC_PLAYPAUSE: + case PLAYPAUSE: keyCode = KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE; break; default: diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommand.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommand.java new file mode 100644 index 000000000..a257b1d2d --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommand.java @@ -0,0 +1,15 @@ +package nodomain.freeyourgadget.gadgetbridge.protocol; + + +public abstract class GBDeviceCommand { + public CommandClass commandClass = CommandClass.UNKNOWN; + + public enum CommandClass { + UNKNOWN, + MUSIC_CONTROL, + CALL_CONTROL, + APP_INFO, + VERSION_INFO + } +} + diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommandAppInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommandAppInfo.java new file mode 100644 index 000000000..696f9b208 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommandAppInfo.java @@ -0,0 +1,11 @@ +package nodomain.freeyourgadget.gadgetbridge.protocol; + +import nodomain.freeyourgadget.gadgetbridge.GBDeviceApp; + +public class GBDeviceCommandAppInfo extends GBDeviceCommand { + public GBDeviceApp apps[]; + + public GBDeviceCommandAppInfo() { + commandClass = CommandClass.APP_INFO; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommandCallControl.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommandCallControl.java new file mode 100644 index 000000000..4f981a245 --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommandCallControl.java @@ -0,0 +1,20 @@ +package nodomain.freeyourgadget.gadgetbridge.protocol; + + +public class GBDeviceCommandCallControl extends GBDeviceCommand { + public Command command = Command.UNKNOWN; + + public GBDeviceCommandCallControl() { + commandClass = CommandClass.CALL_CONTROL; + } + + public enum Command { + UNKNOWN, + ACCEPT, + END, + INCOMING, + OUTGOING, + REJECT, + START, + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommandMusicControl.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommandMusicControl.java new file mode 100644 index 000000000..4ffe6b33e --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommandMusicControl.java @@ -0,0 +1,19 @@ +package nodomain.freeyourgadget.gadgetbridge.protocol; + + +public class GBDeviceCommandMusicControl extends GBDeviceCommand { + public Command command = Command.UNKNOWN; + + public GBDeviceCommandMusicControl() { + commandClass = CommandClass.MUSIC_CONTROL; + } + + public enum Command { + UNKNOWN, + PLAY, + PAUSE, + PLAYPAUSE, + NEXT, + PREVIOUS, + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommandVersionInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommandVersionInfo.java new file mode 100644 index 000000000..0da8df00d --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/GBDeviceCommandVersionInfo.java @@ -0,0 +1,10 @@ +package nodomain.freeyourgadget.gadgetbridge.protocol; + +public class GBDeviceCommandVersionInfo extends GBDeviceCommand { + public String fwVersion = "N/A"; + public String hwVersion = "N/A"; + + public GBDeviceCommandVersionInfo() { + commandClass = CommandClass.VERSION_INFO; + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/PebbleProtocol.java similarity index 86% rename from app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PebbleProtocol.java rename to app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/PebbleProtocol.java index 15ba3a529..6661c9bb4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/PebbleProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/protocol/PebbleProtocol.java @@ -1,4 +1,4 @@ -package nodomain.freeyourgadget.gadgetbridge; +package nodomain.freeyourgadget.gadgetbridge.protocol; import android.util.Log; @@ -6,6 +6,9 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.SimpleTimeZone; +import nodomain.freeyourgadget.gadgetbridge.GBCommand; +import nodomain.freeyourgadget.gadgetbridge.GBDeviceApp; + public class PebbleProtocol { static private String TAG = "PebbleProtocol"; @@ -13,7 +16,7 @@ public class PebbleProtocol { static final short ENDPOINT_FIRMWARE = 1; static final short ENDPOINT_TIME = 11; static final short ENDPOINT_FIRMWAREVERSION = 16; - static final short ENDPOINT_PHONEVERSION = 17; + public static final short ENDPOINT_PHONEVERSION = 17; static final short ENDPOINT_SYSTEMMESSAGE = 18; static final short ENDPOINT_MUSICCONTROL = 32; static final short ENDPOINT_PHONECONTROL = 33; @@ -30,7 +33,7 @@ public class PebbleProtocol { static final short ENDPOINT_SYSREG = 5000; static final short ENDPOINT_FCTREG = 5001; static final short ENDPOINT_APPMANAGER = 6000; - static final short ENDPOINT_DATALOG = 6778; + public static final short ENDPOINT_DATALOG = 6778; static final short ENDPOINT_RUNKEEPER = 7000; static final short ENDPOINT_SCREENSHOT = 8000; static final short ENDPOINT_PUTBYTES = (short) 48879; @@ -91,7 +94,7 @@ public class PebbleProtocol { static final byte PHONEVERSION_REMOTE_OS_UNKNOWN = 0; static final byte PHONEVERSION_REMOTE_OS_IOS = 1; - static final byte PHONEVERSION_REMOTE_OS_ANDROID = 2; + public static final byte PHONEVERSION_REMOTE_OS_ANDROID = 2; static final byte PHONEVERSION_REMOTE_OS_OSX = 3; static final byte PHONEVERSION_REMOTE_OS_LINUX = 4; static final byte PHONEVERSION_REMOTE_OS_WINDOWS = 5; @@ -242,69 +245,69 @@ public class PebbleProtocol { return buf.array(); } - public static GBCommandBundle decodeResponse(byte[] responseData) { + public static GBDeviceCommand decodeResponse(byte[] responseData) { ByteBuffer buf = ByteBuffer.wrap(responseData); buf.order(ByteOrder.BIG_ENDIAN); short length = buf.getShort(); short endpoint = buf.getShort(); byte pebbleCmd = buf.get(); - GBCommandBundle cmd = new GBCommandBundle(); + GBDeviceCommand cmd = null; switch (endpoint) { case ENDPOINT_MUSICCONTROL: - cmd.commandClass = GBCommandClass.MUSIC_CONTROL; + GBDeviceCommandMusicControl musicCmd = new GBDeviceCommandMusicControl(); switch (pebbleCmd) { case MUSICCONTROL_NEXT: - cmd.command = GBCommand.MUSIC_NEXT; + musicCmd.command = GBDeviceCommandMusicControl.Command.NEXT; break; case MUSICCONTROL_PREVIOUS: - cmd.command = GBCommand.MUSIC_PREVIOUS; + musicCmd.command = GBDeviceCommandMusicControl.Command.PREVIOUS; break; case MUSICCONTROL_PLAY: - cmd.command = GBCommand.MUSIC_PLAY; + musicCmd.command = GBDeviceCommandMusicControl.Command.PLAY; break; case MUSICCONTROL_PAUSE: - cmd.command = GBCommand.MUSIC_PAUSE; + musicCmd.command = GBDeviceCommandMusicControl.Command.PAUSE; break; case MUSICCONTROL_PLAYPAUSE: - cmd.command = GBCommand.MUSIC_PLAYPAUSE; + musicCmd.command = GBDeviceCommandMusicControl.Command.PLAYPAUSE; break; default: - cmd.command = GBCommand.UNDEFINEND; break; } + cmd = musicCmd; break; case ENDPOINT_PHONECONTROL: - cmd.commandClass = GBCommandClass.CALL_CONTROL; + GBDeviceCommandCallControl callCmd = new GBDeviceCommandCallControl(); switch (pebbleCmd) { case PHONECONTROL_HANGUP: - cmd.command = GBCommand.CALL_END; + callCmd.command = GBDeviceCommandCallControl.Command.END; break; default: Log.i(TAG, "Unknown PHONECONTROL command" + pebbleCmd); - cmd.command = GBCommand.UNDEFINEND; break; } + cmd = callCmd; break; case ENDPOINT_FIRMWAREVERSION: + GBDeviceCommandVersionInfo versionCmd = new GBDeviceCommandVersionInfo(); + int version = buf.getInt(); byte[] versionString = new byte[32]; buf.get(versionString, 0, 32); - cmd.commandClass = GBCommandClass.VERSION_INFO; - cmd.command = GBCommand.VERSION_FIRMWARE; - cmd.info = new String[]{new String(versionString).trim()}; - Log.i(TAG, "Got firmware version: " + cmd.info); + versionCmd.fwVersion = new String(versionString).trim(); + Log.i(TAG, "Got firmware version: " + versionCmd.fwVersion); + cmd = versionCmd; break; case ENDPOINT_APPMANAGER: - cmd.commandClass = GBCommandClass.APP_INFO; switch (pebbleCmd) { case APPMANAGER_GETAPPBANKSTATUS: - cmd.command = GBCommand.APP_INFO_NAME; + GBDeviceCommandAppInfo appInfoCmd = new GBDeviceCommandAppInfo(); int banks = buf.getInt(); int banksUsed = buf.getInt(); byte[] appName = new byte[32]; byte[] creatorName = new byte[32]; - cmd.info = new String[banksUsed * 2]; + appInfoCmd.apps = new GBDeviceApp[banksUsed]; for (int i = 0; i < banksUsed; i++) { buf.getInt(); // id @@ -312,14 +315,13 @@ public class PebbleProtocol { buf.get(appName, 0, 32); buf.get(creatorName, 0, 32); int flags = buf.getInt(); - short appVersion = buf.getShort(); - cmd.info[i * 2] = new String(appName).trim(); - cmd.info[i * 2 + 1] = new String(creatorName).trim(); + Short appVersion = buf.getShort(); + appInfoCmd.apps[i] = new GBDeviceApp(new String(appName).trim(), new String(creatorName).trim(), appVersion.toString()); } + cmd = appInfoCmd; break; default: Log.i(TAG, "Unknown APPMANAGER command" + pebbleCmd); - cmd.command = GBCommand.UNDEFINEND; break; } break;