diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 1df4bcb..fb8b0c5 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -7,10 +7,13 @@
android:glEsVersion="0x00020000"
android:required="true" />
+
+
+
blockList;
@@ -25,6 +24,18 @@ public class BridgeBlockListBuilder {
return this.addOperation(new OperationBlockDefinition(id, message, arguments, operation));
}
+ public BridgeBlockListBuilder addTrigger(String id, String message,
+ List arguments,
+ String key) {
+ return this.addTrigger(new TriggerBlockDefinition(id, message, arguments, key));
+ }
+
+ private BridgeBlockListBuilder addTrigger(TriggerBlockDefinition block) {
+ this.blockList.add(block);
+
+ return this;
+ }
+
private BridgeBlockListBuilder addOperation(ProgramakerBridgeConfigurationBlock block) {
this.blockList.add(block);
diff --git a/app/src/main/java/com/codigoparallevar/minicards/bridge/blocks/DefaultAndroidBlocks.java b/app/src/main/java/com/codigoparallevar/minicards/bridge/blocks/DefaultAndroidBlocks.java
index 4883875..8e6412f 100644
--- a/app/src/main/java/com/codigoparallevar/minicards/bridge/blocks/DefaultAndroidBlocks.java
+++ b/app/src/main/java/com/codigoparallevar/minicards/bridge/blocks/DefaultAndroidBlocks.java
@@ -53,8 +53,8 @@ public class DefaultAndroidBlocks {
notificationManager.createNotificationChannel(vibrationChannel);
}
-
- return new BridgeBlockListBuilder()
+ // OPERATIONS
+ BridgeBlockListBuilder builder = new BridgeBlockListBuilder()
// Notifications
.addOperation(
"notifications_new",
@@ -109,7 +109,6 @@ public class DefaultAndroidBlocks {
pattern[i * 2] = VIBRATION_ACTIVE_TIME;
pattern[i * 2 + 1] = VIBRATION_REST_TIME;
}
- // pattern[0] = 0; // Start immediately
Notification notif = new NotificationCompat
.Builder(ctx, ProgramakerBridgeService.BridgeUserVibrationNotificationChannel)
@@ -145,5 +144,22 @@ public class DefaultAndroidBlocks {
}
)
;
+
+ // Signal blocks
+ builder
+ .addTrigger(
+ "on_wifi_connected",
+ "When WIFI connects",
+ Collections.emptyList(),// TODO: Save content to variable
+ "on_wifi_connected"
+ )
+ .addTrigger(
+ "on_wifi_disconnected",
+ "When WIFI connection is lost",
+ Collections.emptyList(),
+ "on_wifi_disconnected"
+ );
+
+ return builder;
}
}
diff --git a/app/src/main/java/com/codigoparallevar/minicards/bridge/blocks/OperationBlockDefinition.java b/app/src/main/java/com/codigoparallevar/minicards/bridge/blocks/OperationBlockDefinition.java
index 4d48d5c..95503e7 100644
--- a/app/src/main/java/com/codigoparallevar/minicards/bridge/blocks/OperationBlockDefinition.java
+++ b/app/src/main/java/com/codigoparallevar/minicards/bridge/blocks/OperationBlockDefinition.java
@@ -13,7 +13,7 @@ import org.json.JSONObject;
import java.util.List;
class OperationBlockDefinition implements ProgramakerBridgeConfigurationBlock {
- private final static String LogTag = "PM OpBlockDefinition";
+ private final static String LogTag = "PM OpBlockDef";
private final String id;
private final String message;
diff --git a/app/src/main/java/com/codigoparallevar/minicards/bridge/blocks/TriggerBlockDefinition.java b/app/src/main/java/com/codigoparallevar/minicards/bridge/blocks/TriggerBlockDefinition.java
new file mode 100644
index 0000000..fc989ca
--- /dev/null
+++ b/app/src/main/java/com/codigoparallevar/minicards/bridge/blocks/TriggerBlockDefinition.java
@@ -0,0 +1,67 @@
+package com.codigoparallevar.minicards.bridge.blocks;
+
+import android.util.Log;
+
+import com.programaker.bridge.ProgramakerBridgeConfigurationBlock;
+
+import org.jetbrains.annotations.NotNull;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.List;
+
+class TriggerBlockDefinition implements ProgramakerBridgeConfigurationBlock {
+ private final static String LogTag = "PM TriggerBlockDef";
+
+ private final String id;
+ private final String message;
+ private final List args;
+ private final String key;
+
+ public TriggerBlockDefinition(String id, String message, List args,
+ String key) {
+ this.id = id;
+ this.message = message;
+ this.args = args;
+ this.key = key;
+ }
+
+ @NotNull
+ @Override
+ public JSONObject serialize() {
+ JSONObject obj = new JSONObject();
+
+ try {
+ JSONArray arguments = new JSONArray();
+ for (BlockArgumentDefinition arg : this.args) {
+ arguments.put(arg.serialize());
+ }
+
+ obj.put("id", this.id);
+ obj.put("function_name", this.id);
+ obj.put("message", this.message);
+ obj.put("arguments", arguments);
+ obj.put("save_to", JSONObject.NULL);
+ obj.put("expected_value", JSONObject.NULL);
+ obj.put("block_type", "trigger");
+ obj.put("key", this.key);
+ obj.put("subkey", JSONObject.NULL);
+ } catch (JSONException ex) {
+ Log.e(LogTag, "Error serializing block definition: " + ex, ex);
+ }
+
+ return obj;
+ }
+
+ @NotNull
+ @Override
+ public String getFunctionName() {
+ return this.id;
+ }
+
+ @Override
+ public void call(@NotNull List> arguments) throws Exception {
+ throw new IllegalArgumentException("Non executable block");
+ }
+}
diff --git a/app/src/main/java/com/codigoparallevar/minicards/bridge/helpers/StatusStreamer.java b/app/src/main/java/com/codigoparallevar/minicards/bridge/helpers/StatusStreamer.java
new file mode 100644
index 0000000..41b90a9
--- /dev/null
+++ b/app/src/main/java/com/codigoparallevar/minicards/bridge/helpers/StatusStreamer.java
@@ -0,0 +1,78 @@
+package com.codigoparallevar.minicards.bridge.helpers;
+
+import android.content.Context;
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.net.wifi.SupplicantState;
+import android.net.wifi.WifiInfo;
+import android.net.wifi.WifiManager;
+import android.os.Build;
+
+import com.programaker.bridge.ProgramakerBridge;
+
+import org.json.JSONObject;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class StatusStreamer {
+ private final Context ctx;
+ private final ProgramakerBridge bridge;
+ private WifiNetworkCallbackReceiver networkCallback = null;
+
+ public StatusStreamer(Context ctx, ProgramakerBridge bridge) {
+ this.ctx = ctx;
+ this.bridge = bridge;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ this.networkCallback = new WifiNetworkCallbackReceiver(this);
+ }
+ }
+
+ public void run() {
+
+ if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
+ return;
+ }
+
+ NetworkRequest.Builder builder = new NetworkRequest.Builder();
+ builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
+
+ ConnectivityManager connManager = (ConnectivityManager) this.ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
+ assert connManager != null;
+
+ connManager.registerNetworkCallback(builder.build(), this.networkCallback);
+ }
+
+ public void stop() {
+ ConnectivityManager connManager = (ConnectivityManager) this.ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
+ assert connManager != null;
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
+ connManager.unregisterNetworkCallback(this.networkCallback);
+ }
+ }
+
+ public void onWifiNetworkConnected(Network network) {
+ WifiManager wifiManager = (WifiManager) this.ctx.getSystemService(Context.WIFI_SERVICE);
+ WifiInfo wifiInfo;
+
+ wifiInfo = wifiManager.getConnectionInfo();
+ String ssid = "";
+ if (wifiInfo.getSupplicantState() == SupplicantState.COMPLETED) {
+ // This might not return the SSID in case the user has not granted location permissions to the app
+ // see: https://stackoverflow.com/a/54446042
+ ssid = wifiInfo.getSSID();
+ }
+
+ Map data = new HashMap<>();
+ data.put("ssid", ssid);
+
+ this.bridge.sendSignal("on_wifi_connected", new JSONObject(data));
+ }
+
+ public void onWifiNetworkDisconnected() {
+ this.bridge.sendSignal("on_wifi_disconnected", new JSONObject());
+ }
+}
diff --git a/app/src/main/java/com/codigoparallevar/minicards/bridge/helpers/WifiNetworkCallbackReceiver.java b/app/src/main/java/com/codigoparallevar/minicards/bridge/helpers/WifiNetworkCallbackReceiver.java
new file mode 100644
index 0000000..b958397
--- /dev/null
+++ b/app/src/main/java/com/codigoparallevar/minicards/bridge/helpers/WifiNetworkCallbackReceiver.java
@@ -0,0 +1,34 @@
+package com.codigoparallevar.minicards.bridge.helpers;
+
+import android.net.ConnectivityManager;
+import android.net.Network;
+import android.os.Build;
+
+import androidx.annotation.RequiresApi;
+
+@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
+class WifiNetworkCallbackReceiver extends ConnectivityManager.NetworkCallback {
+ private final StatusStreamer streamer;
+
+ public WifiNetworkCallbackReceiver(StatusStreamer statusStreamer) {
+ this.streamer = statusStreamer;
+ }
+
+ @Override
+ public void onAvailable(Network network) {
+ super.onAvailable(network);
+ this.streamer.onWifiNetworkConnected(network);
+ }
+
+ @Override
+ public void onUnavailable() {
+ super.onUnavailable();
+ this.streamer.onWifiNetworkDisconnected();
+ }
+
+ @Override
+ public void onLost(Network network) {
+ super.onLost(network);
+ this.streamer.onWifiNetworkDisconnected();
+ }
+}
diff --git a/app/src/main/java/com/programaker/bridge/ProgramakerBridge.kt b/app/src/main/java/com/programaker/bridge/ProgramakerBridge.kt
index fa05cf7..6fe418e 100644
--- a/app/src/main/java/com/programaker/bridge/ProgramakerBridge.kt
+++ b/app/src/main/java/com/programaker/bridge/ProgramakerBridge.kt
@@ -173,4 +173,21 @@ class ProgramakerBridge(
fun stop() {
webSocket?.close(1000, null)
}
+
+ fun sendSignal(key: String, content: JSONObject) {
+ if (webSocket == null) {
+ Log.w(LogTag, "Cannot send signal (key=$key) on closed channel")
+ return
+ }
+
+ webSocket!!.send(JSONObject(hashMapOf(
+ "type" to "NOTIFICATION",
+ "key" to key,
+ "subkey" to JSONObject.NULL,
+ "to_user" to JSONObject.NULL,
+ "value" to content,
+ "content" to content
+ )
+ ).toString())
+ }
}
\ No newline at end of file