From 60f805f15cd646f54530f6f4b82fe89f3b7bb039 Mon Sep 17 00:00:00 2001 From: Giovanni Harting Date: Sun, 11 Oct 2015 21:52:39 +0200 Subject: [PATCH] switched to json-rpc (ref LedD d5f403d5573d13e6b8f3113a1c62a096ea721f19) fixed duplicate connections were made when adding a daemon --- app/build.gradle | 5 +- app/libs/holo-color-picker_ledd_version.aar | Bin 0 -> 29387 bytes app/src/main/AndroidManifest.xml | 1 + .../com/idlegandalf/ledd/ColorActivity.java | 7 +- .../ledd/callbacks/AddControllerCallback.java | 2 +- .../ledd/callbacks/AddStripeCallback.java | 2 + .../ledd/callbacks/RecieveColorCallback.java | 2 +- .../ledd/callbacks/StripesCallback.java | 2 +- .../ledd/components/AnswerTask.java | 4 +- .../ledd/components/LedDRequest.java | 6 +- .../idlegandalf/ledd/components/Sendable.java | 21 +- .../ledd/fragments/AddControllerDialog.java | 2 +- .../ledd/fragments/AddStripeDialog.java | 8 +- .../idlegandalf/ledd/helper/LedDHelper.java | 203 ++++++++---------- .../ledd/services/ColorService.java | 57 +++-- .../res/drawable-hdpi/ic_clear_black_48dp.png | Bin 0 -> 309 bytes .../res/drawable-hdpi/ic_clear_white_48dp.png | Bin 0 -> 347 bytes .../res/drawable-mdpi/ic_clear_black_48dp.png | Bin 0 -> 235 bytes .../res/drawable-mdpi/ic_clear_white_48dp.png | Bin 0 -> 257 bytes .../drawable-xhdpi/ic_clear_black_48dp.png | Bin 0 -> 377 bytes .../drawable-xhdpi/ic_clear_white_48dp.png | Bin 0 -> 436 bytes .../drawable-xxhdpi/ic_clear_black_48dp.png | Bin 0 -> 511 bytes .../drawable-xxhdpi/ic_clear_white_48dp.png | Bin 0 -> 524 bytes .../drawable-xxxhdpi/ic_clear_black_48dp.png | Bin 0 -> 665 bytes .../drawable-xxxhdpi/ic_clear_white_48dp.png | Bin 0 -> 702 bytes app/src/main/res/layout/navigation_header.xml | 18 +- 26 files changed, 165 insertions(+), 175 deletions(-) create mode 100644 app/libs/holo-color-picker_ledd_version.aar create mode 100644 app/src/main/res/drawable-hdpi/ic_clear_black_48dp.png create mode 100644 app/src/main/res/drawable-hdpi/ic_clear_white_48dp.png create mode 100644 app/src/main/res/drawable-mdpi/ic_clear_black_48dp.png create mode 100644 app/src/main/res/drawable-mdpi/ic_clear_white_48dp.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_clear_black_48dp.png create mode 100644 app/src/main/res/drawable-xhdpi/ic_clear_white_48dp.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_clear_black_48dp.png create mode 100644 app/src/main/res/drawable-xxhdpi/ic_clear_white_48dp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_clear_black_48dp.png create mode 100644 app/src/main/res/drawable-xxxhdpi/ic_clear_white_48dp.png diff --git a/app/build.gradle b/app/build.gradle index feb6c88..49f0398 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -60,11 +60,12 @@ dependencies { compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.android.support:support-v4:23.0.1' compile 'com.squareup.okhttp:okhttp:2.5.0' - compile 'com.google.code.gson:gson:2.3.1' + compile 'com.google.code.gson:gson:2.4' compile 'com.jakewharton:butterknife:7.0.1' compile 'com.koushikdutta.async:androidasync:2.1.6' compile 'com.android.support:design:23.0.1' compile 'com.larswerkman:HoloColorPicker:1.5@aar' - compile 'com.google.guava:guava:19.0-rc1' + compile 'com.google.guava:guava:19.0-rc2' + compile 'com.thetransactioncompany:jsonrpc2-base:1.38' provided 'org.projectlombok:lombok:1.16.6' } diff --git a/app/libs/holo-color-picker_ledd_version.aar b/app/libs/holo-color-picker_ledd_version.aar new file mode 100644 index 0000000000000000000000000000000000000000..ee686e15593ecc9de8c7e9c347d31e5aba62f284 GIT binary patch literal 29387 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 + ledStripes; @@ -302,7 +305,7 @@ public class ColorActivity extends AppCompatActivity implements NavigationView.O } @Override - public void onGetFailed(String message) { + public void onGetFailed(int code, String message) { Snackbar.make(findViewById(android.R.id.content), getString(R.string.snackbar_no_connection_stripes) + message, Snackbar .LENGTH_LONG).show(); @@ -366,7 +369,7 @@ public class ColorActivity extends AppCompatActivity implements NavigationView.O } @Override - public void onRecievFailed(String msg) { + public void onRecievFailed(int code, String msg) { } diff --git a/app/src/main/java/com/idlegandalf/ledd/callbacks/AddControllerCallback.java b/app/src/main/java/com/idlegandalf/ledd/callbacks/AddControllerCallback.java index 2f44e6d..8e7a3a7 100644 --- a/app/src/main/java/com/idlegandalf/ledd/callbacks/AddControllerCallback.java +++ b/app/src/main/java/com/idlegandalf/ledd/callbacks/AddControllerCallback.java @@ -28,6 +28,6 @@ public interface AddControllerCallback extends BaseCallback { */ void onControllerAdded(Controller controller); - void onAddFailed(String msg, String detail); + void onAddFailed(int code, String msg); } diff --git a/app/src/main/java/com/idlegandalf/ledd/callbacks/AddStripeCallback.java b/app/src/main/java/com/idlegandalf/ledd/callbacks/AddStripeCallback.java index e85df6e..cf5e724 100644 --- a/app/src/main/java/com/idlegandalf/ledd/callbacks/AddStripeCallback.java +++ b/app/src/main/java/com/idlegandalf/ledd/callbacks/AddStripeCallback.java @@ -23,4 +23,6 @@ import com.idlegandalf.ledd.components.LedStripe; public interface AddStripeCallback extends BaseCallback { void onAddSuccessfully(LedStripe stripe); + + void onAddFailed(int code, String msg); } diff --git a/app/src/main/java/com/idlegandalf/ledd/callbacks/RecieveColorCallback.java b/app/src/main/java/com/idlegandalf/ledd/callbacks/RecieveColorCallback.java index ef09596..8e32116 100644 --- a/app/src/main/java/com/idlegandalf/ledd/callbacks/RecieveColorCallback.java +++ b/app/src/main/java/com/idlegandalf/ledd/callbacks/RecieveColorCallback.java @@ -23,5 +23,5 @@ import com.idlegandalf.ledd.components.LedStripe; public interface RecieveColorCallback extends BaseCallback { void onColorRecieved(LedStripe stripe); - void onRecievFailed(String msg); + void onRecievFailed(int code, String msg); } diff --git a/app/src/main/java/com/idlegandalf/ledd/callbacks/StripesCallback.java b/app/src/main/java/com/idlegandalf/ledd/callbacks/StripesCallback.java index f9f247a..7e72ec0 100644 --- a/app/src/main/java/com/idlegandalf/ledd/callbacks/StripesCallback.java +++ b/app/src/main/java/com/idlegandalf/ledd/callbacks/StripesCallback.java @@ -26,5 +26,5 @@ import java.util.List; public interface StripesCallback extends BaseCallback { void onSuccess(List stripes); - void onGetFailed(String message); + void onGetFailed(int code, String message); } diff --git a/app/src/main/java/com/idlegandalf/ledd/components/AnswerTask.java b/app/src/main/java/com/idlegandalf/ledd/components/AnswerTask.java index 8033071..84bda26 100644 --- a/app/src/main/java/com/idlegandalf/ledd/components/AnswerTask.java +++ b/app/src/main/java/com/idlegandalf/ledd/components/AnswerTask.java @@ -19,11 +19,11 @@ package com.idlegandalf.ledd.components; -import org.json.JSONObject; +import com.thetransactioncompany.jsonrpc2.JSONRPC2Response; public abstract class AnswerTask { public abstract void onConnectionFailed(String message); - public abstract void onResponse(JSONObject response); + public abstract void onResponse(JSONRPC2Response response); } diff --git a/app/src/main/java/com/idlegandalf/ledd/components/LedDRequest.java b/app/src/main/java/com/idlegandalf/ledd/components/LedDRequest.java index b8273e2..7190a7e 100644 --- a/app/src/main/java/com/idlegandalf/ledd/components/LedDRequest.java +++ b/app/src/main/java/com/idlegandalf/ledd/components/LedDRequest.java @@ -18,16 +18,16 @@ package com.idlegandalf.ledd.components; -import org.json.JSONObject; +import com.thetransactioncompany.jsonrpc2.JSONRPC2Request; import lombok.Getter; @Getter public class LedDRequest { - JSONObject request; + JSONRPC2Request request; AnswerTask task; - public LedDRequest(JSONObject request, AnswerTask task) { + public LedDRequest(JSONRPC2Request request, AnswerTask task) { this.request = request; this.task = task; } diff --git a/app/src/main/java/com/idlegandalf/ledd/components/Sendable.java b/app/src/main/java/com/idlegandalf/ledd/components/Sendable.java index af380fd..27c30fe 100644 --- a/app/src/main/java/com/idlegandalf/ledd/components/Sendable.java +++ b/app/src/main/java/com/idlegandalf/ledd/components/Sendable.java @@ -18,33 +18,26 @@ package com.idlegandalf.ledd.components; -import org.json.JSONException; -import org.json.JSONObject; +import com.thetransactioncompany.jsonrpc2.JSONRPC2Request; +import com.thetransactioncompany.jsonrpc2.JSONRPC2Response; -import java.util.UUID; +import org.json.JSONException; import lombok.Getter; @Getter public class Sendable { LedDDaemon recipient; - JSONObject message; - String ref; + JSONRPC2Request request; AnswerTask onAnswer; - public Sendable(JSONObject msg, AnswerTask task, LedDDaemon ledDDaemon) throws JSONException { - this(msg, UUID.randomUUID().toString(), task, ledDDaemon); - } - - public Sendable(JSONObject msg, String ref, AnswerTask task, LedDDaemon recipient) throws JSONException { - this.message = msg; - this.ref = ref; - this.message.put("ref", ref); + public Sendable(JSONRPC2Request request, AnswerTask task, LedDDaemon recipient) throws JSONException { + this.request = request; this.onAnswer = task; this.recipient = recipient; } - public void onResponse(JSONObject object) { + public void onResponse(JSONRPC2Response object) { if (onAnswer != null) { onAnswer.onResponse(object); } diff --git a/app/src/main/java/com/idlegandalf/ledd/fragments/AddControllerDialog.java b/app/src/main/java/com/idlegandalf/ledd/fragments/AddControllerDialog.java index eee524a..eda28dd 100644 --- a/app/src/main/java/com/idlegandalf/ledd/fragments/AddControllerDialog.java +++ b/app/src/main/java/com/idlegandalf/ledd/fragments/AddControllerDialog.java @@ -190,7 +190,7 @@ public class AddControllerDialog extends DialogFragment implements DialogInterfa } @Override - public void onAddFailed(final String msg, String detail) { + public void onAddFailed(final int code, final String msg) { getActivity().runOnUiThread(new Runnable() { @Override public void run() { diff --git a/app/src/main/java/com/idlegandalf/ledd/fragments/AddStripeDialog.java b/app/src/main/java/com/idlegandalf/ledd/fragments/AddStripeDialog.java index 5b81531..4a41ae7 100644 --- a/app/src/main/java/com/idlegandalf/ledd/fragments/AddStripeDialog.java +++ b/app/src/main/java/com/idlegandalf/ledd/fragments/AddStripeDialog.java @@ -258,7 +258,6 @@ public class AddStripeDialog extends DialogFragment implements DialogInterface.O LedDHelper helper = ColorApplication.getInstance().getHelperForDaemon((LedDDaemon) daemonSpinner.getSelectedItem()); - if (helper != null) { helper.addStripe(stripe, new AddStripeCallback() { @Override @@ -275,6 +274,11 @@ public class AddStripeDialog extends DialogFragment implements DialogInterface.O dismiss(); } + @Override + public void onAddFailed(int code, String msg) { + + } + @Override public void onConnectionFailed(final String message) { getActivity().runOnUiThread(new Runnable() { @@ -415,7 +419,7 @@ public class AddStripeDialog extends DialogFragment implements DialogInterface.O } @Override - public void onGetFailed(String message) { + public void onGetFailed(int code, String message) { } diff --git a/app/src/main/java/com/idlegandalf/ledd/helper/LedDHelper.java b/app/src/main/java/com/idlegandalf/ledd/helper/LedDHelper.java index 7a57bea..de589a0 100644 --- a/app/src/main/java/com/idlegandalf/ledd/helper/LedDHelper.java +++ b/app/src/main/java/com/idlegandalf/ledd/helper/LedDHelper.java @@ -38,13 +38,19 @@ import com.idlegandalf.ledd.components.LedDDaemon; import com.idlegandalf.ledd.components.LedDRequest; import com.idlegandalf.ledd.components.LedStripe; import com.idlegandalf.ledd.services.ColorService; +import com.thetransactioncompany.jsonrpc2.JSONRPC2Error; +import com.thetransactioncompany.jsonrpc2.JSONRPC2Request; +import com.thetransactioncompany.jsonrpc2.JSONRPC2Response; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.UUID; import java.util.concurrent.LinkedBlockingQueue; public class LedDHelper { @@ -52,7 +58,7 @@ public class LedDHelper { final String ACTION_GETCOLOR = "get_color"; final String ACTION_ADDCONTROLLER = "add_controller"; final String ACTION_GETALLSTRIPES = "get_stripes"; - final String ACTION_ADDSTRIPES = "add_stripe"; + final String ACTION_ADDSTRIPE = "add_stripe"; final String ACTION_TESTCHANNEL = "test_channel"; final String ACTION_DISCOVER = "discover"; private Context context; @@ -92,34 +98,33 @@ public class LedDHelper { * @param c controller object */ public void addController(final Controller c, final AddControllerCallback callback) { - JSONObject jnson = new JSONObject(); + Map params = new HashMap<>(); - try { - jnson.put("action", ACTION_ADDCONTROLLER); - jnson.put("channels", c.getChannels()); - jnson.put("i2c_dev", c.getI2c_device()); - jnson.put("address", c.getAddress()); - } catch (JSONException e) { - e.printStackTrace(); - } + params.put("channels", c.getChannels()); + params.put("i2c_dev", c.getI2c_device()); + params.put("address", c.getAddress()); - addRequestToQueue(jnson, new AnswerTask() { + JSONRPC2Request request = new JSONRPC2Request(ACTION_ADDCONTROLLER, params, UUID.randomUUID().toString()); + + addRequestToQueue(request, new AnswerTask() { @Override public void onConnectionFailed(String message) { - callback.onAddFailed(message, ""); + callback.onConnectionFailed(message); } @Override - public void onResponse(JSONObject response) { - try { - if (response.getBoolean("success")) { - c.setId(response.getInt("cid")); + public void onResponse(JSONRPC2Response response) { + if (response.indicatesSuccess()) { + try { + JSONObject json = new JSONObject(response.getResult().toString()); + c.setId(json.getInt("cid")); callback.onControllerAdded(c); - } else { - callback.onAddFailed(response.getString("message"), response.getString("message_detail")); + } catch (JSONException e) { + e.printStackTrace(); } - } catch (Exception e) { - e.printStackTrace(); + } else { + @SuppressWarnings("ThrowableResultOfMethodCallIgnored") JSONRPC2Error error = response.getError(); + callback.onAddFailed(error.getCode(), error.getMessage()); } } }); @@ -129,27 +134,20 @@ public class LedDHelper { * Get stripes known to daemon */ public void getStripes(final StripesCallback callback) { - JSONObject jnson = new JSONObject(); - - try { - jnson.put("action", ACTION_GETALLSTRIPES); - } catch (JSONException e) { - e.printStackTrace(); - } - - addRequestToQueue(jnson, new AnswerTask() { + addRequestToQueue(new JSONRPC2Request(ACTION_GETALLSTRIPES, UUID.randomUUID().toString()), new AnswerTask() { @Override public void onConnectionFailed(String message) { - callback.onGetFailed(message); + callback.onConnectionFailed(message); } @Override - public void onResponse(JSONObject response) { + public void onResponse(JSONRPC2Response response) { try { - if (response.getBoolean("success")) { + if (response.indicatesSuccess()) { ledDDaemon.getControllers().clear(); List list = new ArrayList<>(); - JSONArray jcontrollers = response.getJSONArray("controller"); + JSONObject json = new JSONObject(response.getResult().toString()); + JSONArray jcontrollers = json.getJSONArray("controller"); for (int i = 0; i < jcontrollers.length(); i++) { JSONObject row = jcontrollers.getJSONObject(i); @@ -180,8 +178,8 @@ public class LedDHelper { callback.onSuccess(list); } else { - if (response.has("message")) callback.onGetFailed(response.getString("message")); - else callback.onGetFailed("unknown error"); + @SuppressWarnings("ThrowableResultOfMethodCallIgnored") JSONRPC2Error error = response.getError(); + callback.onGetFailed(error.getCode(), error.getMessage()); } } catch (Exception e) { e.printStackTrace(); @@ -196,26 +194,20 @@ public class LedDHelper { * @param ledStripe Stripe */ public void setColor(LedStripe ledStripe) { + Map hsv = new HashMap<>(); - JSONObject jnson = new JSONObject(); - JSONObject hsv = new JSONObject(); + hsv.put("h", ledStripe.getColor().getHue()); + hsv.put("s", ledStripe.getColor().getSaturation()); + hsv.put("v", ledStripe.getColor().getValue()); - try { - hsv.put("h", ledStripe.getColor().getHue()); - hsv.put("s", ledStripe.getColor().getSaturation()); - - hsv.put("v", ledStripe.getColor().getValue()); + Map params = new HashMap<>(); + params.put("sid", ledStripe.getId()); + params.put("hsv", hsv); - jnson.put("action", ACTION_SETCOLOR); - jnson.put("sid", ledStripe.getId()); - jnson.put("hsv", hsv); + JSONRPC2Request request = new JSONRPC2Request(ACTION_SETCOLOR, params, UUID.randomUUID().toString()); - } catch (JSONException e) { - e.printStackTrace(); - } - - addRequestToQueue(jnson, null); + addRequestToQueue(request, null); } /** @@ -224,33 +216,29 @@ public class LedDHelper { * @param ledStripe Stripe */ public void getColor(final LedStripe ledStripe, final RecieveColorCallback callback) { - JSONObject jnson = new JSONObject(); + HashMap params = new HashMap<>(); + params.put("sid", ledStripe.getId()); - try { - jnson.put("action", ACTION_GETCOLOR); - jnson.put("sid", ledStripe.getId()); - } catch (JSONException e) { - e.printStackTrace(); - } - - addRequestToQueue(jnson, new AnswerTask() { + addRequestToQueue(new JSONRPC2Request(ACTION_GETCOLOR, params, UUID.randomUUID().toString()), new AnswerTask() { @Override public void onConnectionFailed(String message) { - callback.onRecievFailed(message); + callback.onConnectionFailed(message); } @Override - public void onResponse(JSONObject response) { - try { - if (response.getBoolean("success")) { - JSONArray hsv = response.getJSONArray("color"); + public void onResponse(JSONRPC2Response response) { + if (response.indicatesSuccess()) { + try { + JSONObject json = new JSONObject(response.getResult().toString()); + JSONArray hsv = json.getJSONArray("color"); ledStripe.setColor(new HSV(hsv.getDouble(0), hsv.getDouble(1), hsv.getDouble(2))); callback.onColorRecieved(ledStripe); - } else { - callback.onRecievFailed(response.getString("message")); + } catch (JSONException e) { + e.printStackTrace(); } - } catch (Exception e) { - e.printStackTrace(); + } else { + @SuppressWarnings("ThrowableResultOfMethodCallIgnored") JSONRPC2Error error = response.getError(); + callback.onRecievFailed(error.getCode(), error.getMessage()); } } }); @@ -264,26 +252,20 @@ public class LedDHelper { * @param value value (1= on, 0 = off) */ public void testChannel(Controller c, int channel, int value) { - JSONObject jnson = new JSONObject(); + HashMap params = new HashMap<>(); - try { - jnson.put("action", ACTION_TESTCHANNEL); + params.put("cid", c.getId()); + params.put("channel", channel); + params.put("value", value); - jnson.put("cid", c.getId()); - jnson.put("channel", channel); - jnson.put("value", value); - } catch (JSONException e) { - e.printStackTrace(); - } - - addRequestToQueue(jnson, new AnswerTask() { + addRequestToQueue(new JSONRPC2Request(ACTION_TESTCHANNEL, params, UUID.randomUUID().toString()), new AnswerTask() { @Override public void onConnectionFailed(String message) { } @Override - public void onResponse(JSONObject response) { + public void onResponse(JSONRPC2Response response) { } }); @@ -293,25 +275,18 @@ public class LedDHelper { * Get information about an ledd daemon */ public void discover(final DiscoverCallback callback) { - JSONObject jnson = new JSONObject(); - - try { - jnson.put("action", ACTION_DISCOVER); - } catch (JSONException e) { - e.printStackTrace(); - } - - addRequestToQueue(jnson, new AnswerTask() { + addRequestToQueue(new JSONRPC2Request(ACTION_DISCOVER, UUID.randomUUID().toString()), new AnswerTask() { @Override public void onConnectionFailed(String message) { callback.onConnectionFailed(message); } @Override - public void onResponse(JSONObject response) { + public void onResponse(JSONRPC2Response response) { try { - if (response.getBoolean("success")) { - callback.onDiscoverSuccessfully(response.getString("version")); + if (response.indicatesSuccess()) { + JSONObject json = new JSONObject(response.getResult().toString()); + callback.onDiscoverSuccessfully(json.getString("version")); } } catch (Exception e) { e.printStackTrace(); @@ -324,40 +299,34 @@ public class LedDHelper { * Get information about an ledd daemon */ public void addStripe(final LedStripe ledStripe, final AddStripeCallback callback) { - JSONObject jnson = new JSONObject(); + HashMap params = new HashMap<>(); + HashMap mapping = new HashMap<>(); - try { - jnson.put("action", ACTION_ADDSTRIPES); + params.put("name", ledStripe.getName()); + params.put("rgb", ledStripe.isRGB()); - JSONObject stripe = new JSONObject(); + mapping.put("r", ledStripe.getChannelRed()); + mapping.put("g", ledStripe.getChannelGreen()); + mapping.put("b", ledStripe.getChannelBlue()); + params.put("map", mapping); + params.put("cid", ledStripe.getController().getId()); - stripe.put("name", ledStripe.getName()); - stripe.put("rgb", ledStripe.isRGB()); - - JSONObject mapping = new JSONObject(); - mapping.put("r", ledStripe.getChannelRed()); - mapping.put("g", ledStripe.getChannelGreen()); - mapping.put("b", ledStripe.getChannelBlue()); - stripe.put("map", mapping); - stripe.put("cid", ledStripe.getController().getId()); - jnson.put("stripe", stripe); - - } catch (JSONException e) { - e.printStackTrace(); - } - - addRequestToQueue(jnson, new AnswerTask() { + addRequestToQueue(new JSONRPC2Request(ACTION_ADDSTRIPE, params, UUID.randomUUID().toString()), new AnswerTask() { @Override public void onConnectionFailed(String message) { callback.onConnectionFailed(message); } @Override - public void onResponse(JSONObject response) { + public void onResponse(JSONRPC2Response response) { try { - if (response.getBoolean("success")) { - ledStripe.setId(response.getInt("sid")); + if (response.indicatesSuccess()) { + JSONObject json = new JSONObject(response.getResult().toString()); + ledStripe.setId(json.getInt("sid")); callback.onAddSuccessfully(ledStripe); + } else { + @SuppressWarnings("ThrowableResultOfMethodCallIgnored") JSONRPC2Error error = response.getError(); + callback.onAddFailed(error.getCode(), error.getMessage()); } } catch (Exception e) { e.printStackTrace(); @@ -366,8 +335,8 @@ public class LedDHelper { }); } - private void addRequestToQueue(JSONObject json, AnswerTask task) { - if (json != null && json.length() > 0) dRequests.add(new LedDRequest(json, task)); + private void addRequestToQueue(JSONRPC2Request request, AnswerTask task) { + if (request != null) dRequests.add(new LedDRequest(request, task)); } public void teardown() { diff --git a/app/src/main/java/com/idlegandalf/ledd/services/ColorService.java b/app/src/main/java/com/idlegandalf/ledd/services/ColorService.java index fd23af6..b32c143 100644 --- a/app/src/main/java/com/idlegandalf/ledd/services/ColorService.java +++ b/app/src/main/java/com/idlegandalf/ledd/services/ColorService.java @@ -33,9 +33,11 @@ import com.koushikdutta.async.DataEmitter; import com.koushikdutta.async.Util; import com.koushikdutta.async.callback.ConnectCallback; import com.koushikdutta.async.callback.DataCallback; +import com.thetransactioncompany.jsonrpc2.JSONRPC2ParseException; +import com.thetransactioncompany.jsonrpc2.JSONRPC2Request; +import com.thetransactioncompany.jsonrpc2.JSONRPC2Response; import org.json.JSONException; -import org.json.JSONObject; import java.io.UnsupportedEncodingException; import java.net.InetSocketAddress; @@ -80,19 +82,24 @@ public class ColorService extends Service { DataCallback dataCallback = new DataCallback() { @Override public void onDataAvailable(DataEmitter emitter, ByteBufferList bb) { - try { - JSONObject resp = new JSONObject(new String(bb.getAllByteArray())); + JSONRPC2Response reqIn = null; - if (sendableHashMap.containsKey(resp.getString("ref"))) { - sendableHashMap.get(resp.getString("ref")).onResponse(resp); - sendableHashMap.remove(resp.getString("ref")); - if (timeoutHashMap.containsKey(resp.getString("ref")) && timeoutHashMap.get(resp.getString("ref")) != null) - timeoutHashMap.get(resp.getString("ref")).cancel(false); - timeoutHashMap.remove(resp.getString("ref")); - } - } catch (JSONException e) { + try { + reqIn = JSONRPC2Response.parse(new String(bb.getAllByteArray())); + + } catch (JSONRPC2ParseException e) { e.printStackTrace(); } + + if (reqIn != null) { + if (sendableHashMap.containsKey(reqIn.getID().toString())) { + sendableHashMap.get(reqIn.getID().toString()).onResponse(reqIn); + sendableHashMap.remove(reqIn.getID().toString()); + if (timeoutHashMap.containsKey(reqIn.getID().toString()) && timeoutHashMap.get(reqIn.getID().toString()) != null) + timeoutHashMap.get(reqIn.getID().toString()).cancel(false); + timeoutHashMap.remove(reqIn.getID().toString()); + } + } } }; @@ -111,22 +118,32 @@ public class ColorService extends Service { if (item instanceof Sendable) { final Sendable sendable = (Sendable) item; - if (socketHashMap.containsKey(sendable.getRecipient()) && socketHashMap.get(sendable.getRecipient()).getServer().isRunning - ()) { + if (socketHashMap.containsKey(sendable.getRecipient())) { + if (socketHashMap.get(sendable.getRecipient()) == null) { + // if server is not running yet, readd item to queue + workQueue.add(item); + continue; + } else if (!socketHashMap.get(sendable.getRecipient()).getServer().isRunning()) { + // connection probably closed or was interrupted -> reconnect + socketHashMap.remove(sendable.getRecipient()); + workQueue.add(item); + continue; + } - Util.writeAll(socketHashMap.get(sendable.getRecipient()), (sendable.getMessage().toString() + "\n").getBytes("UTF-8"), + Util.writeAll(socketHashMap.get(sendable.getRecipient()), (sendable.getRequest().toString() + "\n").getBytes("UTF-8"), null); - sendableHashMap.put(sendable.getRef(), sendable); + sendableHashMap.put((String) sendable.getRequest().getID(), sendable); if (!poolExecutor.isTerminating() && !poolExecutor.isTerminated()) - timeoutHashMap.put(sendable.getRef(), poolExecutor.schedule(new Runnable() { + timeoutHashMap.put((String) sendable.getRequest().getID(), poolExecutor.schedule(new Runnable() { @Override public void run() { sendable.onNoResponse(); - timeoutHashMap.remove(sendable.getRef()); - sendableHashMap.remove(sendable.getRef()); + timeoutHashMap.remove(sendable.getRequest().getID()); + sendableHashMap.remove(sendable.getRequest().getID()); } }, 1000, TimeUnit.MILLISECONDS)); } else { + socketHashMap.put(sendable.getRecipient(), null); AsyncServer.getDefault().connectSocket(new InetSocketAddress(sendable.getRecipient().getAddress(), sendable .getRecipient().getPort()), new ConnectCallback() { @Override @@ -160,10 +177,10 @@ public class ColorService extends Service { } public class ColorBinder extends Binder { - public void queueSend(LedDDaemon rec, JSONObject msg, AnswerTask answerTask) { + public void queueSend(LedDDaemon rec, JSONRPC2Request request, AnswerTask answerTask) { Sendable sendable = null; try { - sendable = new Sendable(msg, answerTask, rec); + sendable = new Sendable(request, answerTask, rec); } catch (JSONException e) { e.printStackTrace(); } diff --git a/app/src/main/res/drawable-hdpi/ic_clear_black_48dp.png b/app/src/main/res/drawable-hdpi/ic_clear_black_48dp.png new file mode 100644 index 0000000000000000000000000000000000000000..51b4401ca053ca8cad6e9903646709a2f44444df GIT binary patch literal 309 zcmeAS@N?(olHy`uVBq!ia0y~yVDJE84i*LmhW}5h&oD4B{PA>g45?szd&8RVkb!{f z#qgO&RTCF0di>Ps3vqkUR9|}B=;-cuhbPYQICH}C`JCc+^43`)LN6D1#>%9JUt7as zF?&;4Y2h3mkJicWm)LcDR$%l~!>$D~J8I&& z`<4wRoL5=bf6=S?c=Ncft>tnPmbI;x%l|&Q1M!^AeIx&8@dUfhv-4JM(mB0J=d_l-jllx7wHFdxP9ML? z=<`y=B!cmcj>>UItCNKc3GT;_d#d~`uv;>Zt?JQ!%f6Ba3<|{Ln;{GPTRQ|?&!s0lPq=f*?JSyI958!BvVC*3j`s1wIG=!v%i_xBa{1J+URkDA7HS%+5_qL< zy;j+)`QHQ01Fx$6d-b-ylIgXh5~HocO_uAQS*|y`uvIy1<6QEbbH(${pH;@C3!ZbX zikFYDS6a6|&E5BUewWI@ulyPZznV>4_VVB|*{h#fuHSZ%yVUG!y^YmC^Iwj=j{uEFRm_653`c~$LTV+X(mSw z8*5{^QnL{MhYQ?o=a=>*wfFy;xJvZs4;RB-k6m3P){9*Ik=@E|7wGe@LQrto;zOeI zweEcEJS1N)aa#6=%ftTtu?3$y_Qm;KG0)}PcilW!@Lt$6*NWK7VGlq1M)#HnKCynj zC-d%y=f1DI)(32O_5Zcs#t5#FVdQ&MBb@0ESC#XaE2J literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_clear_black_48dp.png b/app/src/main/res/drawable-xhdpi/ic_clear_black_48dp.png new file mode 100644 index 0000000000000000000000000000000000000000..df42feecb812b02df59b016f4d9ba995be1da82a GIT binary patch literal 377 zcmeAS@N?(olHy`uVBq!ia0y~yU`POA4i*Lm29JsRH#0CWI(WJ`hEy=Vy>&N}DNw}q z;oXL1b5_r_=FK=2C_O`=atD8+0)HK|V)b3NYqR1l=1d9l(p(B6o=&exIoa`GjyGT2 zf8*?Tk`Di8nqHUL`|sCWhA;8Yrzu~X&*@OF=J9tX!j8wn?!EAqef}2AwMQzoLGtU~3-8$H|KOJ$ z;|pmsm-!L*)fsAMANX3!bp1PL+h40;ZgSr4wYOu6JxZ9ODrWsMV_ZAOw|4r1>HqltC%xSS3IcFA#P16<$f#A@_LPBv Ofx*+&&t;ucLK6TL>aSb? literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xhdpi/ic_clear_white_48dp.png b/app/src/main/res/drawable-xhdpi/ic_clear_white_48dp.png new file mode 100644 index 0000000000000000000000000000000000000000..39641921925f090e33df2767a4ee5e6d5911194f GIT binary patch literal 436 zcmeAS@N?(olHy`uVBq!ia0y~yU`POA4i*Lm29JsRH#0CWR(rZQhE&{oJL}@aW&d%L$PIoQo-StxTn+E zdwyKJ{-5>36#oMa;ti5>_t`xW4y$FTSfQHprB&GMR~4sq?ZKA0`@)#i{-mz-|KTpr zp!TytuDj+?bsQ|21Fu&g)?=#dNRaPj?Yga#1`KhyDUX9Wm_4ysoPO3*$%5D03 zzOzDZUdQv35H;%aAI2f0OzFaY3+3CFdrm@rC k9Lf#f_J8{sH1LMiWPXmU)Lg#Z3=9kmp00i_>zopr0C?*8xBvhE literal 0 HcmV?d00001 diff --git a/app/src/main/res/drawable-xxhdpi/ic_clear_white_48dp.png b/app/src/main/res/drawable-xxhdpi/ic_clear_white_48dp.png new file mode 100644 index 0000000000000000000000000000000000000000..4927bc242e23be272c9fd4be0f4da56a0e1c54d6 GIT binary patch literal 524 zcmeAS@N?(olHy`uVBq!ia0y~yV3+{H9Lx+13>Rhybuln7Xa)F$xH2#>{3i~y?LMUs zGOi@ZFPK5@fx=z+d-oqIDegb;tUN)6fq}8b)5S5Q;?~<+zJ1LG0<4KViYFQN{Vz>7 z5M!5QqBl81SPoEOxrMVPLZ22=McV^D+ZBFNR+uvG}{`Pg)iVkjJ+T8P{#UmkI2Y6Z+ScwsXTDS|N9m; zrQ6Pv1Mf2{-90w}CO7L`X45?szbFh(tfq|i6 z!QYkQE15t{1fDV1dWWw}&mxUKTpPH(JnlAsR|yu-JD{9eY#!NQbLph(^PNrqtrb}8 ztL)Dmk4c}oEHZue_UjMtKc5jD*i`!OoZ)ws7tie{Eok}w!|%gCr9YklNAAy8_+!d> z=>9x~KRHdpe>@9bKF{|M`1g_x^9j4qiSsHGkN`AtkPM+ZRs$pCUhg7)-3Y8qg_H!;;IH2!g5`so{R zfL~>TyoZAQ1cy4|9M?bR)o(nze*X6z`RDr8=kGnwH9E_AD1O3%PJ7O(ACni%w=bSq z&0R0V@W-L)gSg6zC;m-)TkScye)y|$)O$C5_^!@T@7PrLPvyl!|E3S$&mVu|`p5Ia xd3(_WOc@v$j01c^Tp1V`{*wr{Pkq$H zz`!6-666=mz{_*^*pZ{3K3m#YTkY7s?Mk=KMg|5ZEl(H6kczmscO3Ji0tMI}@*FuP z@%YSN|JlAvwr>oY{cNS!*ZB{$IS(rI{<{AEdQ|q>t=CY9+Pe5SW{Y{>b^rB${xzxT z@%PHz`5))6PPkS-Z~J=Lf1w6%+M6{0Ye{@_J~*Xb)aUnqQ5&-#;Rol)b1nN5VDO;5 ziSxgf#Mkw;V9^$Nu48{!Cmh?q_`z?Rg$W1te@nM{@abFf!P}{a_~rc^8xQcarrC?% z_#2b(y}0r2dDb#G=gxW7_9N%57dX6r&a`_z_nSJs4Zn9Dc!$R6p3i-+US+R*nZ5Xn zzcCNK7dPHN&-$iZe8c_N19g>*zrM0Q`7S=;emp~6edC?;@n0Wo7XwR`Gyc8{S69vW z^Dj)@Kc-(C6Xm&nNxg0F`4e;Da7_Q@H_w~?1$|pS@9%YOksE)-E3Dn$FaO^Cr%vO- z?}ZNU+nM&tqq^=%ou0*;x;pFQ=#EA6#{FEuAA8}BKygty8|wEY{IlWzvHaVPT#E@T{}wj=6b^kLuYIFHh38K&>*w@a2kgT> w>~gMrAg^8VcIBb!<4R|rTSa3;^w#}nPcbcf{ABhC1_lNOPgg&ebxsLQ0E^at$p8QV literal 0 HcmV?d00001 diff --git a/app/src/main/res/layout/navigation_header.xml b/app/src/main/res/layout/navigation_header.xml index 8454339..9bc6475 100644 --- a/app/src/main/res/layout/navigation_header.xml +++ b/app/src/main/res/layout/navigation_header.xml @@ -18,26 +18,26 @@ --> + android:layout_width="match_parent" + android:layout_height="192dp" + android:background="?attr/colorPrimaryDark" + android:gravity="bottom" + android:padding="16dp" + android:theme="@style/ThemeOverlay.AppCompat.Dark"> \ No newline at end of file