From ec1f4505bdcad6a8de405b0e446769878632a728 Mon Sep 17 00:00:00 2001 From: Daniele Gobbetti Date: Sat, 17 Mar 2018 18:50:53 +0100 Subject: [PATCH] Pebble: prevent crashing when the ExternalPebbleJS Activity was not running when receiving configuration data from the external browser. Parse the passed data to load the correct watchface javascript, and ensure the currently connected device is a Pebble (and try to reconnect if there is no device connected, as a bonus) --- .../activities/ExternalPebbleJSActivity.java | 75 ++++++++++++++++--- .../gadgetbridge/util/WebViewSingleton.java | 7 ++ 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ExternalPebbleJSActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ExternalPebbleJSActivity.java index 7da2f0c383..fe3914d1af 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ExternalPebbleJSActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/ExternalPebbleJSActivity.java @@ -34,19 +34,26 @@ import android.widget.Toast; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.List; import java.util.Objects; import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.R; +import nodomain.freeyourgadget.gadgetbridge.devices.DeviceManager; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.DeviceService; +import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; +import nodomain.freeyourgadget.gadgetbridge.service.DeviceCommunicationService; import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.webview.GBChromeClient; import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.webview.GBWebClient; import nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.webview.JSInterface; +import nodomain.freeyourgadget.gadgetbridge.util.DeviceHelper; import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.WebViewSingleton; +import static nodomain.freeyourgadget.gadgetbridge.model.DeviceService.ACTION_CONNECT; + public class ExternalPebbleJSActivity extends AbstractGBActivity { private static final Logger LOG = LoggerFactory.getLogger(ExternalPebbleJSActivity.class); @@ -64,24 +71,69 @@ public class ExternalPebbleJSActivity extends AbstractGBActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Bundle extras = getIntent().getExtras(); + + boolean showConfig = false; + + UUID currentUUID = null; + GBDevice currentDevice = null; + if (extras == null) { - throw new IllegalArgumentException("Must provide device and uuid in extras when invoking this activity"); - } + confUri = getIntent().getData(); + if(confUri.getScheme().equals("gadgetbridge")) { + try { + currentUUID = UUID.fromString(confUri.getHost()); + } catch (IllegalArgumentException e) { + LOG.error("UUID in incoming configuration is not a valid UUID: " +confUri.toString()); + } - if (extras.getBoolean(START_BG_WEBVIEW, false)) { - startBackgroundWebViewAndFinish(); - return; - } + //first check if we are still connected to a pebble + DeviceManager deviceManager = ((GBApplication) getApplication()).getDeviceManager(); + List deviceList = deviceManager.getDevices(); + for (GBDevice device : deviceList) { + if (device.getState() == GBDevice.State.INITIALIZED) { + if (device.getType().equals(DeviceType.PEBBLE)) { + currentDevice = device; + break; + } else { + LOG.error("attempting to load pebble configuration but a different device type is connected!!!"); + finish(); + return; + } + } + } + if (currentDevice == null) { + //then try to reconnect to last connected device + String btDeviceAddress = GBApplication.getPrefs().getPreferences().getString("last_device_address", null); + if (btDeviceAddress != null) { + GBDevice candidate = DeviceHelper.getInstance().findAvailableDevice(btDeviceAddress, this); + if(!candidate.isConnected() && candidate.getType() == DeviceType.PEBBLE){ + Intent intent = new Intent(this, DeviceCommunicationService.class) + .setAction(ACTION_CONNECT) + .putExtra(GBDevice.EXTRA_DEVICE, currentDevice); + this.startService(intent); + currentDevice = candidate; + } + } + } - GBDevice currentDevice = extras.getParcelable(GBDevice.EXTRA_DEVICE); - UUID currentUUID = (UUID) extras.getSerializable(DeviceService.EXTRA_APP_UUID); + showConfig = true; //we are getting incoming configuration data + } + } else { + currentDevice = extras.getParcelable(GBDevice.EXTRA_DEVICE); + currentUUID = (UUID) extras.getSerializable(DeviceService.EXTRA_APP_UUID); + + if (extras.getBoolean(START_BG_WEBVIEW, false)) { + startBackgroundWebViewAndFinish(); + return; + } + showConfig = extras.getBoolean(SHOW_CONFIG, false); + } if (GBApplication.getGBPrefs().isBackgroundJsEnabled()) { - if (extras.getBoolean(SHOW_CONFIG, false)) { + if (showConfig) { Objects.requireNonNull(currentDevice, "Must provide a device when invoking this activity"); Objects.requireNonNull(currentUUID, "Must provide a uuid when invoking this activity"); - - WebViewSingleton.runJavascriptInterface(currentDevice, currentUUID); + WebViewSingleton.runJavascriptInterface(this, currentDevice, currentUUID); } // FIXME: is this really supposed to be outside the check for SHOW_CONFIG? @@ -161,6 +213,7 @@ public class ExternalPebbleJSActivity extends AbstractGBActivity { } catch (IllegalArgumentException e) { GB.toast("returned uri: " + confUri.toString(), Toast.LENGTH_LONG, GB.ERROR); } + myWebView.stopLoading(); myWebView.loadUrl("file:///android_asset/app_config/configure.html?" + queryString); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/WebViewSingleton.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/WebViewSingleton.java index 75c01f2202..261cddddb4 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/WebViewSingleton.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/WebViewSingleton.java @@ -156,6 +156,13 @@ public class WebViewSingleton { } } + public static void runJavascriptInterface(@NonNull Activity context, @NonNull GBDevice device, @NonNull UUID uuid) { + if (webViewSingleton.instance == null || webViewSingleton.contextWrapper == null) { + ensureCreated(context); + } + runJavascriptInterface(device, uuid); + } + public static void runJavascriptInterface(@NonNull GBDevice device, @NonNull UUID uuid) { if (uuid.equals(currentRunningUUID)) { LOG.debug("WEBVIEW uuid not changed keeping the old context");