From faaa04b6709f085618a54caede2e4fb5f4a9db83 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 20 Aug 2015 18:55:22 +0200 Subject: [PATCH 1/8] App Installation: various improvements - make FwAppInstallerActivity wait for a completely initialized device - check basalt/aplite compatibility with pbw to be installed and report intead of crashing - fix crash when trying to install pbw with all app slots full --- app/src/main/AndroidManifest.xml | 3 +-- .../activities/FwAppInstallerActivity.java | 2 +- .../devices/pebble/PBWInstallHandler.java | 13 ++++++++++--- .../gadgetbridge/devices/pebble/PBWReader.java | 1 - .../service/devices/pebble/PebbleIoThread.java | 10 ++++++---- 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 957a6be6d..27d00cd9e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,9 +5,8 @@ - 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 9f85914d1..87dc334ef 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java @@ -47,7 +47,7 @@ public class FwAppInstallerActivity extends Activity implements InstallActivity } else if (action.equals(GBDevice.ACTION_DEVICE_CHANGED)) { device = intent.getParcelableExtra(GBDevice.EXTRA_DEVICE); if (device != null) { - if (!device.isConnected()) { + if (!device.isInitialized()) { setInstallEnabled(false); if (mayConnect) { GB.toast(FwAppInstallerActivity.this, getString(R.string.connecting), Toast.LENGTH_SHORT, GB.INFO); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWInstallHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWInstallHandler.java index f7043c104..cae52c637 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWInstallHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWInstallHandler.java @@ -17,12 +17,11 @@ import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; public class PBWInstallHandler implements InstallHandler { private final Context mContext; - private final PBWReader mPBWReader; + private PBWReader mPBWReader; private final Uri mUri; public PBWInstallHandler(Uri uri, Context context) { mContext = context; - mPBWReader = new PBWReader(uri, context, ""); // FIXME: we should know the platform here mUri = uri; } @@ -34,6 +33,13 @@ public class PBWInstallHandler implements InstallHandler { return; } + mPBWReader = new PBWReader(mUri, mContext, device.getHardwareVersion().equals("dvt") ? "basalt" : "aplite"); + if (!mPBWReader.isValid()) { + installActivity.setInfoText("pbw/pbz is broken or incompatible with your Hardware or Firmware."); + installActivity.setInstallEnabled(false); + return; + } + if (mPBWReader.isFirmware()) { String hwRevision = mPBWReader.getHWRevision(); if (hwRevision != null && hwRevision.equals(device.getHardwareVersion())) { @@ -77,7 +83,8 @@ public class PBWInstallHandler implements InstallHandler { } public boolean isValid() { - return mPBWReader.isValid(); + // always pretend it is valid, as we cant know yet about hw/fw version + return true; } } \ No newline at end of file diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWReader.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWReader.java index 4c97bfdb6..b9f85a676 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWReader.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/pebble/PBWReader.java @@ -147,7 +147,6 @@ public class PBWReader { if (appName != null && appCreator != null && appVersion != null) { // FIXME: dont assume WATCHFACE app = new GBDeviceApp(uuid, appName, appCreator, appVersion, GBDeviceApp.Type.WATCHFACE); - isValid = true; } } catch (JSONException e) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java index 44a113c60..68758bf2e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java @@ -480,10 +480,12 @@ public class PebbleIoThread extends GBDeviceIoThread { mPBWReader = null; mIsInstalling = false; - try { - mZis.close(); - } catch (IOException e) { - // ignore + if (mZis != null) { + try { + mZis.close(); + } catch (IOException e) { + // ignore + } } mZis = null; mAppInstallToken = -1; From ff6d28cdc876adc6bbe6bb707d7fbfb305eaa722 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 20 Aug 2015 22:41:38 +0200 Subject: [PATCH 2/8] Remove INTERNET permission Accidentially commited my local change to make the emulator connection work. (Yes I know I had been warned) --- app/src/main/AndroidManifest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 27d00cd9e..957a6be6d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -5,8 +5,9 @@ - + From 6869fc85ee5ce40ab7739b755e1a73919a2746eb Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Thu, 20 Aug 2015 22:51:55 +0200 Subject: [PATCH 3/8] update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ff84cc7a..35ae1483b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,10 @@ ####Version (next) * Pebble: experimental watchapp installation support for FW 3.x/Pebble Time +* Pebble: support Pebble emulator via TCP connection (needs rebuild with INTERNET permission) * Pebble: use SMS/EMAIL icons for FW 3.x/Pebble Time * Support going forward/backwards in time in the activy charts +* Various small bugfixes to the App/Fw Installation Activity ####Version 0.4.6 * Mi Band: Fixed negative number of steps displayed (#91) From a1cb246e27e5ea0dd7902e2016ebba7de21e34e4 Mon Sep 17 00:00:00 2001 From: cpfeiffer Date: Fri, 21 Aug 2015 00:58:18 +0200 Subject: [PATCH 4/8] Add and use a "client interface" for the actions of the service Previously, the DeviceCommunicationService was invoked directly, via Intent intent = new Intent(foo, bar); intent.setExtra(EXTRA_BAZ, baz); startService(...); and this was scattered throughout GadgetBridge. Now there is a "frontend" available, so that you can call the service more easily, like GBApplication.deviceService().connect(); For a start, this client interface (DeviceService) actually implements the same interface (EventHandler) as the receiving side (DeviceSupport). This may change in the future. This will also make testing much easier, because we can use this client interface to invoke the test service as well. --- .../gadgetbridge/GBApplication.java | 13 ++ .../activities/AppManagerActivity.java | 16 +- .../activities/ConfigureAlarms.java | 6 +- .../activities/ControlCenter.java | 46 +---- .../activities/DebugActivity.java | 73 +++---- .../activities/FwAppInstallerActivity.java | 18 +- .../activities/charts/ChartsActivity.java | 6 +- .../adapter/GBAlarmListAdapter.java | 2 +- .../gadgetbridge/devices/EventHandler.java | 11 +- .../devices/miband/MiBandPairingActivity.java | 7 +- .../BluetoothStateChangeReceiver.java | 8 +- .../externalevents/K9Receiver.java | 10 +- .../externalevents/MusicPlaybackReceiver.java | 9 +- .../externalevents/NotificationListener.java | 8 +- .../externalevents/PebbleReceiver.java | 8 +- .../externalevents/PhoneCallReceiver.java | 8 +- .../externalevents/SMSReceiver.java | 8 +- .../externalevents/TimeChangeReceiver.java | 6 +- .../gadgetbridge/impl/GBDeviceService.java | 186 ++++++++++++++++++ .../gadgetbridge/model/DeviceService.java | 68 +++++++ .../service/DeviceCommunicationService.java | 80 +++----- .../service/ServiceDeviceSupport.java | 24 +-- .../service/devices/miband/MiBandSupport.java | 20 +- .../devices/pebble/PebbleIoThread.java | 2 +- .../devices/pebble/PebbleProtocol.java | 7 +- .../service/devices/pebble/PebbleSupport.java | 2 +- .../serial/AbstractSerialDeviceSupport.java | 16 +- .../service/serial/GBDeviceProtocol.java | 10 +- .../freeyourgadget/gadgetbridge/util/GB.java | 7 - 29 files changed, 378 insertions(+), 307 deletions(-) create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java create mode 100644 app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java index 204933f52..51661b44b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java @@ -19,6 +19,9 @@ import java.util.concurrent.locks.ReentrantLock; import nodomain.freeyourgadget.gadgetbridge.database.ActivityDatabaseHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; +import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceService; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceService; +import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; public class GBApplication extends Application { @@ -27,12 +30,18 @@ public class GBApplication extends Application { private static GBApplication context; private static ActivityDatabaseHandler mActivityDatabaseHandler; private static final Lock dbLock = new ReentrantLock(); + private static DeviceService deviceService; public GBApplication() { context = this; + deviceService = createDeviceService(); // don't do anything here, add it to onCreate instead } + protected DeviceService createDeviceService() { + return new GBDeviceService(this, DeviceCommunicationService.class); + } + @Override public void onCreate() { super.onCreate(); @@ -82,6 +91,10 @@ public class GBApplication extends Application { return context; } + public static DeviceService deviceService() { + return deviceService; + } + /** * Returns the DBHandler instance for reading/writing or throws GBException * when that was not successful diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AppManagerActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AppManagerActivity.java index 32292a772..94c8837f4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AppManagerActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/AppManagerActivity.java @@ -23,9 +23,11 @@ import java.util.ArrayList; import java.util.List; import java.util.UUID; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.adapter.GBDeviceAppAdapter; import nodomain.freeyourgadget.gadgetbridge.impl.GBDeviceApp; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceService; import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; @@ -93,10 +95,7 @@ public class AppManagerActivity extends Activity { @Override public void onItemClick(AdapterView parent, View v, int position, long id) { UUID uuid = appList.get(position).getUUID(); - Intent startAppIntent = new Intent(AppManagerActivity.this, DeviceCommunicationService.class); - startAppIntent.setAction(DeviceCommunicationService.ACTION_STARTAPP); - startAppIntent.putExtra("app_uuid", uuid.toString()); - startService(startAppIntent); + GBApplication.deviceService().onAppStart(uuid); } }); @@ -113,9 +112,7 @@ public class AppManagerActivity extends Activity { LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filter); - Intent startIntent = new Intent(this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_REQUEST_APPINFO); - startService(startIntent); + GBApplication.deviceService().onAppInfoReq(); } @Override @@ -133,10 +130,7 @@ public class AppManagerActivity extends Activity { switch (item.getItemId()) { case R.id.appmanager_app_delete: if (selectedApp != null) { - Intent deleteIntent = new Intent(this, DeviceCommunicationService.class); - deleteIntent.setAction(DeviceCommunicationService.ACTION_DELETEAPP); - deleteIntent.putExtra("app_uuid", selectedApp.getUUID().toString()); - startService(deleteIntent); + GBApplication.deviceService().onAppDelete(selectedApp.getUUID()); } return true; default: diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java index d4eb10260..9c263cf5e 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ConfigureAlarms.java @@ -11,6 +11,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; import nodomain.freeyourgadget.gadgetbridge.impl.GBAlarm; import nodomain.freeyourgadget.gadgetbridge.R; @@ -78,9 +79,6 @@ public class ConfigureAlarms extends ListActivity { } private void sendAlarmsToDevice() { - Intent startIntent = new Intent(ConfigureAlarms.this, DeviceCommunicationService.class); - startIntent.putParcelableArrayListExtra("alarms", mGBAlarmListAdapter.getAlarmList()); - startIntent.setAction(DeviceCommunicationService.ACTION_SET_ALARMS); - startService(startIntent); + GBApplication.deviceService().onSetAlarms(mGBAlarmListAdapter.getAlarmList()); } } 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 1ea4e7461..0ce5a4268 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ControlCenter.java @@ -29,6 +29,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Set; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsActivity; import nodomain.freeyourgadget.gadgetbridge.adapter.GBDeviceAdapter; @@ -112,10 +113,7 @@ public class ControlCenter extends Activity { startActivity(startIntent); } } else { - Intent startIntent = new Intent(ControlCenter.this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_CONNECT); - startIntent.putExtra(DeviceCommunicationService.EXTRA_DEVICE_ADDRESS, deviceList.get(position).getAddress()); - startService(startIntent); + GBApplication.deviceService().connect(deviceList.get(position).getAddress()); } } }); @@ -141,33 +139,17 @@ public class ControlCenter extends Activity { Intent enableIntent = new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS"); startActivity(enableIntent); } - Intent startIntent = new Intent(this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_START); - startService(startIntent); + GBApplication.deviceService().start(); if (GB.isBluetoothEnabled() && deviceList.isEmpty()) { // start discovery when no devices are present startActivity(new Intent(this, DiscoveryActivity.class)); } else { - requestDeviceInfo(); + GBApplication.deviceService().requestDeviceInfo(); } } - /** - * Requests information from the {@link DeviceCommunicationService} about the connection state, - * firmware info, etc. - *

- * Note that this will not need a connection to the device -- only the cached information - * from the service will be reported. - */ - private void requestDeviceInfo() { - Intent versionInfoIntent = new Intent(ControlCenter.this, DeviceCommunicationService.class); - versionInfoIntent.setAction(DeviceCommunicationService.ACTION_REQUEST_DEVICEINFO); - startService(versionInfoIntent); - } - - @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { super.onCreateContextMenu(menu, v, menuInfo); @@ -209,17 +191,13 @@ public class ControlCenter extends Activity { return true; case R.id.controlcenter_fetch_activity_data: if (selectedDevice != null) { - Intent startIntent = new Intent(this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_FETCH_ACTIVITY_DATA); - startService(startIntent); + GBApplication.deviceService().onFetchActivityData(); } return true; case R.id.controlcenter_disconnect: if (selectedDevice != null) { selectedDevice = null; - Intent startIntent = new Intent(this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_DISCONNECT); - startService(startIntent); + GBApplication.deviceService().disconnect(); } return true; case R.id.controlcenter_find_device: @@ -247,9 +225,7 @@ public class ControlCenter extends Activity { return true; case R.id.controlcenter_take_screenshot: if (selectedDevice != null) { - Intent startIntent = new Intent(this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_REQUEST_SCREENSHOT); - startService(startIntent); + GBApplication.deviceService().onScreenshotReq(); } return true; default: @@ -258,10 +234,7 @@ public class ControlCenter extends Activity { } private void findDevice(boolean start) { - Intent startIntent = new Intent(this, DeviceCommunicationService.class); - startIntent.putExtra("find_start", start); - startIntent.setAction(DeviceCommunicationService.ACTION_FIND_DEVICE); - startService(startIntent); + GBApplication.deviceService().onFindDevice(start); } @Override @@ -284,8 +257,7 @@ public class ControlCenter extends Activity { startActivity(debugIntent); return true; case R.id.action_quit: - Intent stopIntent = new Intent(this, DeviceCommunicationService.class); - stopService(stopIntent); + GBApplication.deviceService().quit(); Intent quitIntent = new Intent(ControlCenter.ACTION_QUIT); LocalBroadcastManager.getInstance(this).sendBroadcast(quitIntent); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java index 5f672f45f..4ed351465 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/DebugActivity.java @@ -21,14 +21,13 @@ import org.slf4j.LoggerFactory; import java.io.File; -import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; -import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.GBApplication; -import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; +import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand; import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; +import nodomain.freeyourgadget.gadgetbridge.util.GB; public class DebugActivity extends Activity { @@ -70,23 +69,17 @@ public class DebugActivity extends Activity { sendSMSButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent startIntent = new Intent(DebugActivity.this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_NOTIFICATION_SMS); - startIntent.putExtra("notification_sender", getResources().getText(R.string.app_name)); - startIntent.putExtra("notification_body", editContent.getText().toString()); - startService(startIntent); + GBApplication.deviceService().onSMS(getResources().getText(R.string.app_name).toString(), editContent.getText().toString()); } }); sendEmailButton = (Button) findViewById(R.id.sendEmailButton); sendEmailButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent startIntent = new Intent(DebugActivity.this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_NOTIFICATION_EMAIL); - startIntent.putExtra("notification_sender", getResources().getText(R.string.app_name)); - startIntent.putExtra("notification_subject", getResources().getText(R.string.test)); - startIntent.putExtra("notification_body", editContent.getText().toString()); - startService(startIntent); + GBApplication.deviceService().onEmail( + getResources().getText(R.string.app_name).toString(), + getResources().getText(R.string.test).toString(), + editContent.getText().toString()); } }); @@ -94,22 +87,20 @@ public class DebugActivity extends Activity { incomingCallButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent startIntent = new Intent(DebugActivity.this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_CALLSTATE); - startIntent.putExtra("call_phonenumber", editContent.getText().toString()); - startIntent.putExtra("call_command", ServiceCommand.CALL_INCOMING.ordinal()); - startService(startIntent); + GBApplication.deviceService().onSetCallState( + editContent.getText().toString(), + null, + ServiceCommand.CALL_INCOMING); } }); outgoingCallButton = (Button) findViewById(R.id.outgoingCallButton); outgoingCallButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent startIntent = new Intent(DebugActivity.this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_CALLSTATE); - startIntent.putExtra("call_phonenumber", editContent.getText().toString()); - startIntent.putExtra("call_command", ServiceCommand.CALL_OUTGOING.ordinal()); - startService(startIntent); + GBApplication.deviceService().onSetCallState( + editContent.getText().toString(), + null, + ServiceCommand.CALL_OUTGOING); } }); @@ -117,20 +108,20 @@ public class DebugActivity extends Activity { startCallButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent startIntent = new Intent(DebugActivity.this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_CALLSTATE); - startIntent.putExtra("call_command", ServiceCommand.CALL_START.ordinal()); - startService(startIntent); + GBApplication.deviceService().onSetCallState( + null, + null, + ServiceCommand.CALL_START); } }); endCallButton = (Button) findViewById(R.id.endCallButton); endCallButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent startIntent = new Intent(DebugActivity.this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_CALLSTATE); - startIntent.putExtra("call_command", ServiceCommand.CALL_END.ordinal()); - startService(startIntent); + GBApplication.deviceService().onSetCallState( + null, + null, + ServiceCommand.CALL_END); } }); @@ -153,9 +144,7 @@ public class DebugActivity extends Activity { rebootButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent startIntent = new Intent(DebugActivity.this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_REBOOT); - startService(startIntent); + GBApplication.deviceService().onReboot(); } }); @@ -163,12 +152,10 @@ public class DebugActivity extends Activity { setMusicInfoButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent startIntent = new Intent(DebugActivity.this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_SETMUSICINFO); - startIntent.putExtra("music_artist", editContent.getText().toString() + "(artist)"); - startIntent.putExtra("music_album", editContent.getText().toString() + "(album)"); - startIntent.putExtra("music_track", editContent.getText().toString() + "(track)"); - startService(startIntent); + GBApplication.deviceService().onSetMusicInfo( + editContent.getText().toString() + "(artist)", + editContent.getText().toString() + "(album)", + editContent.getText().toString() + "(tracl)"); } }); @@ -176,9 +163,7 @@ public class DebugActivity extends Activity { setTimeButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - Intent startIntent = new Intent(DebugActivity.this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_SETTIME); - startService(startIntent); + GBApplication.deviceService().onSetTime(); } }); 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 87dc334ef..0c7452fbb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/FwAppInstallerActivity.java @@ -18,11 +18,11 @@ import android.widget.Toast; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; import nodomain.freeyourgadget.gadgetbridge.devices.InstallHandler; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; -import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; import nodomain.freeyourgadget.gadgetbridge.util.GB; @@ -65,12 +65,7 @@ public class FwAppInstallerActivity extends Activity implements InstallActivity private void connect() { mayConnect = false; // only do that once per #onCreate - Intent startIntent = new Intent(FwAppInstallerActivity.this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_CONNECT); - if (device != null) { - startIntent.putExtra(GBDevice.EXTRA_DEVICE, device); - } - startService(startIntent); + GBApplication.deviceService().connect(device != null ? device.getAddress() : null); } private void validateInstallation() { @@ -102,10 +97,7 @@ public class FwAppInstallerActivity extends Activity implements InstallActivity public void onClick(View v) { setInstallEnabled(false); installHandler.onStartInstall(device); - Intent startIntent = new Intent(FwAppInstallerActivity.this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_INSTALL); - startIntent.putExtra("uri", uri); - startService(startIntent); + GBApplication.deviceService().onInstallApp(uri); } }); @@ -120,9 +112,7 @@ public class FwAppInstallerActivity extends Activity implements InstallActivity if (device == null || !device.isConnected()) { connect(); } else { - Intent deviceInfoIntent = new Intent(this, DeviceCommunicationService.class); - deviceInfoIntent.setAction(DeviceCommunicationService.ACTION_REQUEST_DEVICEINFO); - startService(deviceInfoIntent); + GBApplication.deviceService().requestDeviceInfo(); } } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java index c2e2cfb16..e25c00ccb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/charts/ChartsActivity.java @@ -24,10 +24,10 @@ import org.slf4j.LoggerFactory; import java.util.Locale; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; -import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; public class ChartsActivity extends FragmentActivity implements ChartsHost { @@ -147,9 +147,7 @@ public class ChartsActivity extends FragmentActivity implements ChartsHost { public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.charts_fetch_activity_data: - Intent startIntent = new Intent(this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_FETCH_ACTIVITY_DATA); - startService(startIntent); + GBApplication.deviceService().onFetchActivityData(); return true; default: break; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBAlarmListAdapter.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBAlarmListAdapter.java index 525f47f4e..8e2df7665 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBAlarmListAdapter.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/adapter/GBAlarmListAdapter.java @@ -57,7 +57,7 @@ public class GBAlarmListAdapter extends ArrayAdapter { Collections.sort(alarmList); } - public ArrayList getAlarmList() { + public ArrayList getAlarmList() { return alarmList; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java index e3b6ada00..915c352eb 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/EventHandler.java @@ -1,6 +1,7 @@ package nodomain.freeyourgadget.gadgetbridge.devices; import android.net.Uri; +import android.support.annotation.Nullable; import java.util.ArrayList; import java.util.UUID; @@ -20,16 +21,14 @@ public interface EventHandler { void onGenericNotification(String title, String details); - void onSetTime(long ts); + void onSetTime(); - void onSetAlarms(ArrayList alarms); + void onSetAlarms(ArrayList alarms); - void onSetCallState(String number, String name, ServiceCommand command); + void onSetCallState(@Nullable String number, @Nullable String name, ServiceCommand command); void onSetMusicInfo(String artist, String album, String track); - void onBatteryInfoReq(); - void onInstallApp(Uri uri); void onAppInfoReq(); @@ -38,8 +37,6 @@ public interface EventHandler { void onAppDelete(UUID uuid); - void onPhoneVersion(byte os); - void onFetchActivityData(); void onReboot(); 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 aba2ab631..ba756e496 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 @@ -12,6 +12,7 @@ import android.support.v4.content.LocalBroadcastManager; import android.widget.TextView; import android.widget.Toast; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter; import nodomain.freeyourgadget.gadgetbridge.devices.DeviceCoordinator; @@ -105,11 +106,7 @@ public class MiBandPairingActivity extends Activity { IntentFilter filter = new IntentFilter(GBDevice.ACTION_DEVICE_CHANGED); LocalBroadcastManager.getInstance(this).registerReceiver(mPairingReceiver, filter); - Intent serviceIntent = new Intent(this, DeviceCommunicationService.class); - serviceIntent.setAction(DeviceCommunicationService.ACTION_CONNECT); - serviceIntent.putExtra(DeviceCommunicationService.EXTRA_PERFORM_PAIR, true); - serviceIntent.putExtra(DeviceCommunicationService.EXTRA_DEVICE_ADDRESS, macAddress); - startService(serviceIntent); + GBApplication.deviceService().connect(macAddress, true); } private void pairingFinished(boolean pairedSuccessfully) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothStateChangeReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothStateChangeReceiver.java index 9d1681c35..b68eb5617 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothStateChangeReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/BluetoothStateChangeReceiver.java @@ -8,6 +8,7 @@ import android.content.SharedPreferences; import android.preference.PreferenceManager; import android.support.v4.content.LocalBroadcastManager; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenter; import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; @@ -27,12 +28,9 @@ public class BluetoothStateChangeReceiver extends BroadcastReceiver { return; } - Intent connectIntent = new Intent(context, DeviceCommunicationService.class); - connectIntent.setAction(DeviceCommunicationService.ACTION_CONNECT); - context.startService(connectIntent); + GBApplication.deviceService().connect(); } else if (intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1) == BluetoothAdapter.STATE_OFF) { - Intent stopIntent = new Intent(context, DeviceCommunicationService.class); - context.stopService(stopIntent); + GBApplication.deviceService().quit(); Intent quitIntent = new Intent(ControlCenter.ACTION_QUIT); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/K9Receiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/K9Receiver.java index afbe5baa9..519020f0b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/K9Receiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/K9Receiver.java @@ -12,7 +12,7 @@ import android.preference.PreferenceManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; public class K9Receiver extends BroadcastReceiver { @@ -65,12 +65,6 @@ public class K9Receiver extends BroadcastReceiver { } while (c.moveToNext()); c.close(); - Intent startIntent = new Intent(context, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_NOTIFICATION_EMAIL); - startIntent.putExtra("notification_sender", sender); - startIntent.putExtra("notification_subject", subject); - startIntent.putExtra("notification_body", preview); - - context.startService(startIntent); + GBApplication.deviceService().onEmail(sender, subject, preview); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/MusicPlaybackReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/MusicPlaybackReceiver.java index 45d957735..45ce6cda3 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/MusicPlaybackReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/MusicPlaybackReceiver.java @@ -7,7 +7,7 @@ import android.content.Intent; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; public class MusicPlaybackReceiver extends BroadcastReceiver { private static final Logger LOG = LoggerFactory.getLogger(MusicPlaybackReceiver.class); @@ -20,11 +20,6 @@ public class MusicPlaybackReceiver extends BroadcastReceiver { LOG.info("Current track: " + artist + ", " + album + ", " + track); - Intent startIntent = new Intent(context, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_SETMUSICINFO); - startIntent.putExtra("music_artist", artist); - startIntent.putExtra("music_album", album); - startIntent.putExtra("music_track", track); - context.startService(startIntent); + GBApplication.deviceService().onSetMusicInfo(artist, album, track); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java index 4865f027a..d046bd1ca 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/NotificationListener.java @@ -17,6 +17,7 @@ import android.support.v4.content.LocalBroadcastManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; public class NotificationListener extends NotificationListenerService { @@ -111,13 +112,8 @@ public class NotificationListener extends NotificationListenerService { } if (content != null) { - Intent startIntent = new Intent(NotificationListener.this, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_NOTIFICATION_GENERIC); - startIntent.putExtra("notification_title", title); - startIntent.putExtra("notification_body", content); - startService(startIntent); + GBApplication.deviceService().onGenericNotification(title, content); } - } private boolean isServiceRunning() { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PebbleReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PebbleReceiver.java index a74f995c4..78130230f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PebbleReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PebbleReceiver.java @@ -12,7 +12,7 @@ import org.json.JSONException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; public class PebbleReceiver extends BroadcastReceiver { @@ -51,11 +51,7 @@ public class PebbleReceiver extends BroadcastReceiver { } if (title != null && body != null) { - Intent startIntent = new Intent(context, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_NOTIFICATION_SMS); - startIntent.putExtra("notification_sender", title); - startIntent.putExtra("notification_body", body); - context.startService(startIntent); + GBApplication.deviceService().onSMS(title, body); } } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PhoneCallReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PhoneCallReceiver.java index c462c94b5..f19a84d99 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PhoneCallReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/PhoneCallReceiver.java @@ -5,7 +5,7 @@ import android.content.Context; import android.content.Intent; import android.telephony.TelephonyManager; -import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand; @@ -62,11 +62,7 @@ public class PhoneCallReceiver extends BroadcastReceiver { break; } if (callCommand != null) { - Intent startIntent = new Intent(context, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_CALLSTATE); - startIntent.putExtra("call_phonenumber", mSavedNumber); - startIntent.putExtra("call_command", callCommand.ordinal()); - context.startService(startIntent); + GBApplication.deviceService().onSetCallState(mSavedNumber, null, callCommand); } mLastState = state; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java index 599366cd2..72cff9990 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/SMSReceiver.java @@ -9,7 +9,7 @@ import android.os.PowerManager; import android.preference.PreferenceManager; import android.telephony.SmsMessage; -import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; public class SMSReceiver extends BroadcastReceiver { @@ -36,11 +36,7 @@ public class SMSReceiver extends BroadcastReceiver { String body = message.getDisplayMessageBody(); String sender = message.getOriginatingAddress(); if (sender != null && body != null) { - Intent startIntent = new Intent(context, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_NOTIFICATION_SMS); - startIntent.putExtra("notification_sender", sender); - startIntent.putExtra("notification_body", body); - context.startService(startIntent); + GBApplication.deviceService().onSMS(sender, body); } } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/TimeChangeReceiver.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/TimeChangeReceiver.java index 3142f24b6..eb91eec81 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/TimeChangeReceiver.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/externalevents/TimeChangeReceiver.java @@ -9,7 +9,7 @@ import android.preference.PreferenceManager; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; +import nodomain.freeyourgadget.gadgetbridge.GBApplication; public class TimeChangeReceiver extends BroadcastReceiver { @@ -23,9 +23,7 @@ public class TimeChangeReceiver extends BroadcastReceiver { if (sharedPrefs.getBoolean("datetime_synconconnect", true) && (action.equals(Intent.ACTION_TIME_CHANGED) || action.equals(Intent.ACTION_TIMEZONE_CHANGED))) { LOG.info("Time or Timezone changed, syncing with device"); - Intent startIntent = new Intent(context, DeviceCommunicationService.class); - startIntent.setAction(DeviceCommunicationService.ACTION_SETTIME); - context.startService(startIntent); + GBApplication.deviceService().onSetTime(); } } } \ No newline at end of file diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java new file mode 100644 index 000000000..3bb2415ec --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/impl/GBDeviceService.java @@ -0,0 +1,186 @@ +package nodomain.freeyourgadget.gadgetbridge.impl; + +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.support.annotation.Nullable; + +import java.util.ArrayList; +import java.util.UUID; + +import nodomain.freeyourgadget.gadgetbridge.model.Alarm; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceService; +import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand; + +public class GBDeviceService implements DeviceService { + protected final Context mContext; + protected final Class mServiceClass; + + public GBDeviceService(Context context, Class serviceClass) { + mContext = context; + mServiceClass = serviceClass; + } + + private Intent createIntent() { + Intent startIntent = new Intent(mContext, mServiceClass); + return startIntent; + } + + protected void invokeService(Intent intent) { + mContext.startService(intent); + } + + protected void stopService(Intent intent) { + mContext.stopService(intent); + } + + @Override + public void start() { + Intent intent = createIntent().setAction(ACTION_START); + invokeService(intent); + } + + @Override + public void connect() { + connect(null, false); + } + + @Override + public void connect(@Nullable String deviceAddress) { + connect(deviceAddress, false); + } + + @Override + public void connect(@Nullable String deviceAddress, boolean performPair) { + Intent intent = createIntent().setAction(ACTION_CONNECT) + .putExtra(EXTRA_DEVICE_ADDRESS, deviceAddress) + .putExtra(EXTRA_PERFORM_PAIR, performPair); + invokeService(intent); + } + + @Override + public void disconnect() { + Intent intent = createIntent().setAction(ACTION_DISCONNECT); + invokeService(intent); + } + + @Override + public void quit() { + Intent intent = createIntent(); + stopService(intent); + } + + @Override + public void requestDeviceInfo() { + Intent intent = createIntent().setAction(ACTION_REQUEST_DEVICEINFO); + invokeService(intent); + } + + @Override + public void onSMS(String from, String body) { + Intent intent = createIntent().setAction(ACTION_NOTIFICATION_SMS) + .putExtra(EXTRA_NOTIFICATION_SENDER, from) + .putExtra(EXTRA_NOTIFICATION_BODY, body); + invokeService(intent); + } + + @Override + public void onEmail(String from, String subject, String body) { + Intent intent = createIntent().setAction(ACTION_NOTIFICATION_EMAIL) + .putExtra(EXTRA_NOTIFICATION_SENDER, from) + .putExtra(EXTRA_NOTIFICATION_SUBJECT, subject) + .putExtra(EXTRA_NOTIFICATION_BODY, body); + invokeService(intent); + } + + @Override + public void onGenericNotification(String title, String details) { + Intent intent = createIntent().setAction(ACTION_NOTIFICATION_GENERIC) + .putExtra(EXTRA_NOTIFICATION_TITLE, title) + .putExtra(EXTRA_NOTIFICATION_BODY, details); + invokeService(intent); + } + + @Override + public void onSetTime() { + Intent intent = createIntent().setAction(ACTION_SETTIME); + invokeService(intent); + } + + @Override + public void onSetAlarms(ArrayList alarms) { + Intent intent = createIntent().setAction(ACTION_SET_ALARMS) + .putParcelableArrayListExtra(EXTRA_ALARMS, alarms); + invokeService(intent); + } + + @Override + public void onSetCallState(String number, String name, ServiceCommand command) { + // name is actually ignored and provided by the service itself... + Intent intent = createIntent().setAction(ACTION_CALLSTATE) + .putExtra(EXTRA_CALL_PHONENUMBER, number) + .putExtra(EXTRA_CALL_COMMAND, command); + invokeService(intent); + } + + @Override + public void onSetMusicInfo(String artist, String album, String track) { + Intent intent = createIntent().setAction(ACTION_SETMUSICINFO) + .putExtra(EXTRA_MUSIC_ARTIST, artist) + .putExtra(EXTRA_MUSIC_TRACK, track); + invokeService(intent); + } + + @Override + public void onInstallApp(Uri uri) { + Intent intent = createIntent().setAction(ACTION_INSTALL) + .putExtra(EXTRA_URI, uri); + invokeService(intent); + } + + @Override + public void onAppInfoReq() { + Intent intent = createIntent().setAction(ACTION_REQUEST_APPINFO); + invokeService(intent); + } + + @Override + public void onAppStart(UUID uuid) { + Intent intent = createIntent().setAction(ACTION_STARTAPP) + .putExtra(EXTRA_APP_UUID, uuid); + invokeService(intent); + } + + @Override + public void onAppDelete(UUID uuid) { + Intent intent = createIntent().setAction(ACTION_DELETEAPP) + .putExtra(EXTRA_APP_UUID, uuid); + invokeService(intent); + } + + @Override + public void onFetchActivityData() { + Intent intent = createIntent().setAction(ACTION_FETCH_ACTIVITY_DATA); + invokeService(intent); + } + + @Override + public void onReboot() { + Intent intent = createIntent().setAction(ACTION_REBOOT); + invokeService(intent); + } + + @Override + public void onFindDevice(boolean start) { + Intent intent = createIntent().setAction(ACTION_FIND_DEVICE) + .putExtra(EXTRA_APP_UUID, start); + invokeService(intent); + } + + @Override + public void onScreenshotReq() { + Intent intent = createIntent().setAction(ACTION_REQUEST_SCREENSHOT); + invokeService(intent); + } +} diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java new file mode 100644 index 000000000..05d3281eb --- /dev/null +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/model/DeviceService.java @@ -0,0 +1,68 @@ +package nodomain.freeyourgadget.gadgetbridge.model; + +import android.support.annotation.Nullable; + +import nodomain.freeyourgadget.gadgetbridge.devices.EventHandler; +import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; + +/** + * + */ +public interface DeviceService extends EventHandler { + static final String PREFIX = "nodomain.freeyourgadget.gadgetbridge.devices"; + + static final String ACTION_START = PREFIX + ".action.start"; + static final String ACTION_CONNECT = PREFIX + ".action.connect"; + static final String ACTION_NOTIFICATION_GENERIC = PREFIX + ".action.notification_generic"; + static final String ACTION_NOTIFICATION_SMS = PREFIX + ".action.notification_sms"; + static final String ACTION_NOTIFICATION_EMAIL = PREFIX + ".action.notification_email"; + static final String ACTION_CALLSTATE = PREFIX + ".action.callstate"; + static final String ACTION_SETTIME = PREFIX + ".action.settime"; + static final String ACTION_SETMUSICINFO = PREFIX + ".action.setmusicinfo"; + static final String ACTION_REQUEST_DEVICEINFO = PREFIX + ".action.request_deviceinfo"; + static final String ACTION_REQUEST_APPINFO = PREFIX + ".action.request_appinfo"; + static final String ACTION_REQUEST_SCREENSHOT = PREFIX + ".action.request_screenshot"; + static final String ACTION_STARTAPP = PREFIX + ".action.startapp"; + static final String ACTION_DELETEAPP = PREFIX + ".action.deleteapp"; + static final String ACTION_INSTALL = PREFIX + ".action.install"; + static final String ACTION_REBOOT = PREFIX + ".action.reboot"; + static final String ACTION_FETCH_ACTIVITY_DATA = PREFIX + ".action.fetch_activity_data"; + static final String ACTION_DISCONNECT = PREFIX + ".action.disconnect"; + static final String ACTION_FIND_DEVICE = PREFIX + ".action.find_device"; + static final String ACTION_SET_ALARMS = PREFIX + ".action.set_alarms"; + + static final String EXTRA_DEVICE_ADDRESS = "device_address"; + static final String EXTRA_NOTIFICATION_TITLE = "notification_title"; + static final String EXTRA_NOTIFICATION_BODY = "notification_body"; + static final String EXTRA_NOTIFICATION_SENDER = "notification_sender"; + static final String EXTRA_NOTIFICATION_SUBJECT = "notification_subject"; + static final String EXTRA_FIND_START = "find_start"; + static final String EXTRA_CALL_COMMAND = "call_command"; + static final String EXTRA_CALL_PHONENUMBER = "call_phonenumber"; + static final String EXTRA_MUSIC_ARTIST = "music_artist"; + static final String EXTRA_MUSIC_ALBUM = "music_album"; + static final String EXTRA_MUSIC_TRACK = "music_track"; + static final String EXTRA_APP_UUID = "app_uuid"; + static final String EXTRA_URI = "uri"; + static final String EXTRA_ALARMS = "alarms"; + static final String EXTRA_PERFORM_PAIR = "perform_pair"; + + + + void start(); + + void connect(); + void connect(@Nullable String deviceAddress); + void connect(@Nullable String deviceAddress, boolean performPair); + void disconnect(); + + void quit(); + /** + * Requests information from the {@link DeviceCommunicationService} about the connection state, + * firmware info, etc. + *

+ * Note that this will not need a connection to the device -- only the cached information + * from the service will be reported. + */ + void requestDeviceInfo(); +} 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 a5d8ee9c3..c91200a74 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/DeviceCommunicationService.java @@ -27,46 +27,10 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand; import nodomain.freeyourgadget.gadgetbridge.util.GB; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.*; public class DeviceCommunicationService extends Service { - public static final String ACTION_START - = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.start"; - public static final String ACTION_CONNECT - = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.connect"; - public static final String ACTION_NOTIFICATION_GENERIC - = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.notification_generic"; - public static final String ACTION_NOTIFICATION_SMS - = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.notification_sms"; - public static final String ACTION_NOTIFICATION_EMAIL - = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.notification_email"; - public static final String ACTION_CALLSTATE - = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.callstate"; - public static final String ACTION_SETTIME - = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.settime"; - public static final String ACTION_SETMUSICINFO - = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.setmusicinfo"; - public static final String ACTION_REQUEST_DEVICEINFO - = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.request_deviceinfo"; - public static final String ACTION_REQUEST_APPINFO - = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.request_appinfo"; - public static final String ACTION_REQUEST_SCREENSHOT - = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.request_screenshot"; - public static final String ACTION_STARTAPP - = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.startapp"; - public static final String ACTION_DELETEAPP - = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.deleteapp"; - public static final String ACTION_INSTALL - = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.install"; - public static final String ACTION_REBOOT = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.reboot"; - public static final String ACTION_FETCH_ACTIVITY_DATA = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.fetch_activity_data"; - public static final String ACTION_DISCONNECT = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.disconnect"; - public static final String ACTION_FIND_DEVICE = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.find_device"; - public static final String ACTION_SET_ALARMS = "nodomain.freeyourgadget.gadgetbridge.devicecommunicationservice.action.set_alarms"; - - public static final String EXTRA_PERFORM_PAIR = "perform_pair"; - private static final Logger LOG = LoggerFactory.getLogger(DeviceCommunicationService.class); - public static final String EXTRA_DEVICE_ADDRESS = "device_address"; private boolean mStarted = false; @@ -179,22 +143,22 @@ public class DeviceCommunicationService extends Service { mGBDevice.sendDeviceUpdateIntent(this); break; case ACTION_NOTIFICATION_GENERIC: { - String title = intent.getStringExtra("notification_title"); - String body = intent.getStringExtra("notification_body"); + String title = intent.getStringExtra(EXTRA_NOTIFICATION_TITLE); + String body = intent.getStringExtra(EXTRA_NOTIFICATION_BODY); mDeviceSupport.onGenericNotification(title, body); break; } case ACTION_NOTIFICATION_SMS: { - String sender = intent.getStringExtra("notification_sender"); - String body = intent.getStringExtra("notification_body"); + String sender = intent.getStringExtra(EXTRA_NOTIFICATION_SENDER); + String body = intent.getStringExtra(EXTRA_NOTIFICATION_BODY); String senderName = getContactDisplayNameByNumber(sender); mDeviceSupport.onSMS(senderName, body); break; } case ACTION_NOTIFICATION_EMAIL: { - String sender = intent.getStringExtra("notification_sender"); - String subject = intent.getStringExtra("notification_subject"); - String body = intent.getStringExtra("notification_body"); + String sender = intent.getStringExtra(EXTRA_NOTIFICATION_SENDER); + String subject = intent.getStringExtra(EXTRA_NOTIFICATION_SUBJECT); + String body = intent.getStringExtra(EXTRA_NOTIFICATION_BODY); mDeviceSupport.onEmail(sender, subject, body); break; } @@ -212,14 +176,14 @@ public class DeviceCommunicationService extends Service { break; } case ACTION_FIND_DEVICE: { - boolean start = intent.getBooleanExtra("find_start", false); + boolean start = intent.getBooleanExtra(EXTRA_FIND_START, false); mDeviceSupport.onFindDevice(start); break; } case ACTION_CALLSTATE: - ServiceCommand command = ServiceCommand.values()[intent.getIntExtra("call_command", 0)]; // UGLY + ServiceCommand command = (ServiceCommand) intent.getSerializableExtra(EXTRA_CALL_COMMAND); - String phoneNumber = intent.getStringExtra("call_phonenumber"); + String phoneNumber = intent.getStringExtra(EXTRA_CALL_PHONENUMBER); String callerName = null; if (phoneNumber != null) { callerName = getContactDisplayNameByNumber(phoneNumber); @@ -227,12 +191,12 @@ public class DeviceCommunicationService extends Service { mDeviceSupport.onSetCallState(phoneNumber, callerName, command); break; case ACTION_SETTIME: - mDeviceSupport.onSetTime(-1); + mDeviceSupport.onSetTime(); break; case ACTION_SETMUSICINFO: - String artist = intent.getStringExtra("music_artist"); - String album = intent.getStringExtra("music_album"); - String track = intent.getStringExtra("music_track"); + String artist = intent.getStringExtra(EXTRA_MUSIC_ARTIST); + String album = intent.getStringExtra(EXTRA_MUSIC_ALBUM); + String track = intent.getStringExtra(EXTRA_MUSIC_TRACK); mDeviceSupport.onSetMusicInfo(artist, album, track); break; case ACTION_REQUEST_APPINFO: @@ -241,23 +205,25 @@ public class DeviceCommunicationService extends Service { case ACTION_REQUEST_SCREENSHOT: mDeviceSupport.onScreenshotReq(); break; - case ACTION_STARTAPP: - UUID uuid = UUID.fromString(intent.getStringExtra("app_uuid")); + case ACTION_STARTAPP: { + UUID uuid = (UUID) intent.getSerializableExtra(EXTRA_APP_UUID); mDeviceSupport.onAppStart(uuid); break; - case ACTION_DELETEAPP: - uuid = UUID.fromString(intent.getStringExtra("app_uuid")); + } + case ACTION_DELETEAPP: { + UUID uuid = (UUID) intent.getSerializableExtra(EXTRA_APP_UUID); mDeviceSupport.onAppDelete(uuid); break; + } case ACTION_INSTALL: - Uri uri = intent.getParcelableExtra("uri"); + Uri uri = intent.getParcelableExtra(EXTRA_URI); if (uri != null) { LOG.info("will try to install app/fw"); mDeviceSupport.onInstallApp(uri); } break; case ACTION_SET_ALARMS: - ArrayList alarms = intent.getParcelableArrayListExtra("alarms"); + ArrayList alarms = intent.getParcelableArrayListExtra(EXTRA_ALARMS); mDeviceSupport.onSetAlarms(alarms); break; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java index 4e87fd172..a659dc458 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/ServiceDeviceSupport.java @@ -11,9 +11,9 @@ import java.util.ArrayList; import java.util.EnumSet; import java.util.UUID; -import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.Alarm; +import nodomain.freeyourgadget.gadgetbridge.model.ServiceCommand; /** * Wraps another device support instance and supports busy-checking and throttling of events. @@ -135,11 +135,11 @@ public class ServiceDeviceSupport implements DeviceSupport { } @Override - public void onSetTime(long ts) { + public void onSetTime() { if (checkBusy("set time") || checkThrottle("set time")) { return; } - delegate.onSetTime(ts); + delegate.onSetTime(); } // No throttling for the other events @@ -160,14 +160,6 @@ public class ServiceDeviceSupport implements DeviceSupport { delegate.onSetMusicInfo(artist, album, track); } - @Override - public void onBatteryInfoReq() { - if (checkBusy("battery info request")) { - return; - } - delegate.onBatteryInfoReq(); - } - @Override public void onInstallApp(Uri uri) { if (checkBusy("install app")) { @@ -200,14 +192,6 @@ public class ServiceDeviceSupport implements DeviceSupport { delegate.onAppDelete(uuid); } - @Override - public void onPhoneVersion(byte os) { - if (checkBusy("phone version")) { - return; - } - delegate.onPhoneVersion(os); - } - @Override public void onFetchActivityData() { if (checkBusy("fetch activity data")) { @@ -241,7 +225,7 @@ public class ServiceDeviceSupport implements DeviceSupport { } @Override - public void onSetAlarms(ArrayList alarms) { + public void onSetAlarms(ArrayList alarms) { if (checkBusy("set alarms")) { return; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java index 8c8e3cea9..b191b450d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/miband/MiBandSupport.java @@ -379,7 +379,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { } @Override - public void onSetAlarms(ArrayList alarms) { + public void onSetAlarms(ArrayList alarms) { try { BluetoothGattCharacteristic characteristic = getCharacteristic(MiBandService.UUID_CHARACTERISTIC_CONTROL_POINT); TransactionBuilder builder = performInitialized("Set alarm"); @@ -410,7 +410,7 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { } @Override - public void onSetTime(long ts) { + public void onSetTime() { try { TransactionBuilder builder = performInitialized("Set date and time"); setCurrentTime(builder); @@ -476,17 +476,6 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { // not supported } - @Override - public void onBatteryInfoReq() { - try { - TransactionBuilder builder = performInitialized("Get MI Band battery info"); - requestBatteryInfo(builder); - builder.queue(getQueue()); - } catch (IOException ex) { - LOG.error("Unable to read battery info from MI", ex); - } - } - @Override public void onReboot() { try { @@ -584,11 +573,6 @@ public class MiBandSupport extends AbstractBTLEDeviceSupport { // not supported } - @Override - public void onPhoneVersion(byte os) { - // not supported - } - @Override public void onScreenshotReq() { // not supported diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java index 68758bf2e..79b56c1e2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java @@ -320,7 +320,7 @@ public class PebbleIoThread extends GBDeviceIoThread { SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getContext()); if (sharedPrefs.getBoolean("datetime_synconconnect", true)) { LOG.info("syncing time"); - write(mPebbleProtocol.encodeSetTime(-1)); + write(mPebbleProtocol.encodeSetTime()); } gbDevice.setState(GBDevice.State.INITIALIZED); return false; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java index 4b38b3d02..3adf245a1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java @@ -299,10 +299,8 @@ public class PebbleProtocol extends GBDeviceProtocol { } @Override - public byte[] encodeSetTime(long ts) { - if (ts == -1) { - ts = System.currentTimeMillis(); - } + public byte[] encodeSetTime() { + long ts = System.currentTimeMillis(); long ts_offset = (SimpleTimeZone.getDefault().getOffset(ts)); ByteBuffer buf; if (isFw3x) { @@ -701,7 +699,6 @@ public class PebbleProtocol extends GBDeviceProtocol { return buf.array(); } - @Override public byte[] encodePhoneVersion(byte os) { return encodePhoneVersion3x(os); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleSupport.java index 0d2f26ab9..590bbb1df 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleSupport.java @@ -43,7 +43,7 @@ public class PebbleSupport extends AbstractSerialDeviceSupport { } @Override - public void onSetAlarms(ArrayList alarms) { + public void onSetAlarms(ArrayList alarms) { //nothing to do ATM } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java index 9220a6b3a..387e8111b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/AbstractSerialDeviceSupport.java @@ -129,8 +129,8 @@ public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport } @Override - public void onSetTime(long ts) { - byte[] bytes = gbDeviceProtocol.encodeSetTime(ts); + public void onSetTime() { + byte[] bytes = gbDeviceProtocol.encodeSetTime(); sendToDevice(bytes); } @@ -146,12 +146,6 @@ public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport sendToDevice(bytes); } - @Override - public void onBatteryInfoReq() { - byte[] bytes = gbDeviceProtocol.encodeBatteryInfoReq(); - sendToDevice(bytes); - } - @Override public void onAppInfoReq() { byte[] bytes = gbDeviceProtocol.encodeAppInfoReq(); @@ -170,12 +164,6 @@ public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport sendToDevice(bytes); } - @Override - public void onPhoneVersion(byte os) { - byte[] bytes = gbDeviceProtocol.encodePhoneVersion(os); - sendToDevice(bytes); - } - @Override public void onFetchActivityData() { byte[] bytes = gbDeviceProtocol.encodeSynchronizeActivityData(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java index b5fe9ba77..20133c3b9 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/serial/GBDeviceProtocol.java @@ -19,7 +19,7 @@ public abstract class GBDeviceProtocol { return null; } - public byte[] encodeSetTime(long ts) { + public byte[] encodeSetTime() { return null; } @@ -35,10 +35,6 @@ public abstract class GBDeviceProtocol { return null; } - public byte[] encodeBatteryInfoReq() { - return null; - } - public byte[] encodeAppInfoReq() { return null; } @@ -55,10 +51,6 @@ public abstract class GBDeviceProtocol { return null; } - public byte[] encodePhoneVersion(byte os) { - return null; - } - public byte[] encodeSynchronizeActivityData() { return null; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java index b7fa7c016..0a46040a0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java @@ -14,8 +14,6 @@ import android.os.Looper; import android.support.v4.app.NotificationCompat; import android.widget.Toast; -import com.github.pfichtner.durationformatter.DurationFormatter; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -24,11 +22,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import java.text.DateFormat; -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.concurrent.TimeUnit; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; From 2b0acd649b916d753a52474d5456f6550cfd4922 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Fri, 21 Aug 2015 13:18:53 +0200 Subject: [PATCH 5/8] Pebble: close TCP socket when disconnecting from emulator. Prevents hang. --- .../service/devices/pebble/PebbleIoThread.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java index 79b56c1e2..281995296 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleIoThread.java @@ -502,6 +502,13 @@ public class PebbleIoThread extends GBDeviceIoThread { e.printStackTrace(); } } + if (mTCPSocket != null) { + try { + mTCPSocket.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } } private enum PebbleAppInstallState { From 6e8097899801f0c93942705c01c30a18630c192e Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Fri, 21 Aug 2015 14:29:12 +0200 Subject: [PATCH 6/8] Pebble: Add generic method for Blobdb endpoint for deduplicating code. --- .../devices/pebble/PebbleProtocol.java | 108 ++++++++---------- 1 file changed, 48 insertions(+), 60 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java index 3adf245a1..e0271d4a0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java @@ -178,6 +178,7 @@ public class PebbleProtocol extends GBDeviceProtocol { static final short LENGTH_APPFETCH = 2; static final short LENGTH_APPRUNSTATE = 17; + static final short LENGTH_BLOBDB = 21; static final short LENGTH_PING = 5; static final short LENGTH_PHONEVERSION = 17; static final short LENGTH_REMOVEAPP_2X = 17; @@ -396,6 +397,37 @@ public class PebbleProtocol extends GBDeviceProtocol { return buf.array(); } + private byte[] encodeBlobdb(UUID uuid, byte command, byte db, byte[] blob) { + + int length = LENGTH_BLOBDB; + if (blob != null) { + length += blob.length + 2; + } + + ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + length); + + buf.order(ByteOrder.BIG_ENDIAN); + buf.putShort((short) length); + buf.putShort(ENDPOINT_BLOBDB); + + buf.order(ByteOrder.LITTLE_ENDIAN); + buf.put(command); + buf.putShort((short) mRandom.nextInt()); // token + buf.put(db); + buf.put(LENGTH_UUID); + buf.order(ByteOrder.BIG_ENDIAN); + buf.putLong(uuid.getMostSignificantBits()); + buf.putLong(uuid.getLeastSignificantBits()); + buf.order(ByteOrder.LITTLE_ENDIAN); + + if (blob != null) { + buf.putShort((short) blob.length); + buf.put(blob); + } + + return buf.array(); + } + private byte[] encodeBlobdbNotification(int timestamp, String title, String subtitle, String body, byte type) { String[] parts = {title, subtitle, body}; @@ -408,7 +440,6 @@ public class PebbleProtocol extends GBDeviceProtocol { icon_id = 45; } // Calculate length first - final short BLOBDB_LENGTH = 23; final short NOTIFICATION_PIN_LENGTH = 46; final short ACTIONS_LENGTH = 17; @@ -432,31 +463,18 @@ public class PebbleProtocol extends GBDeviceProtocol { attributes_length += ACTIONS_LENGTH; } - short length = (short) (BLOBDB_LENGTH + NOTIFICATION_PIN_LENGTH + attributes_length); + UUID uuid = UUID.randomUUID(); short pin_length = (short) (NOTIFICATION_PIN_LENGTH + attributes_length); - // Encode Prefix - ByteBuffer buf = ByteBuffer.allocate(length + LENGTH_PREFIX); - - buf.order(ByteOrder.BIG_ENDIAN); - buf.putShort(length); - buf.putShort(ENDPOINT_BLOBDB); - - buf.order(ByteOrder.LITTLE_ENDIAN); - - // blobdb - 23 bytes - buf.put(BLOBDB_INSERT); - buf.putShort((short) mRandom.nextInt()); // token - buf.put(BLOBDB_NOTIFICATION); - buf.put(LENGTH_UUID); // uuid length - byte[] uuid_buf = new byte[LENGTH_UUID]; - mRandom.nextBytes(uuid_buf); - buf.put(uuid_buf); // random UUID - buf.putShort(pin_length); // length of the encapsulated data + ByteBuffer buf = ByteBuffer.allocate(pin_length); // pin - 46 bytes - buf.put(uuid_buf); // random UUID - buf.put(uuid_buf); // parent UUID + buf.order(ByteOrder.BIG_ENDIAN); + buf.putLong(uuid.getMostSignificantBits()); + buf.putLong(uuid.getLeastSignificantBits()); + buf.putLong(uuid.getMostSignificantBits()); + buf.putLong(uuid.getLeastSignificantBits()); + buf.order(ByteOrder.LITTLE_ENDIAN); buf.putInt(timestamp); // 32-bit timestamp buf.putShort((short) 0); // duration buf.put((byte) 0x01); // type (0x01 = notification) @@ -498,36 +516,16 @@ public class PebbleProtocol extends GBDeviceProtocol { buf.put(actionstring.getBytes()); } - return buf.array(); + return encodeBlobdb(UUID.randomUUID(), BLOBDB_INSERT, BLOBDB_NOTIFICATION, buf.array()); } public byte[] encodeInstallMetadata(UUID uuid, String appName, short appVersion, short sdkVersion, int flags, int iconId) { - // Calculate length first - final short BLOBDB_LENGTH = 23; final short METADATA_LENGTH = 126; - final short length = (short) (BLOBDB_LENGTH + METADATA_LENGTH); - byte[] name_buf = new byte[96]; System.arraycopy(appName.getBytes(), 0, name_buf, 0, appName.length()); - ByteBuffer buf = ByteBuffer.allocate(length + LENGTH_PREFIX); + ByteBuffer buf = ByteBuffer.allocate(METADATA_LENGTH); - // Encode Prefix - buf.order(ByteOrder.BIG_ENDIAN); - buf.putShort(length); - buf.putShort(ENDPOINT_BLOBDB); - - buf.order(ByteOrder.LITTLE_ENDIAN); - // blobdb - 23 bytes - buf.put(BLOBDB_INSERT); // insert - buf.putShort((short) mRandom.nextInt()); // token - buf.put(BLOBDB_APP); - buf.put(LENGTH_UUID); - buf.order(ByteOrder.BIG_ENDIAN); - buf.putLong(uuid.getMostSignificantBits()); // watchapp uuid - buf.putLong(uuid.getLeastSignificantBits()); - buf.order(ByteOrder.LITTLE_ENDIAN); - buf.putShort(METADATA_LENGTH); // length of the encapsulated data buf.order(ByteOrder.BIG_ENDIAN); buf.putLong(uuid.getMostSignificantBits()); // watchapp uuid buf.putLong(uuid.getLeastSignificantBits()); @@ -540,7 +538,7 @@ public class PebbleProtocol extends GBDeviceProtocol { buf.put((byte) 0); // app_face_template_id buf.put(name_buf); // 96 bytes - return buf.array(); + return encodeBlobdb(uuid, BLOBDB_INSERT, BLOBDB_APP, buf.array()); } public byte[] encodeAppFetchAck() { @@ -628,28 +626,18 @@ public class PebbleProtocol extends GBDeviceProtocol { @Override public byte[] encodeAppDelete(UUID uuid) { - ByteBuffer buf; if (isFw3x) { - buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_REMOVEAPP_3X); - buf.order(ByteOrder.BIG_ENDIAN); - buf.putShort(LENGTH_REMOVEAPP_3X); - buf.putShort(ENDPOINT_BLOBDB); - buf.order(ByteOrder.LITTLE_ENDIAN); - buf.put(BLOBDB_DELETE); - buf.putShort((short) mRandom.nextInt()); // token - buf.put(BLOBDB_APP); - buf.put(LENGTH_UUID); - buf.order(ByteOrder.BIG_ENDIAN); + return encodeBlobdb(uuid, BLOBDB_DELETE, BLOBDB_APP, null); } else { - buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_REMOVEAPP_2X); + ByteBuffer buf = ByteBuffer.allocate(LENGTH_PREFIX + LENGTH_REMOVEAPP_2X); buf.order(ByteOrder.BIG_ENDIAN); buf.putShort(LENGTH_REMOVEAPP_2X); buf.putShort(ENDPOINT_APPMANAGER); buf.put(APPMANAGER_REMOVEAPP); + buf.putLong(uuid.getMostSignificantBits()); + buf.putLong(uuid.getLeastSignificantBits()); + return buf.array(); } - buf.putLong(uuid.getMostSignificantBits()); - buf.putLong(uuid.getLeastSignificantBits()); - return buf.array(); } private byte[] encodePhoneVersion2x(byte os) { From df417e5c6cc2cf49bf7b4e976ef5ea6b0857aab2 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Fri, 21 Aug 2015 15:23:48 +0200 Subject: [PATCH 7/8] Fix bug regarding setting wear location. Closes #95 --- .../gadgetbridge/devices/miband/MiBandCoordinator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a2f9cc9b9..3c33cb090 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 @@ -120,7 +120,7 @@ public class MiBandCoordinator implements DeviceCoordinator { public static int getWearLocation(String miBandAddress) throws IllegalArgumentException { int location = 0; //left hand SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(GBApplication.getContext()); - if (prefs.getString(MiBandConst.PREF_MIBAND_WEARSIDE, "left") == "right") { + if ("right".equals(prefs.getString(MiBandConst.PREF_MIBAND_WEARSIDE, "left"))) { location = 1; // right hand } return location; From 12337836bce9b6bdb66bee51b1bc6597f53c2b71 Mon Sep 17 00:00:00 2001 From: Andreas Shimokawa Date: Fri, 21 Aug 2015 16:06:23 +0200 Subject: [PATCH 8/8] bump version, update CHANGELOG.md --- CHANGELOG.md | 3 ++- app/build.gradle | 4 ++-- .../gadgetbridge/service/devices/pebble/PebbleProtocol.java | 3 +-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 35ae1483b..059f79567 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ###Changelog -####Version (next) +####Version 0.5.0 +* Mi Band: fix setting wear location * Pebble: experimental watchapp installation support for FW 3.x/Pebble Time * Pebble: support Pebble emulator via TCP connection (needs rebuild with INTERNET permission) * Pebble: use SMS/EMAIL icons for FW 3.x/Pebble Time diff --git a/app/build.gradle b/app/build.gradle index a3e33c2b4..899f5c545 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -12,8 +12,8 @@ android { applicationId "nodomain.freeyourgadget.gadgetbridge" minSdkVersion 19 targetSdkVersion 21 - versionCode 20 - versionName "0.4.6" + versionCode 21 + versionName "0.5.0" } buildTypes { release { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java index e0271d4a0..82329a9fc 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/pebble/PebbleProtocol.java @@ -38,7 +38,7 @@ public class PebbleProtocol extends GBDeviceProtocol { static final short ENDPOINT_PHONECONTROL = 33; static final short ENDPOINT_APPLICATIONMESSAGE = 48; static final short ENDPOINT_LAUNCHER = 49; - static final short ENDPOINT_APPRUNSTATE = 52; + static final short ENDPOINT_APPRUNSTATE = 52; // 3.x only static final short ENDPOINT_LOGS = 2000; static final short ENDPOINT_PING = 2001; static final short ENDPOINT_LOGDUMP = 2002; @@ -182,7 +182,6 @@ public class PebbleProtocol extends GBDeviceProtocol { static final short LENGTH_PING = 5; static final short LENGTH_PHONEVERSION = 17; static final short LENGTH_REMOVEAPP_2X = 17; - static final short LENGTH_REMOVEAPP_3X = 21; static final short LENGTH_REFRESHAPP = 5; static final short LENGTH_SETTIME = 5; static final short LENGTH_SYSTEMMESSAGE = 2;