Backed out changeset 8b44017765ac (bug 1045975) for Windows non-unified bustage.

CLOSED TREE
This commit is contained in:
Ryan VanderMeulen 2014-08-07 15:13:54 -04:00
Родитель 2dc2f9e427
Коммит 82ac6c981d
18 изменённых файлов: 761 добавлений и 236 удалений

Просмотреть файл

@ -11428,8 +11428,12 @@ public:
// Handling a request from user input in non-fullscreen mode.
// Do a normal permission check.
nsCOMPtr<nsPIDOMWindow> window = doc->GetInnerWindow();
nsContentPermissionUtils::AskPermission(this, window);
nsCOMPtr<nsIContentPermissionPrompt> prompt =
do_CreateInstance(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
if (prompt) {
prompt->Prompt(this);
}
return NS_OK;
}
@ -11458,10 +11462,10 @@ NS_IMETHODIMP
nsPointerLockPermissionRequest::GetTypes(nsIArray** aTypes)
{
nsTArray<nsString> emptyOptions;
return nsContentPermissionUtils::CreatePermissionArray(NS_LITERAL_CSTRING("pointerLock"),
NS_LITERAL_CSTRING("unused"),
emptyOptions,
aTypes);
return CreatePermissionArray(NS_LITERAL_CSTRING("pointerLock"),
NS_LITERAL_CSTRING("unused"),
emptyOptions,
aTypes);
}
NS_IMETHODIMP

Просмотреть файл

@ -14,7 +14,6 @@
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/PContentPermissionRequestParent.h"
#include "mozilla/dom/ScriptSettings.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/unused.h"
#include "nsComponentManagerUtils.h"
@ -24,7 +23,6 @@
#include "nsCxPusher.h"
#include "nsJSUtils.h"
#include "nsISupportsPrimitives.h"
#include "nsServiceManagerUtils.h"
using mozilla::unused; // <snicker>
using namespace mozilla::dom;
@ -155,11 +153,9 @@ ContentPermissionType::GetOptions(nsIArray** aOptions)
return NS_OK;
}
// nsContentPermissionUtils
/* static */ uint32_t
nsContentPermissionUtils::ConvertPermissionRequestToArray(nsTArray<PermissionRequest>& aSrcArray,
nsIMutableArray* aDesArray)
uint32_t
ConvertPermissionRequestToArray(nsTArray<PermissionRequest>& aSrcArray,
nsIMutableArray* aDesArray)
{
uint32_t len = aSrcArray.Length();
for (uint32_t i = 0; i < len; i++) {
@ -172,46 +168,11 @@ nsContentPermissionUtils::ConvertPermissionRequestToArray(nsTArray<PermissionReq
return len;
}
/* static */ uint32_t
nsContentPermissionUtils::ConvertArrayToPermissionRequest(nsIArray* aSrcArray,
nsTArray<PermissionRequest>& aDesArray)
{
uint32_t len = 0;
aSrcArray->GetLength(&len);
for (uint32_t i = 0; i < len; i++) {
nsCOMPtr<nsIContentPermissionType> cpt = do_QueryElementAt(aSrcArray, i);
nsAutoCString type;
nsAutoCString access;
cpt->GetType(type);
cpt->GetAccess(access);
nsCOMPtr<nsIArray> optionArray;
cpt->GetOptions(getter_AddRefs(optionArray));
uint32_t optionsLength = 0;
if (optionArray) {
optionArray->GetLength(&optionsLength);
}
nsTArray<nsString> options;
for (uint32_t j = 0; j < optionsLength; ++j) {
nsCOMPtr<nsISupportsString> isupportsString = do_QueryElementAt(optionArray, j);
if (isupportsString) {
nsString option;
isupportsString->GetData(option);
options.AppendElement(option);
}
}
aDesArray.AppendElement(PermissionRequest(type, access, options));
}
return len;
}
/* static */ nsresult
nsContentPermissionUtils::CreatePermissionArray(const nsACString& aType,
const nsACString& aAccess,
const nsTArray<nsString>& aOptions,
nsIArray** aTypesArray)
nsresult
CreatePermissionArray(const nsACString& aType,
const nsACString& aAccess,
const nsTArray<nsString>& aOptions,
nsIArray** aTypesArray)
{
nsCOMPtr<nsIMutableArray> types = do_CreateInstance(NS_ARRAY_CONTRACTID);
nsRefPtr<ContentPermissionType> permType = new ContentPermissionType(aType,
@ -223,60 +184,14 @@ nsContentPermissionUtils::CreatePermissionArray(const nsACString& aType,
return NS_OK;
}
/* static */ PContentPermissionRequestParent*
nsContentPermissionUtils::CreateContentPermissionRequestParent(const nsTArray<PermissionRequest>& aRequests,
Element* element,
const IPC::Principal& principal)
PContentPermissionRequestParent*
CreateContentPermissionRequestParent(const nsTArray<PermissionRequest>& aRequests,
Element* element,
const IPC::Principal& principal)
{
return new ContentPermissionRequestParent(aRequests, element, principal);
}
/* static */ nsresult
nsContentPermissionUtils::AskPermission(nsIContentPermissionRequest* aRequest, nsPIDOMWindow* aWindow)
{
MOZ_ASSERT(!aWindow || aWindow->IsInnerWindow());
NS_ENSURE_STATE(aWindow && aWindow->IsCurrentInnerWindow());
// for content process
if (XRE_GetProcessType() == GeckoProcessType_Content) {
nsRefPtr<RemotePermissionRequest> req =
new RemotePermissionRequest(aRequest, aWindow);
MOZ_ASSERT(NS_IsMainThread()); // IPC can only be execute on main thread.
TabChild* child = TabChild::GetFrom(aWindow->GetDocShell());
NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
nsCOMPtr<nsIArray> typeArray;
nsresult rv = aRequest->GetTypes(getter_AddRefs(typeArray));
NS_ENSURE_SUCCESS(rv, rv);
nsTArray<PermissionRequest> permArray;
ConvertArrayToPermissionRequest(typeArray, permArray);
nsCOMPtr<nsIPrincipal> principal;
rv = aRequest->GetPrincipal(getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
req->IPDLAddRef();
child->SendPContentPermissionRequestConstructor(req,
permArray,
IPC::Principal(principal));
req->Sendprompt();
return NS_OK;
}
// for chrome process
nsCOMPtr<nsIContentPermissionPrompt> prompt =
do_GetService(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
if (prompt) {
prompt->Prompt(aRequest);
}
return NS_OK;
}
} // namespace dom
} // namespace mozilla
@ -298,7 +213,7 @@ nsContentPermissionRequestProxy::Init(const nsTArray<PermissionRequest>& request
mParent = parent;
mPermissionRequests = requests;
nsCOMPtr<nsIContentPermissionPrompt> prompt = do_GetService(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
nsCOMPtr<nsIContentPermissionPrompt> prompt = do_CreateInstance(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
if (!prompt) {
return NS_ERROR_FAILURE;
}
@ -319,7 +234,7 @@ NS_IMETHODIMP
nsContentPermissionRequestProxy::GetTypes(nsIArray** aTypes)
{
nsCOMPtr<nsIMutableArray> types = do_CreateInstance(NS_ARRAY_CONTRACTID);
if (mozilla::dom::nsContentPermissionUtils::ConvertPermissionRequestToArray(mPermissionRequests, types)) {
if (ConvertPermissionRequestToArray(mPermissionRequests, types)) {
types.forget(aTypes);
return NS_OK;
}
@ -447,50 +362,110 @@ nsContentPermissionRequestProxy::Allow(JS::HandleValue aChoices)
// RemotePermissionRequest
NS_IMPL_ISUPPORTS0(RemotePermissionRequest)
// static
uint32_t
RemotePermissionRequest::ConvertArrayToPermissionRequest(
nsIArray* aSrcArray,
nsTArray<PermissionRequest>& aDesArray)
{
uint32_t len = 0;
aSrcArray->GetLength(&len);
for (uint32_t i = 0; i < len; i++) {
nsCOMPtr<nsIContentPermissionType> cpt = do_QueryElementAt(aSrcArray, i);
nsAutoCString type;
nsAutoCString access;
cpt->GetType(type);
cpt->GetAccess(access);
nsCOMPtr<nsIArray> optionArray;
cpt->GetOptions(getter_AddRefs(optionArray));
uint32_t optionsLength = 0;
if (optionArray) {
optionArray->GetLength(&optionsLength);
}
nsTArray<nsString> options;
for (uint32_t j = 0; j < optionsLength; ++j) {
nsCOMPtr<nsISupportsString> isupportsString = do_QueryElementAt(optionArray, j);
if (isupportsString) {
nsString option;
isupportsString->GetData(option);
options.AppendElement(option);
}
}
aDesArray.AppendElement(PermissionRequest(type, access, options));
}
return len;
}
NS_IMPL_ISUPPORTS(RemotePermissionRequest, nsIContentPermissionRequest)
RemotePermissionRequest::RemotePermissionRequest(
nsIContentPermissionRequest* aRequest,
nsPIDOMWindow* aWindow)
: mRequest(aRequest)
, mWindow(aWindow)
, mIPCOpen(false)
{
}
void
RemotePermissionRequest::DoCancel()
// nsIContentPermissionRequest methods
NS_IMETHODIMP
RemotePermissionRequest::GetTypes(nsIArray** aTypes)
{
NS_ASSERTION(mRequest, "We need a request");
mRequest->Cancel();
return mRequest->GetTypes(aTypes);
}
void
RemotePermissionRequest::DoAllow(JS::HandleValue aChoices)
NS_IMETHODIMP
RemotePermissionRequest::GetPrincipal(nsIPrincipal **aRequestingPrincipal)
{
NS_ENSURE_ARG_POINTER(aRequestingPrincipal);
return mRequest->GetPrincipal(aRequestingPrincipal);
}
NS_IMETHODIMP
RemotePermissionRequest::GetWindow(nsIDOMWindow** aRequestingWindow)
{
NS_ENSURE_ARG_POINTER(aRequestingWindow);
return mRequest->GetWindow(aRequestingWindow);
}
NS_IMETHODIMP
RemotePermissionRequest::GetElement(nsIDOMElement** aRequestingElement)
{
NS_ENSURE_ARG_POINTER(aRequestingElement);
*aRequestingElement = nullptr;
return NS_OK;
}
NS_IMETHODIMP
RemotePermissionRequest::Cancel()
{
NS_ASSERTION(mRequest, "We need a request");
mRequest->Allow(aChoices);
return mRequest->Cancel();
}
// PContentPermissionRequestChild
NS_IMETHODIMP
RemotePermissionRequest::Allow(JS::HandleValue aChoices)
{
NS_ASSERTION(mRequest, "We need a request");
return mRequest->Allow(aChoices);
}
// PCOMContentPermissionRequestChild
bool
RemotePermissionRequest::Recv__delete__(const bool& aAllow,
const nsTArray<PermissionChoice>& aChoices)
{
if (aAllow && mWindow->IsCurrentInnerWindow()) {
// Use 'undefined' if no choice is provided.
if (aChoices.IsEmpty()) {
DoAllow(JS::UndefinedHandleValue);
return true;
}
// Convert choices to a JS val if any.
// {"type1": "choice1", "type2": "choiceA"}
AutoJSAPI jsapi;
if (NS_WARN_IF(!jsapi.Init(mWindow))) {
return true; // This is not an IPC error.
}
JSContext* cx = jsapi.cx();
JS::Rooted<JSObject*> obj(cx);
obj = JS_NewObject(cx, nullptr, JS::NullPtr(), JS::NullPtr());
@ -504,9 +479,9 @@ RemotePermissionRequest::Recv__delete__(const bool& aAllow,
}
}
JS::RootedValue val(cx, JS::ObjectValue(*obj));
DoAllow(val);
(void) Allow(val);
} else {
DoCancel();
(void) Cancel();
}
return true;
}

Просмотреть файл

@ -8,11 +8,7 @@
#include "nsIContentPermissionPrompt.h"
#include "nsTArray.h"
#include "nsIMutableArray.h"
#include "mozilla/dom/PContentPermissionRequestChild.h"
// Microsoft's API Name hackery sucks
// XXXbz Doing this in a header is a gigantic footgun. See
// https://bugzilla.mozilla.org/show_bug.cgi?id=932421#c3 for why.
#undef LoadImage
#include "PCOMContentPermissionRequestChild.h"
class nsPIDOMWindow;
class nsContentPermissionRequestProxy;
@ -53,31 +49,18 @@ protected:
nsTArray<nsString> mOptions;
};
class nsContentPermissionUtils
{
public:
static uint32_t
ConvertPermissionRequestToArray(nsTArray<PermissionRequest>& aSrcArray,
nsIMutableArray* aDesArray);
uint32_t ConvertPermissionRequestToArray(nsTArray<PermissionRequest>& aSrcArray,
nsIMutableArray* aDesArray);
static uint32_t
ConvertArrayToPermissionRequest(nsIArray* aSrcArray,
nsTArray<PermissionRequest>& aDesArray);
nsresult CreatePermissionArray(const nsACString& aType,
const nsACString& aAccess,
const nsTArray<nsString>& aOptions,
nsIArray** aTypesArray);
static nsresult
CreatePermissionArray(const nsACString& aType,
const nsACString& aAccess,
const nsTArray<nsString>& aOptions,
nsIArray** aTypesArray);
static PContentPermissionRequestParent*
CreateContentPermissionRequestParent(const nsTArray<PermissionRequest>& aRequests,
Element* element,
const IPC::Principal& principal);
static nsresult
AskPermission(nsIContentPermissionRequest* aRequest, nsPIDOMWindow* aWindow);
};
PContentPermissionRequestParent*
CreateContentPermissionRequestParent(const nsTArray<PermissionRequest>& aRequests,
Element* element,
const IPC::Principal& principal);
} // namespace dom
} // namespace mozilla
@ -92,7 +75,6 @@ class nsContentPermissionRequestProxy : public nsIContentPermissionRequest
nsresult Init(const nsTArray<mozilla::dom::PermissionRequest>& requests,
mozilla::dom::ContentPermissionRequestParent* parent);
void OnParentDestroyed();
private:
@ -106,11 +88,12 @@ class nsContentPermissionRequestProxy : public nsIContentPermissionRequest
/**
* RemotePermissionRequest will send a prompt ipdl request to b2g process.
*/
class RemotePermissionRequest MOZ_FINAL : public nsISupports
, public mozilla::dom::PContentPermissionRequestChild
class RemotePermissionRequest : public nsIContentPermissionRequest
, public PCOMContentPermissionRequestChild
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICONTENTPERMISSIONREQUEST
RemotePermissionRequest(nsIContentPermissionRequest* aRequest,
nsPIDOMWindow* aWindow);
@ -118,31 +101,16 @@ public:
// It will be called when prompt dismissed.
virtual bool Recv__delete__(const bool &aAllow,
const nsTArray<PermissionChoice>& aChoices) MOZ_OVERRIDE;
virtual void IPDLRelease() MOZ_OVERRIDE { Release(); }
void IPDLAddRef()
{
mIPCOpen = true;
AddRef();
}
void IPDLRelease()
{
mIPCOpen = false;
Release();
}
static uint32_t ConvertArrayToPermissionRequest(
nsIArray* aSrcArray,
nsTArray<PermissionRequest>& aDesArray);
private:
virtual ~RemotePermissionRequest()
{
MOZ_ASSERT(!mIPCOpen, "Protocol must not be open when RemotePermissionRequest is destroyed.");
}
void DoAllow(JS::HandleValue aChoices);
void DoCancel();
virtual ~RemotePermissionRequest() {}
nsCOMPtr<nsIContentPermissionRequest> mRequest;
nsCOMPtr<nsPIDOMWindow> mWindow;
bool mIPCOpen;
};
#endif // nsContentPermissionHelper_h

Просмотреть файл

@ -3856,7 +3856,43 @@ NS_IMETHODIMP
nsDOMWindowUtils::AskPermission(nsIContentPermissionRequest* aRequest)
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
return nsContentPermissionUtils::AskPermission(aRequest, window->GetCurrentInnerWindow());
nsRefPtr<RemotePermissionRequest> req =
new RemotePermissionRequest(aRequest, window->GetCurrentInnerWindow());
// for content process
if (XRE_GetProcessType() == GeckoProcessType_Content) {
MOZ_ASSERT(NS_IsMainThread()); // IPC can only be execute on main thread.
dom::TabChild* child = dom::TabChild::GetFrom(window->GetDocShell());
NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
nsCOMPtr<nsIArray> typeArray;
nsresult rv = req->GetTypes(getter_AddRefs(typeArray));
NS_ENSURE_SUCCESS(rv, rv);
nsTArray<PermissionRequest> permArray;
RemotePermissionRequest::ConvertArrayToPermissionRequest(typeArray, permArray);
nsCOMPtr<nsIPrincipal> principal;
rv = req->GetPrincipal(getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
req->AddRef();
child->SendPContentPermissionRequestConstructor(req,
permArray,
IPC::Principal(principal));
req->Sendprompt();
return NS_OK;
}
// for chrome process
nsCOMPtr<nsIContentPermissionPrompt> prompt =
do_GetService(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
if (prompt) {
prompt->Prompt(req);
}
return NS_OK;
}
NS_INTERFACE_MAP_BEGIN(nsTranslationNodeList)

Просмотреть файл

@ -9,16 +9,16 @@
#include "nsPIDOMWindow.h"
#include "mozilla/Services.h"
#include "nsContentPermissionHelper.h"
#include "nsIContentPermissionPrompt.h"
#include "nsIObserverService.h"
#include "nsIPermissionManager.h"
#include "nsIScriptObjectPrincipal.h"
#include "DOMCameraControl.h"
#include "nsDOMClassInfo.h"
#include "CameraCommon.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/CameraManagerBinding.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/TabChild.h"
#include "PCOMContentPermissionRequestChild.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -122,6 +122,7 @@ nsDOMCameraManager::CreateInstance(nsPIDOMWindow* aWindow)
}
class CameraPermissionRequest : public nsIContentPermissionRequest
, public PCOMContentPermissionRequestChild
, public nsIRunnable
{
public:
@ -148,6 +149,14 @@ public:
{
}
bool Recv__delete__(const bool& aAllow,
const InfallibleTArray<PermissionChoice>& choices);
void IPDLRelease()
{
Release();
}
protected:
virtual ~CameraPermissionRequest()
{
@ -179,7 +188,48 @@ NS_IMPL_CYCLE_COLLECTING_RELEASE(CameraPermissionRequest)
NS_IMETHODIMP
CameraPermissionRequest::Run()
{
return nsContentPermissionUtils::AskPermission(this, mWindow);
if (XRE_GetProcessType() == GeckoProcessType_Content) {
TabChild* child = TabChild::GetFrom(mWindow->GetDocShell());
if (!child) {
return NS_ERROR_NOT_AVAILABLE;
}
// Retain a reference so the object isn't deleted without IPDL's knowledge.
// Corresponding release occurs in DeallocPContentPermissionRequest.
AddRef();
nsTArray<PermissionRequest> permArray;
nsTArray<nsString> emptyOptions;
permArray.AppendElement(PermissionRequest(
NS_LITERAL_CSTRING("camera"),
NS_LITERAL_CSTRING("unused"),
emptyOptions));
child->SendPContentPermissionRequestConstructor(this, permArray,
IPC::Principal(mPrincipal));
Sendprompt();
return NS_OK;
}
nsCOMPtr<nsIContentPermissionPrompt> prompt =
do_GetService(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
if (prompt) {
prompt->Prompt(this);
}
return NS_OK;
}
bool
CameraPermissionRequest::Recv__delete__(const bool& aAllow,
const InfallibleTArray<PermissionChoice>& choices)
{
if (aAllow) {
Allow(JS::UndefinedHandleValue);
} else {
Cancel();
}
return true;
}
NS_IMETHODIMP
@ -244,10 +294,10 @@ NS_IMETHODIMP
CameraPermissionRequest::GetTypes(nsIArray** aTypes)
{
nsTArray<nsString> emptyOptions;
return nsContentPermissionUtils::CreatePermissionArray(NS_LITERAL_CSTRING("camera"),
NS_LITERAL_CSTRING("unused"),
emptyOptions,
aTypes);
return CreatePermissionArray(NS_LITERAL_CSTRING("camera"),
NS_LITERAL_CSTRING("unused"),
emptyOptions,
aTypes);
}
void

Просмотреть файл

@ -18,6 +18,7 @@
#include "mozilla/dom/FileSystemUtils.h"
#include "mozilla/dom/ipc/Blob.h"
#include "mozilla/dom/PBrowserChild.h"
#include "mozilla/dom/PContentPermissionRequestChild.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/dom/ScriptSettings.h"
@ -45,6 +46,7 @@
#include "nsContentUtils.h"
#include "nsCxPusher.h"
#include "nsXULAppAPI.h"
#include "TabChild.h"
#include "DeviceStorageFileDescriptor.h"
#include "DeviceStorageRequestChild.h"
#include "nsCRT.h"
@ -1783,6 +1785,7 @@ StringToJsval(nsPIDOMWindow* aWindow, nsAString& aString,
class DeviceStorageCursorRequest MOZ_FINAL
: public nsIContentPermissionRequest
, public PCOMContentPermissionRequestChild
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@ -1794,6 +1797,24 @@ public:
DeviceStorageCursorRequest(nsDOMDeviceStorageCursor* aCursor)
: mCursor(aCursor) { }
bool Recv__delete__(const bool& allow,
const InfallibleTArray<PermissionChoice>& choices)
{
MOZ_ASSERT(choices.IsEmpty(), "DeviceStorageCursor doesn't support permission choice");
if (allow) {
Allow(JS::UndefinedHandleValue);
}
else {
Cancel();
}
return true;
}
void IPDLRelease()
{
Release();
}
private:
~DeviceStorageCursorRequest() {}
@ -2028,10 +2049,10 @@ nsDOMDeviceStorageCursor::GetTypes(nsIArray** aTypes)
NS_ENSURE_SUCCESS(rv, rv);
nsTArray<nsString> emptyOptions;
return nsContentPermissionUtils::CreatePermissionArray(type,
NS_LITERAL_CSTRING("read"),
emptyOptions,
aTypes);
return CreatePermissionArray(type,
NS_LITERAL_CSTRING("read"),
emptyOptions,
aTypes);
}
NS_IMETHODIMP
@ -2116,6 +2137,27 @@ nsDOMDeviceStorageCursor::Continue(ErrorResult& aRv)
mOkToCallContinue = false;
}
bool
nsDOMDeviceStorageCursor::Recv__delete__(const bool& allow,
const InfallibleTArray<PermissionChoice>& choices)
{
MOZ_ASSERT(choices.IsEmpty(), "DeviceStorageCursor doesn't support permission choice");
if (allow) {
Allow(JS::UndefinedHandleValue);
}
else {
Cancel();
}
return true;
}
void
nsDOMDeviceStorageCursor::IPDLRelease()
{
Release();
}
void
nsDOMDeviceStorageCursor::RequestComplete()
{
@ -2664,6 +2706,7 @@ private:
class DeviceStorageRequest MOZ_FINAL
: public nsIContentPermissionRequest
, public nsIRunnable
, public PCOMContentPermissionRequestChild
{
public:
@ -2731,8 +2774,7 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(DeviceStorageRequest,
nsIContentPermissionRequest)
NS_IMETHOD Run()
{
NS_IMETHOD Run() {
MOZ_ASSERT(NS_IsMainThread());
if (mozilla::Preferences::GetBool("device.storage.prompt.testing", false)) {
@ -2740,7 +2782,48 @@ public:
return NS_OK;
}
return nsContentPermissionUtils::AskPermission(this, mWindow);
if (XRE_GetProcessType() == GeckoProcessType_Content) {
// because owner implements nsITabChild, we can assume that it is
// the one and only TabChild.
TabChild* child = TabChild::GetFrom(mWindow->GetDocShell());
if (!child) {
return NS_OK;
}
// Retain a reference so the object isn't deleted without IPDL's
// knowledge. Corresponding release occurs in
// DeallocPContentPermissionRequest.
AddRef();
nsCString type;
nsresult rv = DeviceStorageTypeChecker::GetPermissionForType(
mFile->mStorageType, type);
if (NS_FAILED(rv)) {
return rv;
}
nsCString access;
rv = DeviceStorageTypeChecker::GetAccessForRequest(
DeviceStorageRequestType(mRequestType), access);
if (NS_FAILED(rv)) {
return rv;
}
nsTArray<PermissionRequest> permArray;
nsTArray<nsString> emptyOptions;
permArray.AppendElement(PermissionRequest(type, access, emptyOptions));
child->SendPContentPermissionRequestConstructor(
this, permArray, IPC::Principal(mPrincipal));
Sendprompt();
return NS_OK;
}
nsCOMPtr<nsIContentPermissionPrompt> prompt
= do_CreateInstance(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
if (prompt) {
prompt->Prompt(this);
}
return NS_OK;
}
NS_IMETHODIMP GetTypes(nsIArray** aTypes)
@ -2760,7 +2843,7 @@ public:
}
nsTArray<nsString> emptyOptions;
return nsContentPermissionUtils::CreatePermissionArray(type, access, emptyOptions, aTypes);
return CreatePermissionArray(type, access, emptyOptions, aTypes);
}
NS_IMETHOD GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
@ -3125,6 +3208,25 @@ public:
return NS_OK;
}
bool Recv__delete__(const bool& allow,
const InfallibleTArray<PermissionChoice>& choices)
{
MOZ_ASSERT(choices.IsEmpty(), "DeviceStorage doesn't support permission choice");
if (allow) {
Allow(JS::UndefinedHandleValue);
}
else {
Cancel();
}
return true;
}
void IPDLRelease()
{
Release();
}
private:
~DeviceStorageRequest() {}
@ -4130,7 +4232,42 @@ nsDOMDeviceStorage::EnumerateInternal(const nsAString& aPath,
return cursor.forget();
}
nsContentPermissionUtils::AskPermission(r, win);
if (XRE_GetProcessType() == GeckoProcessType_Content) {
// because owner implements nsITabChild, we can assume that it is
// the one and only TabChild.
TabChild* child = TabChild::GetFrom(win->GetDocShell());
if (!child) {
return cursor.forget();
}
// Retain a reference so the object isn't deleted without IPDL's knowledge.
// Corresponding release occurs in DeallocPContentPermissionRequest.
r->AddRef();
nsCString type;
aRv = DeviceStorageTypeChecker::GetPermissionForType(mStorageType, type);
if (aRv.Failed()) {
return nullptr;
}
nsTArray<PermissionRequest> permArray;
nsTArray<nsString> emptyOptions;
permArray.AppendElement(PermissionRequest(type,
NS_LITERAL_CSTRING("read"),
emptyOptions));
child->SendPContentPermissionRequestConstructor(r,
permArray,
IPC::Principal(mPrincipal));
r->Sendprompt();
return cursor.forget();
}
nsCOMPtr<nsIContentPermissionPrompt> prompt
= do_CreateInstance(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
if (prompt) {
prompt->Prompt(r);
}
return cursor.forget();
}

Просмотреть файл

@ -7,6 +7,7 @@
class nsPIDOMWindow;
#include "mozilla/Attributes.h"
#include "PCOMContentPermissionRequestChild.h"
#include "DOMRequest.h"
#include "DOMCursor.h"
@ -190,6 +191,7 @@ private:
class nsDOMDeviceStorageCursor MOZ_FINAL
: public mozilla::dom::DOMCursor
, public nsIContentPermissionRequest
, public PCOMContentPermissionRequestChild
, public mozilla::dom::devicestorage::DeviceStorageRequestChildCallback
{
public:
@ -210,6 +212,10 @@ public:
bool mOkToCallContinue;
PRTime mSince;
virtual bool Recv__delete__(const bool& allow,
const InfallibleTArray<PermissionChoice>& choices) MOZ_OVERRIDE;
virtual void IPDLRelease() MOZ_OVERRIDE;
void GetStorageType(nsAString & aType);
void RequestComplete() MOZ_OVERRIDE;

Просмотреть файл

@ -8,9 +8,10 @@
#include "mozilla/dom/FileSystemBase.h"
#include "mozilla/dom/FileSystemTaskBase.h"
#include "mozilla/dom/FileSystemUtils.h"
#include "mozilla/dom/TabChild.h"
#include "nsIDocument.h"
#include "nsPIDOMWindow.h"
#include "nsContentPermissionHelper.h"
#include "nsString.h"
namespace mozilla {
namespace dom {
@ -61,14 +62,34 @@ FileSystemPermissionRequest::~FileSystemPermissionRequest()
{
}
bool
FileSystemPermissionRequest::Recv__delete__(const bool& aAllow,
const InfallibleTArray<PermissionChoice>& aChoices)
{
MOZ_ASSERT(aChoices.IsEmpty(),
"FileSystemPermissionRequest doesn't support permission choice");
if (aAllow) {
Allow(JS::UndefinedHandleValue);
} else {
Cancel();
}
return true;
}
void
FileSystemPermissionRequest::IPDLRelease()
{
Release();
}
NS_IMETHODIMP
FileSystemPermissionRequest::GetTypes(nsIArray** aTypes)
{
nsTArray<nsString> emptyOptions;
return nsContentPermissionUtils::CreatePermissionArray(mPermissionType,
mPermissionAccess,
emptyOptions,
aTypes);
return CreatePermissionArray(mPermissionType,
mPermissionAccess,
emptyOptions,
aTypes);
}
NS_IMETHODIMP
@ -126,12 +147,42 @@ FileSystemPermissionRequest::Run()
return NS_OK;
}
if (FileSystemUtils::IsParentProcess()) {
nsCOMPtr<nsIContentPermissionPrompt> prompt
= do_CreateInstance(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
if (!prompt || NS_FAILED(prompt->Prompt(this))) {
Cancel();
}
return NS_OK;
}
if (!mWindow) {
Cancel();
return NS_OK;
}
nsContentPermissionUtils::AskPermission(this, mWindow);
// because owner implements nsITabChild, we can assume that it is
// the one and only TabChild.
TabChild* child = TabChild::GetFrom(mWindow->GetDocShell());
if (!child) {
Cancel();
return NS_OK;
}
// Retain a reference so the object isn't deleted without IPDL's
// knowledge. Corresponding release occurs in
// DeallocPContentPermissionRequest.
AddRef();
nsTArray<PermissionRequest> permArray;
nsTArray<nsString> emptyOptions;
permArray.AppendElement(PermissionRequest(mPermissionType,
mPermissionAccess,
emptyOptions));
child->SendPContentPermissionRequestConstructor(
this, permArray, IPC::Principal(mPrincipal));
Sendprompt();
return NS_OK;
}

Просмотреть файл

@ -7,11 +7,12 @@
#ifndef mozilla_dom_FileSystemPermissionRequest_h
#define mozilla_dom_FileSystemPermissionRequest_h
#include "PCOMContentPermissionRequestChild.h"
#include "nsAutoPtr.h"
#include "nsContentPermissionHelper.h"
#include "nsIRunnable.h"
#include "nsIContentPermissionPrompt.h"
#include "nsString.h"
class nsCString;
class nsPIDOMWindow;
namespace mozilla {
@ -22,12 +23,22 @@ class FileSystemTaskBase;
class FileSystemPermissionRequest MOZ_FINAL
: public nsIContentPermissionRequest
, public nsIRunnable
, public PCOMContentPermissionRequestChild
{
public:
// Request permission for the given task.
static void
RequestForTask(FileSystemTaskBase* aTask);
// Overrides PCOMContentPermissionRequestChild
virtual void
IPDLRelease() MOZ_OVERRIDE;
bool
Recv__delete__(const bool& aAllow,
const InfallibleTArray<PermissionChoice>& aChoices) MOZ_OVERRIDE;
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSICONTENTPERMISSIONREQUEST
NS_DECL_NSIRUNNABLE

Просмотреть файл

@ -0,0 +1,38 @@
/* 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 PCOMContentPermissionRequestChild_h
#define PCOMContentPermissionRequestChild_h
#include "mozilla/dom/PContentPermissionRequestChild.h"
// Microsoft's API Name hackery sucks
// XXXbz Doing this in a header is a gigantic footgun. See
// https://bugzilla.mozilla.org/show_bug.cgi?id=932421#c3 for why.
#undef CreateEvent
#undef LoadImage
/*
PContentPermissionRequestChild implementations also are
XPCOM objects. Addref() is called on their implementation
before SendPContentPermissionRequestConstructor is called.
When Dealloc is called, IPDLRelease() is called.
Implementations of this method are expected to call
Release() on themselves. See Bug 594261 for more
information.
*/
class PCOMContentPermissionRequestChild : public mozilla::dom::PContentPermissionRequestChild {
public:
virtual void IPDLRelease() = 0;
#ifdef DEBUG
PCOMContentPermissionRequestChild() : mIPCOpen(false) {}
virtual ~PCOMContentPermissionRequestChild() {
// mIPCOpen is set to true in TabChild::SendPContentPermissionRequestConstructor
// and set to false in TabChild::DeallocPContentPermissionRequest
MOZ_ASSERT(!mIPCOpen, "Protocol must not be open when PCOMContentPermissionRequestChild is destroyed.");
}
bool mIPCOpen;
#endif /* DEBUG */
};
#endif

Просмотреть файл

@ -68,7 +68,7 @@
#include "nsWeakReference.h"
#include "nsWindowWatcher.h"
#include "PermissionMessageUtils.h"
#include "nsContentPermissionHelper.h"
#include "PCOMContentPermissionRequestChild.h"
#include "PuppetWidget.h"
#include "StructuredCloneUtils.h"
#include "nsViewportInfo.h"
@ -82,6 +82,10 @@
#include "nsColorPickerProxy.h"
#ifdef DEBUG
#include "PCOMContentPermissionRequestChild.h"
#endif /* DEBUG */
#define BROWSER_ELEMENT_CHILD_SCRIPT \
NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js")
@ -1403,6 +1407,19 @@ TabChild::SendPendingTouchPreventedResponse(bool aPreventDefault,
}
}
#ifdef DEBUG
PContentPermissionRequestChild*
TabChild:: SendPContentPermissionRequestConstructor(PContentPermissionRequestChild* aActor,
const InfallibleTArray<PermissionRequest>& aRequests,
const IPC::Principal& aPrincipal)
{
PCOMContentPermissionRequestChild* child = static_cast<PCOMContentPermissionRequestChild*>(aActor);
PContentPermissionRequestChild* request = PBrowserChild::SendPContentPermissionRequestConstructor(aActor, aRequests, aPrincipal);
child->mIPCOpen = true;
return request;
}
#endif /* DEBUG */
void
TabChild::DestroyWindow()
{
@ -2343,9 +2360,13 @@ TabChild::AllocPContentPermissionRequestChild(const InfallibleTArray<PermissionR
bool
TabChild::DeallocPContentPermissionRequestChild(PContentPermissionRequestChild* actor)
{
RemotePermissionRequest* child = static_cast<RemotePermissionRequest*>(actor);
child->IPDLRelease();
return true;
PCOMContentPermissionRequestChild* child =
static_cast<PCOMContentPermissionRequestChild*>(actor);
#ifdef DEBUG
child->mIPCOpen = false;
#endif /* DEBUG */
child->IPDLRelease();
return true;
}
PFilePickerChild*

Просмотреть файл

@ -386,6 +386,13 @@ public:
AllocPColorPickerChild(const nsString& title, const nsString& initialColor) MOZ_OVERRIDE;
virtual bool DeallocPColorPickerChild(PColorPickerChild* actor) MOZ_OVERRIDE;
#ifdef DEBUG
virtual PContentPermissionRequestChild*
SendPContentPermissionRequestConstructor(PContentPermissionRequestChild* aActor,
const InfallibleTArray<PermissionRequest>& aRequests,
const IPC::Principal& aPrincipal);
#endif /* DEBUG */
virtual PContentPermissionRequestChild*
AllocPContentPermissionRequestChild(const InfallibleTArray<PermissionRequest>& aRequests,
const IPC::Principal& aPrincipal) MOZ_OVERRIDE;

Просмотреть файл

@ -714,7 +714,7 @@ PContentPermissionRequestParent*
TabParent::AllocPContentPermissionRequestParent(const InfallibleTArray<PermissionRequest>& aRequests,
const IPC::Principal& aPrincipal)
{
return nsContentPermissionUtils::CreateContentPermissionRequestParent(aRequests, mFrameElement, aPrincipal);
return CreateContentPermissionRequestParent(aRequests, mFrameElement, aPrincipal);
}
bool

Просмотреть файл

@ -6,6 +6,7 @@
EXPORTS += [
'nsICachedFileDescriptorListener.h',
'PCOMContentPermissionRequestChild.h',
]
EXPORTS.mozilla.dom.ipc += [

Просмотреть файл

@ -16,7 +16,9 @@
#include "nsPIDOMWindow.h"
#include "nsTArray.h"
#include "GetUserMediaRequest.h"
#include "PCOMContentPermissionRequestChild.h"
#include "mozilla/dom/PBrowserChild.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/MediaStreamTrackBinding.h"
#include "nsISupportsPrimitives.h"
#include "nsServiceManagerUtils.h"
@ -108,6 +110,7 @@ namespace {
* to its owned type.
*/
class MediaPermissionRequest : public nsIContentPermissionRequest
, public PCOMContentPermissionRequestChild
{
public:
NS_DECL_ISUPPORTS
@ -116,6 +119,11 @@ public:
MediaPermissionRequest(nsRefPtr<dom::GetUserMediaRequest> &aRequest,
nsTArray<nsCOMPtr<nsIMediaDevice> > &aDevices);
// It will be called when prompt dismissed.
virtual bool Recv__delete__(const bool &allow,
const InfallibleTArray<PermissionChoice>& choices) MOZ_OVERRIDE;
virtual void IPDLRelease() MOZ_OVERRIDE { Release(); }
already_AddRefed<nsPIDOMWindow> GetOwner();
protected:
@ -308,6 +316,29 @@ MediaPermissionRequest::GetOwner()
return window.forget();
}
//PCOMContentPermissionRequestChild
bool
MediaPermissionRequest::Recv__delete__(const bool& allow,
const InfallibleTArray<PermissionChoice>& choices)
{
if (allow) {
// get selected device name for audio and video
nsString audioDevice, videoDevice;
for (uint32_t i = 0; i < choices.Length(); ++i) {
const nsString &choice = choices[i].choice();
if (choices[i].type().EqualsLiteral(AUDIO_PERMISSION_NAME)) {
audioDevice = choice;
} else if (choices[i].type().EqualsLiteral(VIDEO_PERMISSION_NAME)) {
videoDevice = choice;
}
}
(void) DoAllow(audioDevice, videoDevice);
} else {
(void) Cancel();
}
return true;
}
// Success callback for MediaManager::GetUserMediaDevices().
class MediaDeviceSuccessCallback: public nsIGetUserMediaDevicesSuccessCallback
{
@ -369,8 +400,45 @@ MediaDeviceSuccessCallback::OnSuccess(nsIVariant* aDevices)
nsresult
MediaDeviceSuccessCallback::DoPrompt(nsRefPtr<MediaPermissionRequest> &req)
{
nsCOMPtr<nsPIDOMWindow> window(req->GetOwner());
return dom::nsContentPermissionUtils::AskPermission(req, window);
// for content process
if (XRE_GetProcessType() == GeckoProcessType_Content) {
MOZ_ASSERT(NS_IsMainThread()); // IPC can only be execute on main thread.
nsresult rv;
nsCOMPtr<nsPIDOMWindow> window(req->GetOwner());
NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
dom::TabChild* child = dom::TabChild::GetFrom(window->GetDocShell());
NS_ENSURE_TRUE(child, NS_ERROR_FAILURE);
nsCOMPtr<nsIArray> typeArray;
rv = req->GetTypes(getter_AddRefs(typeArray));
NS_ENSURE_SUCCESS(rv, rv);
nsTArray<PermissionRequest> permArray;
RemotePermissionRequest::ConvertArrayToPermissionRequest(typeArray, permArray);
nsCOMPtr<nsIPrincipal> principal;
rv = req->GetPrincipal(getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
req->AddRef();
child->SendPContentPermissionRequestConstructor(req,
permArray,
IPC::Principal(principal));
req->Sendprompt();
return NS_OK;
}
// for chrome process
nsCOMPtr<nsIContentPermissionPrompt> prompt =
do_GetService(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
if (prompt) {
prompt->Prompt(req);
}
return NS_OK;
}
// Error callback for MediaManager::GetUserMediaDevices()

Просмотреть файл

@ -5,6 +5,7 @@
#include "nsXULAppAPI.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/Telemetry.h"
#include "nsISettingsService.h"
@ -23,6 +24,7 @@
#include "mozilla/unused.h"
#include "mozilla/Preferences.h"
#include "mozilla/ClearOnShutdown.h"
#include "PCOMContentPermissionRequestChild.h"
#include "mozilla/dom/PermissionMessageUtils.h"
class nsIPrincipal;
@ -58,6 +60,7 @@ class nsGeolocationRequest
: public nsIContentPermissionRequest
, public nsITimerCallback
, public nsIGeolocationUpdate
, public PCOMContentPermissionRequestChild
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
@ -82,10 +85,14 @@ class nsGeolocationRequest
void NotifyErrorAndShutdown(uint16_t);
nsIPrincipal* GetPrincipal();
virtual bool Recv__delete__(const bool& allow,
const InfallibleTArray<PermissionChoice>& choices) MOZ_OVERRIDE;
virtual void IPDLRelease() MOZ_OVERRIDE { Release(); }
bool IsWatch() { return mIsWatchPositionRequest; }
int32_t WatchId() { return mWatchId; }
private:
virtual ~nsGeolocationRequest();
~nsGeolocationRequest();
bool mIsWatchPositionRequest;
@ -162,22 +169,21 @@ NS_IMPL_ISUPPORTS(GeolocationSettingsCallback, nsISettingsServiceCallback)
class RequestPromptEvent : public nsRunnable
{
public:
RequestPromptEvent(nsGeolocationRequest* aRequest, nsWeakPtr aWindow)
: mRequest(aRequest)
, mWindow(aWindow)
RequestPromptEvent(nsGeolocationRequest* request)
: mRequest(request)
{
}
NS_IMETHOD Run()
{
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
nsContentPermissionUtils::AskPermission(mRequest, window);
NS_IMETHOD Run() {
nsCOMPtr<nsIContentPermissionPrompt> prompt = do_CreateInstance(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
if (prompt) {
prompt->Prompt(mRequest);
}
return NS_OK;
}
private:
nsRefPtr<nsGeolocationRequest> mRequest;
nsWeakPtr mWindow;
};
class RequestAllowEvent : public nsRunnable
@ -378,10 +384,10 @@ NS_IMETHODIMP
nsGeolocationRequest::GetTypes(nsIArray** aTypes)
{
nsTArray<nsString> emptyOptions;
return nsContentPermissionUtils::CreatePermissionArray(NS_LITERAL_CSTRING("geolocation"),
NS_LITERAL_CSTRING("unused"),
emptyOptions,
aTypes);
return CreatePermissionArray(NS_LITERAL_CSTRING("geolocation"),
NS_LITERAL_CSTRING("unused"),
emptyOptions,
aTypes);
}
NS_IMETHODIMP
@ -594,6 +600,18 @@ nsGeolocationRequest::Shutdown()
}
}
bool nsGeolocationRequest::Recv__delete__(const bool& allow,
const InfallibleTArray<PermissionChoice>& choices)
{
MOZ_ASSERT(choices.IsEmpty(), "Geolocation doesn't support permission choice");
if (allow) {
(void) Allow(JS::UndefinedHandleValue);
} else {
(void) Cancel();
}
return true;
}
////////////////////////////////////////////////////
// nsGeolocationService
////////////////////////////////////////////////////
@ -1451,7 +1469,37 @@ Geolocation::RegisterRequestWithPrompt(nsGeolocationRequest* request)
return true;
}
nsCOMPtr<nsIRunnable> ev = new RequestPromptEvent(request, mOwner);
if (XRE_GetProcessType() == GeckoProcessType_Content) {
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mOwner);
if (!window) {
return true;
}
// because owner implements nsITabChild, we can assume that it is
// the one and only TabChild.
TabChild* child = TabChild::GetFrom(window->GetDocShell());
if (!child) {
return false;
}
nsTArray<PermissionRequest> permArray;
nsTArray<nsString> emptyOptions;
permArray.AppendElement(PermissionRequest(NS_LITERAL_CSTRING("geolocation"),
NS_LITERAL_CSTRING("unused"),
emptyOptions));
// Retain a reference so the object isn't deleted without IPDL's knowledge.
// Corresponding release occurs in DeallocPContentPermissionRequest.
request->AddRef();
child->SendPContentPermissionRequestConstructor(request,
permArray,
IPC::Principal(mPrincipal));
request->Sendprompt();
return true;
}
nsCOMPtr<nsIRunnable> ev = new RequestPromptEvent(request);
NS_DispatchToMainThread(ev);
return true;
}

Просмотреть файл

@ -9,9 +9,11 @@
#include "nsXULAppAPI.h"
#include "mozilla/dom/PBrowserChild.h"
#include "nsIDOMDesktopNotification.h"
#include "TabChild.h"
#include "mozilla/Preferences.h"
#include "nsGlobalWindow.h"
#include "nsIAppsService.h"
#include "PCOMContentPermissionRequestChild.h"
#include "nsIScriptSecurityManager.h"
#include "nsServiceManagerUtils.h"
#include "PermissionMessageUtils.h"
@ -22,10 +24,12 @@ namespace dom {
/*
* Simple Request
*/
class DesktopNotificationRequest : public nsIContentPermissionRequest
, public nsRunnable
class DesktopNotificationRequest : public nsIContentPermissionRequest,
public nsRunnable,
public PCOMContentPermissionRequestChild
{
virtual ~DesktopNotificationRequest()
~DesktopNotificationRequest()
{
}
@ -38,11 +42,27 @@ public:
NS_IMETHOD Run() MOZ_OVERRIDE
{
nsCOMPtr<nsPIDOMWindow> window = mDesktopNotification->GetOwner();
nsContentPermissionUtils::AskPermission(this, window);
nsCOMPtr<nsIContentPermissionPrompt> prompt =
do_CreateInstance(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
if (prompt) {
prompt->Prompt(this);
}
return NS_OK;
}
virtual bool Recv__delete__(const bool& aAllow,
const InfallibleTArray<PermissionChoice>& choices) MOZ_OVERRIDE
{
MOZ_ASSERT(choices.IsEmpty(), "DesktopNotification doesn't support permission choice");
if (aAllow) {
(void) Allow(JS::UndefinedHandleValue);
} else {
(void) Cancel();
}
return true;
}
virtual void IPDLRelease() MOZ_OVERRIDE { Release(); }
nsRefPtr<DesktopNotification> mDesktopNotification;
};
@ -144,6 +164,38 @@ DesktopNotification::Init()
{
nsRefPtr<DesktopNotificationRequest> request = new DesktopNotificationRequest(this);
// if we are in the content process, then remote it to the parent.
if (XRE_GetProcessType() == GeckoProcessType_Content) {
// if for some reason mOwner is null, just silently
// bail. The user will not see a notification, and that
// is fine.
if (!GetOwner())
return;
// because owner implements nsITabChild, we can assume that it is
// the one and only TabChild for this docshell.
TabChild* child = TabChild::GetFrom(GetOwner()->GetDocShell());
// Retain a reference so the object isn't deleted without IPDL's knowledge.
// Corresponding release occurs in DeallocPContentPermissionRequest.
nsRefPtr<DesktopNotificationRequest> copy = request;
nsTArray<PermissionRequest> permArray;
nsTArray<nsString> emptyOptions;
permArray.AppendElement(PermissionRequest(
NS_LITERAL_CSTRING("desktop-notification"),
NS_LITERAL_CSTRING("unused"),
emptyOptions));
child->SendPContentPermissionRequestConstructor(copy.forget().take(),
permArray,
IPC::Principal(mPrincipal));
request->Sendprompt();
return;
}
// otherwise, dispatch it
NS_DispatchToMainThread(request);
}
@ -258,7 +310,7 @@ DesktopNotificationCenter::WrapObject(JSContext* aCx)
/* ------------------------------------------------------------------------ */
NS_IMPL_ISUPPORTS_INHERITED(DesktopNotificationRequest, nsRunnable,
nsIContentPermissionRequest)
nsIContentPermissionRequest)
NS_IMETHODIMP
DesktopNotificationRequest::GetPrincipal(nsIPrincipal * *aRequestingPrincipal)
@ -311,10 +363,10 @@ NS_IMETHODIMP
DesktopNotificationRequest::GetTypes(nsIArray** aTypes)
{
nsTArray<nsString> emptyOptions;
return nsContentPermissionUtils::CreatePermissionArray(NS_LITERAL_CSTRING("desktop-notification"),
NS_LITERAL_CSTRING("unused"),
emptyOptions,
aTypes);
return CreatePermissionArray(NS_LITERAL_CSTRING("desktop-notification"),
NS_LITERAL_CSTRING("unused"),
emptyOptions,
aTypes);
}
} // namespace dom

Просмотреть файл

@ -2,11 +2,13 @@
* 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 "PCOMContentPermissionRequestChild.h"
#include "mozilla/dom/Notification.h"
#include "mozilla/dom/AppNotificationServiceOptionsBinding.h"
#include "mozilla/dom/OwningNonNull.h"
#include "mozilla/dom/Promise.h"
#include "mozilla/Preferences.h"
#include "TabChild.h"
#include "nsContentUtils.h"
#include "nsIAlertsService.h"
#include "nsIAppsService.h"
@ -91,7 +93,7 @@ public:
}
private:
virtual ~NotificationStorageCallback()
~NotificationStorageCallback()
{
DropData();
}
@ -142,6 +144,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(NotificationStorageCallback)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
class NotificationPermissionRequest : public nsIContentPermissionRequest,
public PCOMContentPermissionRequestChild,
public nsIRunnable
{
public:
@ -157,6 +160,10 @@ public:
mPermission(NotificationPermission::Default),
mCallback(aCallback) {}
bool Recv__delete__(const bool& aAllow,
const InfallibleTArray<PermissionChoice>& choices);
void IPDLRelease() { Release(); }
protected:
virtual ~NotificationPermissionRequest() {}
@ -249,7 +256,38 @@ NotificationPermissionRequest::Run()
return DispatchCallback();
}
return nsContentPermissionUtils::AskPermission(this, mWindow);
if (XRE_GetProcessType() == GeckoProcessType_Content) {
// because owner implements nsITabChild, we can assume that it is
// the one and only TabChild.
TabChild* child = TabChild::GetFrom(mWindow->GetDocShell());
if (!child) {
return NS_ERROR_NOT_AVAILABLE;
}
// Retain a reference so the object isn't deleted without IPDL's knowledge.
// Corresponding release occurs in DeallocPContentPermissionRequest.
AddRef();
nsTArray<PermissionRequest> permArray;
nsTArray<nsString> emptyOptions;
permArray.AppendElement(PermissionRequest(
NS_LITERAL_CSTRING("desktop-notification"),
NS_LITERAL_CSTRING("unused"),
emptyOptions));
child->SendPContentPermissionRequestConstructor(this, permArray,
IPC::Principal(mPrincipal));
Sendprompt();
return NS_OK;
}
nsCOMPtr<nsIContentPermissionPrompt> prompt =
do_GetService(NS_CONTENT_PERMISSION_PROMPT_CONTRACTID);
if (prompt) {
prompt->Prompt(this);
}
return NS_OK;
}
NS_IMETHODIMP
@ -314,10 +352,24 @@ NS_IMETHODIMP
NotificationPermissionRequest::GetTypes(nsIArray** aTypes)
{
nsTArray<nsString> emptyOptions;
return nsContentPermissionUtils::CreatePermissionArray(NS_LITERAL_CSTRING("desktop-notification"),
NS_LITERAL_CSTRING("unused"),
emptyOptions,
aTypes);
return CreatePermissionArray(NS_LITERAL_CSTRING("desktop-notification"),
NS_LITERAL_CSTRING("unused"),
emptyOptions,
aTypes);
}
bool
NotificationPermissionRequest::Recv__delete__(const bool& aAllow,
const InfallibleTArray<PermissionChoice>& choices)
{
MOZ_ASSERT(choices.IsEmpty(), "Notification doesn't support permission choice");
if (aAllow) {
(void) Allow(JS::UndefinedHandleValue);
} else {
(void) Cancel();
}
return true;
}
NS_IMPL_ISUPPORTS(NotificationTask, nsIRunnable)