mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1288297 - Construct PresentationRequest with multiple URLs, r=smaug
This commit is contained in:
parent
5a098d36c7
commit
4317633349
@ -72,7 +72,7 @@ AvailabilityCollection::Remove(PresentationAvailability* aAvailability)
|
||||
}
|
||||
|
||||
already_AddRefed<PresentationAvailability>
|
||||
AvailabilityCollection::Find(const uint64_t aWindowId, const nsAString& aUrl)
|
||||
AvailabilityCollection::Find(const uint64_t aWindowId, const nsTArray<nsString>& aUrls)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
@ -85,7 +85,7 @@ AvailabilityCollection::Find(const uint64_t aWindowId, const nsAString& aUrl)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (availability->Equals(aWindowId, aUrl)) {
|
||||
if (availability->Equals(aWindowId, aUrls)) {
|
||||
RefPtr<PresentationAvailability> matchedAvailability = availability.get();
|
||||
return matchedAvailability.forget();
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ public:
|
||||
void Remove(PresentationAvailability* aAvailability);
|
||||
|
||||
already_AddRefed<PresentationAvailability>
|
||||
Find(const uint64_t aWindowId, const nsAString& aUrl);
|
||||
Find(const uint64_t aWindowId, const nsTArray<nsString>& aUrls);
|
||||
|
||||
private:
|
||||
friend class StaticAutoPtr<AvailabilityCollection>;
|
||||
|
@ -37,20 +37,20 @@ NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
|
||||
|
||||
/* static */ already_AddRefed<PresentationAvailability>
|
||||
PresentationAvailability::Create(nsPIDOMWindowInner* aWindow,
|
||||
const nsAString& aUrl,
|
||||
const nsTArray<nsString>& aUrls,
|
||||
RefPtr<Promise>& aPromise)
|
||||
{
|
||||
RefPtr<PresentationAvailability> availability =
|
||||
new PresentationAvailability(aWindow, aUrl);
|
||||
new PresentationAvailability(aWindow, aUrls);
|
||||
return NS_WARN_IF(!availability->Init(aPromise)) ? nullptr
|
||||
: availability.forget();
|
||||
}
|
||||
|
||||
PresentationAvailability::PresentationAvailability(nsPIDOMWindowInner* aWindow,
|
||||
const nsAString& aUrl)
|
||||
const nsTArray<nsString>& aUrls)
|
||||
: DOMEventTargetHelper(aWindow)
|
||||
, mIsAvailable(false)
|
||||
, mUrl(aUrl)
|
||||
, mUrls(aUrls)
|
||||
{
|
||||
}
|
||||
|
||||
@ -120,10 +120,15 @@ PresentationAvailability::WrapObject(JSContext* aCx,
|
||||
|
||||
bool
|
||||
PresentationAvailability::Equals(const uint64_t aWindowID,
|
||||
const nsAString& aUrl) const
|
||||
const nsTArray<nsString>& aUrls) const
|
||||
{
|
||||
if (GetOwner() && GetOwner()->WindowID() == aWindowID &&
|
||||
mUrl.Equals(aUrl)) {
|
||||
mUrls.Length() == aUrls.Length()) {
|
||||
for (const auto& url : aUrls) {
|
||||
if (!mUrls.Contains(url)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -162,8 +167,7 @@ PresentationAvailability::NotifyAvailableChange(bool aIsAvailable)
|
||||
void
|
||||
PresentationAvailability::UpdateAvailabilityAndDispatchEvent(bool aIsAvailable)
|
||||
{
|
||||
PRES_DEBUG("%s:id[%s]\n", __func__,
|
||||
NS_ConvertUTF16toUTF8(mUrl).get());
|
||||
PRES_DEBUG("%s\n", __func__);
|
||||
bool isChanged = (aIsAvailable != mIsAvailable);
|
||||
|
||||
mIsAvailable = aIsAvailable;
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
|
||||
static already_AddRefed<PresentationAvailability>
|
||||
Create(nsPIDOMWindowInner* aWindow,
|
||||
const nsAString& aUrl,
|
||||
const nsTArray<nsString>& aUrls,
|
||||
RefPtr<Promise>& aPromise);
|
||||
|
||||
virtual void DisconnectFromOwner() override;
|
||||
@ -37,7 +37,7 @@ public:
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
|
||||
bool Equals(const uint64_t aWindowID, const nsAString& aUrl) const;
|
||||
bool Equals(const uint64_t aWindowID, const nsTArray<nsString>& aUrls) const;
|
||||
|
||||
bool IsCachedValueReady();
|
||||
|
||||
@ -50,7 +50,7 @@ public:
|
||||
|
||||
private:
|
||||
explicit PresentationAvailability(nsPIDOMWindowInner* aWindow,
|
||||
const nsAString& aUrl);
|
||||
const nsTArray<nsString>& aUrls);
|
||||
|
||||
virtual ~PresentationAvailability();
|
||||
|
||||
@ -64,7 +64,7 @@ private:
|
||||
|
||||
nsTArray<RefPtr<Promise>> mPromises;
|
||||
|
||||
nsString mUrl;
|
||||
nsTArray<nsString> mUrls;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -25,11 +25,9 @@ using namespace mozilla::dom;
|
||||
NS_IMPL_ISUPPORTS(PresentationRequesterCallback, nsIPresentationServiceCallback)
|
||||
|
||||
PresentationRequesterCallback::PresentationRequesterCallback(PresentationRequest* aRequest,
|
||||
const nsAString& aUrl,
|
||||
const nsAString& aSessionId,
|
||||
Promise* aPromise)
|
||||
: mRequest(aRequest)
|
||||
, mUrl(aUrl)
|
||||
, mSessionId(aSessionId)
|
||||
, mPromise(aPromise)
|
||||
{
|
||||
@ -44,12 +42,16 @@ PresentationRequesterCallback::~PresentationRequesterCallback()
|
||||
|
||||
// nsIPresentationServiceCallback
|
||||
NS_IMETHODIMP
|
||||
PresentationRequesterCallback::NotifySuccess()
|
||||
PresentationRequesterCallback::NotifySuccess(const nsAString& aUrl)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (aUrl.IsEmpty()) {
|
||||
return NotifyError(NS_ERROR_DOM_OPERATION_ERR);
|
||||
}
|
||||
|
||||
RefPtr<PresentationConnection> connection =
|
||||
PresentationConnection::Create(mRequest->GetOwner(), mSessionId, mUrl,
|
||||
PresentationConnection::Create(mRequest->GetOwner(), mSessionId, aUrl,
|
||||
nsIPresentationService::ROLE_CONTROLLER);
|
||||
if (NS_WARN_IF(!connection)) {
|
||||
mPromise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
|
||||
@ -79,11 +81,10 @@ NS_IMPL_ISUPPORTS_INHERITED0(PresentationReconnectCallback,
|
||||
|
||||
PresentationReconnectCallback::PresentationReconnectCallback(
|
||||
PresentationRequest* aRequest,
|
||||
const nsAString& aUrl,
|
||||
const nsAString& aSessionId,
|
||||
Promise* aPromise,
|
||||
PresentationConnection* aConnection)
|
||||
: PresentationRequesterCallback(aRequest, aUrl, aSessionId, aPromise)
|
||||
: PresentationRequesterCallback(aRequest, aSessionId, aPromise)
|
||||
, mConnection(aConnection)
|
||||
{
|
||||
}
|
||||
@ -93,7 +94,7 @@ PresentationReconnectCallback::~PresentationReconnectCallback()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationReconnectCallback::NotifySuccess()
|
||||
PresentationReconnectCallback::NotifySuccess(const nsAString& aUrl)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
@ -116,7 +117,7 @@ PresentationReconnectCallback::NotifySuccess()
|
||||
} else {
|
||||
// Use |PresentationRequesterCallback::NotifySuccess| to create a new
|
||||
// connection since we don't find one that can be reused.
|
||||
rv = PresentationRequesterCallback::NotifySuccess();
|
||||
rv = PresentationRequesterCallback::NotifySuccess(aUrl);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
@ -31,7 +31,6 @@ public:
|
||||
NS_DECL_NSIPRESENTATIONSERVICECALLBACK
|
||||
|
||||
PresentationRequesterCallback(PresentationRequest* aRequest,
|
||||
const nsAString& aUrl,
|
||||
const nsAString& aSessionId,
|
||||
Promise* aPromise);
|
||||
|
||||
@ -39,7 +38,6 @@ protected:
|
||||
virtual ~PresentationRequesterCallback();
|
||||
|
||||
RefPtr<PresentationRequest> mRequest;
|
||||
nsString mUrl;
|
||||
nsString mSessionId;
|
||||
RefPtr<Promise> mPromise;
|
||||
};
|
||||
@ -51,7 +49,6 @@ public:
|
||||
NS_DECL_NSIPRESENTATIONSERVICECALLBACK
|
||||
|
||||
PresentationReconnectCallback(PresentationRequest* aRequest,
|
||||
const nsAString& aUrl,
|
||||
const nsAString& aSessionId,
|
||||
Promise* aPromise,
|
||||
PresentationConnection* aConnection);
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "mozilla/dom/PresentationRequestBinding.h"
|
||||
#include "mozilla/dom/PresentationConnectionAvailableEvent.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/Move.h"
|
||||
#include "mozIThirdPartyUtil.h"
|
||||
#include "nsContentSecurityManager.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
@ -64,6 +65,16 @@ GetAbsoluteURL(const nsAString& aUrl,
|
||||
PresentationRequest::Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aUrl,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
Sequence<nsString> urls;
|
||||
urls.AppendElement(aUrl, fallible);
|
||||
return Constructor(aGlobal, urls, aRv);
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<PresentationRequest>
|
||||
PresentationRequest::Constructor(const GlobalObject& aGlobal,
|
||||
const Sequence<nsString>& aUrls,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMWindowInner> window = do_QueryInterface(aGlobal.GetAsSupports());
|
||||
if (!window) {
|
||||
@ -71,31 +82,35 @@ PresentationRequest::Constructor(const GlobalObject& aGlobal,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Ensure the URL is not empty.
|
||||
if (NS_WARN_IF(aUrl.IsEmpty())) {
|
||||
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
if (aUrls.IsEmpty()) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Resolve relative URL to absolute URL
|
||||
nsCOMPtr<nsIURI> baseUri = window->GetDocBaseURI();
|
||||
nsTArray<nsString> urls;
|
||||
for (const auto& url : aUrls) {
|
||||
nsAutoString absoluteUrl;
|
||||
nsresult rv =
|
||||
GetAbsoluteURL(url, baseUri, window->GetExtantDoc(), absoluteUrl);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(NS_ERROR_DOM_SYNTAX_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsAutoString absoluteUrl;
|
||||
nsresult rv = GetAbsoluteURL(aUrl, baseUri, window->GetExtantDoc(), absoluteUrl);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
return nullptr;
|
||||
urls.AppendElement(absoluteUrl);
|
||||
}
|
||||
|
||||
RefPtr<PresentationRequest> request =
|
||||
new PresentationRequest(window, absoluteUrl);
|
||||
new PresentationRequest(window, Move(urls));
|
||||
return NS_WARN_IF(!request->Init()) ? nullptr : request.forget();
|
||||
}
|
||||
|
||||
PresentationRequest::PresentationRequest(nsPIDOMWindowInner* aWindow,
|
||||
const nsAString& aUrl)
|
||||
nsTArray<nsString>&& aUrls)
|
||||
: DOMEventTargetHelper(aWindow)
|
||||
, mUrl(aUrl)
|
||||
, mUrls(Move(aUrls))
|
||||
{
|
||||
}
|
||||
|
||||
@ -152,7 +167,7 @@ PresentationRequest::StartWithDevice(const nsAString& aDeviceId,
|
||||
}
|
||||
|
||||
if (IsProhibitMixedSecurityContexts(doc) &&
|
||||
!IsPrioriAuthenticatedURL(mUrl)) {
|
||||
!IsAllURLAuthenticated()) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
@ -185,8 +200,8 @@ PresentationRequest::StartWithDevice(const nsAString& aDeviceId,
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresentationServiceCallback> callback =
|
||||
new PresentationRequesterCallback(this, mUrl, id, promise);
|
||||
rv = service->StartSession(mUrl, id, origin, aDeviceId, GetOwner()->WindowID(), callback);
|
||||
new PresentationRequesterCallback(this, id, promise);
|
||||
rv = service->StartSession(mUrls, id, origin, aDeviceId, GetOwner()->WindowID(), callback);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
|
||||
}
|
||||
@ -216,7 +231,7 @@ PresentationRequest::Reconnect(const nsAString& aPresentationId,
|
||||
}
|
||||
|
||||
if (IsProhibitMixedSecurityContexts(doc) &&
|
||||
!IsPrioriAuthenticatedURL(mUrl)) {
|
||||
!IsAllURLAuthenticated()) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
@ -262,7 +277,7 @@ PresentationRequest::FindOrCreatePresentationConnection(
|
||||
if (connection) {
|
||||
nsAutoString url;
|
||||
connection->GetUrl(url);
|
||||
if (url.Equals(mUrl)) {
|
||||
if (mUrls.Contains(url)) {
|
||||
switch (connection->State()) {
|
||||
case PresentationConnectionState::Closed:
|
||||
// We found the matched connection.
|
||||
@ -293,13 +308,12 @@ PresentationRequest::FindOrCreatePresentationConnection(
|
||||
|
||||
nsCOMPtr<nsIPresentationServiceCallback> callback =
|
||||
new PresentationReconnectCallback(this,
|
||||
mUrl,
|
||||
aPresentationId,
|
||||
aPromise,
|
||||
connection);
|
||||
|
||||
nsresult rv =
|
||||
service->ReconnectSession(mUrl,
|
||||
service->ReconnectSession(mUrls,
|
||||
aPresentationId,
|
||||
nsIPresentationService::ROLE_CONTROLLER,
|
||||
callback);
|
||||
@ -311,8 +325,7 @@ PresentationRequest::FindOrCreatePresentationConnection(
|
||||
already_AddRefed<Promise>
|
||||
PresentationRequest::GetAvailability(ErrorResult& aRv)
|
||||
{
|
||||
PRES_DEBUG("%s:id[%s]\n", __func__,
|
||||
NS_ConvertUTF16toUTF8(mUrl).get());
|
||||
PRES_DEBUG("%s\n", __func__);
|
||||
nsCOMPtr<nsIGlobalObject> global = do_QueryInterface(GetOwner());
|
||||
if (NS_WARN_IF(!global)) {
|
||||
aRv.Throw(NS_ERROR_UNEXPECTED);
|
||||
@ -331,7 +344,7 @@ PresentationRequest::GetAvailability(ErrorResult& aRv)
|
||||
}
|
||||
|
||||
if (IsProhibitMixedSecurityContexts(doc) &&
|
||||
!IsPrioriAuthenticatedURL(mUrl)) {
|
||||
!IsAllURLAuthenticated()) {
|
||||
promise->MaybeReject(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return promise.forget();
|
||||
}
|
||||
@ -363,13 +376,12 @@ PresentationRequest::FindOrCreatePresentationAvailability(RefPtr<Promise>& aProm
|
||||
}
|
||||
|
||||
RefPtr<PresentationAvailability> availability =
|
||||
collection->Find(GetOwner()->WindowID(), mUrl);
|
||||
collection->Find(GetOwner()->WindowID(), mUrls);
|
||||
|
||||
if (!availability) {
|
||||
availability = PresentationAvailability::Create(GetOwner(), mUrl, aPromise);
|
||||
availability = PresentationAvailability::Create(GetOwner(), mUrls, aPromise);
|
||||
} else {
|
||||
PRES_DEBUG(">resolve with same object:id[%s]\n",
|
||||
NS_ConvertUTF16toUTF8(mUrl).get());
|
||||
PRES_DEBUG(">resolve with same object\n");
|
||||
|
||||
// Fetching cached available devices is asynchronous in our implementation,
|
||||
// we need to ensure the promise is resolved in order.
|
||||
@ -474,3 +486,15 @@ PresentationRequest::IsPrioriAuthenticatedURL(const nsAString& aUrl)
|
||||
csm->IsOriginPotentiallyTrustworthy(principal, &isTrustworthyOrigin);
|
||||
return isTrustworthyOrigin;
|
||||
}
|
||||
|
||||
bool
|
||||
PresentationRequest::IsAllURLAuthenticated()
|
||||
{
|
||||
for (const auto& url : mUrls) {
|
||||
if (!IsPrioriAuthenticatedURL(url)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#ifndef mozilla_dom_PresentationRequest_h
|
||||
#define mozilla_dom_PresentationRequest_h
|
||||
|
||||
#include "mozilla/dom/BindingDeclarations.h"
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
|
||||
class nsIDocument;
|
||||
@ -23,9 +24,15 @@ class PresentationRequest final : public DOMEventTargetHelper
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
static already_AddRefed<PresentationRequest> Constructor(const GlobalObject& aGlobal,
|
||||
const nsAString& aUrl,
|
||||
ErrorResult& aRv);
|
||||
static already_AddRefed<PresentationRequest> Constructor(
|
||||
const GlobalObject& aGlobal,
|
||||
const nsAString& aUrl,
|
||||
ErrorResult& aRv);
|
||||
|
||||
static already_AddRefed<PresentationRequest> Constructor(
|
||||
const GlobalObject& aGlobal,
|
||||
const Sequence<nsString>& aUrls,
|
||||
ErrorResult& aRv);
|
||||
|
||||
virtual JSObject* WrapObject(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aGivenProto) override;
|
||||
@ -47,7 +54,7 @@ public:
|
||||
|
||||
private:
|
||||
PresentationRequest(nsPIDOMWindowInner* aWindow,
|
||||
const nsAString& aUrl);
|
||||
nsTArray<nsString>&& aUrls);
|
||||
|
||||
~PresentationRequest();
|
||||
|
||||
@ -64,7 +71,9 @@ private:
|
||||
// Implement https://w3c.github.io/webappsec-mixed-content/#a-priori-authenticated-url
|
||||
bool IsPrioriAuthenticatedURL(const nsAString& aUrl);
|
||||
|
||||
nsString mUrl;
|
||||
bool IsAllURLAuthenticated();
|
||||
|
||||
nsTArray<nsString> mUrls;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -59,6 +59,44 @@ IsSameDevice(nsIPresentationDevice* aDevice, nsIPresentationDevice* aDeviceAnoth
|
||||
return true;
|
||||
}
|
||||
|
||||
static nsresult
|
||||
ConvertURLArrayHelper(const nsTArray<nsString>& aUrls, nsIArray** aResult)
|
||||
{
|
||||
if (!aResult) {
|
||||
return NS_ERROR_INVALID_POINTER;
|
||||
}
|
||||
|
||||
*aResult = nullptr;
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIMutableArray> urls =
|
||||
do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
for (const auto& url : aUrls) {
|
||||
nsCOMPtr<nsISupportsString> isupportsString =
|
||||
do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = isupportsString->SetData(url);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
rv = urls->AppendElement(isupportsString, false);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
urls.forget(aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Implementation of PresentationDeviceRequest
|
||||
*/
|
||||
@ -69,7 +107,7 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPRESENTATIONDEVICEREQUEST
|
||||
|
||||
PresentationDeviceRequest(const nsAString& aRequestUrl,
|
||||
PresentationDeviceRequest(const nsTArray<nsString>& aUrls,
|
||||
const nsAString& aId,
|
||||
const nsAString& aOrigin,
|
||||
uint64_t aWindowId,
|
||||
@ -77,9 +115,10 @@ public:
|
||||
|
||||
private:
|
||||
virtual ~PresentationDeviceRequest() = default;
|
||||
nsresult CreateSessionInfo(nsIPresentationDevice* aDevice);
|
||||
nsresult CreateSessionInfo(nsIPresentationDevice* aDevice,
|
||||
const nsAString& aSelectedRequestUrl);
|
||||
|
||||
nsString mRequestUrl;
|
||||
nsTArray<nsString> mRequestUrls;
|
||||
nsString mId;
|
||||
nsString mOrigin;
|
||||
uint64_t mWindowId;
|
||||
@ -94,18 +133,18 @@ LazyLogModule gPresentationLog("Presentation");
|
||||
NS_IMPL_ISUPPORTS(PresentationDeviceRequest, nsIPresentationDeviceRequest)
|
||||
|
||||
PresentationDeviceRequest::PresentationDeviceRequest(
|
||||
const nsAString& aRequestUrl,
|
||||
const nsTArray<nsString>& aUrls,
|
||||
const nsAString& aId,
|
||||
const nsAString& aOrigin,
|
||||
uint64_t aWindowId,
|
||||
nsIPresentationServiceCallback* aCallback)
|
||||
: mRequestUrl(aRequestUrl)
|
||||
: mRequestUrls(aUrls)
|
||||
, mId(aId)
|
||||
, mOrigin(aOrigin)
|
||||
, mWindowId(aWindowId)
|
||||
, mCallback(aCallback)
|
||||
{
|
||||
MOZ_ASSERT(!mRequestUrl.IsEmpty());
|
||||
MOZ_ASSERT(!mRequestUrls.IsEmpty());
|
||||
MOZ_ASSERT(!mId.IsEmpty());
|
||||
MOZ_ASSERT(!mOrigin.IsEmpty());
|
||||
MOZ_ASSERT(mCallback);
|
||||
@ -119,29 +158,47 @@ PresentationDeviceRequest::GetOrigin(nsAString& aOrigin)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationDeviceRequest::GetRequestURL(nsAString& aRequestUrl)
|
||||
PresentationDeviceRequest::GetRequestURLs(nsIArray** aUrls)
|
||||
{
|
||||
aRequestUrl = mRequestUrl;
|
||||
return NS_OK;
|
||||
return ConvertURLArrayHelper(mRequestUrls, aUrls);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationDeviceRequest::Select(nsIPresentationDevice* aDevice)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aDevice);
|
||||
|
||||
nsresult rv = CreateSessionInfo(aDevice);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
mCallback->NotifyError(rv);
|
||||
return rv;
|
||||
if (NS_WARN_IF(!aDevice)) {
|
||||
MOZ_ASSERT(false, "|aDevice| should noe be null.");
|
||||
mCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR);
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return mCallback->NotifySuccess();
|
||||
// Select the most suitable URL for starting the presentation.
|
||||
nsAutoString selectedRequestUrl;
|
||||
for (const auto& url : mRequestUrls) {
|
||||
bool isSupported;
|
||||
if (NS_SUCCEEDED(aDevice->IsRequestedUrlSupported(url, &isSupported)) &&
|
||||
isSupported) {
|
||||
selectedRequestUrl.Assign(url);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedRequestUrl.IsEmpty()) {
|
||||
return mCallback->NotifyError(NS_ERROR_DOM_NOT_FOUND_ERR);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(NS_FAILED(CreateSessionInfo(aDevice, selectedRequestUrl)))) {
|
||||
return mCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR);
|
||||
}
|
||||
|
||||
return mCallback->NotifySuccess(selectedRequestUrl);
|
||||
}
|
||||
|
||||
nsresult
|
||||
PresentationDeviceRequest::CreateSessionInfo(nsIPresentationDevice* aDevice)
|
||||
PresentationDeviceRequest::CreateSessionInfo(
|
||||
nsIPresentationDevice* aDevice,
|
||||
const nsAString& aSelectedRequestUrl)
|
||||
{
|
||||
nsCOMPtr<nsIPresentationService> service =
|
||||
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
|
||||
@ -152,7 +209,7 @@ PresentationDeviceRequest::CreateSessionInfo(nsIPresentationDevice* aDevice)
|
||||
// Create the controlling session info
|
||||
RefPtr<PresentationSessionInfo> info =
|
||||
static_cast<PresentationService*>(service.get())->
|
||||
CreateControllingSessionInfo(mRequestUrl, mId, mWindowId);
|
||||
CreateControllingSessionInfo(aSelectedRequestUrl, mId, mWindowId);
|
||||
if (NS_WARN_IF(!info)) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
@ -572,23 +629,22 @@ PresentationService::IsAppInstalled(nsIURI* aUri)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationService::StartSession(const nsAString& aUrl,
|
||||
PresentationService::StartSession(const nsTArray<nsString>& aUrls,
|
||||
const nsAString& aSessionId,
|
||||
const nsAString& aOrigin,
|
||||
const nsAString& aDeviceId,
|
||||
uint64_t aWindowId,
|
||||
nsIPresentationServiceCallback* aCallback)
|
||||
{
|
||||
PRES_DEBUG("%s:url[%s], id[%s]\n", __func__,
|
||||
NS_ConvertUTF16toUTF8(aUrl).get(),
|
||||
NS_ConvertUTF16toUTF8(aSessionId).get());
|
||||
PRES_DEBUG("%s:id[%s]\n", __func__, NS_ConvertUTF16toUTF8(aSessionId).get());
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aCallback);
|
||||
MOZ_ASSERT(!aSessionId.IsEmpty());
|
||||
MOZ_ASSERT(!aUrls.IsEmpty());
|
||||
|
||||
nsCOMPtr<nsIPresentationDeviceRequest> request =
|
||||
new PresentationDeviceRequest(aUrl,
|
||||
new PresentationDeviceRequest(aUrls,
|
||||
aSessionId,
|
||||
aOrigin,
|
||||
aWindowId,
|
||||
@ -617,15 +673,11 @@ PresentationService::StartSession(const nsAString& aUrl,
|
||||
return aCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIMutableArray> presentationUrls =
|
||||
do_CreateInstance(NS_ARRAY_CONTRACTID);
|
||||
if (!presentationUrls) {
|
||||
nsCOMPtr<nsIArray> presentationUrls;
|
||||
if (NS_WARN_IF(NS_FAILED(
|
||||
ConvertURLArrayHelper(aUrls, getter_AddRefs(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(presentationUrls, getter_AddRefs(devices));
|
||||
@ -747,18 +799,17 @@ PresentationService::TerminateSession(const nsAString& aSessionId,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationService::ReconnectSession(const nsAString& aUrl,
|
||||
PresentationService::ReconnectSession(const nsTArray<nsString>& aUrls,
|
||||
const nsAString& aSessionId,
|
||||
uint8_t aRole,
|
||||
nsIPresentationServiceCallback* aCallback)
|
||||
{
|
||||
PRES_DEBUG("%s:url[%s], id[%s]\n", __func__,
|
||||
NS_ConvertUTF16toUTF8(aUrl).get(),
|
||||
NS_ConvertUTF16toUTF8(aSessionId).get());
|
||||
PRES_DEBUG("%s:id[%s]\n", __func__, NS_ConvertUTF16toUTF8(aSessionId).get());
|
||||
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!aSessionId.IsEmpty());
|
||||
MOZ_ASSERT(aCallback);
|
||||
MOZ_ASSERT(!aUrls.IsEmpty());
|
||||
|
||||
if (aRole != nsIPresentationService::ROLE_CONTROLLER) {
|
||||
MOZ_ASSERT(false, "Only controller can call ReconnectSession.");
|
||||
@ -774,7 +825,7 @@ PresentationService::ReconnectSession(const nsAString& aUrl,
|
||||
return aCallback->NotifyError(NS_ERROR_DOM_NOT_FOUND_ERR);
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!info->GetUrl().Equals(aUrl))) {
|
||||
if (NS_WARN_IF(!aUrls.Contains(info->GetUrl()))) {
|
||||
return aCallback->NotifyError(NS_ERROR_DOM_NOT_FOUND_ERR);
|
||||
}
|
||||
|
||||
|
@ -806,7 +806,7 @@ PresentationControllingInfo::NotifyReconnected()
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
return mReconnectCallback->NotifySuccess();
|
||||
return mReconnectCallback->NotifySuccess(GetUrl());
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIArray;
|
||||
interface nsIPresentationDevice;
|
||||
|
||||
%{C++
|
||||
@ -19,8 +20,8 @@ interface nsIPresentationDeviceRequest : nsISupports
|
||||
// The origin which initiate the request.
|
||||
readonly attribute DOMString origin;
|
||||
|
||||
// The URL to be opened after selection.
|
||||
readonly attribute DOMString requestURL;
|
||||
// The array of candidate URLs.
|
||||
readonly attribute nsIArray requestURLs;
|
||||
|
||||
/*
|
||||
* Callback after selecting a device
|
||||
|
@ -15,15 +15,23 @@ interface nsIPresentationSessionListener;
|
||||
{ 0x9e, 0x4f, 0x40, 0x58, 0xb8, 0x51, 0x98, 0x32 } }
|
||||
#define PRESENTATION_SERVICE_CONTRACTID \
|
||||
"@mozilla.org/presentation/presentationservice;1"
|
||||
|
||||
#include "nsTArray.h"
|
||||
|
||||
class nsString;
|
||||
%}
|
||||
|
||||
[ref] native URLArrayRef(const nsTArray<nsString>);
|
||||
|
||||
[scriptable, uuid(12073206-0065-4b10-9488-a6eb9b23e65b)]
|
||||
interface nsIPresentationServiceCallback : nsISupports
|
||||
{
|
||||
/*
|
||||
* Called when the operation succeeds.
|
||||
*
|
||||
* @param url: the selected request url used to start or reconnect a session.
|
||||
*/
|
||||
void notifySuccess();
|
||||
void notifySuccess(in DOMString url);
|
||||
|
||||
/*
|
||||
* Called when the operation fails.
|
||||
@ -47,7 +55,7 @@ interface nsIPresentationService : nsISupports
|
||||
* Start a new presentation session and display a prompt box which asks users
|
||||
* to select a device.
|
||||
*
|
||||
* @param url: The url of presenting page.
|
||||
* @param urls: The candidate Urls of presenting page. Only one url would be used.
|
||||
* @param sessionId: An ID to identify presentation session.
|
||||
* @param origin: The url of requesting page.
|
||||
* @param deviceId: The specified device of handling this request, null string
|
||||
@ -61,12 +69,12 @@ interface nsIPresentationService : nsISupports
|
||||
* established successfully with the selected device.
|
||||
* Otherwise, NotifyError() is called with a error message.
|
||||
*/
|
||||
void startSession(in DOMString url,
|
||||
in DOMString sessionId,
|
||||
in DOMString origin,
|
||||
in DOMString deviceId,
|
||||
in unsigned long long windowId,
|
||||
in nsIPresentationServiceCallback callback);
|
||||
[noscript] void startSession(in URLArrayRef urls,
|
||||
in DOMString sessionId,
|
||||
in DOMString origin,
|
||||
in DOMString deviceId,
|
||||
in unsigned long long windowId,
|
||||
in nsIPresentationServiceCallback callback);
|
||||
|
||||
/*
|
||||
* Send the message to the session.
|
||||
@ -101,17 +109,17 @@ interface nsIPresentationService : nsISupports
|
||||
/*
|
||||
* Reconnect the session.
|
||||
*
|
||||
* @param url: The url of presenting page.
|
||||
* @param url: The request Urls.
|
||||
* @param sessionId: An ID to identify presentation session.
|
||||
* @param role: Identify the function called by controller or receiver.
|
||||
* @param callback: NotifySuccess() is called when a control channel
|
||||
* is opened successfully.
|
||||
* Otherwise, NotifyError() is called with a error message.
|
||||
*/
|
||||
void reconnectSession(in DOMString url,
|
||||
in DOMString sessionId,
|
||||
in uint8_t role,
|
||||
in nsIPresentationServiceCallback callback);
|
||||
[noscript] void reconnectSession(in URLArrayRef urls,
|
||||
in DOMString sessionId,
|
||||
in uint8_t role,
|
||||
in nsIPresentationServiceCallback callback);
|
||||
|
||||
/*
|
||||
* Register an availability listener. Must be called from the main thread.
|
||||
|
@ -15,7 +15,7 @@ namespace dom {
|
||||
|
||||
struct StartSessionRequest
|
||||
{
|
||||
nsString url;
|
||||
nsString[] urls;
|
||||
nsString sessionId;
|
||||
nsString origin;
|
||||
nsString deviceId;
|
||||
@ -44,7 +44,7 @@ struct TerminateSessionRequest
|
||||
|
||||
struct ReconnectSessionRequest
|
||||
{
|
||||
nsString url;
|
||||
nsString[] urls;
|
||||
nsString sessionId;
|
||||
uint8_t role;
|
||||
};
|
||||
|
@ -15,6 +15,7 @@ sync protocol PPresentationRequest
|
||||
|
||||
child:
|
||||
async __delete__(nsresult result);
|
||||
async NotifyRequestUrlSelected(nsString aUrl);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -163,12 +163,17 @@ PresentationRequestChild::Recv__delete__(const nsresult& aResult)
|
||||
}
|
||||
|
||||
if (mCallback) {
|
||||
if (NS_SUCCEEDED(aResult)) {
|
||||
NS_WARN_IF(NS_FAILED(mCallback->NotifySuccess()));
|
||||
} else {
|
||||
if (NS_FAILED(aResult)) {
|
||||
NS_WARN_IF(NS_FAILED(mCallback->NotifyError(aResult)));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PresentationRequestChild::RecvNotifyRequestUrlSelected(const nsString& aUrl)
|
||||
{
|
||||
NS_WARN_IF(NS_FAILED(mCallback->NotifySuccess(aUrl)));
|
||||
return true;
|
||||
}
|
||||
|
@ -78,6 +78,9 @@ public:
|
||||
virtual bool
|
||||
Recv__delete__(const nsresult& aResult) override;
|
||||
|
||||
virtual bool
|
||||
RecvNotifyRequestUrlSelected(const nsString& aUrl) override;
|
||||
|
||||
private:
|
||||
virtual ~PresentationRequestChild();
|
||||
|
||||
|
@ -52,7 +52,7 @@ PresentationIPCService::~PresentationIPCService()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::StartSession(const nsAString& aUrl,
|
||||
PresentationIPCService::StartSession(const nsTArray<nsString>& aUrls,
|
||||
const nsAString& aSessionId,
|
||||
const nsAString& aOrigin,
|
||||
const nsAString& aDeviceId,
|
||||
@ -65,7 +65,7 @@ PresentationIPCService::StartSession(const nsAString& aUrl,
|
||||
nsIPresentationService::ROLE_CONTROLLER);
|
||||
}
|
||||
|
||||
return SendRequest(aCallback, StartSessionRequest(nsString(aUrl),
|
||||
return SendRequest(aCallback, StartSessionRequest(aUrls,
|
||||
nsString(aSessionId),
|
||||
nsString(aOrigin),
|
||||
nsString(aDeviceId),
|
||||
@ -135,7 +135,7 @@ PresentationIPCService::TerminateSession(const nsAString& aSessionId,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationIPCService::ReconnectSession(const nsAString& aUrl,
|
||||
PresentationIPCService::ReconnectSession(const nsTArray<nsString>& aUrls,
|
||||
const nsAString& aSessionId,
|
||||
uint8_t aRole,
|
||||
nsIPresentationServiceCallback* aCallback)
|
||||
@ -147,7 +147,7 @@ PresentationIPCService::ReconnectSession(const nsAString& aUrl,
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
return SendRequest(aCallback, ReconnectSessionRequest(nsString(aUrl),
|
||||
return SendRequest(aCallback, ReconnectSessionRequest(aUrls,
|
||||
nsString(aSessionId),
|
||||
aRole));
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "DCPresentationChannelDescription.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsIPresentationDeviceManager.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "PresentationBuilderParent.h"
|
||||
@ -333,7 +334,7 @@ PresentationRequestParent::DoRequest(const StartSessionRequest& aRequest)
|
||||
MOZ_ASSERT(mService);
|
||||
mNeedRegisterBuilder = true;
|
||||
mSessionId = aRequest.sessionId();
|
||||
return mService->StartSession(aRequest.url(), aRequest.sessionId(),
|
||||
return mService->StartSession(aRequest.urls(), aRequest.sessionId(),
|
||||
aRequest.origin(), aRequest.deviceId(),
|
||||
aRequest.windowId(), this);
|
||||
}
|
||||
@ -347,16 +348,16 @@ PresentationRequestParent::DoRequest(const SendSessionMessageRequest& aRequest)
|
||||
// compromised child process can't fake the ID.
|
||||
if (NS_WARN_IF(!static_cast<PresentationService*>(mService.get())->
|
||||
IsSessionAccessible(aRequest.sessionId(), aRequest.role(), OtherPid()))) {
|
||||
return NotifyError(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return SendResponse(NS_ERROR_DOM_SECURITY_ERR);
|
||||
}
|
||||
|
||||
nsresult rv = mService->SendSessionMessage(aRequest.sessionId(),
|
||||
aRequest.role(),
|
||||
aRequest.data());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NotifyError(rv);
|
||||
return SendResponse(rv);
|
||||
}
|
||||
return NotifySuccess();
|
||||
return SendResponse(NS_OK);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -368,16 +369,16 @@ PresentationRequestParent::DoRequest(const CloseSessionRequest& aRequest)
|
||||
// compromised child process can't fake the ID.
|
||||
if (NS_WARN_IF(!static_cast<PresentationService*>(mService.get())->
|
||||
IsSessionAccessible(aRequest.sessionId(), aRequest.role(), OtherPid()))) {
|
||||
return NotifyError(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return SendResponse(NS_ERROR_DOM_SECURITY_ERR);
|
||||
}
|
||||
|
||||
nsresult rv = mService->CloseSession(aRequest.sessionId(),
|
||||
aRequest.role(),
|
||||
aRequest.closedReason());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NotifyError(rv);
|
||||
return SendResponse(rv);
|
||||
}
|
||||
return NotifySuccess();
|
||||
return SendResponse(NS_OK);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -389,14 +390,14 @@ PresentationRequestParent::DoRequest(const TerminateSessionRequest& aRequest)
|
||||
// compromised child process can't fake the ID.
|
||||
if (NS_WARN_IF(!static_cast<PresentationService*>(mService.get())->
|
||||
IsSessionAccessible(aRequest.sessionId(), aRequest.role(), OtherPid()))) {
|
||||
return NotifyError(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return SendResponse(NS_ERROR_DOM_SECURITY_ERR);
|
||||
}
|
||||
|
||||
nsresult rv = mService->TerminateSession(aRequest.sessionId(), aRequest.role());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NotifyError(rv);
|
||||
return SendResponse(rv);
|
||||
}
|
||||
return NotifySuccess();
|
||||
return SendResponse(NS_OK);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -411,12 +412,12 @@ PresentationRequestParent::DoRequest(const ReconnectSessionRequest& aRequest)
|
||||
|
||||
// NOTE: Return NS_ERROR_DOM_NOT_FOUND_ERR here to match the spec.
|
||||
// https://w3c.github.io/presentation-api/#reconnecting-to-a-presentation
|
||||
return NotifyError(NS_ERROR_DOM_NOT_FOUND_ERR);
|
||||
return SendResponse(NS_ERROR_DOM_NOT_FOUND_ERR);
|
||||
}
|
||||
|
||||
mNeedRegisterBuilder = true;
|
||||
mSessionId = aRequest.sessionId();
|
||||
return mService->ReconnectSession(aRequest.url(),
|
||||
return mService->ReconnectSession(aRequest.urls(),
|
||||
aRequest.sessionId(),
|
||||
aRequest.role(),
|
||||
this);
|
||||
@ -431,18 +432,18 @@ PresentationRequestParent::DoRequest(const BuildTransportRequest& aRequest)
|
||||
// compromised child process can't fake the ID.
|
||||
if (NS_WARN_IF(!static_cast<PresentationService*>(mService.get())->
|
||||
IsSessionAccessible(aRequest.sessionId(), aRequest.role(), OtherPid()))) {
|
||||
return NotifyError(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return SendResponse(NS_ERROR_DOM_SECURITY_ERR);
|
||||
}
|
||||
|
||||
nsresult rv = mService->BuildTransport(aRequest.sessionId(), aRequest.role());
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return NotifyError(rv);
|
||||
return SendResponse(rv);
|
||||
}
|
||||
return NotifySuccess();
|
||||
return SendResponse(NS_OK);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresentationRequestParent::NotifySuccess()
|
||||
PresentationRequestParent::NotifySuccess(const nsAString& aUrl)
|
||||
{
|
||||
if (mNeedRegisterBuilder) {
|
||||
RefPtr<PresentationParent> parent = static_cast<PresentationParent*>(Manager());
|
||||
@ -451,6 +452,7 @@ PresentationRequestParent::NotifySuccess()
|
||||
nsIPresentationService::ROLE_CONTROLLER));
|
||||
}
|
||||
|
||||
Unused << SendNotifyRequestUrlSelected(nsString(aUrl));
|
||||
return SendResponse(NS_OK);
|
||||
}
|
||||
|
||||
|
@ -238,6 +238,29 @@ function teardown() {
|
||||
gScript.sendAsyncMessage('teardown');
|
||||
}
|
||||
|
||||
function testConstructRequestError() {
|
||||
return Promise.all([
|
||||
new Promise(function(aResolve, aReject) {
|
||||
try {
|
||||
request = new PresentationRequest("\\\\\\");
|
||||
}
|
||||
catch(e) {
|
||||
is(e.name, "SyntaxError", "Expect to get SyntaxError.");
|
||||
aResolve();
|
||||
}
|
||||
}),
|
||||
new Promise(function(aResolve, aReject) {
|
||||
try {
|
||||
request = new PresentationRequest([]);
|
||||
}
|
||||
catch(e) {
|
||||
is(e.name, "NotSupportedError", "Expect to get NotSupportedError.");
|
||||
aResolve();
|
||||
}
|
||||
}),
|
||||
]);
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
ok(window.PresentationRequest, "PresentationRequest should be available.");
|
||||
|
||||
@ -248,6 +271,7 @@ function runTests() {
|
||||
then(testCloseConnection).
|
||||
then(testReconnect).
|
||||
then(testCloseConnection).
|
||||
then(testConstructRequestError).
|
||||
then(teardown);
|
||||
}
|
||||
|
||||
|
@ -41,17 +41,6 @@ function setup() {
|
||||
});
|
||||
}
|
||||
|
||||
function testCreateRequestWithEmptyURL() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
try {
|
||||
request = new PresentationRequest("");
|
||||
} catch (aError) {
|
||||
is(aError.name, "SyntaxError", "SyntaxError is expected when using an empty URL.");
|
||||
aResolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function testStartConnectionCancelPrompt() {
|
||||
return new Promise(function(aResolve, aReject) {
|
||||
gScript.addMessageListener('device-prompt', function devicePromptHandler() {
|
||||
@ -380,8 +369,7 @@ function teardown() {
|
||||
function runTests() {
|
||||
ok(window.PresentationRequest, "PresentationRequest should be available.");
|
||||
|
||||
testCreateRequestWithEmptyURL().
|
||||
then(setup).
|
||||
setup().
|
||||
then(testStartConnectionCancelPrompt).
|
||||
then(testStartConnectionNoDevice).
|
||||
then(testStartConnectionUnexpectedControlChannelCloseBeforeDataTransportInit).
|
||||
|
@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
[Constructor(DOMString url),
|
||||
Constructor(sequence<DOMString> urls),
|
||||
Pref="dom.presentation.controller.enabled"]
|
||||
interface PresentationRequest : EventTarget {
|
||||
/*
|
||||
|
@ -46,17 +46,12 @@ PresentationDevicePrompt.prototype = {
|
||||
return this.bundle.GetStringFromName(aName);
|
||||
},
|
||||
|
||||
_loadDevices: function(requestURL) {
|
||||
_loadDevices: function(requestURLs) {
|
||||
debug("_loadDevices");
|
||||
|
||||
let presentationUrls = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
|
||||
let url = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
|
||||
url.data = requestURL;
|
||||
presentationUrls.appendElement(url, false);
|
||||
|
||||
let deviceManager = Cc["@mozilla.org/presentation-device/manager;1"]
|
||||
.getService(Ci.nsIPresentationDeviceManager);
|
||||
let devices = deviceManager.getAvailableDevices(presentationUrls).QueryInterface(Ci.nsIArray);
|
||||
let devices = deviceManager.getAvailableDevices(requestURLs).QueryInterface(Ci.nsIArray);
|
||||
|
||||
// Re-load the available devices
|
||||
this._devices = [];
|
||||
@ -118,7 +113,7 @@ PresentationDevicePrompt.prototype = {
|
||||
debug("promptDeviceSelection");
|
||||
|
||||
// Load available presentation devices into this._devices
|
||||
this._loadDevices(aRequest.requestURL);
|
||||
this._loadDevices(aRequest.requestURLs);
|
||||
|
||||
if (!this._devices.length) { // Cancel request if no available device
|
||||
aRequest.cancel(Cr.NS_ERROR_DOM_NOT_FOUND_ERR);
|
||||
|
Loading…
Reference in New Issue
Block a user