diff --git a/Android/ZeroConf/ZeroConf.java b/Android/ZeroConf/ZeroConf.java index ff2035b8..2b83904b 100644 --- a/Android/ZeroConf/ZeroConf.java +++ b/Android/ZeroConf/ZeroConf.java @@ -4,14 +4,14 @@ * @author Matt Kane * Copyright (c) Triggertrap Ltd. 2012. All Rights Reserved. * Available under the terms of the MIT License. - * + * */ package com.triggertrap; import java.io.IOException; - -import org.apache.cordova.api.Plugin; +import org.apache.cordova.api.CallbackContext; +import org.apache.cordova.api.CordovaPlugin; import org.apache.cordova.api.PluginResult; import org.apache.cordova.api.PluginResult.Status; import org.json.JSONArray; @@ -26,124 +26,110 @@ import javax.jmdns.ServiceInfo; import javax.jmdns.ServiceListener; -public class ZeroConf extends Plugin { - WifiManager.MulticastLock lock; +public class ZeroConf extends CordovaPlugin { + WifiManager.MulticastLock lock; private JmDNS jmdns = null; private ServiceListener listener; - private String callback; - - @Override - public PluginResult execute(String action, JSONArray args, String callbackId) { - this.callback = callbackId; + private static final String LOG_TAG = "ZeroConf"; + @Override + public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { + Log.d(LOG_TAG,"action:" + action + " callbackId:" + callbackContext.getCallbackId() ); if (action.equals("watch")) { String type = args.optString(0); if (type != null) { - watch(type); + try { + watch(type, callbackContext); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + PluginResult pluginResult = new PluginResult(PluginResult.Status.NO_RESULT); + pluginResult.setKeepCallback(true); + callbackContext.sendPluginResult(pluginResult); } else { - return new PluginResult(PluginResult.Status.ERROR, "Service type not specified"); + callbackContext.error("Service type not specified."); } } else if (action.equals("unwatch")) { String type = args.optString(0); if (type != null) { - unwatch(type); + unwatch(type); } else { - return new PluginResult(PluginResult.Status.ERROR, "Service type not specified"); + callbackContext.error("Service type not specified."); } } else if (action.equals("register")) { JSONObject obj = args.optJSONObject(0); if (obj != null) { - String type = obj.optString("type"); - String name = obj.optString("name"); - int port = obj.optInt("port"); - String text = obj.optString("text"); - if(type == null) { - return new PluginResult(PluginResult.Status.ERROR, "Missing required service info"); - } - register(type, name, port, text); + String type = obj.optString("type"); + String name = obj.optString("name"); + int port = obj.optInt("port"); + String text = obj.optString("text"); + if(type == null) { + callbackContext.error("Missing required service info."); + } + register(type, name, port, text); } else { - return new PluginResult(PluginResult.Status.ERROR, "Missing required service info"); + callbackContext.error("Missing required service info."); + } + } else if (action.equals("close")) { + if(jmdns != null) { + try { + jmdns.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } else if (action.equals("unregister")) { + if(jmdns != null) { + jmdns.unregisterAllServices(); } - - } else if (action.equals("close")) { - if(jmdns != null) { - try { - jmdns.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } else if (action.equals("unregister")) { - if(jmdns != null) { - jmdns.unregisterAllServices(); - } - + } else if (action.equals("list")) { + String type = args.optString(0); + int timeout = args.optInt(1); + if (type != null) { + try { + list(type, timeout, callbackContext); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } else { + callbackContext.error("Service type not specified."); + } + } else { - Log.e("ZeroConf", "Invalid action: " + action); - return new PluginResult(PluginResult.Status.INVALID_ACTION); + Log.e(LOG_TAG, "Invalid action: " + action); + return false; } - PluginResult result = new PluginResult(Status.NO_RESULT); - result.setKeepCallback(true); - return result; - } - - private void watch(String type) { - if(jmdns == null) { - setupWatcher(); - } - Log.d("ZeroConf", "Watch " + type); - Log.d("ZeroConf", "Name: " + jmdns.getName() + " host: " + jmdns.getHostName()); - jmdns.addServiceListener(type, listener); - } - private void unwatch(String type) { - if(jmdns == null) { - return; - } - jmdns.removeServiceListener(type, listener); - } - - private void register (String type, String name, int port, String text) { - if(name == null) { - name = ""; - } - - if(text == null) { - text = ""; - } - - try { - ServiceInfo service = ServiceInfo.create(type, name, port, text); - jmdns.registerService(service); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private void setupWatcher() { - Log.d("ZeroConf", "Setup watcher"); - WifiManager wifi = (WifiManager) this.cordova.getActivity().getSystemService(android.content.Context.WIFI_SERVICE); + PluginResult result = new PluginResult(Status.NO_RESULT); + result.setKeepCallback(true); + callbackContext.sendPluginResult(result); + return true; + } + + private void watch(String type, final CallbackContext callbackContext) throws IOException { + WifiManager wifi = (WifiManager) this.cordova.getActivity().getSystemService(android.content.Context.WIFI_SERVICE); lock = wifi.createMulticastLock("ZeroConfPluginLock"); lock.setReferenceCounted(true); lock.acquire(); try { - jmdns = JmDNS.create(); + if(jmdns == null) { + jmdns = JmDNS.create(); + } listener = new ServiceListener() { public void serviceResolved(ServiceEvent ev) { - Log.d("ZeroConf", "Resolved"); - - sendCallback("added", ev.getInfo()); + Log.d(LOG_TAG, "Resolved"); + sendCallback("added", ev.getInfo(), callbackContext); } public void serviceRemoved(ServiceEvent ev) { - Log.d("ZeroConf", "Removed"); - - sendCallback("removed", ev.getInfo()); + Log.d(LOG_TAG, "Removed"); + sendCallback("removed", ev.getInfo(), callbackContext); } public void serviceAdded(ServiceEvent event) { - Log.d("ZeroConf", "Added"); - + Log.d(LOG_TAG, "Added"); // Force serviceResolved to be called again jmdns.requestServiceInfo(event.getType(), event.getName(), 1); } @@ -153,62 +139,110 @@ public void serviceAdded(ServiceEvent event) { e.printStackTrace(); return; } - } - - public void sendCallback(String action, ServiceInfo info) { - JSONObject status = new JSONObject(); - try { - status.put("action", action); - status.put("service", jsonifyService(info)); - Log.d("ZeroConf", "Sending result: " + status.toString()); - - PluginResult result = new PluginResult(PluginResult.Status.OK, status); - result.setKeepCallback(true); - this.success(result, this.callback); - - } catch (JSONException e) { - - e.printStackTrace(); - } - - - } - - - public static JSONObject jsonifyService(ServiceInfo info) { - JSONObject obj = new JSONObject(); - try { - obj.put("application", info.getApplication()); - obj.put("domain", info.getDomain()); - obj.put("port", info.getPort()); - obj.put("name", info.getName()); - obj.put("server", info.getServer()); - obj.put("description", info.getNiceTextString()); - obj.put("protocol", info.getProtocol()); - obj.put("qualifiedname", info.getQualifiedName()); - obj.put("type", info.getType()); - - JSONArray addresses = new JSONArray(); - String[] add = info.getHostAddresses(); - for(int i = 0; i < add.length; i++) { - addresses.put(add[i]); - } - obj.put("addresses", addresses); - JSONArray urls = new JSONArray(); - - String[] url = info.getURLs(); - for(int i = 0; i < url.length; i++) { - urls.put(url[i]); - } - obj.put("urls", urls); - - } catch (JSONException e) { - e.printStackTrace(); - return null; - } - - return obj; - - } - + + Log.d(LOG_TAG, "Watch " + type); + Log.d(LOG_TAG, "Name: " + jmdns.getName() + " host: " + jmdns.getHostName()); + jmdns.addServiceListener(type, listener); + } + + private void unwatch(String type) { + if(jmdns == null) { + return; + } + jmdns.removeServiceListener(type, listener); + } + + private void register (String type, String name, int port, String text) { + if(name == null) { + name = ""; + } + + if(text == null) { + text = ""; + } + + try { + ServiceInfo service = ServiceInfo.create(type, name, port, text); + jmdns.registerService(service); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void list(final String type, final int timeout, final CallbackContext callbackContext) throws IOException { + if(jmdns == null) { + jmdns = JmDNS.create(); + } + cordova.getThreadPool().execute(new Runnable() { + public void run() { + ServiceInfo[] serviceInfoList; + serviceInfoList = jmdns.list(type, timeout); + JSONArray services = new JSONArray(); + if (serviceInfoList != null) { + for (int index = 0; index < serviceInfoList.length; index++) { + services.put(jsonifyService(serviceInfoList[index])); + } + } + + Log.d(LOG_TAG, "List " + type); + Log.d(LOG_TAG, "Name: " + jmdns.getName() + " host: " + jmdns.getHostName()); + //PluginResult result = new PluginResult(PluginResult.Status.OK, services); + //result.setKeepCallback(true); + //callbackContext.sendPluginResult(result); + callbackContext.success(services); // Thread-safe. + } + }); + + } + + private void sendCallback(String action, ServiceInfo info, CallbackContext callbackContext) { + JSONObject status = new JSONObject(); + try { + status.put("action", action); + status.put("service", jsonifyService(info)); + Log.d(LOG_TAG, "Sending result: " + status.toString()); + PluginResult result = new PluginResult(PluginResult.Status.OK, status); + result.setKeepCallback(true); + callbackContext.sendPluginResult(result); + } catch (JSONException e) { + e.printStackTrace(); + } + } + + + public static JSONObject jsonifyService(ServiceInfo info) { + JSONObject obj = new JSONObject(); + try { + obj.put("application", info.getApplication()); + obj.put("domain", info.getDomain()); + obj.put("port", info.getPort()); + obj.put("name", info.getName()); + obj.put("server", info.getServer()); + obj.put("description", info.getNiceTextString()); + obj.put("protocol", info.getProtocol()); + obj.put("qualifiedname", info.getQualifiedName()); + obj.put("type", info.getType()); + + JSONArray addresses = new JSONArray(); + String[] add = info.getHostAddresses(); + for(int i = 0; i < add.length; i++) { + addresses.put(add[i]); + } + obj.put("addresses", addresses); + JSONArray urls = new JSONArray(); + + String[] url = info.getURLs(); + for(int i = 0; i < url.length; i++) { + urls.put(url[i]); + } + obj.put("urls", urls); + + } catch (JSONException e) { + e.printStackTrace(); + return null; + } + + return obj; + } + } diff --git a/Android/ZeroConf/ZeroConf.js b/Android/ZeroConf/ZeroConf.js index 1fbc2ea9..acec59af 100644 --- a/Android/ZeroConf/ZeroConf.js +++ b/Android/ZeroConf/ZeroConf.js @@ -1,37 +1,59 @@ /** - * ZeroConf plugin for Cordova/Phonegap + * ZeroConf plugin for Cordova/Phonecordova * * @author Matt Kane * Copyright (c) Triggertrap Ltd. 2012. All Rights Reserved. * Available under the terms of the MIT License. - * + * */ -var ZeroConf = { - watch: function(type, callback) { - return cordova.exec(function(result) { - if(callback) { - callback(result); - } - - }, ZeroConf.fail, "ZeroConf", "watch", [type]); - }, - unwatch: function(type) { - return cordova.exec(null, ZeroConf.fail, "ZeroConf", "unwatch", [type]); - }, - close: function() { - return cordova.exec(null, ZeroConf.fail, "ZeroConf", "close", []) - }, - register: function(type, name, port, text) { - if(!type) { - console.error("'type' is a required field"); - return; - } - return cordova.exec(null, ZeroConf.fail, "ZeroConf", "register", [type, name, port, text]); - } - unregister: function() { - return cordova.exec(null, ZeroConf.fail, "ZeroConf", "unregister", []) - }, - fail: function (o) { - console.error("Error " + JSON.stringify(o)); - } -} \ No newline at end of file +var ZeroConf = function() { }; + +ZeroConf.prototype.watch = function(type, callback) { + return cordova.exec(function(result) { + if(callback) { + callback(result); + } + + }, ZeroConf.fail, "ZeroConf", "watch", [type]); +}; + +ZeroConf.prototype.list = function(type, timeout, callback) { + return cordova.exec(function(result) { + if(callback) { + callback(result); + } + + }, ZeroConf.fail, "ZeroConf", "list", [type,timeout]); +}; + +ZeroConf.prototype.unwatch = function(type) { + return cordova.exec(null, ZeroConf.fail, "ZeroConf", "unwatch", [type]); +}; + +ZeroConf.prototype.close = function() { + return cordova.exec(null, ZeroConf.fail, "ZeroConf", "close", []); +}; + +ZeroConf.prototype.register = function(type, name, port, text) { + if(!type) { + console.error("'type' is a required field"); + return; + } + return cordova.exec(null, ZeroConf.fail, "ZeroConf", "register", [type, name, port, text]); +}; + +ZeroConf.prototype.unregister = function() { + return cordova.exec(null, ZeroConf.fail, "ZeroConf", "unregister", []); +}; + +ZeroConf.prototype.fail = function (o) { + console.error("Error " + JSON.stringify(o)); +}; + + +if(!window.plugins) { + window.plugins = {}; +} +if (!window.plugins.ZeroConf) { + window.plugins.ZeroConf = new ZeroConf(); +}