mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1194049 - Part 4: clear discovered devices when re-discover; r=schien
This commit is contained in:
parent
954342b979
commit
c8a3adf7a3
@ -153,6 +153,11 @@ PresentationDeviceManager::GetAvailableDevices(nsIArray** aRetVal)
|
||||
NS_ENSURE_ARG_POINTER(aRetVal);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Bug 1194049: some providers may discontinue discovery after timeout.
|
||||
// Call |ForceDiscovery()| here to make sure device lists are updated.
|
||||
NS_DispatchToMainThread(
|
||||
NS_NewRunnableMethod(this, &PresentationDeviceManager::ForceDiscovery));
|
||||
|
||||
nsCOMPtr<nsIMutableArray> devices = do_CreateInstance(NS_ARRAY_CONTRACTID);
|
||||
for (uint32_t i = 0; i < mDevices.Length(); ++i) {
|
||||
devices->AppendElement(mDevices[i], false);
|
||||
|
@ -13,7 +13,7 @@ interface nsIPresentationDeviceProvider;
|
||||
%}
|
||||
|
||||
/*
|
||||
* Manager for the device availablility. User can observe "presentation-device-change"
|
||||
* Manager for the device availability. User can observe "presentation-device-change"
|
||||
* for any update of the available devices.
|
||||
*/
|
||||
[scriptable, uuid(beb61db5-3d5f-454f-a15a-dbfa0337c569)]
|
||||
@ -41,6 +41,8 @@ interface nsIPresentationDeviceManager : nsISupports
|
||||
|
||||
/*
|
||||
* Retrieve all available devices, return a list of nsIPresentationDevice.
|
||||
* The returned list is a cached device list and could be out-of-date.
|
||||
* Observe device change events to get following updates.
|
||||
*/
|
||||
nsIArray getAvailableDevices();
|
||||
};
|
||||
|
@ -159,6 +159,8 @@ MulticastDNSDeviceProvider::Uninit()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
ClearDevices();
|
||||
|
||||
Preferences::RemoveObservers(this, kObservedPrefs);
|
||||
|
||||
StopDiscovery(NS_OK);
|
||||
@ -244,6 +246,8 @@ MulticastDNSDeviceProvider::UnregisterService(nsresult aReason)
|
||||
nsresult
|
||||
MulticastDNSDeviceProvider::StopDiscovery(nsresult aReason)
|
||||
{
|
||||
LOG_I("StopDiscovery (0x%08x)", aReason);
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mDiscoveryTimer);
|
||||
|
||||
@ -257,6 +261,163 @@ MulticastDNSDeviceProvider::StopDiscovery(nsresult aReason)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MulticastDNSDeviceProvider::AddDevice(const nsACString& aServiceName,
|
||||
const nsACString& aServiceType,
|
||||
const nsACString& aHost,
|
||||
const uint16_t aPort)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mPresentationServer);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIPresentationDevice> device;
|
||||
if (NS_WARN_IF(NS_FAILED(rv =
|
||||
mPresentationServer->CreateTCPDevice(aHost, /* ID */
|
||||
aServiceName,
|
||||
aServiceType,
|
||||
aHost,
|
||||
aPort,
|
||||
getter_AddRefs(device))))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresentationDeviceListener> listener;
|
||||
if (NS_SUCCEEDED(GetListener(getter_AddRefs(listener))) && listener) {
|
||||
unused << listener->AddDevice(device);
|
||||
}
|
||||
|
||||
mDevices.AppendElement(Device(aHost, DeviceState::eActive));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MulticastDNSDeviceProvider::UpdateDevice(const uint32_t aIndex,
|
||||
const nsACString& aServiceName,
|
||||
const nsACString& aServiceType,
|
||||
const nsACString& aHost,
|
||||
const uint16_t aPort)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mPresentationServer);
|
||||
|
||||
if (NS_WARN_IF(aIndex >= mDevices.Length())) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIPresentationDevice> device;
|
||||
if (NS_WARN_IF(NS_FAILED(rv =
|
||||
mPresentationServer->UpdateTCPDevice(aHost, /* ID */
|
||||
aServiceName,
|
||||
aServiceType,
|
||||
aHost,
|
||||
aPort,
|
||||
getter_AddRefs(device))))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresentationDeviceListener> listener;
|
||||
if (NS_SUCCEEDED(GetListener(getter_AddRefs(listener))) && listener) {
|
||||
unused << listener->UpdateDevice(device);
|
||||
}
|
||||
|
||||
mDevices[aIndex].state = DeviceState::eActive;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MulticastDNSDeviceProvider::RemoveDevice(const uint32_t aIndex)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mPresentationServer);
|
||||
|
||||
if (NS_WARN_IF(aIndex >= mDevices.Length())) {
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
nsCString deviceId = mDevices[aIndex].id;
|
||||
LOG_I("RemoveDevice: %s", deviceId.get());
|
||||
|
||||
nsCOMPtr<nsIPresentationDevice> device;
|
||||
if (NS_FAILED(mPresentationServer->GetTCPDevice(deviceId,
|
||||
getter_AddRefs(device)))) {
|
||||
LOG_I("ignore non-existing device: %s", deviceId.get());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
if (NS_WARN_IF(NS_FAILED(rv = mPresentationServer->RemoveTCPDevice(deviceId)))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresentationDeviceListener> listener;
|
||||
if (NS_SUCCEEDED(GetListener(getter_AddRefs(listener))) && listener) {
|
||||
unused << listener->RemoveDevice(device);
|
||||
}
|
||||
|
||||
mDevices.RemoveElementAt(aIndex);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
MulticastDNSDeviceProvider::FindDevice(const nsACString& aId,
|
||||
uint32_t& aIndex)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
size_t index = mDevices.IndexOf(Device(aId, DeviceState::eUnknown),
|
||||
0,
|
||||
DeviceIdComparator());
|
||||
|
||||
if (index == mDevices.NoIndex) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aIndex = index;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
MulticastDNSDeviceProvider::MarkAllDevicesUnknown()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
for (auto& device : mDevices) {
|
||||
device.state = DeviceState::eUnknown;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MulticastDNSDeviceProvider::ClearUnknownDevices()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
size_t i = mDevices.Length();
|
||||
while (i > 0) {
|
||||
--i;
|
||||
if (mDevices[i].state == DeviceState::eUnknown) {
|
||||
NS_WARN_IF(NS_FAILED(RemoveDevice(i)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MulticastDNSDeviceProvider::ClearDevices()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
size_t i = mDevices.Length();
|
||||
while (i > 0) {
|
||||
--i;
|
||||
NS_WARN_IF(NS_FAILED(RemoveDevice(i)));
|
||||
}
|
||||
}
|
||||
|
||||
// nsIPresentationDeviceProvider
|
||||
NS_IMETHODIMP
|
||||
MulticastDNSDeviceProvider::GetListener(nsIPresentationDeviceListener** aListener)
|
||||
@ -267,7 +428,13 @@ MulticastDNSDeviceProvider::GetListener(nsIPresentationDeviceListener** aListene
|
||||
return NS_ERROR_INVALID_POINTER;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresentationDeviceListener> listener = do_QueryReferent(mDeviceListener);
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPresentationDeviceListener> listener =
|
||||
do_QueryReferent(mDeviceListener, &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
listener.forget(aListener);
|
||||
|
||||
return NS_OK;
|
||||
@ -304,8 +471,19 @@ MulticastDNSDeviceProvider::ForceDiscovery()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(mDiscoveryTimer);
|
||||
MOZ_ASSERT(mMulticastDNS);
|
||||
|
||||
// if it's already discovering, extend existing discovery timeout.
|
||||
if (mIsDiscovering) {
|
||||
unused << mDiscoveryTimer->Cancel();
|
||||
|
||||
NS_WARN_IF(NS_FAILED(mDiscoveryTimer->Init(this,
|
||||
mDiscveryTimeoutMs,
|
||||
nsITimer::TYPE_ONE_SHOT)));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
StopDiscovery(NS_OK);
|
||||
|
||||
nsresult rv;
|
||||
@ -327,6 +505,8 @@ MulticastDNSDeviceProvider::OnDiscoveryStarted(const nsACString& aServiceType)
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mDiscoveryTimer);
|
||||
|
||||
MarkAllDevicesUnknown();
|
||||
|
||||
nsresult rv;
|
||||
if (NS_WARN_IF(NS_FAILED(rv = mDiscoveryTimer->Init(this,
|
||||
mDiscveryTimeoutMs,
|
||||
@ -334,6 +514,8 @@ MulticastDNSDeviceProvider::OnDiscoveryStarted(const nsACString& aServiceType)
|
||||
return rv;
|
||||
}
|
||||
|
||||
mIsDiscovering = true;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -343,6 +525,10 @@ MulticastDNSDeviceProvider::OnDiscoveryStopped(const nsACString& aServiceType)
|
||||
LOG_I("OnDiscoveryStopped");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
ClearUnknownDevices();
|
||||
|
||||
mIsDiscovering = false;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -369,13 +555,6 @@ MulticastDNSDeviceProvider::OnServiceFound(nsIDNSServiceInfo* aServiceInfo)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresentationDevice> device;
|
||||
if (NS_SUCCEEDED(mPresentationServer->GetTCPDevice(serviceName,
|
||||
getter_AddRefs(device)))) {
|
||||
LOG_I("device exists");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mMulticastDNS) {
|
||||
if (NS_WARN_IF(NS_FAILED(rv = mMulticastDNS->ResolveService(
|
||||
aServiceInfo, mWrappedListener)))) {
|
||||
@ -404,18 +583,19 @@ MulticastDNSDeviceProvider::OnServiceLost(nsIDNSServiceInfo* aServiceInfo)
|
||||
|
||||
LOG_I("OnServiceLost: %s", serviceName.get());
|
||||
|
||||
nsCOMPtr<nsIPresentationDevice> device;
|
||||
if (NS_FAILED(mPresentationServer->GetTCPDevice(serviceName,
|
||||
getter_AddRefs(device)))) {
|
||||
return NS_OK; // ignore non-existing device;
|
||||
nsAutoCString host;
|
||||
if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetHost(host)))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_WARN_IF(NS_FAILED(mPresentationServer->RemoveTCPDevice(serviceName)));
|
||||
uint32_t index;
|
||||
if (!FindDevice(host, index)) {
|
||||
// given device was not found
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresentationDeviceListener> listener;
|
||||
GetListener(getter_AddRefs(listener));
|
||||
if (listener) {
|
||||
listener->RemoveDevice(device);
|
||||
if (NS_WARN_IF(NS_FAILED(rv = RemoveDevice(index)))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -525,18 +705,6 @@ MulticastDNSDeviceProvider::OnServiceResolved(nsIDNSServiceInfo* aServiceInfo)
|
||||
|
||||
LOG_I("OnServiceResolved: %s", serviceName.get());
|
||||
|
||||
nsCOMPtr<nsIPresentationDevice> device;
|
||||
nsCOMPtr<nsIPresentationDeviceListener> listener;
|
||||
GetListener(getter_AddRefs(listener));
|
||||
|
||||
if (NS_SUCCEEDED(mPresentationServer->GetTCPDevice(serviceName,
|
||||
getter_AddRefs(device)))) {
|
||||
NS_WARN_IF(NS_FAILED(mPresentationServer->RemoveTCPDevice(serviceName)));
|
||||
if (listener) {
|
||||
NS_WARN_IF(NS_FAILED(listener->RemoveDevice(device)));
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoCString host;
|
||||
if (NS_WARN_IF(NS_FAILED(rv = aServiceInfo->GetHost(host)))) {
|
||||
return rv;
|
||||
@ -552,17 +720,18 @@ MulticastDNSDeviceProvider::OnServiceResolved(nsIDNSServiceInfo* aServiceInfo)
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(rv = mPresentationServer->CreateTCPDevice(serviceName,
|
||||
serviceName,
|
||||
serviceType,
|
||||
host,
|
||||
port,
|
||||
getter_AddRefs(device))))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (listener) {
|
||||
listener->AddDevice(device);
|
||||
uint32_t index;
|
||||
if (FindDevice(host, index)) {
|
||||
return UpdateDevice(index,
|
||||
serviceName,
|
||||
serviceType,
|
||||
host,
|
||||
port);
|
||||
} else {
|
||||
return AddDevice(serviceName,
|
||||
serviceType,
|
||||
host,
|
||||
port);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -670,9 +839,9 @@ MulticastDNSDeviceProvider::OnDiscoverableChanged(bool aEnabled)
|
||||
}
|
||||
|
||||
nsresult
|
||||
MulticastDNSDeviceProvider::OnServiceNameChanged(const nsCString& aServiceName)
|
||||
MulticastDNSDeviceProvider::OnServiceNameChanged(const nsACString& aServiceName)
|
||||
{
|
||||
LOG_I("serviceName = %s\n", aServiceName.get());
|
||||
LOG_I("serviceName = %s\n", PromiseFlatCString(aServiceName).get());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mServiceName = aServiceName;
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "nsITCPPresentationServer.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsWeakPtr.h"
|
||||
|
||||
namespace mozilla {
|
||||
@ -46,15 +47,55 @@ public:
|
||||
nsresult Uninit();
|
||||
|
||||
private:
|
||||
enum class DeviceState : uint32_t {
|
||||
eUnknown,
|
||||
eActive
|
||||
};
|
||||
|
||||
struct Device final {
|
||||
explicit Device(const nsACString& aId, DeviceState aState)
|
||||
: id(aId), state(aState)
|
||||
{
|
||||
}
|
||||
|
||||
nsCString id;
|
||||
DeviceState state;
|
||||
};
|
||||
|
||||
struct DeviceIdComparator {
|
||||
bool Equals(const Device& aA, const Device& aB) const {
|
||||
return aA.id == aB.id;
|
||||
}
|
||||
};
|
||||
|
||||
virtual ~MulticastDNSDeviceProvider();
|
||||
nsresult RegisterService();
|
||||
nsresult UnregisterService(nsresult aReason);
|
||||
nsresult StopDiscovery(nsresult aReason);
|
||||
|
||||
// device manipulation
|
||||
nsresult AddDevice(const nsACString& aServiceName,
|
||||
const nsACString& aServiceType,
|
||||
const nsACString& aHost,
|
||||
const uint16_t aPort);
|
||||
nsresult UpdateDevice(const uint32_t aIndex,
|
||||
const nsACString& aServiceName,
|
||||
const nsACString& aServiceType,
|
||||
const nsACString& aHost,
|
||||
const uint16_t aPort);
|
||||
nsresult RemoveDevice(const uint32_t aIndex);
|
||||
bool FindDevice(const nsACString& aId,
|
||||
uint32_t& aIndex);
|
||||
|
||||
void MarkAllDevicesUnknown();
|
||||
void ClearUnknownDevices();
|
||||
void ClearDevices();
|
||||
|
||||
// preferences
|
||||
nsresult OnDiscoveryChanged(bool aEnabled);
|
||||
nsresult OnDiscoveryTimeoutChanged(uint32_t aTimeoutMs);
|
||||
nsresult OnDiscoverableChanged(bool aEnabled);
|
||||
nsresult OnServiceNameChanged(const nsCString& aServiceName);
|
||||
nsresult OnServiceNameChanged(const nsACString& aServiceName);
|
||||
|
||||
bool mInitialized = false;
|
||||
nsWeakPtr mDeviceListener;
|
||||
@ -65,7 +106,10 @@ private:
|
||||
nsCOMPtr<nsICancelable> mDiscoveryRequest;
|
||||
nsCOMPtr<nsICancelable> mRegisterRequest;
|
||||
|
||||
nsTArray<Device> mDevices;
|
||||
|
||||
bool mDiscoveryEnabled = false;
|
||||
bool mIsDiscovering = false;
|
||||
uint32_t mDiscveryTimeoutMs;
|
||||
nsCOMPtr<nsITimer> mDiscoveryTimer;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* global Services, do_register_cleanup, do_test_pending */
|
||||
|
||||
"use strict";
|
||||
|
||||
@ -48,7 +49,7 @@ function ContractHook(aContractID, aClass) {
|
||||
this._newFactory = new MockFactory(aClass);
|
||||
|
||||
if (!this.hookedMap.has(this._contractID)) {
|
||||
this.hookedMap.set(this._contractID, new Array());
|
||||
this.hookedMap.set(this._contractID, []);
|
||||
}
|
||||
|
||||
this.init();
|
||||
@ -158,13 +159,26 @@ MockDNSServiceInfo.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
function TestPresentationDeviceListener() {}
|
||||
function TestPresentationDeviceListener() {
|
||||
this.devices = {};
|
||||
}
|
||||
TestPresentationDeviceListener.prototype = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceListener]),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceListener,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
|
||||
addDevice: function(device) {},
|
||||
removeDevice: function(device) {},
|
||||
updateDevice: function(device) {}
|
||||
addDevice: function(device) { this.devices[device.id] = device; },
|
||||
removeDevice: function(device) { delete this.devices[device.id]; },
|
||||
updateDevice: function(device) { this.devices[device.id] = device; },
|
||||
|
||||
count: function() {
|
||||
var size = 0, key;
|
||||
for (key in this.devices) {
|
||||
if (this.devices.hasOwnProperty(key)) {
|
||||
++size;
|
||||
}
|
||||
}
|
||||
return size;
|
||||
}
|
||||
};
|
||||
|
||||
function createDevice(host, port, serviceName, serviceType, domainName, attributes) {
|
||||
@ -337,26 +351,19 @@ function addDevice() {
|
||||
|
||||
let contractHook = new ContractHook(SD_CONTRACT_ID, mockObj);
|
||||
let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
|
||||
let listener = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceListener,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
addDevice: function(device) { this.devices.push(device); },
|
||||
removeDevice: function(device) {},
|
||||
updateDevice: function(device) {},
|
||||
devices: []
|
||||
};
|
||||
Assert.equal(listener.devices.length, 0);
|
||||
let listener = new TestPresentationDeviceListener();
|
||||
Assert.equal(listener.count(), 0);
|
||||
|
||||
// Start discovery
|
||||
provider.listener = listener;
|
||||
Assert.equal(listener.devices.length, 1);
|
||||
Assert.equal(listener.count(), 1);
|
||||
|
||||
// Force discovery again
|
||||
provider.forceDiscovery();
|
||||
Assert.equal(listener.devices.length, 1);
|
||||
Assert.equal(listener.count(), 1);
|
||||
|
||||
provider.listener = null;
|
||||
Assert.equal(listener.devices.length, 1);
|
||||
Assert.equal(listener.count(), 1);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
@ -424,24 +431,191 @@ function addDeviceDynamically() {
|
||||
|
||||
let contractHook = new ContractHook(SD_CONTRACT_ID, mockObj);
|
||||
let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
|
||||
let listener = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceListener,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
addDevice: function(device) { this.devices.push(device); },
|
||||
removeDevice: function(device) {},
|
||||
updateDevice: function(device) {},
|
||||
devices: []
|
||||
};
|
||||
let listener = new TestPresentationDeviceListener();
|
||||
provider.listener = listener;
|
||||
Assert.equal(listener.devices.length, 0);
|
||||
Assert.equal(listener.count(), 0);
|
||||
|
||||
// Enable discovery
|
||||
Services.prefs.setBoolPref(PREF_DISCOVERY, true);
|
||||
Assert.equal(listener.devices.length, 1);
|
||||
Assert.equal(listener.count(), 1);
|
||||
|
||||
// Try discovery again
|
||||
provider.forceDiscovery();
|
||||
Assert.equal(listener.devices.length, 1);
|
||||
Assert.equal(listener.count(), 1);
|
||||
|
||||
// Try discovery once more
|
||||
Services.prefs.setBoolPref(PREF_DISCOVERY, false);
|
||||
Services.prefs.setBoolPref(PREF_DISCOVERY, true);
|
||||
provider.forceDiscovery();
|
||||
Assert.equal(listener.count(), 1);
|
||||
|
||||
provider.listener = null;
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function updateDevice() {
|
||||
Services.prefs.setBoolPref(PREF_DISCOVERY, true);
|
||||
|
||||
let mockDevice1 = createDevice("A.local", 12345, "N1", "_mozilla_papi._tcp");
|
||||
let mockDevice2 = createDevice("A.local", 23456, "N2", "_mozilla_papi._tcp");
|
||||
|
||||
let mockObj = {
|
||||
discovered: false,
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
|
||||
startDiscovery: function(serviceType, listener) {
|
||||
listener.onDiscoveryStarted(serviceType);
|
||||
|
||||
if (!this.discovered) {
|
||||
listener.onServiceFound(mockDevice1);
|
||||
} else {
|
||||
listener.onServiceFound(mockDevice2);
|
||||
}
|
||||
this.discovered = true;
|
||||
|
||||
return {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
|
||||
cancel: function() {
|
||||
listener.onDiscoveryStopped(serviceType);
|
||||
}
|
||||
};
|
||||
},
|
||||
registerService: function(serviceInfo, listener) {},
|
||||
resolveService: function(serviceInfo, listener) {
|
||||
Assert.equal(serviceInfo.serviceType, "_mozilla_papi._tcp");
|
||||
if (serviceInfo.serviceName == "N1") {
|
||||
listener.onServiceResolved(mockDevice1);
|
||||
} else if (serviceInfo.serviceName == "N2") {
|
||||
listener.onServiceResolved(mockDevice2);
|
||||
} else {
|
||||
Assert.ok(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let contractHook = new ContractHook(SD_CONTRACT_ID, mockObj);
|
||||
let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
|
||||
let listener = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDeviceListener,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
|
||||
addDevice: function(device) {
|
||||
Assert.ok(!this.isDeviceAdded);
|
||||
Assert.equal(device.id, mockDevice1.host);
|
||||
Assert.equal(device.name, mockDevice1.serviceName);
|
||||
this.isDeviceAdded = true;
|
||||
},
|
||||
removeDevice: function(device) { Assert.ok(false); },
|
||||
updateDevice: function(device) {
|
||||
Assert.ok(!this.isDeviceUpdated);
|
||||
Assert.equal(device.id, mockDevice2.host);
|
||||
Assert.equal(device.name, mockDevice2.serviceName);
|
||||
this.isDeviceUpdated = true;
|
||||
},
|
||||
|
||||
isDeviceAdded: false,
|
||||
isDeviceUpdated: false
|
||||
};
|
||||
Assert.equal(listener.isDeviceAdded, false);
|
||||
Assert.equal(listener.isDeviceUpdated, false);
|
||||
|
||||
// Start discovery
|
||||
provider.listener = listener; // discover: N1
|
||||
|
||||
Assert.equal(listener.isDeviceAdded, true);
|
||||
Assert.equal(listener.isDeviceUpdated, false);
|
||||
|
||||
// temporarily disable to stop discovery and re-enable
|
||||
Services.prefs.setBoolPref(PREF_DISCOVERY, false);
|
||||
Services.prefs.setBoolPref(PREF_DISCOVERY, true);
|
||||
|
||||
provider.forceDiscovery(); // discover: N2
|
||||
|
||||
Assert.equal(listener.isDeviceAdded, true);
|
||||
Assert.equal(listener.isDeviceUpdated, true);
|
||||
|
||||
provider.listener = null;
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function diffDiscovery() {
|
||||
Services.prefs.setBoolPref(PREF_DISCOVERY, true);
|
||||
|
||||
let mockDevice1 = createDevice("A.local", 12345, "N1", "_mozilla_papi._tcp");
|
||||
let mockDevice2 = createDevice("B.local", 23456, "N2", "_mozilla_papi._tcp");
|
||||
let mockDevice3 = createDevice("C.local", 45678, "N3", "_mozilla_papi._tcp");
|
||||
|
||||
let mockObj = {
|
||||
discovered: false,
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
|
||||
startDiscovery: function(serviceType, listener) {
|
||||
listener.onDiscoveryStarted(serviceType);
|
||||
|
||||
if (!this.discovered) {
|
||||
listener.onServiceFound(mockDevice1);
|
||||
listener.onServiceFound(mockDevice2);
|
||||
} else {
|
||||
listener.onServiceFound(mockDevice1);
|
||||
listener.onServiceFound(mockDevice3);
|
||||
}
|
||||
this.discovered = true;
|
||||
|
||||
return {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
|
||||
cancel: function() {
|
||||
listener.onDiscoveryStopped(serviceType);
|
||||
}
|
||||
};
|
||||
},
|
||||
registerService: function(serviceInfo, listener) {},
|
||||
resolveService: function(serviceInfo, listener) {
|
||||
Assert.equal(serviceInfo.serviceType, "_mozilla_papi._tcp");
|
||||
if (serviceInfo.serviceName == "N1") {
|
||||
listener.onServiceResolved(mockDevice1);
|
||||
} else if (serviceInfo.serviceName == "N2") {
|
||||
listener.onServiceResolved(mockDevice2);
|
||||
} else if (serviceInfo.serviceName == "N3") {
|
||||
listener.onServiceResolved(mockDevice3);
|
||||
} else {
|
||||
Assert.ok(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let contractHook = new ContractHook(SD_CONTRACT_ID, mockObj);
|
||||
let provider = Cc[PROVIDER_CONTRACT_ID].createInstance(Ci.nsIPresentationDeviceProvider);
|
||||
let listener = new TestPresentationDeviceListener();
|
||||
Assert.equal(listener.count(), 0);
|
||||
|
||||
// Start discovery
|
||||
provider.listener = listener; // discover: N1, N2
|
||||
Assert.equal(listener.count(), 2);
|
||||
Assert.equal(listener.devices['A.local'].name, mockDevice1.serviceName);
|
||||
Assert.equal(listener.devices['B.local'].name, mockDevice2.serviceName);
|
||||
Assert.ok(!listener.devices['C.local']);
|
||||
|
||||
// temporarily disable to stop discovery and re-enable
|
||||
Services.prefs.setBoolPref(PREF_DISCOVERY, false);
|
||||
Services.prefs.setBoolPref(PREF_DISCOVERY, true);
|
||||
|
||||
provider.forceDiscovery(); // discover: N1, N3, going to remove: N2
|
||||
Assert.equal(listener.count(), 3);
|
||||
Assert.equal(listener.devices['A.local'].name, mockDevice1.serviceName);
|
||||
Assert.equal(listener.devices['B.local'].name, mockDevice2.serviceName);
|
||||
Assert.equal(listener.devices['C.local'].name, mockDevice3.serviceName);
|
||||
|
||||
// temporarily disable to stop discovery and re-enable
|
||||
Services.prefs.setBoolPref(PREF_DISCOVERY, false);
|
||||
Services.prefs.setBoolPref(PREF_DISCOVERY, true);
|
||||
|
||||
provider.forceDiscovery(); // discover: N1, N3, remove: N2
|
||||
Assert.equal(listener.count(), 2);
|
||||
Assert.equal(listener.devices['A.local'].name, mockDevice1.serviceName);
|
||||
Assert.ok(!listener.devices['B.local']);
|
||||
Assert.equal(listener.devices['C.local'].name, mockDevice3.serviceName);
|
||||
|
||||
provider.listener = null;
|
||||
|
||||
@ -517,13 +691,13 @@ function serverClosed() {
|
||||
|
||||
Assert.equal(mockObj.serviceRegistered, 2);
|
||||
Assert.equal(mockObj.serviceUnregistered, 1);
|
||||
Assert.equal(listener.devices.length, 2);
|
||||
Assert.equal(listener.devices.length, 1);
|
||||
|
||||
// Unregister
|
||||
provider.listener = null;
|
||||
Assert.equal(mockObj.serviceRegistered, 2);
|
||||
Assert.equal(mockObj.serviceUnregistered, 2);
|
||||
Assert.equal(listener.devices.length, 2);
|
||||
Assert.equal(listener.devices.length, 1);
|
||||
|
||||
run_next_test();
|
||||
}
|
||||
@ -542,6 +716,8 @@ function run_test() {
|
||||
add_test(addDevice);
|
||||
add_test(noAddDevice);
|
||||
add_test(addDeviceDynamically);
|
||||
add_test(updateDevice);
|
||||
add_test(diffDiscovery);
|
||||
add_test(serverClosed);
|
||||
|
||||
run_next_test();
|
||||
|
Loading…
Reference in New Issue
Block a user