зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1228526 - Part 1, support device filtering by requested presentation URL. r=smaug
MozReview-Commit-ID: JrqeavLGub1 --HG-- extra : rebase_source : fc2eca80d59dc36e97a7af8ed3de6597faf38703
This commit is contained in:
Родитель
6ac132dfe9
Коммит
a2a2c152ab
|
@ -8,6 +8,7 @@
|
|||
|
||||
#include "mozilla/Services.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsCategoryCache.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIMutableArray.h"
|
||||
|
@ -148,7 +149,7 @@ PresentationDeviceManager::GetDeviceAvailable(bool* aRetVal)
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationDeviceManager::GetAvailableDevices(nsIArray** aRetVal)
|
||||
PresentationDeviceManager::GetAvailableDevices(nsIArray* aPresentationUrls, nsIArray** aRetVal)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRetVal);
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
@ -158,9 +159,42 @@ PresentationDeviceManager::GetAvailableDevices(nsIArray** aRetVal)
|
|||
NS_DispatchToMainThread(
|
||||
NewRunnableMethod(this, &PresentationDeviceManager::ForceDiscovery));
|
||||
|
||||
nsTArray<nsString> presentationUrls;
|
||||
if (aPresentationUrls) {
|
||||
uint32_t length;
|
||||
nsresult rv = aPresentationUrls->GetLength(&length);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
for (uint32_t i = 0; i < length; ++i) {
|
||||
nsCOMPtr<nsISupportsString> isupportStr =
|
||||
do_QueryElementAt(aPresentationUrls, i);
|
||||
|
||||
nsAutoString presentationUrl;
|
||||
rv = isupportStr->GetData(presentationUrl);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
presentationUrls.AppendElement(presentationUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIMutableArray> devices = do_CreateInstance(NS_ARRAY_CONTRACTID);
|
||||
for (uint32_t i = 0; i < mDevices.Length(); ++i) {
|
||||
devices->AppendElement(mDevices[i], false);
|
||||
if (presentationUrls.IsEmpty()) {
|
||||
devices->AppendElement(mDevices[i], false);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (uint32_t j = 0; j < presentationUrls.Length(); ++j) {
|
||||
bool isSupported;
|
||||
if (NS_SUCCEEDED(mDevices[i]->IsRequestedUrlSupported(presentationUrls[i],
|
||||
&isSupported)) &&
|
||||
isSupported) {
|
||||
devices->AppendElement(mDevices[i], false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
devices.forget(aRetVal);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "mozIApplication.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
#include "nsIAppsService.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIPresentationControlChannel.h"
|
||||
#include "nsIPresentationDeviceManager.h"
|
||||
|
@ -19,9 +20,11 @@
|
|||
#include "nsIPresentationRequestUIGlue.h"
|
||||
#include "nsIPresentationSessionRequest.h"
|
||||
#include "nsIPresentationTerminateRequest.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsXPCOMCID.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "PresentationLog.h"
|
||||
|
||||
|
@ -612,8 +615,18 @@ PresentationService::StartSession(const nsAString& aUrl,
|
|||
return aCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIMutableArray> presentationUrls
|
||||
= do_CreateInstance(NS_ARRAY_CONTRACTID);
|
||||
if (!presentationUrls) {
|
||||
return aCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR);
|
||||
}
|
||||
nsCOMPtr<nsISupportsString> supportsStr =
|
||||
do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID);
|
||||
supportsStr->SetData(aUrl);
|
||||
presentationUrls->AppendElement(supportsStr, false);
|
||||
|
||||
nsCOMPtr<nsIArray> devices;
|
||||
nsresult rv = deviceManager->GetAvailableDevices(getter_AddRefs(devices));
|
||||
nsresult rv = deviceManager->GetAvailableDevices(presentationUrls, getter_AddRefs(devices));
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return aCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR);
|
||||
}
|
||||
|
|
|
@ -31,6 +31,13 @@ interface nsIPresentationDevice : nsISupports
|
|||
|
||||
// Do something when presentation session is disconnected.
|
||||
void disconnect();
|
||||
|
||||
/*
|
||||
* Query if requested presentation URL is supported.
|
||||
* @params requestedUrl the designated URL for a presentation request.
|
||||
* @returns true if designated URL is supported.
|
||||
*/
|
||||
boolean isRequestedUrlSupported(in DOMString requestedUrl);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -40,10 +40,12 @@ interface nsIPresentationDeviceManager : nsISupports
|
|||
void forceDiscovery();
|
||||
|
||||
/*
|
||||
* Retrieve all available devices, return a list of nsIPresentationDevice.
|
||||
* Retrieve all available devices or all available devices that supports
|
||||
* designated presentation URLs, 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.
|
||||
* @param presentationUrls the target presentation URLs for device filtering
|
||||
*/
|
||||
nsIArray getAvailableDevices();
|
||||
nsIArray getAvailableDevices([optional] in nsIArray presentationUrls);
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "DeviceProviderHelpers.h"
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace presentation {
|
||||
|
||||
static const char* const kFxTVPresentationAppUrls[] = {
|
||||
"app://fling-player.gaiamobile.org/index.html",
|
||||
"app://notification-receiver.gaiamobile.org/index.html",
|
||||
nullptr
|
||||
};
|
||||
|
||||
/* static */ bool
|
||||
DeviceProviderHelpers::IsCommonlySupportedScheme(const nsAString& aUrl)
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(uri), aUrl);
|
||||
if (NS_FAILED(rv) || !uri) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsAutoCString scheme;
|
||||
uri->GetScheme(scheme);
|
||||
if (scheme.LowerCaseEqualsLiteral("http") ||
|
||||
scheme.LowerCaseEqualsLiteral("https")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
DeviceProviderHelpers::IsFxTVSupportedAppUrl(const nsAString& aUrl)
|
||||
{
|
||||
// Check if matched with any presentation Apps on TV.
|
||||
for (uint32_t i = 0; kFxTVPresentationAppUrls[i]; i++) {
|
||||
if (aUrl.EqualsASCII(kFxTVPresentationAppUrls[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace presentation
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
|
@ -0,0 +1,30 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef mozilla_dom_presentation_DeviceProviderHelpers_h
|
||||
#define mozilla_dom_presentation_DeviceProviderHelpers_h
|
||||
|
||||
#include "nsString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace presentation {
|
||||
|
||||
class DeviceProviderHelpers final
|
||||
{
|
||||
public:
|
||||
static bool IsCommonlySupportedScheme(const nsAString& aUrl);
|
||||
static bool IsFxTVSupportedAppUrl(const nsAString& aUrl);
|
||||
|
||||
private:
|
||||
DeviceProviderHelpers() = delete;
|
||||
};
|
||||
|
||||
} // namespace presentation
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_dom_presentation_DeviceProviderHelpers_h
|
|
@ -5,6 +5,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "DisplayDeviceProvider.h"
|
||||
|
||||
#include "DeviceProviderHelpers.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/Services.h"
|
||||
|
@ -117,6 +119,23 @@ DisplayDeviceProvider::HDMIDisplayDevice::Disconnect()
|
|||
return NS_OK;;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
DisplayDeviceProvider::HDMIDisplayDevice::IsRequestedUrlSupported(
|
||||
const nsAString& aRequestedUrl,
|
||||
bool* aRetVal)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!aRetVal) {
|
||||
return NS_ERROR_INVALID_POINTER;
|
||||
}
|
||||
|
||||
// 1-UA device only supports HTTP/HTTPS hosted receiver page.
|
||||
*aRetVal = DeviceProviderHelpers::IsCommonlySupportedScheme(aRequestedUrl);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
DisplayDeviceProvider::HDMIDisplayDevice::OpenTopLevelWindow()
|
||||
{
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "LegacyMDNSDeviceProvider.h"
|
||||
|
||||
#include "DeviceProviderHelpers.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
@ -751,6 +753,21 @@ LegacyMDNSDeviceProvider::Device::Disconnect()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
LegacyMDNSDeviceProvider::Device::IsRequestedUrlSupported(
|
||||
const nsAString& aRequestedUrl,
|
||||
bool* aRetVal)
|
||||
{
|
||||
if (!aRetVal) {
|
||||
return NS_ERROR_INVALID_POINTER;
|
||||
}
|
||||
|
||||
// Legacy TV 2.5 device only support a fixed set of presentation Apps.
|
||||
*aRetVal = DeviceProviderHelpers::IsFxTVSupportedAppUrl(aRequestedUrl);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace legacy
|
||||
} // namespace presentation
|
||||
} // namespace dom
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "MulticastDNSDeviceProvider.h"
|
||||
|
||||
#include "DeviceProviderHelpers.h"
|
||||
#include "MainThreadUtils.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
@ -1222,6 +1224,26 @@ MulticastDNSDeviceProvider::Device::Disconnect()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MulticastDNSDeviceProvider::Device::IsRequestedUrlSupported(
|
||||
const nsAString& aRequestedUrl,
|
||||
bool* aRetVal)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!aRetVal) {
|
||||
return NS_ERROR_INVALID_POINTER;
|
||||
}
|
||||
|
||||
// TV 2.6 also supports presentation Apps and HTTP/HTTPS hosted receiver page.
|
||||
if (DeviceProviderHelpers::IsFxTVSupportedAppUrl(aRequestedUrl) ||
|
||||
DeviceProviderHelpers::IsCommonlySupportedScheme(aRequestedUrl)) {
|
||||
*aRetVal = true;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
} // namespace presentation
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -10,6 +10,7 @@ EXTRA_COMPONENTS += [
|
|||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'DeviceProviderHelpers.cpp',
|
||||
'DisplayDeviceProvider.cpp',
|
||||
'MulticastDNSDeviceProvider.cpp',
|
||||
'PresentationDeviceProviderModule.cpp',
|
||||
|
|
|
@ -22,9 +22,13 @@ var testProvider = {
|
|||
|
||||
var testDevice = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevice]),
|
||||
establishSessionTransport: function(url, presentationId) {
|
||||
establishControlChannel: function() {
|
||||
return null;
|
||||
},
|
||||
disconnect: function() {},
|
||||
isRequestedUrlSupported: function(requestedUrl) {
|
||||
return true;
|
||||
},
|
||||
id: null,
|
||||
name: null,
|
||||
type: null,
|
||||
|
|
|
@ -185,6 +185,10 @@ const mockedDevice = {
|
|||
sendAsyncMessage('control-channel-established');
|
||||
return mockedControlChannel;
|
||||
},
|
||||
disconnect: function() {},
|
||||
isRequestedUrlSupported: function(requestedUrl) {
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
const mockedDevicePrompt = {
|
||||
|
|
|
@ -145,6 +145,10 @@ const mockDevice = {
|
|||
sendAsyncMessage('control-channel-established');
|
||||
return mockControlChannelOfSender;
|
||||
},
|
||||
disconnect: function() {},
|
||||
isRequestedUrlSupported: function(requestedUrl) {
|
||||
return true;
|
||||
},
|
||||
};
|
||||
|
||||
const mockDevicePrompt = {
|
||||
|
|
|
@ -426,6 +426,68 @@ function addDevice() {
|
|||
run_next_test();
|
||||
}
|
||||
|
||||
function filterDevice() {
|
||||
Services.prefs.setBoolPref(PREF_DISCOVERY, true);
|
||||
|
||||
let mockDevice = createDevice("device.local",
|
||||
12345,
|
||||
"service.name",
|
||||
SERVICE_TYPE);
|
||||
let mockObj = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDNSServiceDiscovery]),
|
||||
startDiscovery: function(serviceType, listener) {
|
||||
listener.onDiscoveryStarted(serviceType);
|
||||
listener.onServiceFound(createDevice("",
|
||||
0,
|
||||
mockDevice.serviceName,
|
||||
mockDevice.serviceType));
|
||||
return {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsICancelable]),
|
||||
cancel: function() {}
|
||||
};
|
||||
},
|
||||
registerService: function(serviceInfo, listener) {},
|
||||
resolveService: function(serviceInfo, listener) {
|
||||
Assert.equal(serviceInfo.serviceName, mockDevice.serviceName);
|
||||
Assert.equal(serviceInfo.serviceType, mockDevice.serviceType);
|
||||
listener.onServiceResolved(createDevice(mockDevice.host,
|
||||
mockDevice.port,
|
||||
mockDevice.serviceName,
|
||||
mockDevice.serviceType));
|
||||
}
|
||||
};
|
||||
|
||||
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) {
|
||||
let tests = [
|
||||
{ requestedUrl: "app://fling-player.gaiamobile.org/index.html", supported: true },
|
||||
{ requestedUrl: "app://notification-receiver.gaiamobile.org/index.html", supported: true },
|
||||
{ requestedUrl: "http://example.com", supported: true },
|
||||
{ requestedUrl: "https://example.com", supported: true },
|
||||
{ requestedUrl: "ftp://example.com", supported: false },
|
||||
{ requestedUrl: "app://unknown-app-id", supported: false },
|
||||
{ requestedUrl: "unknowSchem://example.com", supported: false },
|
||||
];
|
||||
|
||||
for (let test of tests) {
|
||||
Assert.equal(device.isRequestedUrlSupported(test.requestedUrl), test.supported);
|
||||
}
|
||||
|
||||
provider.listener = null;
|
||||
run_next_test();
|
||||
},
|
||||
updateDevice: function() {},
|
||||
removeDevice: function() {},
|
||||
onSessionRequest: function() {},
|
||||
};
|
||||
|
||||
provider.listener = listener;
|
||||
}
|
||||
|
||||
function handleSessionRequest() {
|
||||
Services.prefs.setBoolPref(PREF_DISCOVERY, true);
|
||||
Services.prefs.setBoolPref(PREF_DISCOVERABLE, false);
|
||||
|
@ -1239,6 +1301,7 @@ function run_test() {
|
|||
add_test(noRegisterService);
|
||||
add_test(registerServiceDynamically);
|
||||
add_test(addDevice);
|
||||
add_test(filterDevice);
|
||||
add_test(handleSessionRequest);
|
||||
add_test(handleOnSessionRequest);
|
||||
add_test(handleOnSessionRequestFromUnknownDevice);
|
||||
|
|
|
@ -40,6 +40,7 @@ var testProvider = {
|
|||
},
|
||||
};
|
||||
|
||||
const forbiddenRequestedUrl = 'http://example.com';
|
||||
var testDevice = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIPresentationDevice]),
|
||||
id: 'id',
|
||||
|
@ -48,6 +49,10 @@ var testDevice = {
|
|||
establishControlChannel: function(url, presentationId) {
|
||||
return null;
|
||||
},
|
||||
disconnect: function() {},
|
||||
isRequestedUrlSupported: function(requestedUrl) {
|
||||
return forbiddenRequestedUrl !== requestedUrl;
|
||||
},
|
||||
};
|
||||
|
||||
function addProvider() {
|
||||
|
@ -122,6 +127,16 @@ function updateDevice() {
|
|||
manager.QueryInterface(Ci.nsIPresentationDeviceListener).updateDevice(testDevice);
|
||||
}
|
||||
|
||||
function filterDevice() {
|
||||
let presentationUrls = Cc['@mozilla.org/array;1'].createInstance(Ci.nsIMutableArray);
|
||||
let url = Cc['@mozilla.org/supports-string;1'].createInstance(Ci.nsISupportsString);
|
||||
url.data = forbiddenRequestedUrl;
|
||||
presentationUrls.appendElement(url, false);
|
||||
let devices = manager.getAvailableDevices(presentationUrls);
|
||||
Assert.equal(devices.length, 0, 'expect 0 available device for example.com');
|
||||
run_next_test();
|
||||
}
|
||||
|
||||
function sessionRequest() {
|
||||
let testUrl = 'http://www.example.org/';
|
||||
let testPresentationId = 'test-presentation-id';
|
||||
|
@ -217,6 +232,7 @@ add_test(addProvider);
|
|||
add_test(forceDiscovery);
|
||||
add_test(addDevice);
|
||||
add_test(updateDevice);
|
||||
add_test(filterDevice);
|
||||
add_test(sessionRequest);
|
||||
add_test(terminateRequest);
|
||||
add_test(reconnectRequest);
|
||||
|
|
Загрузка…
Ссылка в новой задаче