From a4ec049c18ee4e160c5ff01d51ecdd18febb0e8a Mon Sep 17 00:00:00 2001 From: Mark Finkle Date: Sun, 30 Mar 2014 23:45:52 -0400 Subject: [PATCH] Bug 975123 - Allow for fixed targets/devices for situations where routers block UDP broadcasts r=wesj --- .../android/base/tests/testSimpleDiscovery.js | 2 +- .../modules/SimpleServiceDiscovery.jsm | 62 +++++++++++++++++-- 2 files changed, 57 insertions(+), 7 deletions(-) diff --git a/mobile/android/base/tests/testSimpleDiscovery.js b/mobile/android/base/tests/testSimpleDiscovery.js index 2c69a726007..0b4005d5c96 100644 --- a/mobile/android/base/tests/testSimpleDiscovery.js +++ b/mobile/android/base/tests/testSimpleDiscovery.js @@ -40,7 +40,7 @@ add_test(function test_default() { do_print("Force a detailed ping from a pretend service"); // Poke the service directly to get the discovery to happen - SimpleServiceDiscovery._found(service); + SimpleServiceDiscovery._processService(service); }); run_next_test(); diff --git a/mobile/android/modules/SimpleServiceDiscovery.jsm b/mobile/android/modules/SimpleServiceDiscovery.jsm index c7554df3e26..60c23a323c3 100644 --- a/mobile/android/modules/SimpleServiceDiscovery.jsm +++ b/mobile/android/modules/SimpleServiceDiscovery.jsm @@ -50,6 +50,15 @@ var SimpleServiceDiscovery = { _searchTimeout: Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer), _searchRepeat: Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer), + _forceTrailingSlash: function(aURL) { + // Some devices add the trailing '/' and some don't. Let's make sure + // it's there for consistency. + if (!aURL.endsWith("/")) { + aURL += "/"; + } + return aURL; + }, + // nsIUDPSocketListener implementation onPacketReceived: function(aSocket, aMessage) { // Listen for responses from specific targets. There could be more than one @@ -70,13 +79,19 @@ var SimpleServiceDiscovery = { } if (location && valid) { + location = this._forceTrailingSlash(location); + // When we find a valid response, package up the service information // and pass it on. let service = { location: location, target: target }; - this._found(service); + + try { + this._processService(service); + } catch (e) {} + return true; } return false; @@ -119,6 +134,14 @@ var SimpleServiceDiscovery = { return; } + // Update the timestamp so we can use it to clean out stale services the + // next time we search. + this._searchTimestamp = Date.now(); + + // Look for any fixed IP targets. Some routers might be configured to block + // UDP broadcasts, so this is a way to skip discovery. + this._searchFixedTargets(); + // Perform a UDP broadcast to search for SSDP devices let socket = Cc["@mozilla.org/network/udp-socket;1"].createInstance(Ci.nsIUDPSocket); try { @@ -131,10 +154,6 @@ var SimpleServiceDiscovery = { return; } - // Update the timestamp so we can use it to clean out stale services the - // next time we search. - this._searchTimestamp = Date.now(); - this._searchSocket = socket; this._searchTimeout.initWithCallback(this._searchShutdown.bind(this), SSDP_DISCOVER_TIMEOUT, Ci.nsITimer.TYPE_ONE_SHOT); @@ -150,6 +169,37 @@ var SimpleServiceDiscovery = { } }, + _searchFixedTargets: function _searchFixedTargets() { + let fixedTargets = null; + try { + fixedTargets = Services.prefs.getCharPref("browser.casting.fixedTargets"); + } catch (e) {} + + if (!fixedTargets) { + return; + } + + fixedTargets = JSON.parse(fixedTargets); + for (let fixedTarget of fixedTargets) { + // Verify we have the right data + if (!"location" in fixedTarget || !"target" in fixedTarget) { + continue; + } + + fixedTarget.location = this._forceTrailingSlash(fixedTarget.location); + + let service = { + location: fixedTarget.location, + target: fixedTarget.target + }; + + // We don't assume the fixed target is ready. We still need to ping it. + try { + this._processService(service); + } catch (e) {} + } + }, + // Called when the search timeout is hit. We use it to cleanup the socket and // perform some post-processing on the services list. _searchShutdown: function _searchShutdown() { @@ -202,7 +252,7 @@ var SimpleServiceDiscovery = { return array; }, - _found: function _found(aService) { + _processService: function _processService(aService) { // Use the REST api to request more information about this service let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest); xhr.open("GET", aService.location, true);