Bug 1299061 - Expose the browser that the request was originated in; r=smaug
MozReview-Commit-ID: 2iFQiYeoxBh
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -3638,17 +3638,17 @@ ContentParent::DeallocPPresentationParen
RefPtr<PresentationParent> actor =
dont_AddRef(static_cast<PresentationParent*>(aActor));
return true;
}
bool
ContentParent::RecvPPresentationConstructor(PPresentationParent* aActor)
{
- return static_cast<PresentationParent*>(aActor)->Init();
+ return static_cast<PresentationParent*>(aActor)->Init(mChildID);
}
PFlyWebPublishedServerParent*
ContentParent::AllocPFlyWebPublishedServerParent(const nsString& name,
const FlyWebPublishOptions& params)
{
RefPtr<FlyWebPublishedServerParent> actor =
new FlyWebPublishedServerParent(name, params);
--- a/dom/presentation/PresentationRequest.cpp
+++ b/dom/presentation/PresentationRequest.cpp
@@ -194,19 +194,25 @@ PresentationRequest::StartWithDevice(con
nsCOMPtr<nsIPresentationService> service =
do_GetService(PRESENTATION_SERVICE_CONTRACTID);
if(NS_WARN_IF(!service)) {
promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
return promise.forget();
}
+ // Get xul:browser element in parent process or nsWindowRoot object in child
+ // process. If it's in child process, the corresponding xul:browser element
+ // will be obtained at PresentationRequestParent::DoRequest in its parent
+ // process.
+ nsCOMPtr<nsIDOMEventTarget> handler =
+ do_QueryInterface(GetOwner()->GetChromeEventHandler());
nsCOMPtr<nsIPresentationServiceCallback> callback =
new PresentationRequesterCallback(this, id, promise);
- rv = service->StartSession(mUrls, id, origin, aDeviceId, GetOwner()->WindowID(), callback);
+ rv = service->StartSession(mUrls, id, origin, aDeviceId, GetOwner()->WindowID(), handler, callback);
if (NS_WARN_IF(NS_FAILED(rv))) {
promise->MaybeReject(NS_ERROR_DOM_OPERATION_ERR);
}
return promise.forget();
}
already_AddRefed<Promise>
--- a/dom/presentation/PresentationService.cpp
+++ b/dom/presentation/PresentationService.cpp
@@ -106,47 +106,51 @@ class PresentationDeviceRequest final :
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPRESENTATIONDEVICEREQUEST
PresentationDeviceRequest(const nsTArray<nsString>& aUrls,
const nsAString& aId,
const nsAString& aOrigin,
uint64_t aWindowId,
+ nsIDOMEventTarget* aEventTarget,
nsIPresentationServiceCallback* aCallback);
private:
virtual ~PresentationDeviceRequest() = default;
nsresult CreateSessionInfo(nsIPresentationDevice* aDevice,
const nsAString& aSelectedRequestUrl);
nsTArray<nsString> mRequestUrls;
nsString mId;
nsString mOrigin;
uint64_t mWindowId;
+ nsWeakPtr mChromeEventHandler;
nsCOMPtr<nsIPresentationServiceCallback> mCallback;
};
LazyLogModule gPresentationLog("Presentation");
} // namespace dom
} // namespace mozilla
NS_IMPL_ISUPPORTS(PresentationDeviceRequest, nsIPresentationDeviceRequest)
PresentationDeviceRequest::PresentationDeviceRequest(
const nsTArray<nsString>& aUrls,
const nsAString& aId,
const nsAString& aOrigin,
uint64_t aWindowId,
+ nsIDOMEventTarget* aEventTarget,
nsIPresentationServiceCallback* aCallback)
: mRequestUrls(aUrls)
, mId(aId)
, mOrigin(aOrigin)
, mWindowId(aWindowId)
+ , mChromeEventHandler(do_GetWeakReference(aEventTarget))
, mCallback(aCallback)
{
MOZ_ASSERT(!mRequestUrls.IsEmpty());
MOZ_ASSERT(!mId.IsEmpty());
MOZ_ASSERT(!mOrigin.IsEmpty());
MOZ_ASSERT(mCallback);
}
@@ -159,16 +163,24 @@ PresentationDeviceRequest::GetOrigin(nsA
NS_IMETHODIMP
PresentationDeviceRequest::GetRequestURLs(nsIArray** aUrls)
{
return ConvertURLArrayHelper(mRequestUrls, aUrls);
}
NS_IMETHODIMP
+PresentationDeviceRequest::GetChromeEventHandler(nsIDOMEventTarget** aChromeEventHandler)
+{
+ nsCOMPtr<nsIDOMEventTarget> handler(do_QueryReferent(mChromeEventHandler));
+ handler.forget(aChromeEventHandler);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
PresentationDeviceRequest::Select(nsIPresentationDevice* aDevice)
{
MOZ_ASSERT(NS_IsMainThread());
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;
}
@@ -629,30 +641,32 @@ PresentationService::IsAppInstalled(nsIU
}
NS_IMETHODIMP
PresentationService::StartSession(const nsTArray<nsString>& aUrls,
const nsAString& aSessionId,
const nsAString& aOrigin,
const nsAString& aDeviceId,
uint64_t aWindowId,
+ nsIDOMEventTarget* aEventTarget,
nsIPresentationServiceCallback* aCallback)
{
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(aUrls,
aSessionId,
aOrigin,
aWindowId,
+ aEventTarget,
aCallback);
if (aDeviceId.IsVoid()) {
// Pop up a prompt and ask user to select a device.
nsCOMPtr<nsIPresentationDevicePrompt> prompt =
do_GetService(PRESENTATION_DEVICE_PROMPT_CONTRACTID);
if (NS_WARN_IF(!prompt)) {
return aCallback->NotifyError(NS_ERROR_DOM_OPERATION_ERR);
--- a/dom/presentation/interfaces/nsIPresentationDevicePrompt.idl
+++ b/dom/presentation/interfaces/nsIPresentationDevicePrompt.idl
@@ -1,15 +1,16 @@
/* 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 "nsISupports.idl"
interface nsIArray;
+interface nsIDOMEventTarget;
interface nsIPresentationDevice;
%{C++
#define PRESENTATION_DEVICE_PROMPT_CONTRACTID "@mozilla.org/presentation-device/prompt;1"
%}
/*
* The information and callbacks for device selection
@@ -18,16 +19,19 @@ interface nsIPresentationDevice;
interface nsIPresentationDeviceRequest : nsISupports
{
// The origin which initiate the request.
readonly attribute DOMString origin;
// The array of candidate URLs.
readonly attribute nsIArray requestURLs;
+ // The XUL browser element that the request was originated in.
+ readonly attribute nsIDOMEventTarget chromeEventHandler;
+
/*
* Callback after selecting a device
* @param device The selected device.
*/
void select(in nsIPresentationDevice device);
/*
* Callback after selection failed or canceled by user.
--- a/dom/presentation/interfaces/nsIPresentationService.idl
+++ b/dom/presentation/interfaces/nsIPresentationService.idl
@@ -1,14 +1,15 @@
/* 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 "nsISupports.idl"
+interface nsIDOMEventTarget;
interface nsIInputStream;
interface nsIPresentationAvailabilityListener;
interface nsIPresentationRespondingListener;
interface nsIPresentationSessionListener;
%{C++
#define PRESENTATION_SERVICE_CID \
{ 0x1d9bb10c, 0xc0ab, 0x4fe8, \
@@ -54,31 +55,35 @@ interface nsIPresentationService : nsISu
/*
* Start a new presentation session and display a prompt box which asks users
* to select a device.
*
* @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
- for prompt device selection dialog.
+ * for prompt device selection dialog.
* @param windowId: The inner window ID associated with the presentation
* session. (0 implies no window ID since no actual window
* uses 0 as its ID. Generally it's the case the window is
* located in different process from this service)
+ * @param eventTarget: The chrome event handler, in particular XUL browser
+ * element in parent process, that the request was
+ * originated in.
* @param callback: Invoke the callback when the operation is completed.
* NotifySuccess() is called with |id| if a session is
* established successfully with the selected device.
* Otherwise, NotifyError() is called with a error message.
*/
[noscript] void startSession(in URLArrayRef urls,
in DOMString sessionId,
in DOMString origin,
in DOMString deviceId,
in unsigned long long windowId,
+ in nsIDOMEventTarget eventTarget,
in nsIPresentationServiceCallback callback);
/*
* Send the message to the session.
*
* @param sessionId: An ID to identify presentation session.
* @param role: Identify the function called by controller or receiver.
* @param data: the message being sent out.
--- a/dom/presentation/ipc/PPresentation.ipdl
+++ b/dom/presentation/ipc/PPresentation.ipdl
@@ -5,26 +5,29 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PContent;
include protocol PPresentationRequest;
include protocol PPresentationBuilder;
include InputStreamParams;
+using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
+
namespace mozilla {
namespace dom {
struct StartSessionRequest
{
nsString[] urls;
nsString sessionId;
nsString origin;
nsString deviceId;
uint64_t windowId;
+ TabId tabId;
};
struct SendSessionMessageRequest
{
nsString sessionId;
uint8_t role;
nsString data;
};
--- a/dom/presentation/ipc/PresentationIPCService.cpp
+++ b/dom/presentation/ipc/PresentationIPCService.cpp
@@ -1,16 +1,17 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et ft=cpp : */
/* 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 "mozilla/dom/ContentChild.h"
#include "mozilla/dom/PPresentation.h"
+#include "mozilla/dom/TabParent.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "mozilla/ipc/URIUtils.h"
#include "nsGlobalWindow.h"
#include "nsIPresentationListener.h"
#include "PresentationCallbacks.h"
#include "PresentationChild.h"
#include "PresentationContentSessionInfo.h"
#include "PresentationIPCService.h"
@@ -52,29 +53,35 @@ PresentationIPCService::~PresentationIPC
}
NS_IMETHODIMP
PresentationIPCService::StartSession(const nsTArray<nsString>& aUrls,
const nsAString& aSessionId,
const nsAString& aOrigin,
const nsAString& aDeviceId,
uint64_t aWindowId,
+ nsIDOMEventTarget* aEventTarget,
nsIPresentationServiceCallback* aCallback)
{
if (aWindowId != 0) {
AddRespondingSessionId(aWindowId,
aSessionId,
nsIPresentationService::ROLE_CONTROLLER);
}
+ nsPIDOMWindowInner* window =
+ nsGlobalWindow::GetInnerWindowWithId(aWindowId)->AsInner();
+ TabId tabId = TabParent::GetTabIdFrom(window->GetDocShell());
+
return SendRequest(aCallback, StartSessionRequest(aUrls,
nsString(aSessionId),
nsString(aOrigin),
nsString(aDeviceId),
- aWindowId));
+ aWindowId,
+ tabId));
}
NS_IMETHODIMP
PresentationIPCService::SendSessionMessage(const nsAString& aSessionId,
uint8_t aRole,
const nsAString& aData)
{
MOZ_ASSERT(!aSessionId.IsEmpty());
--- a/dom/presentation/ipc/PresentationParent.cpp
+++ b/dom/presentation/ipc/PresentationParent.cpp
@@ -1,15 +1,16 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* 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 "DCPresentationChannelDescription.h"
+#include "mozilla/dom/ContentProcessManager.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "mozilla/Unused.h"
#include "nsIPresentationDeviceManager.h"
#include "nsServiceManagerUtils.h"
#include "PresentationBuilderParent.h"
#include "PresentationParent.h"
#include "PresentationService.h"
#include "PresentationSessionInfo.h"
@@ -31,20 +32,21 @@ PresentationParent::PresentationParent()
}
/* virtual */ PresentationParent::~PresentationParent()
{
MOZ_COUNT_DTOR(PresentationParent);
}
bool
-PresentationParent::Init()
+PresentationParent::Init(ContentParentId aContentParentId)
{
MOZ_ASSERT(!mService);
mService = do_GetService(PRESENTATION_SERVICE_CONTRACTID);
+ mChildId = aContentParentId;
return NS_WARN_IF(!mService) ? false : true;
}
void
PresentationParent::ActorDestroy(ActorDestroyReason aWhy)
{
mActorDestroyed = true;
@@ -103,17 +105,17 @@ PresentationParent::RecvPPresentationReq
return NS_WARN_IF(NS_FAILED(rv)) ? false : true;
}
PPresentationRequestParent*
PresentationParent::AllocPPresentationRequestParent(
const PresentationIPCRequest& aRequest)
{
MOZ_ASSERT(mService);
- RefPtr<PresentationRequestParent> actor = new PresentationRequestParent(mService);
+ RefPtr<PresentationRequestParent> actor = new PresentationRequestParent(mService, mChildId);
return actor.forget().take();
}
bool
PresentationParent::DeallocPPresentationRequestParent(
PPresentationRequestParent* aActor)
{
RefPtr<PresentationRequestParent> actor =
@@ -305,18 +307,20 @@ PresentationParent::RecvNotifyTransportC
}
/*
* Implementation of PresentationRequestParent
*/
NS_IMPL_ISUPPORTS(PresentationRequestParent, nsIPresentationServiceCallback)
-PresentationRequestParent::PresentationRequestParent(nsIPresentationService* aService)
+PresentationRequestParent::PresentationRequestParent(nsIPresentationService* aService,
+ ContentParentId aContentParentId)
: mService(aService)
+ , mChildId(aContentParentId)
{
MOZ_COUNT_CTOR(PresentationRequestParent);
}
PresentationRequestParent::~PresentationRequestParent()
{
MOZ_COUNT_DTOR(PresentationRequestParent);
}
@@ -329,19 +333,28 @@ PresentationRequestParent::ActorDestroy(
}
nsresult
PresentationRequestParent::DoRequest(const StartSessionRequest& aRequest)
{
MOZ_ASSERT(mService);
mNeedRegisterBuilder = true;
mSessionId = aRequest.sessionId();
+
+ nsCOMPtr<nsIDOMEventTarget> eventTarget;
+ ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
+ RefPtr<TabParent> tp =
+ cpm->GetTopLevelTabParentByProcessAndTabId(mChildId, aRequest.tabId());
+ if (tp) {
+ eventTarget = do_QueryInterface(tp->GetOwnerElement());
+ }
+
return mService->StartSession(aRequest.urls(), aRequest.sessionId(),
aRequest.origin(), aRequest.deviceId(),
- aRequest.windowId(), this);
+ aRequest.windowId(), eventTarget, this);
}
nsresult
PresentationRequestParent::DoRequest(const SendSessionMessageRequest& aRequest)
{
MOZ_ASSERT(mService);
// Validate the accessibility (primarily for receiver side) so that a
--- a/dom/presentation/ipc/PresentationParent.h
+++ b/dom/presentation/ipc/PresentationParent.h
@@ -2,16 +2,17 @@
/* 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_PresentationParent_h__
#define mozilla_dom_PresentationParent_h__
+#include "mozilla/dom/ipc/IdType.h"
#include "mozilla/dom/PPresentationBuilderParent.h"
#include "mozilla/dom/PPresentationParent.h"
#include "mozilla/dom/PPresentationRequestParent.h"
#include "nsIPresentationListener.h"
#include "nsIPresentationService.h"
#include "nsIPresentationSessionTransportBuilder.h"
namespace mozilla {
@@ -25,17 +26,17 @@ class PresentationParent final : public
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPRESENTATIONAVAILABILITYLISTENER
NS_DECL_NSIPRESENTATIONSESSIONLISTENER
NS_DECL_NSIPRESENTATIONRESPONDINGLISTENER
PresentationParent();
- bool Init();
+ bool Init(ContentParentId aContentParentId);
bool RegisterTransportBuilder(const nsString& aSessionId, const uint8_t& aRole);
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
virtual bool
RecvPPresentationRequestConstructor(PPresentationRequestParent* aActor,
const PresentationIPCRequest& aRequest) override;
@@ -81,28 +82,30 @@ public:
private:
virtual ~PresentationParent();
bool mActorDestroyed = false;
nsCOMPtr<nsIPresentationService> mService;
nsTArray<nsString> mSessionIdsAtController;
nsTArray<nsString> mSessionIdsAtReceiver;
nsTArray<uint64_t> mWindowIds;
+ ContentParentId mChildId;
};
class PresentationRequestParent final : public PPresentationRequestParent
, public nsIPresentationServiceCallback
{
friend class PresentationParent;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIPRESENTATIONSERVICECALLBACK
- explicit PresentationRequestParent(nsIPresentationService* aService);
+ explicit PresentationRequestParent(nsIPresentationService* aService,
+ ContentParentId aContentParentId);
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
private:
virtual ~PresentationRequestParent();
nsresult SendResponse(nsresult aResult);
@@ -117,14 +120,15 @@ private:
nsresult DoRequest(const ReconnectSessionRequest& aRequest);
nsresult DoRequest(const BuildTransportRequest& aRequest);
bool mActorDestroyed = false;
bool mNeedRegisterBuilder = false;
nsString mSessionId;
nsCOMPtr<nsIPresentationService> mService;
+ ContentParentId mChildId;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_PresentationParent_h__