import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo

This commit is contained in:
Roy Tam 2018-01-19 03:59:58 +08:00
commit dcd9973243
150858 changed files with 23884658 additions and 0 deletions

View file

@ -0,0 +1,95 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "AppProcessChecker.h"
#include "nsIPermissionManager.h"
namespace mozilla {
namespace dom {
class PContentParent;
} // namespace dom
} // namespace mozilla
class nsIPrincipal;
namespace mozilla {
#if DEBUG
#define LOG(...) printf_stderr(__VA_ARGS__)
#else
#define LOG(...)
#endif
bool
AssertAppProcess(mozilla::dom::PBrowserParent* aActor,
AssertAppProcessType aType,
const char* aCapability)
{
return true;
}
bool
AssertAppStatus(mozilla::dom::PBrowserParent* aActor,
unsigned short aStatus)
{
return true;
}
bool
AssertAppProcess(const mozilla::dom::TabContext& aContext,
AssertAppProcessType aType,
const char* aCapability)
{
return true;
}
bool
AssertAppStatus(const mozilla::dom::TabContext& aContext,
unsigned short aStatus)
{
return true;
}
bool
AssertAppProcess(mozilla::dom::PContentParent* aActor,
AssertAppProcessType aType,
const char* aCapability)
{
return true;
}
bool
AssertAppStatus(mozilla::dom::PContentParent* aActor,
unsigned short aStatus)
{
return true;
}
bool
AssertAppProcess(mozilla::hal_sandbox::PHalParent* aActor,
AssertAppProcessType aType,
const char* aCapability)
{
return true;
}
bool
AssertAppPrincipal(mozilla::dom::PContentParent* aActor,
nsIPrincipal* aPrincipal)
{
return true;
}
uint32_t
CheckPermission(mozilla::dom::PContentParent* aActor,
nsIPrincipal* aPrincipal,
const char* aPermission)
{
return nsIPermissionManager::ALLOW_ACTION;
}
} // namespace mozilla

160
dom/ipc/AppProcessChecker.h Normal file
View file

@ -0,0 +1,160 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_AppProcessChecker_h
#define mozilla_AppProcessChecker_h
#include <stdint.h>
class nsIPrincipal;
namespace mozilla {
namespace dom {
class TabContext;
class PBrowserParent;
class PContentParent;
} // namespace dom
namespace hal_sandbox {
class PHalParent;
} // namespace hal_sandbox
enum AssertAppProcessType {
ASSERT_APP_PROCESS_PERMISSION,
ASSERT_APP_PROCESS_MANIFEST_URL,
ASSERT_APP_HAS_PERMISSION
};
/**
* Return true if the specified browser has the specified capability.
* If this returns false, the browser didn't have the capability and
* will be killed.
*/
bool
AssertAppProcess(mozilla::dom::PBrowserParent* aActor,
AssertAppProcessType aType,
const char* aCapability);
/**
* Return true if the specified app has the specified status.
* If this returns false, the browser will be killed.
*/
bool
AssertAppStatus(mozilla::dom::PBrowserParent* aActor,
unsigned short aStatus);
/**
* Return true if the specified browser has the specified capability.
* If this returns false, the browser didn't have the capability and
* will be killed.
*/
bool
AssertAppProcess(const mozilla::dom::TabContext& aContext,
AssertAppProcessType aType,
const char* aCapability);
/**
* Return true if the specified app has the specified status.
* If this returns false, the browser will be killed.
*/
bool
AssertAppStatus(const mozilla::dom::TabContext& aContext,
unsigned short aStatus);
/**
* Return true if any of the PBrowsers loaded in this content process
* has the specified capability. If this returns false, the process
* didn't have the capability and will be killed.
*/
bool
AssertAppProcess(mozilla::dom::PContentParent* aActor,
AssertAppProcessType aType,
const char* aCapability);
/**
* Return true if any of the PBrowsers loaded in this content process
* has an app with the specified status. If this returns false, the process
* didn't have the status and will be killed.
*/
bool
AssertAppStatus(mozilla::dom::PContentParent* aActor,
unsigned short aStatus);
bool
AssertAppProcess(mozilla::hal_sandbox::PHalParent* aActor,
AssertAppProcessType aType,
const char* aCapability);
// NB: when adding capability checks for other IPDL actors, please add
// them to this file and have them delegate to the two functions above
// as appropriate. For example,
//
// bool AppProcessHasCapability(PNeckoParent* aActor, AssertAppProcessType aType) {
// return AssertAppProcess(aActor->Manager(), aType);
// }
bool
AssertAppPrincipal(mozilla::dom::PContentParent* aParent,
nsIPrincipal* aPrincipal);
/**
* Check if the specified principal is valid, and return the saved permission
* value for permission `aPermission' on that principal.
* See nsIPermissionManager.idl for possible return values.
*
* nsIPermissionManager::UNKNOWN_ACTION is retuned if the principal is invalid.
*/
uint32_t
CheckPermission(mozilla::dom::PContentParent* aParent,
nsIPrincipal* aPrincipal, const char* aPermission);
/**
* Inline function for asserting the process's permission.
*/
template<typename T>
inline bool
AssertAppProcessPermission(T* aActor,
const char* aPermission) {
return AssertAppProcess(aActor,
ASSERT_APP_PROCESS_PERMISSION,
aPermission);
}
/**
* Inline function for asserting the process's manifest URL.
*/
template<typename T>
inline bool
AssertAppProcessManifestURL(T* aActor,
const char* aManifestURL) {
return AssertAppProcess(aActor,
ASSERT_APP_PROCESS_MANIFEST_URL,
aManifestURL);
}
/**
* Inline function for asserting the process's manifest URL.
*/
template<typename T>
inline bool
AssertAppHasPermission(T* aActor,
const char* aPermission) {
return AssertAppProcess(aActor,
ASSERT_APP_HAS_PERMISSION,
aPermission);
}
template<typename T>
inline bool
AssertAppHasStatus(T* aActor,
unsigned short aStatus) {
return AssertAppStatus(aActor, aStatus);
}
} // namespace mozilla
#endif // mozilla_AppProcessChecker_h

4793
dom/ipc/Blob.cpp Normal file

File diff suppressed because it is too large Load diff

246
dom/ipc/BlobChild.h Normal file
View file

@ -0,0 +1,246 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_ipc_BlobChild_h
#define mozilla_dom_ipc_BlobChild_h
#include "mozilla/Attributes.h"
#include "mozilla/dom/PBlobChild.h"
#include "nsCOMPtr.h"
#include "nsID.h"
class nsIEventTarget;
class nsIRemoteBlob;
class nsString;
namespace mozilla {
namespace ipc {
class PBackgroundChild;
} // namespace ipc
namespace dom {
class Blob;
class BlobImpl;
class ContentChild;
class nsIContentChild;
class PBlobStreamChild;
class BlobChild final
: public PBlobChild
{
typedef mozilla::ipc::PBackgroundChild PBackgroundChild;
class RemoteBlobImpl;
friend class RemoteBlobImpl;
class RemoteBlobSliceImpl;
friend class RemoteBlobSliceImpl;
BlobImpl* mBlobImpl;
RemoteBlobImpl* mRemoteBlobImpl;
// One of these will be null and the other non-null.
PBackgroundChild* mBackgroundManager;
nsCOMPtr<nsIContentChild> mContentManager;
nsCOMPtr<nsIEventTarget> mEventTarget;
nsID mParentID;
bool mOwnsBlobImpl;
public:
class FriendKey;
static void
Startup(const FriendKey& aKey);
// These create functions are called on the sending side.
static BlobChild*
GetOrCreate(nsIContentChild* aManager, BlobImpl* aBlobImpl);
static BlobChild*
GetOrCreate(PBackgroundChild* aManager, BlobImpl* aBlobImpl);
// These create functions are called on the receiving side.
static BlobChild*
Create(nsIContentChild* aManager, const ChildBlobConstructorParams& aParams);
static BlobChild*
Create(PBackgroundChild* aManager,
const ChildBlobConstructorParams& aParams);
static void
Destroy(PBlobChild* aActor)
{
delete static_cast<BlobChild*>(aActor);
}
bool
HasManager() const
{
return mBackgroundManager || mContentManager;
}
PBackgroundChild*
GetBackgroundManager() const
{
return mBackgroundManager;
}
nsIContentChild*
GetContentManager() const
{
return mContentManager;
}
const nsID&
ParentID() const;
// Get the BlobImpl associated with this actor. This may always be called
// on the sending side. It may also be called on the receiving side unless
// this is a "mystery" blob that has not yet received a SetMysteryBlobInfo()
// call.
already_AddRefed<BlobImpl>
GetBlobImpl();
// Use this for files.
bool
SetMysteryBlobInfo(const nsString& aName,
const nsString& aContentType,
uint64_t aLength,
int64_t aLastModifiedDate);
// Use this for non-file blobs.
bool
SetMysteryBlobInfo(const nsString& aContentType, uint64_t aLength);
void
AssertIsOnOwningThread() const
#ifdef DEBUG
;
#else
{ }
#endif
private:
// These constructors are called on the sending side.
BlobChild(nsIContentChild* aManager, BlobImpl* aBlobImpl);
BlobChild(PBackgroundChild* aManager, BlobImpl* aBlobImpl);
BlobChild(nsIContentChild* aManager, BlobChild* aOther);
BlobChild(PBackgroundChild* aManager, BlobChild* aOther, BlobImpl* aBlobImpl);
// These constructors are called on the receiving side.
BlobChild(nsIContentChild* aManager,
const ChildBlobConstructorParams& aParams);
BlobChild(PBackgroundChild* aManager,
const ChildBlobConstructorParams& aParams);
// These constructors are called for slices.
BlobChild(nsIContentChild* aManager,
const nsID& aParentID,
RemoteBlobSliceImpl* aRemoteBlobSliceImpl);
BlobChild(PBackgroundChild* aManager,
const nsID& aParentID,
RemoteBlobSliceImpl* aRemoteBlobSliceImpl);
// Only called by Destroy().
~BlobChild();
void
CommonInit(BlobImpl* aBlobImpl);
void
CommonInit(BlobChild* aOther, BlobImpl* aBlobImpl);
void
CommonInit(const ChildBlobConstructorParams& aParams);
void
CommonInit(const nsID& aParentID, RemoteBlobImpl* aRemoteBlobImpl);
template <class ChildManagerType>
static BlobChild*
GetOrCreateFromImpl(ChildManagerType* aManager, BlobImpl* aBlobImpl);
template <class ChildManagerType>
static BlobChild*
CreateFromParams(ChildManagerType* aManager,
const ChildBlobConstructorParams& aParams);
template <class ChildManagerType>
static BlobChild*
SendSliceConstructor(ChildManagerType* aManager,
RemoteBlobSliceImpl* aRemoteBlobSliceImpl,
const ParentBlobConstructorParams& aParams);
static BlobChild*
MaybeGetActorFromRemoteBlob(nsIRemoteBlob* aRemoteBlob,
nsIContentChild* aManager,
BlobImpl* aBlobImpl);
static BlobChild*
MaybeGetActorFromRemoteBlob(nsIRemoteBlob* aRemoteBlob,
PBackgroundChild* aManager,
BlobImpl* aBlobImpl);
void
NoteDyingRemoteBlobImpl();
nsIEventTarget*
EventTarget() const
{
return mEventTarget;
}
bool
IsOnOwningThread() const;
// These methods are only called by the IPDL message machinery.
virtual void
ActorDestroy(ActorDestroyReason aWhy) override;
virtual PBlobStreamChild*
AllocPBlobStreamChild(const uint64_t& aStart,
const uint64_t& aLength) override;
virtual bool
DeallocPBlobStreamChild(PBlobStreamChild* aActor) override;
virtual bool
RecvCreatedFromKnownBlob() override;
};
// Only let ContentChild call BlobChild::Startup() and ensure that
// ContentChild can't access any other BlobChild internals.
class BlobChild::FriendKey final
{
friend class ContentChild;
private:
FriendKey()
{ }
FriendKey(const FriendKey& /* aOther */)
{ }
public:
~FriendKey()
{ }
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ipc_BlobChild_h

260
dom/ipc/BlobParent.h Normal file
View file

@ -0,0 +1,260 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_ipc_BlobParent_h
#define mozilla_dom_ipc_BlobParent_h
#include "mozilla/Attributes.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/dom/PBlobParent.h"
#include "nsCOMPtr.h"
#include "nsTArray.h"
template <class, class> class nsDataHashtable;
class nsIDHashKey;
class nsIEventTarget;
class nsIRemoteBlob;
template <class> class nsRevocableEventPtr;
class nsString;
namespace mozilla {
class Mutex;
namespace ipc {
class PBackgroundParent;
} // namespace ipc
namespace dom {
class ContentParent;
class BlobImpl;
class nsIContentParent;
class PBlobStreamParent;
class BlobParent final
: public PBlobParent
{
typedef mozilla::ipc::PBackgroundParent PBackgroundParent;
class IDTableEntry;
typedef nsDataHashtable<nsIDHashKey, IDTableEntry*> IDTable;
class OpenStreamRunnable;
friend class OpenStreamRunnable;
class RemoteBlobImpl;
struct CreateBlobImplMetadata;
static StaticAutoPtr<IDTable> sIDTable;
static StaticAutoPtr<Mutex> sIDTableMutex;
BlobImpl* mBlobImpl;
RemoteBlobImpl* mRemoteBlobImpl;
// One of these will be null and the other non-null.
PBackgroundParent* mBackgroundManager;
nsCOMPtr<nsIContentParent> mContentManager;
nsCOMPtr<nsIEventTarget> mEventTarget;
// nsIInputStreams backed by files must ensure that the files are actually
// opened and closed on a background thread before we can send their file
// handles across to the child. The child process could crash during this
// process so we need to make sure we cancel the intended response in such a
// case. We do that by holding an array of nsRevocableEventPtr. If the child
// crashes then this actor will be destroyed and the nsRevocableEventPtr
// destructor will cancel any stream events that are currently in flight.
nsTArray<nsRevocableEventPtr<OpenStreamRunnable>> mOpenStreamRunnables;
RefPtr<IDTableEntry> mIDTableEntry;
bool mOwnsBlobImpl;
public:
class FriendKey;
static void
Startup(const FriendKey& aKey);
// These create functions are called on the sending side.
static BlobParent*
GetOrCreate(nsIContentParent* aManager, BlobImpl* aBlobImpl);
static BlobParent*
GetOrCreate(PBackgroundParent* aManager, BlobImpl* aBlobImpl);
// These create functions are called on the receiving side.
static BlobParent*
Create(nsIContentParent* aManager,
const ParentBlobConstructorParams& aParams);
static BlobParent*
Create(PBackgroundParent* aManager,
const ParentBlobConstructorParams& aParams);
static void
Destroy(PBlobParent* aActor)
{
delete static_cast<BlobParent*>(aActor);
}
static already_AddRefed<BlobImpl>
GetBlobImplForID(const nsID& aID);
bool
HasManager() const
{
return mBackgroundManager || mContentManager;
}
PBackgroundParent*
GetBackgroundManager() const
{
return mBackgroundManager;
}
nsIContentParent*
GetContentManager() const
{
return mContentManager;
}
// Get the BlobImpl associated with this actor.
already_AddRefed<BlobImpl>
GetBlobImpl();
void
AssertIsOnOwningThread() const
#ifdef DEBUG
;
#else
{ }
#endif
private:
// These constructors are called on the sending side.
BlobParent(nsIContentParent* aManager, IDTableEntry* aIDTableEntry);
BlobParent(PBackgroundParent* aManager, IDTableEntry* aIDTableEntry);
// These constructors are called on the receiving side.
BlobParent(nsIContentParent* aManager,
BlobImpl* aBlobImpl,
IDTableEntry* aIDTableEntry);
BlobParent(PBackgroundParent* aManager,
BlobImpl* aBlobImpl,
IDTableEntry* aIDTableEntry);
// Only destroyed by BackgroundParentImpl and ContentParent.
~BlobParent();
void
CommonInit(IDTableEntry* aIDTableEntry);
void
CommonInit(BlobImpl* aBlobImpl, IDTableEntry* aIDTableEntry);
template <class ParentManagerType>
static BlobParent*
GetOrCreateFromImpl(ParentManagerType* aManager,
BlobImpl* aBlobImpl);
template <class ParentManagerType>
static BlobParent*
CreateFromParams(ParentManagerType* aManager,
const ParentBlobConstructorParams& aParams);
template <class ParentManagerType>
static BlobParent*
SendSliceConstructor(ParentManagerType* aManager,
const ParentBlobConstructorParams& aParams,
const ChildBlobConstructorParams& aOtherSideParams);
static BlobParent*
MaybeGetActorFromRemoteBlob(nsIRemoteBlob* aRemoteBlob,
nsIContentParent* aManager);
static BlobParent*
MaybeGetActorFromRemoteBlob(nsIRemoteBlob* aRemoteBlob,
PBackgroundParent* aManager);
void
NoteDyingRemoteBlobImpl();
void
NoteRunnableCompleted(OpenStreamRunnable* aRunnable);
nsIEventTarget*
EventTarget() const
{
return mEventTarget;
}
bool
IsOnOwningThread() const;
// These methods are only called by the IPDL message machinery.
virtual void
ActorDestroy(ActorDestroyReason aWhy) override;
virtual PBlobStreamParent*
AllocPBlobStreamParent(const uint64_t& aStart,
const uint64_t& aLength) override;
virtual bool
RecvPBlobStreamConstructor(PBlobStreamParent* aActor,
const uint64_t& aStart,
const uint64_t& aLength) override;
virtual bool
DeallocPBlobStreamParent(PBlobStreamParent* aActor) override;
virtual bool
RecvResolveMystery(const ResolveMysteryParams& aParams) override;
virtual bool
RecvBlobStreamSync(const uint64_t& aStart,
const uint64_t& aLength,
InputStreamParams* aParams,
OptionalFileDescriptorSet* aFDs) override;
virtual bool
RecvWaitForSliceCreation() override;
virtual bool
RecvGetFileId(int64_t* aFileId) override;
virtual bool
RecvGetFilePath(nsString* aFilePath) override;
};
// Only let ContentParent call BlobParent::Startup() and ensure that
// ContentParent can't access any other BlobParent internals.
class BlobParent::FriendKey final
{
friend class ContentParent;
private:
FriendKey()
{ }
FriendKey(const FriendKey& /* aOther */)
{ }
public:
~FriendKey()
{ }
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ipc_BlobParent_h

21
dom/ipc/BlobTypes.ipdlh Normal file
View file

@ -0,0 +1,21 @@
/* 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 protocol PFileDescriptorSet;
using struct mozilla::void_t
from "ipc/IPCMessageUtils.h";
namespace mozilla {
namespace dom {
union OptionalFileDescriptorSet
{
PFileDescriptorSet;
FileDescriptor[];
void_t;
};
}
}

View file

@ -0,0 +1,27 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_CPOWManagerGetter_h
#define mozilla_dom_CPOWManagerGetter_h
namespace mozilla {
namespace jsipc {
class CPOWManager;
} /* namespace jsipc */
namespace dom {
class CPOWManagerGetter
{
public:
virtual mozilla::jsipc::CPOWManager* GetCPOWManager() = 0;
};
} /* namespace dom */
} /* namespace mozilla */
#endif /* mozilla_dom_CPOWManagerGetter_h */

View file

@ -0,0 +1,87 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "ColorPickerParent.h"
#include "nsComponentManagerUtils.h"
#include "nsIDocument.h"
#include "nsIDOMWindow.h"
#include "mozilla/Unused.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/TabParent.h"
using mozilla::Unused;
using namespace mozilla::dom;
NS_IMPL_ISUPPORTS(ColorPickerParent::ColorPickerShownCallback,
nsIColorPickerShownCallback);
NS_IMETHODIMP
ColorPickerParent::ColorPickerShownCallback::Update(const nsAString& aColor)
{
if (mColorPickerParent) {
Unused << mColorPickerParent->SendUpdate(nsString(aColor));
}
return NS_OK;
}
NS_IMETHODIMP
ColorPickerParent::ColorPickerShownCallback::Done(const nsAString& aColor)
{
if (mColorPickerParent) {
Unused << mColorPickerParent->Send__delete__(mColorPickerParent,
nsString(aColor));
}
return NS_OK;
}
void
ColorPickerParent::ColorPickerShownCallback::Destroy()
{
mColorPickerParent = nullptr;
}
bool
ColorPickerParent::CreateColorPicker()
{
mPicker = do_CreateInstance("@mozilla.org/colorpicker;1");
if (!mPicker) {
return false;
}
Element* ownerElement = TabParent::GetFrom(Manager())->GetOwnerElement();
if (!ownerElement) {
return false;
}
nsCOMPtr<nsPIDOMWindowOuter> window = ownerElement->OwnerDoc()->GetWindow();
if (!window) {
return false;
}
return NS_SUCCEEDED(mPicker->Init(window, mTitle, mInitialColor));
}
bool
ColorPickerParent::RecvOpen()
{
if (!CreateColorPicker()) {
Unused << Send__delete__(this, mInitialColor);
return true;
}
mCallback = new ColorPickerShownCallback(this);
mPicker->Open(mCallback);
return true;
};
void
ColorPickerParent::ActorDestroy(ActorDestroyReason aWhy)
{
if (mCallback) {
mCallback->Destroy();
}
}

View file

@ -0,0 +1,61 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_ColorPickerParent_h
#define mozilla_dom_ColorPickerParent_h
#include "mozilla/dom/PColorPickerParent.h"
#include "nsIColorPicker.h"
namespace mozilla {
namespace dom {
class ColorPickerParent : public PColorPickerParent
{
public:
ColorPickerParent(const nsString& aTitle,
const nsString& aInitialColor)
: mTitle(aTitle)
, mInitialColor(aInitialColor)
{}
virtual bool RecvOpen() override;
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
class ColorPickerShownCallback final
: public nsIColorPickerShownCallback
{
public:
explicit ColorPickerShownCallback(ColorPickerParent* aColorPickerParnet)
: mColorPickerParent(aColorPickerParnet)
{}
NS_DECL_ISUPPORTS
NS_DECL_NSICOLORPICKERSHOWNCALLBACK
void Destroy();
private:
~ColorPickerShownCallback() {}
ColorPickerParent* mColorPickerParent;
};
private:
virtual ~ColorPickerParent() {}
bool CreateColorPicker();
RefPtr<ColorPickerShownCallback> mCallback;
nsCOMPtr<nsIColorPicker> mPicker;
nsString mTitle;
nsString mInitialColor;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ColorPickerParent_h

View file

@ -0,0 +1,206 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "mozilla/dom/ContentBridgeChild.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "base/task.h"
using namespace mozilla::ipc;
using namespace mozilla::jsipc;
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS(ContentBridgeChild,
nsIContentChild)
ContentBridgeChild::ContentBridgeChild(Transport* aTransport)
: mTransport(aTransport)
{}
ContentBridgeChild::~ContentBridgeChild()
{
}
void
ContentBridgeChild::ActorDestroy(ActorDestroyReason aWhy)
{
MessageLoop::current()->PostTask(NewRunnableMethod(this, &ContentBridgeChild::DeferredDestroy));
}
/*static*/ ContentBridgeChild*
ContentBridgeChild::Create(Transport* aTransport, ProcessId aOtherPid)
{
RefPtr<ContentBridgeChild> bridge =
new ContentBridgeChild(aTransport);
bridge->mSelfRef = bridge;
DebugOnly<bool> ok = bridge->Open(aTransport, aOtherPid, XRE_GetIOMessageLoop());
MOZ_ASSERT(ok);
return bridge;
}
void
ContentBridgeChild::DeferredDestroy()
{
mSelfRef = nullptr;
// |this| was just destroyed, hands off
}
bool
ContentBridgeChild::RecvAsyncMessage(const nsString& aMsg,
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
const ClonedMessageData& aData)
{
return nsIContentChild::RecvAsyncMessage(aMsg, Move(aCpows), aPrincipal, aData);
}
PBlobChild*
ContentBridgeChild::SendPBlobConstructor(PBlobChild* actor,
const BlobConstructorParams& params)
{
return PContentBridgeChild::SendPBlobConstructor(actor, params);
}
bool
ContentBridgeChild::SendPBrowserConstructor(PBrowserChild* aActor,
const TabId& aTabId,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const ContentParentId& aCpID,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
return PContentBridgeChild::SendPBrowserConstructor(aActor,
aTabId,
aContext,
aChromeFlags,
aCpID,
aIsForApp,
aIsForBrowser);
}
PFileDescriptorSetChild*
ContentBridgeChild::SendPFileDescriptorSetConstructor(const FileDescriptor& aFD)
{
return PContentBridgeChild::SendPFileDescriptorSetConstructor(aFD);
}
PSendStreamChild*
ContentBridgeChild::SendPSendStreamConstructor(PSendStreamChild* aActor)
{
return PContentBridgeChild::SendPSendStreamConstructor(aActor);
}
// This implementation is identical to ContentChild::GetCPOWManager but we can't
// move it to nsIContentChild because it calls ManagedPJavaScriptChild() which
// only exists in PContentChild and PContentBridgeChild.
jsipc::CPOWManager*
ContentBridgeChild::GetCPOWManager()
{
if (PJavaScriptChild* c = LoneManagedOrNullAsserts(ManagedPJavaScriptChild())) {
return CPOWManagerFor(c);
}
return CPOWManagerFor(SendPJavaScriptConstructor());
}
mozilla::jsipc::PJavaScriptChild *
ContentBridgeChild::AllocPJavaScriptChild()
{
return nsIContentChild::AllocPJavaScriptChild();
}
bool
ContentBridgeChild::DeallocPJavaScriptChild(PJavaScriptChild *child)
{
return nsIContentChild::DeallocPJavaScriptChild(child);
}
PBrowserChild*
ContentBridgeChild::AllocPBrowserChild(const TabId& aTabId,
const IPCTabContext &aContext,
const uint32_t& aChromeFlags,
const ContentParentId& aCpID,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
return nsIContentChild::AllocPBrowserChild(aTabId,
aContext,
aChromeFlags,
aCpID,
aIsForApp,
aIsForBrowser);
}
bool
ContentBridgeChild::DeallocPBrowserChild(PBrowserChild* aChild)
{
return nsIContentChild::DeallocPBrowserChild(aChild);
}
bool
ContentBridgeChild::RecvPBrowserConstructor(PBrowserChild* aActor,
const TabId& aTabId,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const ContentParentId& aCpID,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
return ContentChild::GetSingleton()->RecvPBrowserConstructor(aActor,
aTabId,
aContext,
aChromeFlags,
aCpID,
aIsForApp,
aIsForBrowser);
}
PBlobChild*
ContentBridgeChild::AllocPBlobChild(const BlobConstructorParams& aParams)
{
return nsIContentChild::AllocPBlobChild(aParams);
}
bool
ContentBridgeChild::DeallocPBlobChild(PBlobChild* aActor)
{
return nsIContentChild::DeallocPBlobChild(aActor);
}
PSendStreamChild*
ContentBridgeChild::AllocPSendStreamChild()
{
return nsIContentChild::AllocPSendStreamChild();
}
bool
ContentBridgeChild::DeallocPSendStreamChild(PSendStreamChild* aActor)
{
return nsIContentChild::DeallocPSendStreamChild(aActor);
}
PFileDescriptorSetChild*
ContentBridgeChild::AllocPFileDescriptorSetChild(const FileDescriptor& aFD)
{
return nsIContentChild::AllocPFileDescriptorSetChild(aFD);
}
bool
ContentBridgeChild::DeallocPFileDescriptorSetChild(PFileDescriptorSetChild* aActor)
{
return nsIContentChild::DeallocPFileDescriptorSetChild(aActor);
}
} // namespace dom
} // namespace mozilla

View file

@ -0,0 +1,102 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_ContentBridgeChild_h
#define mozilla_dom_ContentBridgeChild_h
#include "mozilla/dom/PContentBridgeChild.h"
#include "mozilla/dom/nsIContentChild.h"
namespace mozilla {
namespace dom {
class ContentBridgeChild final : public PContentBridgeChild
, public nsIContentChild
{
public:
explicit ContentBridgeChild(Transport* aTransport);
NS_DECL_ISUPPORTS
static ContentBridgeChild*
Create(Transport* aTransport, ProcessId aOtherProcess);
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
void DeferredDestroy();
virtual bool RecvAsyncMessage(const nsString& aMsg,
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
const ClonedMessageData& aData) override;
virtual PBlobChild*
SendPBlobConstructor(PBlobChild* actor,
const BlobConstructorParams& aParams) override;
jsipc::CPOWManager* GetCPOWManager() override;
virtual bool SendPBrowserConstructor(PBrowserChild* aActor,
const TabId& aTabId,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const ContentParentId& aCpID,
const bool& aIsForApp,
const bool& aIsForBrowser) override;
virtual mozilla::ipc::PFileDescriptorSetChild*
SendPFileDescriptorSetConstructor(const mozilla::ipc::FileDescriptor&) override;
virtual mozilla::ipc::PSendStreamChild*
SendPSendStreamConstructor(mozilla::ipc::PSendStreamChild*) override;
FORWARD_SHMEM_ALLOCATOR_TO(PContentBridgeChild)
protected:
virtual ~ContentBridgeChild();
virtual PBrowserChild* AllocPBrowserChild(const TabId& aTabId,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const ContentParentId& aCpID,
const bool& aIsForApp,
const bool& aIsForBrowser) override;
virtual bool DeallocPBrowserChild(PBrowserChild*) override;
virtual bool RecvPBrowserConstructor(PBrowserChild* aCctor,
const TabId& aTabId,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const ContentParentId& aCpID,
const bool& aIsForApp,
const bool& aIsForBrowser) override;
virtual mozilla::jsipc::PJavaScriptChild* AllocPJavaScriptChild() override;
virtual bool DeallocPJavaScriptChild(mozilla::jsipc::PJavaScriptChild*) override;
virtual PBlobChild* AllocPBlobChild(const BlobConstructorParams& aParams) override;
virtual bool DeallocPBlobChild(PBlobChild*) override;
virtual mozilla::ipc::PSendStreamChild* AllocPSendStreamChild() override;
virtual bool
DeallocPSendStreamChild(mozilla::ipc::PSendStreamChild* aActor) override;
virtual PFileDescriptorSetChild*
AllocPFileDescriptorSetChild(const mozilla::ipc::FileDescriptor& aFD) override;
virtual bool
DeallocPFileDescriptorSetChild(mozilla::ipc::PFileDescriptorSetChild* aActor) override;
DISALLOW_EVIL_CONSTRUCTORS(ContentBridgeChild);
protected: // members
RefPtr<ContentBridgeChild> mSelfRef;
Transport* mTransport; // owned
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ContentBridgeChild_h

View file

@ -0,0 +1,221 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "mozilla/dom/ContentBridgeParent.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
#include "nsXULAppAPI.h"
#include "nsIObserverService.h"
#include "base/task.h"
using namespace mozilla::ipc;
using namespace mozilla::jsipc;
namespace mozilla {
namespace dom {
NS_IMPL_ISUPPORTS(ContentBridgeParent,
nsIContentParent,
nsIObserver)
ContentBridgeParent::ContentBridgeParent(Transport* aTransport)
: mTransport(aTransport)
{}
ContentBridgeParent::~ContentBridgeParent()
{
}
void
ContentBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
{
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
if (os) {
os->RemoveObserver(this, "content-child-shutdown");
}
MessageLoop::current()->PostTask(NewRunnableMethod(this, &ContentBridgeParent::DeferredDestroy));
}
/*static*/ ContentBridgeParent*
ContentBridgeParent::Create(Transport* aTransport, ProcessId aOtherPid)
{
RefPtr<ContentBridgeParent> bridge =
new ContentBridgeParent(aTransport);
bridge->mSelfRef = bridge;
DebugOnly<bool> ok = bridge->Open(aTransport, aOtherPid,
XRE_GetIOMessageLoop());
MOZ_ASSERT(ok);
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
if (os) {
os->AddObserver(bridge, "content-child-shutdown", false);
}
// Initialize the message manager (and load delayed scripts) now that we
// have established communications with the child.
bridge->mMessageManager->InitWithCallback(bridge);
return bridge.get();
}
void
ContentBridgeParent::DeferredDestroy()
{
mSelfRef = nullptr;
// |this| was just destroyed, hands off
}
bool
ContentBridgeParent::RecvSyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
nsTArray<StructuredCloneData>* aRetvals)
{
return nsIContentParent::RecvSyncMessage(aMsg, aData, Move(aCpows),
aPrincipal, aRetvals);
}
bool
ContentBridgeParent::RecvAsyncMessage(const nsString& aMsg,
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
const ClonedMessageData& aData)
{
return nsIContentParent::RecvAsyncMessage(aMsg, Move(aCpows),
aPrincipal, aData);
}
PBlobParent*
ContentBridgeParent::SendPBlobConstructor(PBlobParent* actor,
const BlobConstructorParams& params)
{
return PContentBridgeParent::SendPBlobConstructor(actor, params);
}
PBrowserParent*
ContentBridgeParent::SendPBrowserConstructor(PBrowserParent* aActor,
const TabId& aTabId,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const ContentParentId& aCpID,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
return PContentBridgeParent::SendPBrowserConstructor(aActor,
aTabId,
aContext,
aChromeFlags,
aCpID,
aIsForApp,
aIsForBrowser);
}
PBlobParent*
ContentBridgeParent::AllocPBlobParent(const BlobConstructorParams& aParams)
{
return nsIContentParent::AllocPBlobParent(aParams);
}
bool
ContentBridgeParent::DeallocPBlobParent(PBlobParent* aActor)
{
return nsIContentParent::DeallocPBlobParent(aActor);
}
mozilla::jsipc::PJavaScriptParent *
ContentBridgeParent::AllocPJavaScriptParent()
{
return nsIContentParent::AllocPJavaScriptParent();
}
bool
ContentBridgeParent::DeallocPJavaScriptParent(PJavaScriptParent *parent)
{
return nsIContentParent::DeallocPJavaScriptParent(parent);
}
PBrowserParent*
ContentBridgeParent::AllocPBrowserParent(const TabId& aTabId,
const IPCTabContext &aContext,
const uint32_t& aChromeFlags,
const ContentParentId& aCpID,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
return nsIContentParent::AllocPBrowserParent(aTabId,
aContext,
aChromeFlags,
aCpID,
aIsForApp,
aIsForBrowser);
}
bool
ContentBridgeParent::DeallocPBrowserParent(PBrowserParent* aParent)
{
return nsIContentParent::DeallocPBrowserParent(aParent);
}
void
ContentBridgeParent::NotifyTabDestroyed()
{
int32_t numLiveTabs = ManagedPBrowserParent().Count();
if (numLiveTabs == 1) {
MessageLoop::current()->PostTask(NewRunnableMethod(this, &ContentBridgeParent::Close));
}
}
// This implementation is identical to ContentParent::GetCPOWManager but we can't
// move it to nsIContentParent because it calls ManagedPJavaScriptParent() which
// only exists in PContentParent and PContentBridgeParent.
jsipc::CPOWManager*
ContentBridgeParent::GetCPOWManager()
{
if (PJavaScriptParent* p = LoneManagedOrNullAsserts(ManagedPJavaScriptParent())) {
return CPOWManagerFor(p);
}
return nullptr;
}
NS_IMETHODIMP
ContentBridgeParent::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData)
{
if (!strcmp(aTopic, "content-child-shutdown")) {
Close();
}
return NS_OK;
}
PFileDescriptorSetParent*
ContentBridgeParent::AllocPFileDescriptorSetParent(const FileDescriptor& aFD)
{
return nsIContentParent::AllocPFileDescriptorSetParent(aFD);
}
bool
ContentBridgeParent::DeallocPFileDescriptorSetParent(PFileDescriptorSetParent* aActor)
{
return nsIContentParent::DeallocPFileDescriptorSetParent(aActor);
}
PSendStreamParent*
ContentBridgeParent::AllocPSendStreamParent()
{
return nsIContentParent::AllocPSendStreamParent();
}
bool
ContentBridgeParent::DeallocPSendStreamParent(PSendStreamParent* aActor)
{
return nsIContentParent::DeallocPSendStreamParent(aActor);
}
} // namespace dom
} // namespace mozilla

View file

@ -0,0 +1,154 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_ContentBridgeParent_h
#define mozilla_dom_ContentBridgeParent_h
#include "mozilla/dom/PContentBridgeParent.h"
#include "mozilla/dom/nsIContentParent.h"
#include "mozilla/dom/ipc/IdType.h"
#include "nsIObserver.h"
namespace mozilla {
namespace dom {
class ContentBridgeParent : public PContentBridgeParent
, public nsIContentParent
, public nsIObserver
{
public:
explicit ContentBridgeParent(Transport* aTransport);
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
void DeferredDestroy();
virtual bool IsContentBridgeParent() const override { return true; }
void NotifyTabDestroyed();
static ContentBridgeParent*
Create(Transport* aTransport, ProcessId aOtherProcess);
virtual PBlobParent*
SendPBlobConstructor(PBlobParent* actor,
const BlobConstructorParams& params) override;
virtual PBrowserParent*
SendPBrowserConstructor(PBrowserParent* aActor,
const TabId& aTabId,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const ContentParentId& aCpID,
const bool& aIsForApp,
const bool& aIsForBrowser) override;
FORWARD_SHMEM_ALLOCATOR_TO(PContentBridgeParent)
jsipc::CPOWManager* GetCPOWManager() override;
virtual ContentParentId ChildID() const override
{
return mChildID;
}
virtual bool IsForApp() const override
{
return mIsForApp;
}
virtual bool IsForBrowser() const override
{
return mIsForBrowser;
}
virtual int32_t Pid() const override
{
// XXX: do we need this for ContentBridgeParent?
return -1;
}
protected:
virtual ~ContentBridgeParent();
void SetChildID(ContentParentId aId)
{
mChildID = aId;
}
void SetIsForApp(bool aIsForApp)
{
mIsForApp = aIsForApp;
}
void SetIsForBrowser(bool aIsForBrowser)
{
mIsForBrowser = aIsForBrowser;
}
void Close()
{
// Trick NewRunnableMethod
PContentBridgeParent::Close();
}
protected:
virtual bool
RecvSyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
nsTArray<StructuredCloneData>* aRetvals) override;
virtual bool RecvAsyncMessage(const nsString& aMsg,
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
const ClonedMessageData& aData) override;
virtual jsipc::PJavaScriptParent* AllocPJavaScriptParent() override;
virtual bool
DeallocPJavaScriptParent(jsipc::PJavaScriptParent*) override;
virtual PBrowserParent*
AllocPBrowserParent(const TabId& aTabId,
const IPCTabContext &aContext,
const uint32_t& aChromeFlags,
const ContentParentId& aCpID,
const bool& aIsForApp,
const bool& aIsForBrowser) override;
virtual bool DeallocPBrowserParent(PBrowserParent*) override;
virtual PBlobParent*
AllocPBlobParent(const BlobConstructorParams& aParams) override;
virtual bool DeallocPBlobParent(PBlobParent*) override;
virtual PSendStreamParent* AllocPSendStreamParent() override;
virtual bool DeallocPSendStreamParent(PSendStreamParent* aActor) override;
virtual PFileDescriptorSetParent*
AllocPFileDescriptorSetParent(const mozilla::ipc::FileDescriptor&) override;
virtual bool
DeallocPFileDescriptorSetParent(PFileDescriptorSetParent*) override;
DISALLOW_EVIL_CONSTRUCTORS(ContentBridgeParent);
protected: // members
RefPtr<ContentBridgeParent> mSelfRef;
Transport* mTransport; // owned
ContentParentId mChildID;
bool mIsForApp;
bool mIsForBrowser;
private:
friend class ContentParent;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ContentBridgeParent_h

3310
dom/ipc/ContentChild.cpp Normal file

File diff suppressed because it is too large Load diff

702
dom/ipc/ContentChild.h Normal file
View file

@ -0,0 +1,702 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_ContentChild_h
#define mozilla_dom_ContentChild_h
#include "mozilla/Attributes.h"
#include "mozilla/dom/ContentBridgeParent.h"
#include "mozilla/dom/nsIContentChild.h"
#include "mozilla/dom/PBrowserOrId.h"
#include "mozilla/dom/PContentChild.h"
#include "nsAutoPtr.h"
#include "nsHashKeys.h"
#include "nsIObserver.h"
#include "nsTHashtable.h"
#include "nsRefPtrHashtable.h"
#include "nsWeakPtr.h"
#include "nsIWindowProvider.h"
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
#include "nsIFile.h"
#endif
struct ChromePackage;
class nsIObserver;
struct SubstitutionMapping;
struct OverrideMapping;
class nsIDomainPolicy;
namespace mozilla {
class RemoteSpellcheckEngineChild;
namespace ipc {
class OptionalURIParams;
class URIParams;
}// namespace ipc
namespace dom {
class AlertObserver;
class ConsoleListener;
class PStorageChild;
class ClonedMessageData;
class TabChild;
class GetFilesHelperChild;
class ContentChild final : public PContentChild
, public nsIWindowProvider
, public nsIContentChild
{
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
typedef mozilla::ipc::FileDescriptor FileDescriptor;
typedef mozilla::ipc::OptionalURIParams OptionalURIParams;
typedef mozilla::ipc::PFileDescriptorSetChild PFileDescriptorSetChild;
typedef mozilla::ipc::URIParams URIParams;
public:
NS_DECL_NSIWINDOWPROVIDER
ContentChild();
virtual ~ContentChild();
NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) override;
NS_IMETHOD_(MozExternalRefCountType) AddRef(void) override { return 1; }
NS_IMETHOD_(MozExternalRefCountType) Release(void) override { return 1; }
struct AppInfo
{
nsCString version;
nsCString buildID;
nsCString name;
nsCString UAName;
nsCString ID;
nsCString vendor;
};
nsresult
ProvideWindowCommon(TabChild* aTabOpener,
mozIDOMWindowProxy* aOpener,
bool aIframeMoz,
uint32_t aChromeFlags,
bool aCalledFromJS,
bool aPositionSpecified,
bool aSizeSpecified,
nsIURI* aURI,
const nsAString& aName,
const nsACString& aFeatures,
bool aForceNoOpener,
bool* aWindowIsNew,
mozIDOMWindowProxy** aReturn);
bool Init(MessageLoop* aIOLoop,
base::ProcessId aParentPid,
IPC::Channel* aChannel);
void InitProcessAttributes();
void InitXPCOM();
void InitGraphicsDeviceData();
static ContentChild* GetSingleton()
{
return sSingleton;
}
const AppInfo& GetAppInfo()
{
return mAppInfo;
}
void SetProcessName(const nsAString& aName, bool aDontOverride = false);
void GetProcessName(nsAString& aName) const;
void GetProcessName(nsACString& aName) const;
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
void GetProfileDir(nsIFile** aProfileDir) const
{
*aProfileDir = mProfileDir;
NS_IF_ADDREF(*aProfileDir);
}
void SetProfileDir(nsIFile* aProfileDir)
{
mProfileDir = aProfileDir;
}
#endif
bool IsAlive() const;
bool IsShuttingDown() const;
static void AppendProcessId(nsACString& aName);
ContentBridgeParent* GetLastBridge()
{
MOZ_ASSERT(mLastBridge);
ContentBridgeParent* parent = mLastBridge;
mLastBridge = nullptr;
return parent;
}
RefPtr<ContentBridgeParent> mLastBridge;
PPluginModuleParent *
AllocPPluginModuleParent(mozilla::ipc::Transport* transport,
base::ProcessId otherProcess) override;
PContentBridgeParent*
AllocPContentBridgeParent(mozilla::ipc::Transport* transport,
base::ProcessId otherProcess) override;
PContentBridgeChild*
AllocPContentBridgeChild(mozilla::ipc::Transport* transport,
base::ProcessId otherProcess) override;
PGMPServiceChild*
AllocPGMPServiceChild(mozilla::ipc::Transport* transport,
base::ProcessId otherProcess) override;
bool
RecvGMPsChanged(nsTArray<GMPCapabilityData>&& capabilities) override;
bool
RecvInitRendering(
Endpoint<PCompositorBridgeChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,
Endpoint<PVRManagerChild>&& aVRBridge,
Endpoint<PVideoDecoderManagerChild>&& aVideoManager) override;
bool
RecvReinitRendering(
Endpoint<PCompositorBridgeChild>&& aCompositor,
Endpoint<PImageBridgeChild>&& aImageBridge,
Endpoint<PVRManagerChild>&& aVRBridge,
Endpoint<PVideoDecoderManagerChild>&& aVideoManager) override;
PProcessHangMonitorChild*
AllocPProcessHangMonitorChild(Transport* aTransport,
ProcessId aOtherProcess) override;
virtual bool RecvSetProcessSandbox(const MaybeFileDesc& aBroker) override;
PBackgroundChild*
AllocPBackgroundChild(Transport* aTransport, ProcessId aOtherProcess)
override;
virtual PBrowserChild* AllocPBrowserChild(const TabId& aTabId,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const ContentParentId& aCpID,
const bool& aIsForApp,
const bool& aIsForBrowser) override;
virtual bool DeallocPBrowserChild(PBrowserChild*) override;
virtual PBlobChild*
AllocPBlobChild(const BlobConstructorParams& aParams) override;
virtual bool DeallocPBlobChild(PBlobChild* aActor) override;
virtual PCrashReporterChild*
AllocPCrashReporterChild(const mozilla::dom::NativeThreadId& id,
const uint32_t& processType) override;
virtual bool
DeallocPCrashReporterChild(PCrashReporterChild*) override;
virtual PHalChild* AllocPHalChild() override;
virtual bool DeallocPHalChild(PHalChild*) override;
virtual PHeapSnapshotTempFileHelperChild*
AllocPHeapSnapshotTempFileHelperChild() override;
virtual bool
DeallocPHeapSnapshotTempFileHelperChild(PHeapSnapshotTempFileHelperChild*) override;
virtual PMemoryReportRequestChild*
AllocPMemoryReportRequestChild(const uint32_t& aGeneration,
const bool& aAnonymize,
const bool& aMinimizeMemoryUsage,
const MaybeFileDesc& aDMDFile) override;
virtual bool
DeallocPMemoryReportRequestChild(PMemoryReportRequestChild* actor) override;
virtual bool
RecvPMemoryReportRequestConstructor(PMemoryReportRequestChild* aChild,
const uint32_t& aGeneration,
const bool& aAnonymize,
const bool &aMinimizeMemoryUsage,
const MaybeFileDesc &aDMDFile) override;
virtual PCycleCollectWithLogsChild*
AllocPCycleCollectWithLogsChild(const bool& aDumpAllTraces,
const FileDescriptor& aGCLog,
const FileDescriptor& aCCLog) override;
virtual bool
DeallocPCycleCollectWithLogsChild(PCycleCollectWithLogsChild* aActor) override;
virtual bool
RecvPCycleCollectWithLogsConstructor(PCycleCollectWithLogsChild* aChild,
const bool& aDumpAllTraces,
const FileDescriptor& aGCLog,
const FileDescriptor& aCCLog) override;
virtual PWebBrowserPersistDocumentChild*
AllocPWebBrowserPersistDocumentChild(PBrowserChild* aBrowser,
const uint64_t& aOuterWindowID) override;
virtual bool
RecvPWebBrowserPersistDocumentConstructor(PWebBrowserPersistDocumentChild *aActor,
PBrowserChild *aBrowser,
const uint64_t& aOuterWindowID) override;
virtual bool
DeallocPWebBrowserPersistDocumentChild(PWebBrowserPersistDocumentChild* aActor) override;
virtual PTestShellChild* AllocPTestShellChild() override;
virtual bool DeallocPTestShellChild(PTestShellChild*) override;
virtual bool RecvPTestShellConstructor(PTestShellChild*) override;
jsipc::CPOWManager* GetCPOWManager() override;
virtual PNeckoChild* AllocPNeckoChild() override;
virtual bool DeallocPNeckoChild(PNeckoChild*) override;
virtual PPrintingChild* AllocPPrintingChild() override;
virtual bool DeallocPPrintingChild(PPrintingChild*) override;
virtual PSendStreamChild*
SendPSendStreamConstructor(PSendStreamChild*) override;
virtual PSendStreamChild* AllocPSendStreamChild() override;
virtual bool DeallocPSendStreamChild(PSendStreamChild*) override;
virtual PScreenManagerChild*
AllocPScreenManagerChild(uint32_t* aNumberOfScreens,
float* aSystemDefaultScale,
bool* aSuccess) override;
virtual bool DeallocPScreenManagerChild(PScreenManagerChild*) override;
virtual PPSMContentDownloaderChild*
AllocPPSMContentDownloaderChild( const uint32_t& aCertType) override;
virtual bool
DeallocPPSMContentDownloaderChild(PPSMContentDownloaderChild* aDownloader) override;
virtual PExternalHelperAppChild*
AllocPExternalHelperAppChild(const OptionalURIParams& uri,
const nsCString& aMimeContentType,
const nsCString& aContentDisposition,
const uint32_t& aContentDispositionHint,
const nsString& aContentDispositionFilename,
const bool& aForceSave,
const int64_t& aContentLength,
const bool& aWasFileChannel,
const OptionalURIParams& aReferrer,
PBrowserChild* aBrowser) override;
virtual bool
DeallocPExternalHelperAppChild(PExternalHelperAppChild *aService) override;
virtual PHandlerServiceChild* AllocPHandlerServiceChild() override;
virtual bool DeallocPHandlerServiceChild(PHandlerServiceChild*) override;
virtual PMediaChild* AllocPMediaChild() override;
virtual bool DeallocPMediaChild(PMediaChild* aActor) override;
virtual PStorageChild* AllocPStorageChild() override;
virtual bool DeallocPStorageChild(PStorageChild* aActor) override;
virtual PPresentationChild* AllocPPresentationChild() override;
virtual bool DeallocPPresentationChild(PPresentationChild* aActor) override;
virtual PFlyWebPublishedServerChild*
AllocPFlyWebPublishedServerChild(const nsString& name,
const FlyWebPublishOptions& params) override;
virtual bool DeallocPFlyWebPublishedServerChild(PFlyWebPublishedServerChild* aActor) override;
virtual bool
RecvNotifyPresentationReceiverLaunched(PBrowserChild* aIframe,
const nsString& aSessionId) override;
virtual bool
RecvNotifyPresentationReceiverCleanUp(const nsString& aSessionId) override;
virtual bool RecvNotifyEmptyHTTPCache() override;
virtual PSpeechSynthesisChild* AllocPSpeechSynthesisChild() override;
virtual bool DeallocPSpeechSynthesisChild(PSpeechSynthesisChild* aActor) override;
virtual bool RecvRegisterChrome(InfallibleTArray<ChromePackage>&& packages,
InfallibleTArray<SubstitutionMapping>&& resources,
InfallibleTArray<OverrideMapping>&& overrides,
const nsCString& locale,
const bool& reset) override;
virtual bool RecvRegisterChromeItem(const ChromeRegistryItem& item) override;
virtual bool RecvClearImageCache(const bool& privateLoader,
const bool& chrome) override;
virtual mozilla::jsipc::PJavaScriptChild* AllocPJavaScriptChild() override;
virtual bool DeallocPJavaScriptChild(mozilla::jsipc::PJavaScriptChild*) override;
virtual PRemoteSpellcheckEngineChild* AllocPRemoteSpellcheckEngineChild() override;
virtual bool DeallocPRemoteSpellcheckEngineChild(PRemoteSpellcheckEngineChild*) override;
virtual bool RecvSetOffline(const bool& offline) override;
virtual bool RecvSetConnectivity(const bool& connectivity) override;
virtual bool RecvSetCaptivePortalState(const int32_t& state) override;
virtual bool RecvNotifyLayerAllocated(const dom::TabId& aTabId, const uint64_t& aLayersId) override;
virtual bool RecvSpeakerManagerNotify() override;
virtual bool RecvBidiKeyboardNotify(const bool& isLangRTL,
const bool& haveBidiKeyboards) override;
virtual bool RecvNotifyVisited(const URIParams& aURI) override;
// auto remove when alertfinished is received.
nsresult AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver);
virtual bool RecvPreferenceUpdate(const PrefSetting& aPref) override;
virtual bool RecvVarUpdate(const GfxVarUpdate& pref) override;
virtual bool RecvDataStoragePut(const nsString& aFilename,
const DataStorageItem& aItem) override;
virtual bool RecvDataStorageRemove(const nsString& aFilename,
const nsCString& aKey,
const DataStorageType& aType) override;
virtual bool RecvDataStorageClear(const nsString& aFilename) override;
virtual bool RecvNotifyAlertsObserver(const nsCString& aType,
const nsString& aData) override;
virtual bool RecvLoadProcessScript(const nsString& aURL) override;
virtual bool RecvAsyncMessage(const nsString& aMsg,
InfallibleTArray<CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
const ClonedMessageData& aData) override;
virtual bool RecvGeolocationUpdate(const GeoPosition& somewhere) override;
virtual bool RecvGeolocationError(const uint16_t& errorCode) override;
virtual bool RecvUpdateDictionaryList(InfallibleTArray<nsString>&& aDictionaries) override;
virtual bool RecvAddPermission(const IPC::Permission& permission) override;
virtual bool RecvFlushMemory(const nsString& reason) override;
virtual bool RecvActivateA11y(const uint32_t& aMsaaID) override;
virtual bool RecvShutdownA11y() override;
virtual bool RecvGarbageCollect() override;
virtual bool RecvCycleCollect() override;
virtual bool RecvAppInfo(const nsCString& version, const nsCString& buildID,
const nsCString& name, const nsCString& UAName,
const nsCString& ID, const nsCString& vendor) override;
virtual bool RecvAppInit() override;
virtual bool
RecvInitServiceWorkers(const ServiceWorkerConfiguration& aConfig) override;
virtual bool
RecvInitBlobURLs(nsTArray<BlobURLRegistrationData>&& aRegistations) override;
virtual bool RecvLastPrivateDocShellDestroyed() override;
virtual bool RecvVolumes(InfallibleTArray<VolumeInfo>&& aVolumes) override;
virtual bool RecvFileSystemUpdate(const nsString& aFsName,
const nsString& aVolumeName,
const int32_t& aState,
const int32_t& aMountGeneration,
const bool& aIsMediaPresent,
const bool& aIsSharing,
const bool& aIsFormatting,
const bool& aIsFake,
const bool& aIsUnmounting,
const bool& aIsRemovable,
const bool& aIsHotSwappable) override;
virtual bool RecvVolumeRemoved(const nsString& aFsName) override;
virtual bool
RecvNotifyProcessPriorityChanged(const hal::ProcessPriority& aPriority) override;
virtual bool RecvMinimizeMemoryUsage() override;
virtual bool RecvLoadAndRegisterSheet(const URIParams& aURI,
const uint32_t& aType) override;
virtual bool RecvUnregisterSheet(const URIParams& aURI,
const uint32_t& aType) override;
virtual bool RecvNotifyPhoneStateChange(const nsString& aState) override;
void AddIdleObserver(nsIObserver* aObserver, uint32_t aIdleTimeInS);
void RemoveIdleObserver(nsIObserver* aObserver, uint32_t aIdleTimeInS);
virtual bool RecvNotifyIdleObserver(const uint64_t& aObserver,
const nsCString& aTopic,
const nsString& aData) override;
virtual bool RecvAssociatePluginId(const uint32_t& aPluginId,
const base::ProcessId& aProcessId) override;
virtual bool RecvLoadPluginResult(const uint32_t& aPluginId,
const bool& aResult) override;
virtual bool RecvUpdateWindow(const uintptr_t& aChildId) override;
virtual bool RecvStartProfiler(const ProfilerInitParams& params) override;
virtual bool RecvPauseProfiler(const bool& aPause) override;
virtual bool RecvStopProfiler() override;
virtual bool RecvGatherProfile() override;
virtual bool RecvDomainSetChanged(const uint32_t& aSetType,
const uint32_t& aChangeType,
const OptionalURIParams& aDomain) override;
virtual bool RecvShutdown() override;
virtual bool
RecvInvokeDragSession(nsTArray<IPCDataTransfer>&& aTransfers,
const uint32_t& aAction) override;
virtual bool RecvEndDragSession(const bool& aDoneDrag,
const bool& aUserCancelled,
const mozilla::LayoutDeviceIntPoint& aEndDragPoint) override;
virtual bool
RecvPush(const nsCString& aScope,
const IPC::Principal& aPrincipal,
const nsString& aMessageId) override;
virtual bool
RecvPushWithData(const nsCString& aScope,
const IPC::Principal& aPrincipal,
const nsString& aMessageId,
InfallibleTArray<uint8_t>&& aData) override;
virtual bool
RecvPushSubscriptionChange(const nsCString& aScope,
const IPC::Principal& aPrincipal) override;
virtual bool
RecvPushError(const nsCString& aScope, const IPC::Principal& aPrincipal,
const nsString& aMessage, const uint32_t& aFlags) override;
virtual bool
RecvNotifyPushSubscriptionModifiedObservers(const nsCString& aScope,
const IPC::Principal& aPrincipal) override;
// Get the directory for IndexedDB files. We query the parent for this and
// cache the value
nsString &GetIndexedDBPath();
ContentParentId GetID() const { return mID; }
#if defined(XP_WIN) && defined(ACCESSIBILITY)
uint32_t GetMsaaID() const { return mMsaaID; }
#endif
bool IsForApp() const { return mIsForApp; }
bool IsForBrowser() const { return mIsForBrowser; }
virtual PBlobChild*
SendPBlobConstructor(PBlobChild* actor,
const BlobConstructorParams& params) override;
virtual PFileDescriptorSetChild*
SendPFileDescriptorSetConstructor(const FileDescriptor&) override;
virtual PFileDescriptorSetChild*
AllocPFileDescriptorSetChild(const FileDescriptor&) override;
virtual bool
DeallocPFileDescriptorSetChild(PFileDescriptorSetChild*) override;
virtual bool SendPBrowserConstructor(PBrowserChild* actor,
const TabId& aTabId,
const IPCTabContext& context,
const uint32_t& chromeFlags,
const ContentParentId& aCpID,
const bool& aIsForApp,
const bool& aIsForBrowser) override;
virtual bool RecvPBrowserConstructor(PBrowserChild* aCctor,
const TabId& aTabId,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const ContentParentId& aCpID,
const bool& aIsForApp,
const bool& aIsForBrowser) override;
FORWARD_SHMEM_ALLOCATOR_TO(PContentChild)
void GetAvailableDictionaries(InfallibleTArray<nsString>& aDictionaries);
PBrowserOrId
GetBrowserOrId(TabChild* aTabChild);
virtual POfflineCacheUpdateChild*
AllocPOfflineCacheUpdateChild(const URIParams& manifestURI,
const URIParams& documentURI,
const PrincipalInfo& aLoadingPrincipalInfo,
const bool& stickDocument) override;
virtual bool
DeallocPOfflineCacheUpdateChild(POfflineCacheUpdateChild* offlineCacheUpdate) override;
virtual PWebrtcGlobalChild* AllocPWebrtcGlobalChild() override;
virtual bool DeallocPWebrtcGlobalChild(PWebrtcGlobalChild *aActor) override;
virtual PContentPermissionRequestChild*
AllocPContentPermissionRequestChild(const InfallibleTArray<PermissionRequest>& aRequests,
const IPC::Principal& aPrincipal,
const TabId& aTabId) override;
virtual bool
DeallocPContentPermissionRequestChild(PContentPermissionRequestChild* actor) override;
// Windows specific - set up audio session
virtual bool
RecvSetAudioSessionData(const nsID& aId,
const nsString& aDisplayName,
const nsString& aIconPath) override;
// GetFiles for WebKit/Blink FileSystem API and Directory API must run on the
// parent process.
void
CreateGetFilesRequest(const nsAString& aDirectoryPath, bool aRecursiveFlag,
nsID& aUUID, GetFilesHelperChild* aChild);
void
DeleteGetFilesRequest(nsID& aUUID, GetFilesHelperChild* aChild);
virtual bool
RecvGetFilesResponse(const nsID& aUUID,
const GetFilesResponseResult& aResult) override;
virtual bool
RecvBlobURLRegistration(const nsCString& aURI, PBlobChild* aBlobChild,
const IPC::Principal& aPrincipal) override;
virtual bool
RecvBlobURLUnregistration(const nsCString& aURI) override;
#if defined(XP_WIN) && defined(ACCESSIBILITY)
bool
SendGetA11yContentId();
#endif // defined(XP_WIN) && defined(ACCESSIBILITY)
/**
* Helper function for protocols that use the GPU process when available.
* Overrides FatalError to just be a warning when communicating with the
* GPU process since we don't want to crash the content process when the
* GPU process crashes.
*/
static void FatalErrorIfNotUsingGPUProcess(const char* const aProtocolName,
const char* const aErrorMsg,
base::ProcessId aOtherPid);
private:
static void ForceKillTimerCallback(nsITimer* aTimer, void* aClosure);
void StartForceKillTimer();
virtual void ActorDestroy(ActorDestroyReason why) override;
virtual void ProcessingError(Result aCode, const char* aReason) override;
InfallibleTArray<nsAutoPtr<AlertObserver> > mAlertObservers;
RefPtr<ConsoleListener> mConsoleListener;
nsTHashtable<nsPtrHashKey<nsIObserver>> mIdleObservers;
InfallibleTArray<nsString> mAvailableDictionaries;
/**
* An ID unique to the process containing our corresponding
* content parent.
*
* We expect our content parent to set this ID immediately after opening a
* channel to us.
*/
ContentParentId mID;
#if defined(XP_WIN) && defined(ACCESSIBILITY)
/**
* This is an a11y-specific unique id for the content process that is
* generated by the chrome process.
*/
uint32_t mMsaaID;
#endif
AppInfo mAppInfo;
bool mIsForApp;
bool mIsForBrowser;
bool mCanOverrideProcessName;
bool mIsAlive;
nsString mProcessName;
static ContentChild* sSingleton;
nsCOMPtr<nsIDomainPolicy> mPolicy;
nsCOMPtr<nsITimer> mForceKillTimer;
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
nsCOMPtr<nsIFile> mProfileDir;
#endif
// Hashtable to keep track of the pending GetFilesHelper objects.
// This GetFilesHelperChild objects are removed when RecvGetFilesResponse is
// received.
nsRefPtrHashtable<nsIDHashKey, GetFilesHelperChild> mGetFilesPendingRequests;
bool mShuttingDown;
DISALLOW_EVIL_CONSTRUCTORS(ContentChild);
};
uint64_t
NextWindowID();
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ContentChild_h

5185
dom/ipc/ContentParent.cpp Normal file

File diff suppressed because it is too large Load diff

1197
dom/ipc/ContentParent.h Normal file

File diff suppressed because it is too large Load diff

162
dom/ipc/ContentProcess.cpp Normal file
View file

@ -0,0 +1,162 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "mozilla/ipc/IOThreadChild.h"
#include "ContentProcess.h"
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
#include "mozilla/WindowsVersion.h"
#endif
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
#include <stdlib.h>
#endif
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
#include "mozilla/Preferences.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsDirectoryService.h"
#include "nsDirectoryServiceDefs.h"
#endif
using mozilla::ipc::IOThreadChild;
namespace mozilla {
namespace dom {
#if defined(XP_WIN) && defined(MOZ_CONTENT_SANDBOX)
static bool
IsSandboxTempDirRequired()
{
// On Windows, a sandbox-writable temp directory is only used
// for Vista or later with sandbox pref level >= 1.
return (IsVistaOrLater() &&
(Preferences::GetInt("security.sandbox.content.level") >= 1));
}
static void
SetTmpEnvironmentVariable(nsIFile* aValue)
{
// Save the TMP environment variable so that is is picked up by GetTempPath().
// Note that we specifically write to the TMP variable, as that is the first
// variable that is checked by GetTempPath() to determine its output.
nsAutoString fullTmpPath;
nsresult rv = aValue->GetPath(fullTmpPath);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
Unused << NS_WARN_IF(!SetEnvironmentVariableW(L"TMP", fullTmpPath.get()));
// We also set TEMP in case there is naughty third-party code that is
// referencing the environment variable directly.
Unused << NS_WARN_IF(!SetEnvironmentVariableW(L"TEMP", fullTmpPath.get()));
}
#endif
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
static bool
IsSandboxTempDirRequired()
{
// On OSX, use the sandbox-writable temp when the pref level >= 1.
return (Preferences::GetInt("security.sandbox.content.level") >= 1);
}
static void
SetTmpEnvironmentVariable(nsIFile* aValue)
{
nsAutoCString fullTmpPath;
nsresult rv = aValue->GetNativePath(fullTmpPath);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
Unused << NS_WARN_IF(setenv("TMPDIR", fullTmpPath.get(), 1) != 0);
}
#endif
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
static void
SetUpSandboxEnvironment()
{
MOZ_ASSERT(nsDirectoryService::gService,
"SetUpSandboxEnvironment relies on nsDirectoryService being initialized");
if (!IsSandboxTempDirRequired()) {
return;
}
nsCOMPtr<nsIFile> sandboxedContentTemp;
nsresult rv =
nsDirectoryService::gService->Get(NS_APP_CONTENT_PROCESS_TEMP_DIR,
NS_GET_IID(nsIFile),
getter_AddRefs(sandboxedContentTemp));
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
// Change the gecko defined temp directory to our sandbox-writable one.
// Undefine returns a failure if the property is not already set.
Unused << nsDirectoryService::gService->Undefine(NS_OS_TEMP_DIR);
rv = nsDirectoryService::gService->Set(NS_OS_TEMP_DIR, sandboxedContentTemp);
if (NS_WARN_IF(NS_FAILED(rv))) {
return;
}
SetTmpEnvironmentVariable(sandboxedContentTemp);
}
#endif
void
ContentProcess::SetAppDir(const nsACString& aPath)
{
mXREEmbed.SetAppDir(aPath);
}
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
void
ContentProcess::SetProfile(const nsACString& aProfile)
{
bool flag;
nsresult rv =
XRE_GetFileFromPath(aProfile.BeginReading(), getter_AddRefs(mProfileDir));
if (NS_FAILED(rv) ||
NS_FAILED(mProfileDir->Exists(&flag)) || !flag) {
NS_WARNING("Invalid profile directory passed to content process.");
mProfileDir = nullptr;
}
}
#endif
bool
ContentProcess::Init()
{
mContent.Init(IOThreadChild::message_loop(),
ParentPid(),
IOThreadChild::channel());
mXREEmbed.Start();
mContent.InitXPCOM();
mContent.InitGraphicsDeviceData();
#if (defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
mContent.SetProfileDir(mProfileDir);
#endif
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
SetUpSandboxEnvironment();
#endif
return true;
}
// Note: CleanUp() never gets called in non-debug builds because we exit early
// in ContentChild::ActorDestroy().
void
ContentProcess::CleanUp()
{
mXREEmbed.Stop();
}
} // namespace dom
} // namespace mozilla

65
dom/ipc/ContentProcess.h Normal file
View file

@ -0,0 +1,65 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 dom_tabs_ContentThread_h
#define dom_tabs_ContentThread_h 1
#include "mozilla/ipc/ProcessChild.h"
#include "mozilla/ipc/ScopedXREEmbed.h"
#include "ContentChild.h"
#if defined(XP_WIN)
#include "mozilla/mscom/MainThreadRuntime.h"
#endif
namespace mozilla {
namespace dom {
/**
* ContentProcess is a singleton on the content process which represents
* the main thread where tab instances live.
*/
class ContentProcess : public mozilla::ipc::ProcessChild
{
typedef mozilla::ipc::ProcessChild ProcessChild;
public:
explicit ContentProcess(ProcessId aParentPid)
: ProcessChild(aParentPid)
{ }
~ContentProcess()
{ }
virtual bool Init() override;
virtual void CleanUp() override;
void SetAppDir(const nsACString& aPath);
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
void SetProfile(const nsACString& aProfile);
#endif
private:
ContentChild mContent;
mozilla::ipc::ScopedXREEmbed mXREEmbed;
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
nsCOMPtr<nsIFile> mProfileDir;
#endif
#if defined(XP_WIN)
// This object initializes and configures COM.
mozilla::mscom::MainThreadRuntime mCOMRuntime;
#endif
DISALLOW_EVIL_CONSTRUCTORS(ContentProcess);
};
} // namespace dom
} // namespace mozilla
#endif // ifndef dom_tabs_ContentThread_h

View file

@ -0,0 +1,372 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "ContentProcessManager.h"
#include "ContentParent.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/ClearOnShutdown.h"
#include "nsPrintfCString.h"
#include "nsIScriptSecurityManager.h"
// XXX need another bug to move this to a common header.
#ifdef DISABLE_ASSERTS_FOR_FUZZING
#define ASSERT_UNLESS_FUZZING(...) do { } while (0)
#else
#define ASSERT_UNLESS_FUZZING(...) MOZ_ASSERT(false, __VA_ARGS__)
#endif
namespace mozilla {
namespace dom {
static uint64_t gTabId = 0;
/* static */
StaticAutoPtr<ContentProcessManager>
ContentProcessManager::sSingleton;
/* static */ ContentProcessManager*
ContentProcessManager::GetSingleton()
{
MOZ_ASSERT(XRE_IsParentProcess());
if (!sSingleton) {
sSingleton = new ContentProcessManager();
ClearOnShutdown(&sSingleton);
}
return sSingleton;
}
void
ContentProcessManager::AddContentProcess(ContentParent* aChildCp,
const ContentParentId& aParentCpId)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aChildCp);
ContentProcessInfo info;
info.mCp = aChildCp;
info.mParentCpId = aParentCpId;
mContentParentMap[aChildCp->ChildID()] = info;
}
void
ContentProcessManager::RemoveContentProcess(const ContentParentId& aChildCpId)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(mContentParentMap.find(aChildCpId) != mContentParentMap.end());
mContentParentMap.erase(aChildCpId);
for (auto iter = mContentParentMap.begin();
iter != mContentParentMap.end();
++iter) {
if (!iter->second.mChildrenCpId.empty()) {
iter->second.mChildrenCpId.erase(aChildCpId);
}
}
}
bool
ContentProcessManager::AddGrandchildProcess(const ContentParentId& aParentCpId,
const ContentParentId& aChildCpId)
{
MOZ_ASSERT(NS_IsMainThread());
auto iter = mContentParentMap.find(aParentCpId);
if (NS_WARN_IF(iter == mContentParentMap.end())) {
ASSERT_UNLESS_FUZZING("Parent process should be already in map!");
return false;
}
iter->second.mChildrenCpId.insert(aChildCpId);
return true;
}
bool
ContentProcessManager::GetParentProcessId(const ContentParentId& aChildCpId,
/*out*/ ContentParentId* aParentCpId)
{
MOZ_ASSERT(NS_IsMainThread());
auto iter = mContentParentMap.find(aChildCpId);
if (NS_WARN_IF(iter == mContentParentMap.end())) {
ASSERT_UNLESS_FUZZING();
return false;
}
*aParentCpId = iter->second.mParentCpId;
return true;
}
ContentParent*
ContentProcessManager::GetContentProcessById(const ContentParentId& aChildCpId)
{
MOZ_ASSERT(NS_IsMainThread());
auto iter = mContentParentMap.find(aChildCpId);
if (NS_WARN_IF(iter == mContentParentMap.end())) {
ASSERT_UNLESS_FUZZING();
return nullptr;
}
return iter->second.mCp;
}
nsTArray<ContentParentId>
ContentProcessManager::GetAllChildProcessById(const ContentParentId& aParentCpId)
{
MOZ_ASSERT(NS_IsMainThread());
nsTArray<ContentParentId> cpIdArray;
auto iter = mContentParentMap.find(aParentCpId);
if (NS_WARN_IF(iter == mContentParentMap.end())) {
ASSERT_UNLESS_FUZZING();
return Move(cpIdArray);
}
for (auto cpIter = iter->second.mChildrenCpId.begin();
cpIter != iter->second.mChildrenCpId.end();
++cpIter) {
cpIdArray.AppendElement(*cpIter);
}
return Move(cpIdArray);
}
TabId
ContentProcessManager::AllocateTabId(const TabId& aOpenerTabId,
const IPCTabContext& aContext,
const ContentParentId& aChildCpId)
{
MOZ_ASSERT(NS_IsMainThread());
auto iter = mContentParentMap.find(aChildCpId);
if (NS_WARN_IF(iter == mContentParentMap.end())) {
ASSERT_UNLESS_FUZZING();
return TabId(0);
}
struct RemoteFrameInfo info;
// If it's a PopupIPCTabContext, it's the case that a TabChild want to
// open a new tab. aOpenerTabId has to be it's parent frame's opener id.
if (aContext.type() == IPCTabContext::TPopupIPCTabContext) {
auto remoteFrameIter = iter->second.mRemoteFrames.find(aOpenerTabId);
if (remoteFrameIter == iter->second.mRemoteFrames.end()) {
ASSERT_UNLESS_FUZZING("Failed to find parent frame's opener id.");
return TabId(0);
}
info.mOpenerTabId = remoteFrameIter->second.mOpenerTabId;
const PopupIPCTabContext &ipcContext = aContext.get_PopupIPCTabContext();
MOZ_ASSERT(ipcContext.opener().type() == PBrowserOrId::TTabId);
remoteFrameIter = iter->second.mRemoteFrames.find(ipcContext.opener().get_TabId());
if (remoteFrameIter == iter->second.mRemoteFrames.end()) {
ASSERT_UNLESS_FUZZING("Failed to find tab id.");
return TabId(0);
}
info.mContext = remoteFrameIter->second.mContext;
}
else {
MaybeInvalidTabContext tc(aContext);
if (!tc.IsValid()) {
NS_ERROR(nsPrintfCString("Received an invalid TabContext from "
"the child process. (%s)",
tc.GetInvalidReason()).get());
return TabId(0);
}
info.mOpenerTabId = aOpenerTabId;
info.mContext = tc.GetTabContext();
}
mUniqueId = ++gTabId;
iter->second.mRemoteFrames[mUniqueId] = info;
return mUniqueId;
}
void
ContentProcessManager::DeallocateTabId(const ContentParentId& aChildCpId,
const TabId& aChildTabId)
{
MOZ_ASSERT(NS_IsMainThread());
auto iter = mContentParentMap.find(aChildCpId);
if (NS_WARN_IF(iter == mContentParentMap.end())) {
ASSERT_UNLESS_FUZZING();
return;
}
auto remoteFrameIter = iter->second.mRemoteFrames.find(aChildTabId);
if (remoteFrameIter != iter->second.mRemoteFrames.end()) {
iter->second.mRemoteFrames.erase(aChildTabId);
}
}
bool
ContentProcessManager::GetTabContextByProcessAndTabId(const ContentParentId& aChildCpId,
const TabId& aChildTabId,
/*out*/ TabContext* aTabContext)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aTabContext);
auto iter = mContentParentMap.find(aChildCpId);
if (NS_WARN_IF(iter == mContentParentMap.end())) {
ASSERT_UNLESS_FUZZING();
return false;
}
auto remoteFrameIter = iter->second.mRemoteFrames.find(aChildTabId);
if (NS_WARN_IF(remoteFrameIter == iter->second.mRemoteFrames.end())) {
ASSERT_UNLESS_FUZZING();
return false;
}
*aTabContext = remoteFrameIter->second.mContext;
return true;
}
nsTArray<TabContext>
ContentProcessManager::GetTabContextByContentProcess(const ContentParentId& aChildCpId)
{
MOZ_ASSERT(NS_IsMainThread());
nsTArray<TabContext> tabContextArray;
auto iter = mContentParentMap.find(aChildCpId);
if (NS_WARN_IF(iter == mContentParentMap.end())) {
ASSERT_UNLESS_FUZZING();
return Move(tabContextArray);
}
for (auto remoteFrameIter = iter->second.mRemoteFrames.begin();
remoteFrameIter != iter->second.mRemoteFrames.end();
++remoteFrameIter) {
tabContextArray.AppendElement(remoteFrameIter->second.mContext);
}
return Move(tabContextArray);
}
bool
ContentProcessManager::GetRemoteFrameOpenerTabId(const ContentParentId& aChildCpId,
const TabId& aChildTabId,
/*out*/TabId* aOpenerTabId)
{
MOZ_ASSERT(NS_IsMainThread());
auto iter = mContentParentMap.find(aChildCpId);
if (NS_WARN_IF(iter == mContentParentMap.end())) {
ASSERT_UNLESS_FUZZING();
return false;
}
auto remoteFrameIter = iter->second.mRemoteFrames.find(aChildTabId);
if (NS_WARN_IF(remoteFrameIter == iter->second.mRemoteFrames.end())) {
ASSERT_UNLESS_FUZZING();
return false;
}
*aOpenerTabId = remoteFrameIter->second.mOpenerTabId;
return true;
}
already_AddRefed<TabParent>
ContentProcessManager::GetTabParentByProcessAndTabId(const ContentParentId& aChildCpId,
const TabId& aChildTabId)
{
MOZ_ASSERT(NS_IsMainThread());
auto iter = mContentParentMap.find(aChildCpId);
if (NS_WARN_IF(iter == mContentParentMap.end())) {
ASSERT_UNLESS_FUZZING();
return nullptr;
}
const ManagedContainer<PBrowserParent>& browsers = iter->second.mCp->ManagedPBrowserParent();
for (auto iter = browsers.ConstIter(); !iter.Done(); iter.Next()) {
RefPtr<TabParent> tab = TabParent::GetFrom(iter.Get()->GetKey());
if (tab->GetTabId() == aChildTabId) {
return tab.forget();
}
}
return nullptr;
}
already_AddRefed<TabParent>
ContentProcessManager::GetTopLevelTabParentByProcessAndTabId(const ContentParentId& aChildCpId,
const TabId& aChildTabId)
{
MOZ_ASSERT(NS_IsMainThread());
// Used to keep the current ContentParentId and the current TabId
// in the iteration(do-while loop below)
ContentParentId currentCpId;
TabId currentTabId;
// To get the ContentParentId and the TabParentId on upper level
ContentParentId parentCpId = aChildCpId;
TabId openerTabId = aChildTabId;
// Stop this loop when the upper ContentParentId of
// the current ContentParentId is chrome(ContentParentId = 0).
do {
// Update the current ContentParentId and TabId in iteration
currentCpId = parentCpId;
currentTabId = openerTabId;
// Get the ContentParentId and TabId on upper level
if (!GetParentProcessId(currentCpId, &parentCpId) ||
!GetRemoteFrameOpenerTabId(currentCpId, currentTabId, &openerTabId)) {
return nullptr;
}
} while (parentCpId);
// Get the top level TabParent by the current ContentParentId and TabId
return GetTabParentByProcessAndTabId(currentCpId, currentTabId);
}
nsTArray<TabId>
ContentProcessManager::GetTabParentsByProcessId(const ContentParentId& aChildCpId)
{
MOZ_ASSERT(NS_IsMainThread());
nsTArray<TabId> tabIdList;
auto iter = mContentParentMap.find(aChildCpId);
if (NS_WARN_IF(iter == mContentParentMap.end())) {
ASSERT_UNLESS_FUZZING();
return Move(tabIdList);
}
for (auto remoteFrameIter = iter->second.mRemoteFrames.begin();
remoteFrameIter != iter->second.mRemoteFrames.end();
++remoteFrameIter) {
tabIdList.AppendElement(remoteFrameIter->first);
}
return Move(tabIdList);
}
uint32_t
ContentProcessManager::GetAppIdByProcessAndTabId(const ContentParentId& aChildCpId,
const TabId& aChildTabId)
{
uint32_t appId = nsIScriptSecurityManager::NO_APP_ID;
if (aChildCpId && aChildTabId) {
TabContext tabContext;
if (GetTabContextByProcessAndTabId(aChildCpId, aChildTabId, &tabContext)) {
appId = tabContext.OwnOrContainingAppId();
}
}
return appId;
}
} // namespace dom
} // namespace mozilla

View file

@ -0,0 +1,166 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_ContentProcessManager_h
#define mozilla_dom_ContentProcessManager_h
#include <map>
#include <set>
#include "mozilla/StaticPtr.h"
#include "mozilla/dom/TabContext.h"
#include "mozilla/dom/ipc/IdType.h"
#include "nsTArray.h"
namespace mozilla {
namespace dom {
class ContentParent;
struct RemoteFrameInfo
{
TabId mOpenerTabId;
TabContext mContext;
};
struct ContentProcessInfo
{
ContentParent* mCp;
ContentParentId mParentCpId;
std::set<ContentParentId> mChildrenCpId;
std::map<TabId, RemoteFrameInfo> mRemoteFrames;
};
class ContentProcessManager final
{
public:
static ContentProcessManager* GetSingleton();
~ContentProcessManager() {MOZ_COUNT_DTOR(ContentProcessManager);};
/**
* Add a new content process into the map.
* If aParentCpId is not 0, it's a nested content process.
*/
void AddContentProcess(ContentParent* aChildCp,
const ContentParentId& aParentCpId = ContentParentId(0));
/**
* Remove the content process by id.
*/
void RemoveContentProcess(const ContentParentId& aChildCpId);
/**
* Add a grandchild content process into the map.
* aParentCpId must be already added in the map by AddContentProcess().
*/
bool AddGrandchildProcess(const ContentParentId& aParentCpId,
const ContentParentId& aChildCpId);
/**
* Get the parent process's id by child process's id.
* Used to check if a child really belongs to the parent.
*/
bool GetParentProcessId(const ContentParentId& aChildCpId,
/*out*/ ContentParentId* aParentCpId);
/**
* Return the ContentParent pointer by id.
*/
ContentParent* GetContentProcessById(const ContentParentId& aChildCpId);
/**
* Return a list of all child process's id.
*/
nsTArray<ContentParentId>
GetAllChildProcessById(const ContentParentId& aParentCpId);
/**
* Allocate a tab id for the given content process's id.
* Used when a content process wants to create a new tab. aOpenerTabId and
* aContext are saved in RemoteFrameInfo, which is a part of
* ContentProcessInfo. We can use the tab id and process id to locate the
* TabContext for future use.
*/
TabId AllocateTabId(const TabId& aOpenerTabId,
const IPCTabContext& aContext,
const ContentParentId& aChildCpId);
/**
* Remove the RemoteFrameInfo by the given process and tab id.
*/
void DeallocateTabId(const ContentParentId& aChildCpId,
const TabId& aChildTabId);
/**
* Get the TabContext by the given content process and tab id.
*/
bool
GetTabContextByProcessAndTabId(const ContentParentId& aChildCpId,
const TabId& aChildTabId,
/*out*/ TabContext* aTabContext);
/**
* Get all TabContext which are inside the given content process.
* Used for AppProcessChecker to cehck app status.
*/
nsTArray<TabContext>
GetTabContextByContentProcess(const ContentParentId& aChildCpId);
/**
* Query a tab's opener id by the given process and tab id.
* XXX Currently not used. Plan to be used for bug 1020179.
*/
bool GetRemoteFrameOpenerTabId(const ContentParentId& aChildCpId,
const TabId& aChildTabId,
/*out*/ TabId* aOpenerTabId);
/**
* Get all TabParents' Ids managed by the givent content process.
* Return empty array when TabParent couldn't be found via aChildCpId
*/
nsTArray<TabId>
GetTabParentsByProcessId(const ContentParentId& aChildCpId);
/**
* Get the TabParent by the given content process and tab id.
* Return nullptr when TabParent couldn't be found via aChildCpId
* and aChildTabId.
* (or probably because the TabParent is not in the chrome process)
*/
already_AddRefed<TabParent>
GetTabParentByProcessAndTabId(const ContentParentId& aChildCpId,
const TabId& aChildTabId);
/**
* Get the TabParent on top level by the given content process and tab id.
*
* This function return the TabParent belong to the chrome process,
* called top-level TabParent here, by given aChildCpId and aChildTabId.
* The given aChildCpId and aChildTabId are related to a content process
* and a tab respectively. In nested-oop, the top-level TabParent isn't
* always the opener tab of the given tab in content process. This function
* will call GetTabParentByProcessAndTabId iteratively until the Tab returned
* is belong to the chrome process.
*/
already_AddRefed<TabParent>
GetTopLevelTabParentByProcessAndTabId(const ContentParentId& aChildCpId,
const TabId& aChildTabId);
/**
* Return appId by given TabId and ContentParentId.
* It will return nsIScriptSecurityManager::NO_APP_ID
* if the given tab is not an app.
*/
uint32_t
GetAppIdByProcessAndTabId(const ContentParentId& aChildCpId,
const TabId& aChildTabId);
private:
static StaticAutoPtr<ContentProcessManager> sSingleton;
TabId mUniqueId;
std::map<ContentParentId, ContentProcessInfo> mContentParentMap;
ContentProcessManager() {MOZ_COUNT_CTOR(ContentProcessManager);};
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ContentProcessManager_h

View file

@ -0,0 +1,42 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "mozilla/plugins/PluginModuleChild.h"
#include "ContentChild.h"
#include "CrashReporterChild.h"
#include "nsXULAppAPI.h"
using mozilla::plugins::PluginModuleChild;
namespace mozilla {
namespace dom {
/*static*/
PCrashReporterChild*
CrashReporterChild::GetCrashReporter()
{
const ManagedContainer<PCrashReporterChild>* reporters = nullptr;
switch (XRE_GetProcessType()) {
case GeckoProcessType_Content: {
ContentChild* child = ContentChild::GetSingleton();
reporters = &child->ManagedPCrashReporterChild();
break;
}
case GeckoProcessType_Plugin: {
PluginModuleChild* child = PluginModuleChild::GetChrome();
reporters = &child->ManagedPCrashReporterChild();
break;
}
default:
break;
}
if (!reporters) {
return nullptr;
}
return LoneManagedOrNullAsserts(*reporters);
}
} // namespace dom
} // namespace mozilla

View file

@ -0,0 +1,32 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_CrashReporterChild_h
#define mozilla_dom_CrashReporterChild_h
#include "mozilla/dom/PCrashReporterChild.h"
namespace mozilla {
namespace dom {
class CrashReporterChild :
public PCrashReporterChild
{
public:
CrashReporterChild() {
MOZ_COUNT_CTOR(CrashReporterChild);
}
~CrashReporterChild() {
MOZ_COUNT_DTOR(CrashReporterChild);
}
static PCrashReporterChild* GetCrashReporter();
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_CrashReporterChild_h

View file

@ -0,0 +1,146 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "CrashReporterParent.h"
#include "mozilla/Sprintf.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/ipc/CrashReporterHost.h"
#include "nsAutoPtr.h"
#include "nsXULAppAPI.h"
#include <time.h>
#include "mozilla/Telemetry.h"
#ifdef MOZ_CRASHREPORTER
#include "nsExceptionHandler.h"
#include "nsICrashService.h"
#include "mozilla/SyncRunnable.h"
#include "nsThreadUtils.h"
#endif
namespace mozilla {
namespace dom {
using namespace mozilla::ipc;
void
CrashReporterParent::AnnotateCrashReport(const nsCString& key,
const nsCString& data)
{
#ifdef MOZ_CRASHREPORTER
mNotes.Put(key, data);
#endif
}
void
CrashReporterParent::ActorDestroy(ActorDestroyReason aWhy)
{
// Implement me! Bug 1005155
}
bool
CrashReporterParent::RecvAppendAppNotes(const nsCString& data)
{
mAppNotes.Append(data);
return true;
}
CrashReporterParent::CrashReporterParent()
:
#ifdef MOZ_CRASHREPORTER
mNotes(4),
#endif
mStartTime(::time(nullptr))
, mInitialized(false)
{
MOZ_COUNT_CTOR(CrashReporterParent);
}
CrashReporterParent::~CrashReporterParent()
{
MOZ_COUNT_DTOR(CrashReporterParent);
}
void
CrashReporterParent::SetChildData(const NativeThreadId& tid,
const uint32_t& processType)
{
mInitialized = true;
mMainThread = tid;
mProcessType = GeckoProcessType(processType);
}
#ifdef MOZ_CRASHREPORTER
bool
CrashReporterParent::GenerateCrashReportForMinidump(nsIFile* minidump,
const AnnotationTable* processNotes)
{
if (!CrashReporter::GetIDFromMinidump(minidump, mChildDumpID)) {
return false;
}
bool result = GenerateChildData(processNotes);
FinalizeChildData();
return result;
}
bool
CrashReporterParent::GenerateChildData(const AnnotationTable* processNotes)
{
MOZ_ASSERT(mInitialized);
if (mChildDumpID.IsEmpty()) {
NS_WARNING("problem with GenerateChildData: no child dump id yet!");
return false;
}
nsAutoCString type;
switch (mProcessType) {
case GeckoProcessType_Content:
type = NS_LITERAL_CSTRING("content");
break;
case GeckoProcessType_Plugin:
case GeckoProcessType_GMPlugin:
type = NS_LITERAL_CSTRING("plugin");
break;
default:
NS_ERROR("unknown process type");
break;
}
mNotes.Put(NS_LITERAL_CSTRING("ProcessType"), type);
char startTime[32];
SprintfLiteral(startTime, "%lld", static_cast<long long>(mStartTime));
mNotes.Put(NS_LITERAL_CSTRING("StartupTime"), nsDependentCString(startTime));
if (!mAppNotes.IsEmpty()) {
mNotes.Put(NS_LITERAL_CSTRING("Notes"), mAppNotes);
}
// Append these notes to the end of the extra file based on the current
// dump id we obtained from CreatePairedMinidumps.
bool ret = CrashReporter::AppendExtraData(mChildDumpID, mNotes);
if (ret && processNotes) {
ret = CrashReporter::AppendExtraData(mChildDumpID, *processNotes);
}
if (!ret) {
NS_WARNING("problem appending child data to .extra");
}
return ret;
}
void
CrashReporterParent::FinalizeChildData()
{
MOZ_ASSERT(mInitialized);
CrashReporterHost::NotifyCrashService(mProcessType, mChildDumpID, &mNotes);
mNotes.Clear();
}
#endif
} // namespace dom
} // namespace mozilla

View file

@ -0,0 +1,306 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_CrashReporterParent_h
#define mozilla_dom_CrashReporterParent_h
#include "mozilla/dom/PCrashReporterParent.h"
#include "mozilla/dom/TabMessageUtils.h"
#include "nsIFile.h"
#ifdef MOZ_CRASHREPORTER
#include "nsExceptionHandler.h"
#include "nsDataHashtable.h"
#endif
namespace mozilla {
namespace dom {
class CrashReporterParent : public PCrashReporterParent
{
#ifdef MOZ_CRASHREPORTER
typedef CrashReporter::AnnotationTable AnnotationTable;
#endif
public:
CrashReporterParent();
virtual ~CrashReporterParent();
#ifdef MOZ_CRASHREPORTER
/*
* Attempt to create a bare-bones crash report, along with extra process-
* specific annotations present in the given AnnotationTable. Calls
* GenerateChildData and FinalizeChildData.
*
* @returns true if successful, false otherwise.
*/
template<class Toplevel>
bool
GenerateCrashReport(Toplevel* t, const AnnotationTable* processNotes);
/*
* Attempt to generate a parent/child pair of minidumps from the given
* toplevel actor. This calls CrashReporter::CreateMinidumpsAndPair to
* generate the minidumps. Crash reporter annotations set prior to this
* call will be saved via PairedDumpCallbackExtra into an .extra file
* under the proper crash id. AnnotateCrashReport annotations are not
* set in this call and the report is not finalized.
*
* @returns true if successful, false otherwise.
*/
template<class Toplevel>
bool
GeneratePairedMinidump(Toplevel* t);
/*
* Attempts to take a minidump of the current process and pair that with
* a named minidump handed in by the caller.
*
* @param aTopLevel - top level actor this reporter is associated with.
* @param aMinidump - the minidump to associate with.
* @param aPairName - the name of the additional minidump.
* @returns true if successful, false otherwise.
*/
template<class Toplevel>
bool
GenerateMinidumpAndPair(Toplevel* aTopLevel, nsIFile* aMinidump,
const nsACString& aPairName);
/**
* Apply child process annotations to an existing paired mindump generated
* with GeneratePairedMinidump.
*
* Be careful about calling generate apis immediately after this call,
* see FinalizeChildData.
*
* @param processNotes (optional) - Additional notes to append. Annotations
* stored in mNotes will also be applied. processNotes can be null.
* @returns true if successful, false otherwise.
*/
bool
GenerateChildData(const AnnotationTable* processNotes);
/**
* Handles main thread finalization tasks after a report has been
* generated. Does the following:
* - register the finished report with the crash service manager
* - records telemetry related data about crashes
*
* Be careful about calling generate apis immediately after this call,
* if this api is called on a non-main thread it will fire off a runnable
* to complete its work async.
*/
void
FinalizeChildData();
/*
* Attempt to generate a full paired dump complete with any child
* annoations, and finalizes the report. Note this call is only valid
* on the main thread. Calling on a background thread will fail.
*
* @returns true if successful, false otherwise.
*/
template<class Toplevel>
bool
GenerateCompleteMinidump(Toplevel* t);
/**
* Submits a raw minidump handed in, calls GenerateChildData and
* FinalizeChildData. Used by content plugins and gmp.
*
* @returns true if successful, false otherwise.
*/
bool
GenerateCrashReportForMinidump(nsIFile* minidump,
const AnnotationTable* processNotes);
/*
* Instantiate a new crash reporter actor from a given parent that manages
* the protocol.
*
* @returns true if successful, false otherwise.
*/
template<class Toplevel>
static bool CreateCrashReporter(Toplevel* actor);
#endif // MOZ_CRASHREPORTER
/*
* Initialize this reporter with data from the child process.
*/
void
SetChildData(const NativeThreadId& id, const uint32_t& processType);
/*
* Returns the ID of the child minidump.
* GeneratePairedMinidump or GenerateCrashReport must be called first.
*/
const nsString& ChildDumpID() const {
return mChildDumpID;
}
/*
* Add an annotation to our internally tracked list of annotations.
* Callers must apply these notes using GenerateChildData otherwise
* the notes will get dropped.
*/
void
AnnotateCrashReport(const nsCString& aKey, const nsCString& aData);
protected:
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
virtual bool RecvAnnotateCrashReport(const nsCString& aKey,
const nsCString& aData) override
{
AnnotateCrashReport(aKey, aData);
return true;
}
virtual bool RecvAppendAppNotes(const nsCString& aData) override;
#ifdef MOZ_CRASHREPORTER
void
NotifyCrashService();
#endif
#ifdef MOZ_CRASHREPORTER
AnnotationTable mNotes;
#endif
nsCString mAppNotes;
nsString mChildDumpID;
// stores the child main thread id
NativeThreadId mMainThread;
time_t mStartTime;
// stores the child process type
GeckoProcessType mProcessType;
bool mInitialized;
};
#ifdef MOZ_CRASHREPORTER
template<class Toplevel>
inline bool
CrashReporterParent::GeneratePairedMinidump(Toplevel* t)
{
mozilla::ipc::ScopedProcessHandle child;
#ifdef XP_MACOSX
child = t->Process()->GetChildTask();
#else
if (!base::OpenPrivilegedProcessHandle(t->OtherPid(), &child.rwget())) {
NS_WARNING("Failed to open child process handle.");
return false;
}
#endif
nsCOMPtr<nsIFile> childDump;
if (CrashReporter::CreateMinidumpsAndPair(child,
mMainThread,
NS_LITERAL_CSTRING("browser"),
nullptr, // pair with a dump of this process and thread
getter_AddRefs(childDump)) &&
CrashReporter::GetIDFromMinidump(childDump, mChildDumpID)) {
return true;
}
return false;
}
template<class Toplevel>
inline bool
CrashReporterParent::GenerateMinidumpAndPair(Toplevel* aTopLevel,
nsIFile* aMinidumpToPair,
const nsACString& aPairName)
{
mozilla::ipc::ScopedProcessHandle childHandle;
#ifdef XP_MACOSX
childHandle = aTopLevel->Process()->GetChildTask();
#else
if (!base::OpenPrivilegedProcessHandle(aTopLevel->OtherPid(),
&childHandle.rwget())) {
NS_WARNING("Failed to open child process handle.");
return false;
}
#endif
nsCOMPtr<nsIFile> targetDump;
if (CrashReporter::CreateMinidumpsAndPair(childHandle,
mMainThread, // child thread id
aPairName,
aMinidumpToPair,
getter_AddRefs(targetDump)) &&
CrashReporter::GetIDFromMinidump(targetDump, mChildDumpID)) {
return true;
}
return false;
}
template<class Toplevel>
inline bool
CrashReporterParent::GenerateCrashReport(Toplevel* t,
const AnnotationTable* processNotes)
{
nsCOMPtr<nsIFile> crashDump;
if (t->TakeMinidump(getter_AddRefs(crashDump), nullptr) &&
CrashReporter::GetIDFromMinidump(crashDump, mChildDumpID)) {
bool result = GenerateChildData(processNotes);
FinalizeChildData();
return result;
}
return false;
}
template<class Toplevel>
inline bool
CrashReporterParent::GenerateCompleteMinidump(Toplevel* t)
{
mozilla::ipc::ScopedProcessHandle child;
if (!NS_IsMainThread()) {
NS_WARNING("GenerateCompleteMinidump can't be called on non-main thread.");
return false;
}
#ifdef XP_MACOSX
child = t->Process()->GetChildTask();
#else
if (!base::OpenPrivilegedProcessHandle(t->OtherPid(), &child.rwget())) {
NS_WARNING("Failed to open child process handle.");
return false;
}
#endif
nsCOMPtr<nsIFile> childDump;
if (CrashReporter::CreateMinidumpsAndPair(child,
mMainThread,
NS_LITERAL_CSTRING("browser"),
nullptr, // pair with a dump of this process and thread
getter_AddRefs(childDump)) &&
CrashReporter::GetIDFromMinidump(childDump, mChildDumpID)) {
bool result = GenerateChildData(nullptr);
FinalizeChildData();
return result;
}
return false;
}
template<class Toplevel>
/* static */ bool
CrashReporterParent::CreateCrashReporter(Toplevel* actor)
{
#ifdef MOZ_CRASHREPORTER
NativeThreadId id;
uint32_t processType;
PCrashReporterParent* p =
actor->CallPCrashReporterConstructor(&id, &processType);
if (p) {
static_cast<CrashReporterParent*>(p)->SetChildData(id, processType);
} else {
NS_ERROR("Error creating crash reporter actor");
}
return !!p;
#endif
return false;
}
#endif
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_CrashReporterParent_h

181
dom/ipc/DOMTypes.ipdlh Normal file
View file

@ -0,0 +1,181 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=4 ts=8 et tw=80 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 protocol PBlob;
include protocol PSendStream;
include IPCStream;
include ProtocolTypes;
using struct mozilla::void_t
from "ipc/IPCMessageUtils.h";
using struct mozilla::SerializedStructuredCloneBuffer
from "ipc/IPCMessageUtils.h";
namespace mozilla {
namespace dom {
union OptionalID
{
nsID;
void_t;
};
struct MessagePortIdentifier
{
nsID uuid;
nsID destinationUuid;
uint32_t sequenceId;
bool neutered;
};
struct ClonedMessageData
{
SerializedStructuredCloneBuffer data;
PBlob[] blobs;
MessagePortIdentifier[] identfiers;
};
struct BlobDataStream
{
IPCStream stream;
uint64_t length;
};
union BlobData
{
// For remote blobs.
nsID;
// For memory-backed blobs.
BlobDataStream;
// For multiplex blobs.
BlobData[];
};
union OptionalBlobData
{
BlobData;
void_t;
};
struct NormalBlobConstructorParams
{
nsString contentType;
uint64_t length;
// This must be of type BlobData in a child->parent message, and will always
// be of type void_t in a parent->child message.
OptionalBlobData optionalBlobData;
};
struct FileBlobConstructorParams
{
nsString name;
nsString contentType;
nsString path;
uint64_t length;
int64_t modDate;
bool isDirectory;
// This must be of type BlobData in a child->parent message, and will always
// be of type void_t in a parent->child message.
OptionalBlobData optionalBlobData;
};
struct SlicedBlobConstructorParams
{
PBlob source;
nsID id;
uint64_t begin;
uint64_t end;
nsString contentType;
};
struct MysteryBlobConstructorParams
{
// Nothing is known about this type of blob.
};
struct KnownBlobConstructorParams
{
nsID id;
};
// This may only be used for same-process inter-thread communication!
struct SameProcessBlobConstructorParams
{
// This member should be reinterpret_cast'd to mozilla::dom::BlobImpl. It
// carries a reference.
intptr_t addRefedBlobImpl;
};
union AnyBlobConstructorParams
{
// These types may be sent to/from parent and child.
NormalBlobConstructorParams;
FileBlobConstructorParams;
SameProcessBlobConstructorParams;
// This type may only be sent from parent to child.
MysteryBlobConstructorParams;
// These types may only be sent from child to parent.
SlicedBlobConstructorParams;
KnownBlobConstructorParams;
};
struct ChildBlobConstructorParams
{
nsID id;
// May not be SlicedBlobConstructorParams or KnownBlobConstructorParams.
AnyBlobConstructorParams blobParams;
};
struct ParentBlobConstructorParams
{
// May not be MysteryBlobConstructorParams.
AnyBlobConstructorParams blobParams;
};
union BlobConstructorParams
{
ChildBlobConstructorParams;
ParentBlobConstructorParams;
};
union IPCDataTransferData
{
nsString; // text
Shmem; // images using Shmem
PBlob; // files
};
struct IPCDataTransferImage
{
uint32_t width;
uint32_t height;
uint32_t stride;
uint8_t format;
};
struct IPCDataTransferItem
{
nsCString flavor;
// The image details are only used when transferring images.
IPCDataTransferImage imageDetails;
IPCDataTransferData data;
};
struct IPCDataTransfer
{
IPCDataTransferItem[] items;
};
} // namespace dom
} // namespace mozilla

View file

@ -0,0 +1,87 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "DatePickerParent.h"
#include "nsComponentManagerUtils.h"
#include "nsIDocument.h"
#include "nsIDOMWindow.h"
#include "mozilla/Unused.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/TabParent.h"
using mozilla::Unused;
using namespace mozilla::dom;
NS_IMPL_ISUPPORTS(DatePickerParent::DatePickerShownCallback,
nsIDatePickerShownCallback);
NS_IMETHODIMP
DatePickerParent::DatePickerShownCallback::Cancel()
{
if (mDatePickerParent) {
Unused << mDatePickerParent->SendCancel();
}
return NS_OK;
}
NS_IMETHODIMP
DatePickerParent::DatePickerShownCallback::Done(const nsAString& aDate)
{
if (mDatePickerParent) {
Unused << mDatePickerParent->Send__delete__(mDatePickerParent,
nsString(aDate));
}
return NS_OK;
}
void
DatePickerParent::DatePickerShownCallback::Destroy()
{
mDatePickerParent = nullptr;
}
bool
DatePickerParent::CreateDatePicker()
{
mPicker = do_CreateInstance("@mozilla.org/datepicker;1");
if (!mPicker) {
return false;
}
Element* ownerElement = TabParent::GetFrom(Manager())->GetOwnerElement();
if (!ownerElement) {
return false;
}
nsCOMPtr<mozIDOMWindowProxy> window = do_QueryInterface(ownerElement->OwnerDoc()->GetWindow());
if (!window) {
return false;
}
return NS_SUCCEEDED(mPicker->Init(window, mTitle, mInitialDate));
}
bool
DatePickerParent::RecvOpen()
{
if (!CreateDatePicker()) {
Unused << Send__delete__(this, mInitialDate);
return true;
}
mCallback = new DatePickerShownCallback(this);
mPicker->Open(mCallback);
return true;
};
void
DatePickerParent::ActorDestroy(ActorDestroyReason aWhy)
{
if (mCallback) {
mCallback->Destroy();
}
}

View file

@ -0,0 +1,61 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_DatePickerParent_h
#define mozilla_dom_DatePickerParent_h
#include "mozilla/dom/PDatePickerParent.h"
#include "nsIDatePicker.h"
namespace mozilla {
namespace dom {
class DatePickerParent : public PDatePickerParent
{
public:
DatePickerParent(const nsString& aTitle,
const nsString& aInitialDate)
: mTitle(aTitle)
, mInitialDate(aInitialDate)
{}
virtual bool RecvOpen() override;
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
class DatePickerShownCallback final
: public nsIDatePickerShownCallback
{
public:
explicit DatePickerShownCallback(DatePickerParent* aDatePickerParnet)
: mDatePickerParent(aDatePickerParnet)
{}
NS_DECL_ISUPPORTS
NS_DECL_NSIDATEPICKERSHOWNCALLBACK
void Destroy();
private:
~DatePickerShownCallback() {}
DatePickerParent* mDatePickerParent;
};
private:
virtual ~DatePickerParent() {}
bool CreateDatePicker();
RefPtr<DatePickerShownCallback> mCallback;
nsCOMPtr<nsIDatePicker> mPicker;
nsString mTitle;
nsString mInitialDate;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_DatePickerParent_h

View file

@ -0,0 +1,306 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "FilePickerParent.h"
#include "nsComponentManagerUtils.h"
#include "nsNetCID.h"
#include "nsIDocument.h"
#include "nsIDOMWindow.h"
#include "nsIFile.h"
#include "nsISimpleEnumerator.h"
#include "mozilla/Unused.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/FileSystemSecurity.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/dom/ipc/BlobParent.h"
using mozilla::Unused;
using namespace mozilla::dom;
NS_IMPL_ISUPPORTS(FilePickerParent::FilePickerShownCallback,
nsIFilePickerShownCallback);
NS_IMETHODIMP
FilePickerParent::FilePickerShownCallback::Done(int16_t aResult)
{
if (mFilePickerParent) {
mFilePickerParent->Done(aResult);
}
return NS_OK;
}
void
FilePickerParent::FilePickerShownCallback::Destroy()
{
mFilePickerParent = nullptr;
}
FilePickerParent::~FilePickerParent()
{
}
// Before sending a blob to the child, we need to get its size and modification
// date. Otherwise it will be sent as a "mystery blob" by
// GetOrCreateActorForBlob, which will cause problems for the child
// process. This runnable stat()s the file off the main thread.
//
// We run code in three places:
// 1. The main thread calls Dispatch() to start the runnable.
// 2. The stream transport thread stat()s the file in Run() and then dispatches
// the same runnable on the main thread.
// 3. The main thread sends the results over IPC.
FilePickerParent::IORunnable::IORunnable(FilePickerParent *aFPParent,
nsTArray<nsCOMPtr<nsIFile>>& aFiles,
bool aIsDirectory)
: mFilePickerParent(aFPParent)
, mIsDirectory(aIsDirectory)
{
mFiles.SwapElements(aFiles);
MOZ_ASSERT_IF(aIsDirectory, mFiles.Length() == 1);
}
bool
FilePickerParent::IORunnable::Dispatch()
{
MOZ_ASSERT(NS_IsMainThread());
mEventTarget = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
if (!mEventTarget) {
return false;
}
nsresult rv = mEventTarget->Dispatch(this, NS_DISPATCH_NORMAL);
return NS_SUCCEEDED(rv);
}
NS_IMETHODIMP
FilePickerParent::IORunnable::Run()
{
// If we're on the main thread, then that means we're done. Just send the
// results.
if (NS_IsMainThread()) {
if (mFilePickerParent) {
mFilePickerParent->SendFilesOrDirectories(mResults);
}
return NS_OK;
}
// We're not on the main thread, so do the IO.
for (uint32_t i = 0; i < mFiles.Length(); ++i) {
if (mIsDirectory) {
nsAutoString path;
nsresult rv = mFiles[i]->GetPath(path);
if (NS_WARN_IF(NS_FAILED(rv))) {
continue;
}
BlobImplOrString* data = mResults.AppendElement();
data->mType = BlobImplOrString::eDirectoryPath;
data->mDirectoryPath = path;
continue;
}
RefPtr<BlobImpl> blobImpl = new BlobImplFile(mFiles[i]);
ErrorResult error;
blobImpl->GetSize(error);
if (NS_WARN_IF(error.Failed())) {
error.SuppressException();
continue;
}
blobImpl->GetLastModified(error);
if (NS_WARN_IF(error.Failed())) {
error.SuppressException();
continue;
}
BlobImplOrString* data = mResults.AppendElement();
data->mType = BlobImplOrString::eBlobImpl;
data->mBlobImpl = blobImpl;
}
// Dispatch ourselves back on the main thread.
if (NS_FAILED(NS_DispatchToMainThread(this))) {
// It's hard to see how we can recover gracefully in this case. The child
// process is waiting for an IPC, but that can only happen on the main
// thread.
MOZ_CRASH();
}
return NS_OK;
}
void
FilePickerParent::IORunnable::Destroy()
{
mFilePickerParent = nullptr;
}
void
FilePickerParent::SendFilesOrDirectories(const nsTArray<BlobImplOrString>& aData)
{
nsIContentParent* parent = TabParent::GetFrom(Manager())->Manager();
if (mMode == nsIFilePicker::modeGetFolder) {
MOZ_ASSERT(aData.Length() <= 1);
if (aData.IsEmpty()) {
Unused << Send__delete__(this, void_t(), mResult);
return;
}
MOZ_ASSERT(aData[0].mType == BlobImplOrString::eDirectoryPath);
// Let's inform the security singleton about the given access of this tab on
// this directory path.
RefPtr<FileSystemSecurity> fss = FileSystemSecurity::GetOrCreate();
fss->GrantAccessToContentProcess(parent->ChildID(),
aData[0].mDirectoryPath);
InputDirectory input;
input.directoryPath() = aData[0].mDirectoryPath;
Unused << Send__delete__(this, input, mResult);
return;
}
InfallibleTArray<PBlobParent*> blobs;
for (unsigned i = 0; i < aData.Length(); i++) {
MOZ_ASSERT(aData[i].mType == BlobImplOrString::eBlobImpl);
BlobParent* blobParent = parent->GetOrCreateActorForBlobImpl(aData[i].mBlobImpl);
if (blobParent) {
blobs.AppendElement(blobParent);
}
}
InputBlobs inblobs;
inblobs.blobsParent().SwapElements(blobs);
Unused << Send__delete__(this, inblobs, mResult);
}
void
FilePickerParent::Done(int16_t aResult)
{
mResult = aResult;
if (mResult != nsIFilePicker::returnOK) {
Unused << Send__delete__(this, void_t(), mResult);
return;
}
nsTArray<nsCOMPtr<nsIFile>> files;
if (mMode == nsIFilePicker::modeOpenMultiple) {
nsCOMPtr<nsISimpleEnumerator> iter;
NS_ENSURE_SUCCESS_VOID(mFilePicker->GetFiles(getter_AddRefs(iter)));
nsCOMPtr<nsISupports> supports;
bool loop = true;
while (NS_SUCCEEDED(iter->HasMoreElements(&loop)) && loop) {
iter->GetNext(getter_AddRefs(supports));
if (supports) {
nsCOMPtr<nsIFile> file = do_QueryInterface(supports);
MOZ_ASSERT(file);
files.AppendElement(file);
}
}
} else {
nsCOMPtr<nsIFile> file;
mFilePicker->GetFile(getter_AddRefs(file));
if (file) {
files.AppendElement(file);
}
}
if (files.IsEmpty()) {
Unused << Send__delete__(this, void_t(), mResult);
return;
}
MOZ_ASSERT(!mRunnable);
mRunnable = new IORunnable(this, files, mMode == nsIFilePicker::modeGetFolder);
// Dispatch to background thread to do I/O:
if (!mRunnable->Dispatch()) {
Unused << Send__delete__(this, void_t(), nsIFilePicker::returnCancel);
}
}
bool
FilePickerParent::CreateFilePicker()
{
mFilePicker = do_CreateInstance("@mozilla.org/filepicker;1");
if (!mFilePicker) {
return false;
}
Element* element = TabParent::GetFrom(Manager())->GetOwnerElement();
if (!element) {
return false;
}
nsCOMPtr<mozIDOMWindowProxy> window = element->OwnerDoc()->GetWindow();
if (!window) {
return false;
}
return NS_SUCCEEDED(mFilePicker->Init(window, mTitle, mMode));
}
bool
FilePickerParent::RecvOpen(const int16_t& aSelectedType,
const bool& aAddToRecentDocs,
const nsString& aDefaultFile,
const nsString& aDefaultExtension,
InfallibleTArray<nsString>&& aFilters,
InfallibleTArray<nsString>&& aFilterNames,
const nsString& aDisplayDirectory,
const nsString& aOkButtonLabel)
{
if (!CreateFilePicker()) {
Unused << Send__delete__(this, void_t(), nsIFilePicker::returnCancel);
return true;
}
mFilePicker->SetAddToRecentDocs(aAddToRecentDocs);
for (uint32_t i = 0; i < aFilters.Length(); ++i) {
mFilePicker->AppendFilter(aFilterNames[i], aFilters[i]);
}
mFilePicker->SetDefaultString(aDefaultFile);
mFilePicker->SetDefaultExtension(aDefaultExtension);
mFilePicker->SetFilterIndex(aSelectedType);
mFilePicker->SetOkButtonLabel(aOkButtonLabel);
if (!aDisplayDirectory.IsEmpty()) {
nsCOMPtr<nsIFile> localFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
if (localFile) {
localFile->InitWithPath(aDisplayDirectory);
mFilePicker->SetDisplayDirectory(localFile);
}
}
mCallback = new FilePickerShownCallback(this);
mFilePicker->Open(mCallback);
return true;
}
void
FilePickerParent::ActorDestroy(ActorDestroyReason aWhy)
{
if (mCallback) {
mCallback->Destroy();
mCallback = nullptr;
}
if (mRunnable) {
mRunnable->Destroy();
mRunnable = nullptr;
}
}

110
dom/ipc/FilePickerParent.h Normal file
View file

@ -0,0 +1,110 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_FilePickerParent_h
#define mozilla_dom_FilePickerParent_h
#include "nsIEventTarget.h"
#include "nsIFilePicker.h"
#include "nsCOMArray.h"
#include "nsThreadUtils.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/PFilePickerParent.h"
class nsIFile;
namespace mozilla {
namespace dom {
class FilePickerParent : public PFilePickerParent
{
public:
FilePickerParent(const nsString& aTitle,
const int16_t& aMode)
: mTitle(aTitle)
, mMode(aMode)
{}
virtual ~FilePickerParent();
void Done(int16_t aResult);
struct BlobImplOrString
{
RefPtr<BlobImpl> mBlobImpl;
nsString mDirectoryPath;
enum {
eBlobImpl,
eDirectoryPath
} mType;
};
void SendFilesOrDirectories(const nsTArray<BlobImplOrString>& aData);
virtual bool RecvOpen(const int16_t& aSelectedType,
const bool& aAddToRecentDocs,
const nsString& aDefaultFile,
const nsString& aDefaultExtension,
InfallibleTArray<nsString>&& aFilters,
InfallibleTArray<nsString>&& aFilterNames,
const nsString& aDisplayDirectory,
const nsString& aOkButtonLabel) override;
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
class FilePickerShownCallback : public nsIFilePickerShownCallback
{
public:
explicit FilePickerShownCallback(FilePickerParent* aFilePickerParent)
: mFilePickerParent(aFilePickerParent)
{ }
NS_DECL_ISUPPORTS
NS_DECL_NSIFILEPICKERSHOWNCALLBACK
void Destroy();
private:
virtual ~FilePickerShownCallback() {}
FilePickerParent* mFilePickerParent;
};
private:
bool CreateFilePicker();
// This runnable is used to do some I/O operation on a separate thread.
class IORunnable : public Runnable
{
FilePickerParent* mFilePickerParent;
nsTArray<nsCOMPtr<nsIFile>> mFiles;
nsTArray<BlobImplOrString> mResults;
nsCOMPtr<nsIEventTarget> mEventTarget;
bool mIsDirectory;
public:
IORunnable(FilePickerParent *aFPParent,
nsTArray<nsCOMPtr<nsIFile>>& aFiles,
bool aIsDirectory);
bool Dispatch();
NS_IMETHOD Run();
void Destroy();
};
RefPtr<IORunnable> mRunnable;
RefPtr<FilePickerShownCallback> mCallback;
nsCOMPtr<nsIFilePicker> mFilePicker;
nsString mTitle;
int16_t mMode;
int16_t mResult;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_FilePickerParent_h

73
dom/ipc/IdType.h Normal file
View file

@ -0,0 +1,73 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_IdType_h
#define mozilla_dom_IdType_h
#include "ipc/IPCMessageUtils.h"
namespace IPC {
template<typename T> struct ParamTraits;
} // namespace IPC
namespace mozilla {
namespace dom {
class ContentParent;
class TabParent;
template<typename T>
class IdType
{
friend struct IPC::ParamTraits<IdType<T>>;
public:
IdType() : mId(0) {}
explicit IdType(uint64_t aId) : mId(aId) {}
operator uint64_t() const { return mId; }
IdType& operator=(uint64_t aId)
{
mId = aId;
return *this;
}
bool operator<(const IdType& rhs)
{
return mId < rhs.mId;
}
private:
uint64_t mId;
};
typedef IdType<TabParent> TabId;
typedef IdType<ContentParent> ContentParentId;
} // namespace dom
} // namespace mozilla
namespace IPC {
template<typename T>
struct ParamTraits<mozilla::dom::IdType<T>>
{
typedef mozilla::dom::IdType<T> paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
WriteParam(aMsg, aParam.mId);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
return ReadParam(aMsg, aIter, &aResult->mId);
}
};
} // namespace IPC
#endif // mozilla_dom_IdType_h

57
dom/ipc/PBlob.ipdl Normal file
View file

@ -0,0 +1,57 @@
/* 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 protocol PBackground;
include protocol PBlobStream;
include protocol PContent;
include protocol PContentBridge;
include protocol PFileDescriptorSet;
include protocol PSendStream;
include BlobTypes;
include DOMTypes;
include InputStreamParams;
namespace mozilla {
namespace dom {
union ResolveMysteryParams
{
NormalBlobConstructorParams;
FileBlobConstructorParams;
};
sync protocol PBlob
{
manager PBackground or PContent or PContentBridge;
manages PBlobStream;
both:
async __delete__();
parent:
async PBlobStream(uint64_t begin, uint64_t length);
async ResolveMystery(ResolveMysteryParams params);
sync BlobStreamSync(uint64_t begin, uint64_t length)
returns (InputStreamParams params, OptionalFileDescriptorSet fds);
sync WaitForSliceCreation();
// Use only for testing!
sync GetFileId()
returns (int64_t fileId);
sync GetFilePath()
returns (nsString filePath);
child:
// This method must be called by the parent when the PBlobParent is fully
// created in order to release the known blob.
async CreatedFromKnownBlob();
};
} // namespace dom
} // namespace mozilla

22
dom/ipc/PBlobStream.ipdl Normal file
View file

@ -0,0 +1,22 @@
/* 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 protocol PBlob;
include protocol PFileDescriptorSet;
include BlobTypes;
include InputStreamParams;
namespace mozilla {
namespace dom {
protocol PBlobStream
{
manager PBlob;
child:
async __delete__(InputStreamParams params, OptionalFileDescriptorSet fds);
};
} // namespace dom
} // namespace mozilla

928
dom/ipc/PBrowser.ipdl Normal file
View file

@ -0,0 +1,928 @@
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=4 ts=8 et tw=80 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 protocol PBlob;
include protocol PColorPicker;
include protocol PContent;
include protocol PContentBridge;
include protocol PDatePicker;
include protocol PDocAccessible;
include protocol PDocumentRenderer;
include protocol PFilePicker;
include protocol PIndexedDBPermissionRequest;
include protocol PRenderFrame;
include protocol PPluginWidget;
include protocol PRemotePrintJob;
include DOMTypes;
include JavaScriptTypes;
include URIParams;
include PPrintingTypes;
include PTabContext;
using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
using class mozilla::gfx::Matrix from "mozilla/gfx/Matrix.h";
using struct gfxSize from "gfxPoint.h";
using CSSRect from "Units.h";
using CSSSize from "Units.h";
using mozilla::LayoutDeviceIntRect from "Units.h";
using mozilla::LayoutDeviceIntPoint from "Units.h";
using mozilla::LayoutDevicePoint from "Units.h";
using mozilla::ScreenIntPoint from "Units.h";
using ScreenIntSize from "Units.h";
using struct mozilla::layers::FrameMetrics from "FrameMetrics.h";
using struct mozilla::layers::ScrollableLayerGuid from "FrameMetrics.h";
using struct mozilla::layers::ZoomConstraints from "FrameMetrics.h";
using mozilla::layers::MaybeZoomConstraints from "FrameMetrics.h";
using mozilla::layers::GeckoContentController::TapType from "mozilla/layers/GeckoContentController.h";
using FrameMetrics::ViewID from "FrameMetrics.h";
using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h";
using nscolor from "nsColor.h";
using class mozilla::WidgetCompositionEvent from "ipc/nsGUIEventIPC.h";
using struct mozilla::widget::IMENotification from "nsIWidget.h";
using struct nsIMEUpdatePreference from "nsIWidget.h";
using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
using mozilla::gfx::IntPoint from "mozilla/gfx/Point.h";
using mozilla::gfx::IntRect from "mozilla/gfx/Rect.h";
using class mozilla::ContentCache from "ipc/nsGUIEventIPC.h";
using class mozilla::WidgetKeyboardEvent from "ipc/nsGUIEventIPC.h";
using class mozilla::WidgetMouseEvent from "ipc/nsGUIEventIPC.h";
using class mozilla::WidgetWheelEvent from "ipc/nsGUIEventIPC.h";
using class mozilla::WidgetDragEvent from "ipc/nsGUIEventIPC.h";
using struct nsRect from "nsRect.h";
using class mozilla::WidgetSelectionEvent from "ipc/nsGUIEventIPC.h";
using class mozilla::WidgetTouchEvent from "ipc/nsGUIEventIPC.h";
using class mozilla::WidgetPluginEvent from "ipc/nsGUIEventIPC.h";
using struct mozilla::dom::RemoteDOMEvent from "mozilla/dom/TabMessageUtils.h";
using mozilla::dom::ScreenOrientationInternal from "mozilla/dom/ScreenOrientation.h";
using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
using mozilla::CSSToScreenScale from "Units.h";
using mozilla::CommandInt from "mozilla/EventForwards.h";
using mozilla::WritingMode from "mozilla/WritingModes.h";
using mozilla::layers::TouchBehaviorFlags from "mozilla/layers/APZUtils.h";
using nsIWidget::TouchPointerState from "nsIWidget.h";
using struct LookAndFeelInt from "mozilla/widget/WidgetMessageUtils.h";
using class mozilla::dom::MessagePort from "mozilla/dom/MessagePort.h";
using class mozilla::dom::ipc::StructuredCloneData from "mozilla/dom/ipc/StructuredCloneData.h";
using mozilla::EventMessage from "mozilla/EventForwards.h";
using nsEventStatus from "mozilla/EventForwards.h";
using mozilla::Modifiers from "mozilla/EventForwards.h";
using nsSizeMode from "nsIWidgetListener.h";
using mozilla::widget::CandidateWindowPosition from "ipc/nsGUIEventIPC.h";
using class mozilla::NativeEventData from "ipc/nsGUIEventIPC.h";
using mozilla::FontRange from "ipc/nsGUIEventIPC.h";
using mozilla::a11y::IAccessibleHolder from "mozilla/a11y/IPCTypes.h";
namespace mozilla {
namespace dom {
struct NativeKeyBinding
{
CommandInt[] singleLineCommands;
CommandInt[] multiLineCommands;
CommandInt[] richTextCommands;
};
union MaybeNativeKeyBinding
{
NativeKeyBinding;
void_t;
};
struct ShowInfo
{
nsString name;
bool fullscreenAllowed;
bool isPrivate;
bool fakeShowInfo;
bool isTransparent;
float dpi;
int32_t widgetRounding;
double defaultScale;
};
union OptionalShmem
{
void_t;
Shmem;
};
nested(upto inside_cpow) sync protocol PBrowser
{
manager PContent or PContentBridge;
manages PColorPicker;
manages PDatePicker;
manages PDocAccessible;
manages PDocumentRenderer;
manages PFilePicker;
manages PIndexedDBPermissionRequest;
manages PRenderFrame;
manages PPluginWidget;
both:
async AsyncMessage(nsString aMessage, CpowEntry[] aCpows,
Principal aPrincipal, ClonedMessageData aData);
/**
* Create a layout frame (encapsulating a remote layer tree) for
* the page that is currently loaded in the <browser>.
*/
async PRenderFrame();
parent:
/**
* Tell the parent process a new accessible document has been created.
* aParentDoc is the accessible document it was created in if any, and
* aParentAcc is the id of the accessible in that document the new document
* is a child of. aMsaaID is the MSAA id for this content process, and
* is only valid on Windows. Set to 0 on other platforms. aDocCOMProxy
* is also Windows-specific and should be set to 0 on other platforms.
*/
async PDocAccessible(nullable PDocAccessible aParentDoc, uint64_t aParentAcc,
uint32_t aMsaaID, IAccessibleHolder aDocCOMProxy);
/*
* Creates a new remoted nsIWidget connection for windowed plugins
* in e10s mode. This is always initiated from the child in response
* to windowed plugin creation.
*/
sync PPluginWidget();
/**
* Return native data of root widget
*/
nested(inside_cpow) sync GetWidgetNativeData() returns (WindowsHandle value);
/**
* Sends an NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW to be adopted by the
* widget's shareable window on the chrome side. Only used on Windows.
*/
async SetNativeChildOfShareableWindow(uintptr_t childWindow);
/**
* When content moves focus from a native plugin window that's a child
* of the native browser window we need to move native focus to the
* browser. Otherwise the plugin window will never relinquish focus.
*/
sync DispatchFocusToTopLevelWindow();
parent:
/**
* When child sends this message, parent should move focus to
* the next or previous focusable element or document.
*/
async MoveFocus(bool forward, bool forDocumentNavigation);
/**
* SizeShellTo request propagation to parent.
*
* aFlag Can indicate if one of the dimensions should be ignored.
* If only one dimension has changed it has to be indicated
* by the nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_* flags.
* aShellItemWidth,
* aShellItemHeight On parent side we won't be able to decide the dimensions
* of the shell item parameter in the original SizeShellTo
* call so we send over its dimensions that will be used
* for the actual resize.
**/
async SizeShellTo(uint32_t aFlag, int32_t aWidth, int32_t aHeight,
int32_t aShellItemWidth, int32_t aShellItemHeight);
/**
* Called by the child to inform the parent that links are dropped into
* content area.
*
* aLinks A flat array of url, name, and type for each link
*/
async DropLinks(nsString[] aLinks);
async Event(RemoteDOMEvent aEvent);
sync SyncMessage(nsString aMessage, ClonedMessageData aData,
CpowEntry[] aCpows, Principal aPrincipal)
returns (StructuredCloneData[] retval);
nested(inside_sync) sync RpcMessage(nsString aMessage, ClonedMessageData aData,
CpowEntry[] aCpows, Principal aPrincipal)
returns (StructuredCloneData[] retval);
/**
* Notifies chrome that there is a focus change involving an editable
* object (input, textarea, document, contentEditable. etc.)
*
* contentCache Cache of content
* notification Whole data of the notification
* preference Native widget preference for IME updates
*/
nested(inside_cpow) sync NotifyIMEFocus(ContentCache contentCache,
IMENotification notification)
returns (nsIMEUpdatePreference preference);
/**
* Notifies chrome that there has been a change in text content
* One call can encompass both a delete and an insert operation
* Only called when NotifyIMEFocus returns PR_TRUE for mWantUpdates
*
* contentCache Cache of content
* notification Whole data of the notification
*/
nested(inside_cpow) async NotifyIMETextChange(ContentCache contentCache,
IMENotification notification);
/**
* Notifies chrome that there is a IME compostion rect updated
*
* contentCache Cache of content
*/
nested(inside_cpow) async NotifyIMECompositionUpdate(ContentCache contentCache,
IMENotification notification);
/**
* Notifies chrome that there has been a change in selection
* Only called when NotifyIMEFocus returns PR_TRUE for mWantUpdates
*
* contentCache Cache of content
* notification Whole data of the notification
*/
nested(inside_cpow) async NotifyIMESelection(ContentCache contentCache,
IMENotification notification);
/**
* Notifies chrome of updating its content cache.
* This is useful if content is modified but we don't need to notify IME.
*
* contentCache Cache of content
*/
nested(inside_cpow) async UpdateContentCache(ContentCache contentCache);
/**
* Notifies IME of mouse button event on a character in focused editor.
*
* Returns true if the mouse button event is consumd by IME.
*/
nested(inside_cpow) sync NotifyIMEMouseButtonEvent(IMENotification notification)
returns (bool consumedByIME);
/**
* Notifies chrome to position change
*
* contentCache Cache of content
*/
nested(inside_cpow) async NotifyIMEPositionChange(ContentCache contentCache,
IMENotification notification);
/**
* Requests chrome to commit or cancel composition of IME.
*
* cancel Set true if composition should be cancelled.
*
* isCommitted Returns true if the request causes composition
* being committed synchronously.
* committedString Returns committed string. The may be non-empty
* string even if cancel is true because IME may
* try to restore selected string which was
* replaced with the composition.
*/
nested(inside_cpow) sync RequestIMEToCommitComposition(bool cancel)
returns (bool isCommitted, nsString committedString);
/**
* OnEventNeedingAckHandled() is called after a child process dispatches a
* composition event or a selection event which is sent from the parent
* process.
*
* message The message value of the handled event.
*/
nested(inside_cpow) async OnEventNeedingAckHandled(EventMessage message);
/**
* Tells chrome to start plugin IME. If this results in a string getting
* committed, the result is in aCommitted (otherwise aCommitted is empty).
*
* aKeyboardEvent The event with which plugin IME is to be started
* panelX and panelY Location in screen coordinates of the IME input panel
* (should be just under the plugin)
* aCommitted The string committed during IME -- otherwise empty
*/
nested(inside_cpow) sync StartPluginIME(WidgetKeyboardEvent aKeyboardEvent,
int32_t panelX, int32_t panelY)
returns (nsString aCommitted);
/**
* Tells chrome (and specifically the appropriate widget) whether or not
* a plugin (inside the widget) has the keyboard focus. Should be sent
* when the keyboard focus changes too or from a plugin.
*
* aFocused Whether or not a plugin is focused
*/
nested(inside_cpow) async SetPluginFocused(bool aFocused);
/**
* Set IME candidate window by windowless plugin if plugin has focus.
*/
async SetCandidateWindowForPlugin(CandidateWindowPosition aPosition);
/**
* Notifies the parent process of native key event data received in a
* plugin process directly.
*
* aKeyEventData The native key event data. The actual type copied into
* NativeEventData depending on the caller. Please check
* PluginInstanceChild.
*/
nested(inside_cpow) async OnWindowedPluginKeyEvent(NativeEventData aKeyEventData);
/**
* When plugin event isn't consumed, call this
*/
async DefaultProcOfPluginEvent(WidgetPluginEvent aEvent);
/**
* Request that the parent process move focus to the browser's frame. If
* canRaise is true, the window can be raised if it is inactive.
*/
async RequestFocus(bool canRaise);
/**
* Indicate, based on the current state, that some commands are enabled and
* some are disabled.
*/
async EnableDisableCommands(nsString action,
nsCString[] enabledCommands,
nsCString[] disabledCommands);
nested(inside_cpow) sync GetInputContext() returns (int32_t IMEEnabled,
int32_t IMEOpen);
nested(inside_cpow) async SetInputContext(int32_t IMEEnabled,
int32_t IMEOpen,
nsString type,
nsString inputmode,
nsString actionHint,
int32_t cause,
int32_t focusChange);
sync IsParentWindowMainWidgetVisible() returns (bool visible);
/**
* Gets the DPI of the screen corresponding to this browser.
*/
sync GetDPI() returns (float value);
/**
* Gets the default scaling factor of the screen corresponding to this browser.
*/
sync GetDefaultScale() returns (double value);
/**
* Gets the rounding of coordinates in the widget.
*/
sync GetWidgetRounding() returns (int32_t value);
/**
* Gets maximum of touch points at current device.
*/
sync GetMaxTouchPoints() returns (uint32_t value);
/**
* Set the native cursor.
* @param value
* The widget cursor to set.
* @param force
* Invalidate any locally cached cursor settings and force an
* update.
*/
async SetCursor(uint32_t value, bool force);
/**
* Set the native cursor using a custom image.
* @param cursorData
* Serialized image data.
* @param width
* Width of the image.
* @param height
* Height of the image.
* @param stride
* Stride used in the image data.
* @param format
* Image format, see gfx::SurfaceFormat for possible values.
* @param hotspotX
* Horizontal hotspot of the image, as specified by the css cursor property.
* @param hotspotY
* Vertical hotspot of the image, as specified by the css cursor property.
* @param force
* Invalidate any locally cached cursor settings and force an
* update.
*/
async SetCustomCursor(nsCString cursorData, uint32_t width, uint32_t height,
uint32_t stride, uint8_t format,
uint32_t hotspotX, uint32_t hotspotY, bool force);
/**
* Used to set the current text of the status tooltip.
* Nowadays this is mainly used for link locations on hover.
*/
async SetStatus(uint32_t type, nsString status);
/**
* Show/hide a tooltip when the mouse hovers over an element in the content
* document.
*/
async ShowTooltip(uint32_t x, uint32_t y, nsString tooltip, nsString direction);
async HideTooltip();
/**
* Create an asynchronous color picker on the parent side,
* but don't open it yet.
*/
async PColorPicker(nsString title, nsString initialColor);
/**
* Create an asynchronous date picker on the parent side,
* but don't open it yet.
*/
async PDatePicker(nsString title, nsString initialDate);
async PFilePicker(nsString aTitle, int16_t aMode);
/**
* Initiates an asynchronous request for one of the special indexedDB
* permissions for the provided principal.
*
* @param principal
* The principal of the request.
*
* NOTE: The principal is untrusted in the parent process. Only
* principals that can live in the content process should
* provided.
*/
async PIndexedDBPermissionRequest(Principal principal);
/**
* window.open from inside <iframe mozbrowser> is special. When the child
* process calls window.open, it creates a new PBrowser (in its own
* process), then calls BrowserFrameOpenWindow on it.
*
* The parent process gets a chance to accept or reject the window.open
* call, and windowOpened is set to true if we ended up going through with
* the window.open.
*
* @param opener the PBrowser whose content called window.open.
*/
sync BrowserFrameOpenWindow(PBrowser opener, PRenderFrame renderFrame,
nsString aURL, nsString aName, nsString aFeatures)
returns (bool windowOpened,
TextureFactoryIdentifier textureFactoryIdentifier,
uint64_t layersId);
/**
* Tells the containing widget whether the given input block results in a
* swipe. Should be called in response to a WidgetWheelEvent that has
* mFlags.mCanTriggerSwipe set on it.
*/
async RespondStartSwipeEvent(uint64_t aInputBlockId, bool aStartSwipe);
/**
* Brings up the auth prompt dialog.
* Called when this is the PBrowserParent for a nested remote iframe.
* aCallbackId corresponds to an nsIAuthPromptCallback that lives in the
* root process. It will be passed back to the root process with either the
* OnAuthAvailable or OnAuthCancelled message.
*/
async AsyncAuthPrompt(nsCString uri, nsString realm, uint64_t aCallbackId);
/**
* Look up dictionary by selected word for OSX
*
* @param aText The word to look up
* @param aFontRange Text decoration of aText
* @param aIsVertical true if vertical layout
*/
async LookUpDictionary(nsString aText, FontRange[] aFontRangeArray,
bool aIsVertical, LayoutDeviceIntPoint aPoint);
async __delete__();
async ReplyKeyEvent(WidgetKeyboardEvent event);
async DispatchAfterKeyboardEvent(WidgetKeyboardEvent event);
sync RequestNativeKeyBindings(WidgetKeyboardEvent event)
returns (MaybeNativeKeyBinding bindings);
async SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout,
int32_t aNativeKeyCode,
uint32_t aModifierFlags,
nsString aCharacters,
nsString aUnmodifiedCharacters,
uint64_t aObserverId);
async SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint,
uint32_t aNativeMessage,
uint32_t aModifierFlags,
uint64_t aObserverId);
async SynthesizeNativeMouseMove(LayoutDeviceIntPoint aPoint,
uint64_t aObserverId);
async SynthesizeNativeMouseScrollEvent(LayoutDeviceIntPoint aPoint,
uint32_t aNativeMessage,
double aDeltaX,
double aDeltaY,
double aDeltaZ,
uint32_t aModifierFlags,
uint32_t aAdditionalFlags,
uint64_t aObserverId);
async SynthesizeNativeTouchPoint(uint32_t aPointerId,
TouchPointerState aPointerState,
LayoutDeviceIntPoint aPoint,
double aPointerPressure,
uint32_t aPointerOrientation,
uint64_t aObserverId);
async SynthesizeNativeTouchTap(LayoutDeviceIntPoint aPoint,
bool aLongTap,
uint64_t aObserverId);
async ClearNativeTouchSequence(uint64_t aObserverId);
/**
* Returns the number of tabs in the window via the out parameter.
* If the number of tabs can't be determined, returns 0.
*
* @param aValue where to store the tab count
*/
sync GetTabCount() returns (uint32_t value);
async AccessKeyNotHandled(WidgetKeyboardEvent event);
child:
async NativeSynthesisResponse(uint64_t aObserverId, nsCString aResponse);
parent:
/**
* Child informs the parent that the graphics objects are ready for
* compositing. This is sent when all pending changes have been
* sent to the compositor and are ready to be shown on the next composite.
* @see PCompositor
* @see RequestNotifyAfterRemotePaint
*/
async RemotePaintIsReady();
/**
* Child informs the parent that the layer tree is already available.
*/
async ForcePaintNoOp(uint64_t aLayerObserverEpoch);
/**
* Sent by the child to the parent to inform it that an update to the
* dimensions has been requested, likely through win.moveTo or resizeTo
*/
async SetDimensions(uint32_t aFlags, int32_t aX, int32_t aY, int32_t aCx, int32_t aCy);
nested(inside_sync) sync DispatchWheelEvent(WidgetWheelEvent event);
nested(inside_sync) sync DispatchMouseEvent(WidgetMouseEvent event);
nested(inside_sync) sync DispatchKeyboardEvent(WidgetKeyboardEvent event);
async InvokeDragSession(IPCDataTransfer[] transfers, uint32_t action,
OptionalShmem visualData,
uint32_t stride, uint8_t format,
LayoutDeviceIntRect dragRect);
async AudioChannelActivityNotification(uint32_t aAudioChannel,
bool aActive);
// After a compositor reset, it is necessary to reconnect each layers ID to
// the compositor of the widget that will render those layers. Note that
// this is sync so we can ensure that messages to the window compositor
// arrive before the TabChild attempts to use its cross-process compositor
// bridge.
sync EnsureLayersConnected();
/**
* Notify parent that one or more entries have been added / removed from
* the child session history.
*
* @param aCount the updated number of entries in child session history
*/
async NotifySessionHistoryChange(uint32_t aCount);
/**
* When the session history is across multiple root docshells, this function
* is used to notify parent that it needs to navigate to an entry out of
* local index of the child.
*
* @param aGlobalIndex The global index of history entry to navigate to.
*/
async RequestCrossBrowserNavigation(uint32_t aGlobalIndex);
child:
/**
* Notify the remote browser that it has been Show()n on this
* side, with the given |visibleRect|. This message is expected
* to trigger creation of the remote browser's "widget".
*
* |Show()| and |Move()| take IntSizes rather than Rects because
* content processes always render to a virtual <0, 0> top-left
* point.
*/
async Show(ScreenIntSize size,
ShowInfo info,
TextureFactoryIdentifier textureFactoryIdentifier,
uint64_t layersId,
nullable PRenderFrame renderFrame,
bool parentIsActive,
nsSizeMode sizeMode);
async LoadURL(nsCString uri, ShowInfo info);
async UpdateDimensions(CSSRect rect, CSSSize size,
ScreenOrientationInternal orientation,
LayoutDeviceIntPoint clientOffset,
LayoutDeviceIntPoint chromeDisp) compressall;
async SizeModeChanged(nsSizeMode sizeMode);
/**
* Sending an activate message moves focus to the child.
*/
async Activate();
async Deactivate();
async ParentActivated(bool aActivated);
async SetKeyboardIndicators(UIStateChangeType showAccelerators,
UIStateChangeType showFocusRings);
/**
* StopIMEStateManagement() is called when the process loses focus and
* should stop managing IME state.
*/
async StopIMEStateManagement();
/**
* MenuKeyboardListenerInstalled() is called when menu keyboard listener
* is installed in the parent process.
*/
async MenuKeyboardListenerInstalled(bool aInstalled);
/**
* @see nsIDOMWindowUtils sendMouseEvent.
*/
async MouseEvent(nsString aType,
float aX,
float aY,
int32_t aButton,
int32_t aClickCount,
int32_t aModifiers,
bool aIgnoreRootScrollFrame);
/**
* When two consecutive mouse move events would be added to the message queue,
* they are 'compressed' by dumping the oldest one.
*/
async RealMouseMoveEvent(WidgetMouseEvent event, ScrollableLayerGuid aGuid, uint64_t aInputBlockId) compress;
/**
* Mouse move events with |reason == eSynthesized| are sent via a separate
* message because they do not generate DOM 'mousemove' events, and the
* 'compress' attribute on RealMouseMoveEvent() could result in a
* |reason == eReal| event being dropped in favour of an |eSynthesized|
* event, and thus a DOM 'mousemove' event to be lost.
*/
async SynthMouseMoveEvent(WidgetMouseEvent event, ScrollableLayerGuid aGuid, uint64_t aInputBlockId);
async RealMouseButtonEvent(WidgetMouseEvent event, ScrollableLayerGuid aGuid, uint64_t aInputBlockId);
async RealKeyEvent(WidgetKeyboardEvent event, MaybeNativeKeyBinding keyBinding);
async MouseWheelEvent(WidgetWheelEvent event, ScrollableLayerGuid aGuid, uint64_t aInputBlockId);
async RealTouchEvent(WidgetTouchEvent aEvent,
ScrollableLayerGuid aGuid,
uint64_t aInputBlockId,
nsEventStatus aApzResponse);
async HandleTap(TapType aType, LayoutDevicePoint point, Modifiers aModifiers,
ScrollableLayerGuid aGuid, uint64_t aInputBlockId);
async RealTouchMoveEvent(WidgetTouchEvent aEvent,
ScrollableLayerGuid aGuid,
uint64_t aInputBlockId,
nsEventStatus aApzResponse);
async RealDragEvent(WidgetDragEvent aEvent, uint32_t aDragAction, uint32_t aDropEffect);
async PluginEvent(WidgetPluginEvent aEvent);
/**
* @see nsIDOMWindowUtils sendKeyEvent.
*/
async KeyEvent(nsString aType,
int32_t aKeyCode,
int32_t aCharCode,
int32_t aModifiers,
bool aPreventDefault);
async CompositionEvent(WidgetCompositionEvent event);
async SelectionEvent(WidgetSelectionEvent event);
/**
* Call PasteTransferable via a controller on the content process
* to handle the command content event, "pasteTransferable".
*/
async PasteTransferable(IPCDataTransfer aDataTransfer,
bool aIsPrivateData,
Principal aRequestingPrincipal);
/**
* Activate event forwarding from client to parent.
*/
async ActivateFrameEvent(nsString aType, bool capture);
async LoadRemoteScript(nsString aURL, bool aRunInGlobalScope);
/**
* Create a asynchronous request to render whatever document is
* loaded in the child when this message arrives. When the
* request finishes, PDocumentRenderer:__delete__ is sent back to
* this side to notify completion.
*
* |documentRect| is the area of the remote document to draw,
* transformed by |transform|. The rendered area will have the
* default background color |bgcolor|. |renderFlags| are the
* nsIPresShell::RenderDocument() flags to use on the remote side,
* and if true, |flushLayout| will do just that before rendering
* the document. The rendered image will be of size |renderSize|.
*/
async PDocumentRenderer(nsRect documentRect, Matrix transform,
nsString bgcolor,
uint32_t renderFlags, bool flushLayout,
IntSize renderSize);
/**
* Sent by the chrome process when it no longer wants this remote
* <browser>. The child side cleans up in response, then
* finalizing its death by sending back __delete__() to the
* parent.
*/
async Destroy();
/**
* Update the child side docShell active (resource use) state.
*
* @param aIsActive
* Whether to activate or deactivate the docshell.
* @param aPreserveLayers
* Whether layer trees should be preserved for inactive docshells.
* @param aLayerObserverEpoch
* The layer observer epoch for this activation. This message should be
* ignored if this epoch has already been observed (via ForcePaint).
*/
async SetDocShellIsActive(bool aIsActive, bool aPreserveLayers, uint64_t aLayerObserverEpoch);
/**
* Notify the child that it shouldn't paint the offscreen displayport.
* This is useful to speed up interactive operations over async
* scrolling performance like resize, tabswitch, pageload.
*
* Each enable call must be matched with a disable call. The child
* will remain in the suppress mode as long as there's
* a single unmatched call.
*/
async SuppressDisplayport(bool aEnabled);
/**
* Navigate by key (Tab/Shift+Tab/F6/Shift+f6).
*/
async NavigateByKey(bool aForward, bool aForDocumentNavigation);
/**
* The parent (chrome thread) requests that the child inform it when
* the graphics objects are ready to display.
* @see PCompositor
* @see RemotePaintIsReady
*/
async RequestNotifyAfterRemotePaint();
/**
* Tell the child that the UI resolution changed for the containing
* window.
* To avoid some sync messages from child to parent, we also send the dpi
* and default scale with the notification.
* If we don't know the dpi and default scale, we just pass in a negative
* value (-1) but in the majority of the cases this saves us from two
* sync requests from the child to the parent.
*/
async UIResolutionChanged(float dpi, int32_t rounding, double scale);
/**
* Tell the child that the system theme has changed, and that a repaint
* is necessary.
*/
async ThemeChanged(LookAndFeelInt[] lookAndFeelIntCache);
/**
* Tell the browser that its frame loader has been swapped
* with another.
*/
async SwappedWithOtherRemoteLoader(IPCTabContext context);
/**
* A potential accesskey was just pressed. Look for accesskey targets
* using the list of provided charCodes.
*
* @param event keyboard event
* @param isTrusted true if triggered by a trusted key event
* @param modifierMask indicates which accesskey modifiers are pressed
*/
async HandleAccessKey(WidgetKeyboardEvent event,
uint32_t[] charCodes, int32_t modifierMask);
/**
* Propagate a refresh to the child process
*/
async AudioChannelChangeNotification(uint32_t aAudioChannel,
float aVolume,
bool aMuted);
/**
* Tells the root child docShell whether or not to use
* global history. This is sent right after the PBrowser
* is bound to a frameloader element.
*/
async SetUseGlobalHistory(bool aUse);
/**
* HandledWindowedPluginKeyEvent() is always called after posting a native
* key event with OnWindowedPluginKeyEvent().
*
* @param aKeyEventData The key event which was posted to the parent
* process.
* @param aIsConsumed true if aKeyEventData is consumed in the
* parent process. Otherwise, false.
*/
async HandledWindowedPluginKeyEvent(NativeEventData aKeyEventData,
bool aIsConsumed);
/**
* Tell the child to print the current page with the given settings.
*
* @param aOuterWindowID the ID of the outer window to print
* @param aPrintData the serialized settings to print with
*/
async Print(uint64_t aOuterWindowID, PrintData aPrintData);
/**
* Update the child with the tab's current top-level native window handle.
* This is used by a11y objects who must expose their native window.
*
* @param aNewHandle The native window handle of the tab's top-level window.
*/
async UpdateNativeWindowHandle(uintptr_t aNewHandle);
/**
* Called when the session history of this particular PBrowser has been
* attached to a grouped session history.
*
* @param aOffset The number of entries in the grouped session
* history before this session history object.
*/
async NotifyAttachGroupedSessionHistory(uint32_t aOffset);
/**
* Notify that the session history associated to this PBrowser has become
* the active history in the grouped session history.
*
* @param aGlobalLength The up-to-date number of entries in the grouped
* session history.
* @param aTargetLocalIndex The target local index to navigate to.
*/
async NotifyPartialSessionHistoryActive(uint32_t aGlobalLength,
uint32_t aTargetLocalIndex);
/**
* Notify that the session history asssociates to this PBrowser has become
* an inactive history in the grouped session history.
*/
async NotifyPartialSessionHistoryDeactive();
/**
* Tell the child that it is a fresh process created for a Large-Allocation
* load.
*/
async SetFreshProcess();
/*
* FIXME: write protocol!
state LIVE:
send LoadURL goto LIVE;
//etc.
send Destroy goto DYING;
state DYING:
discard send blah;
// etc.
recv __delete__;
*/
};
}
}

View file

@ -0,0 +1,21 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set sw=2 ts=8 et tw=80 ft=c: */
/* 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 protocol PBrowser;
using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
namespace mozilla {
namespace dom {
union PBrowserOrId
{
nullable PBrowser;
TabId;
};
} // namespace dom
} // namespace mozilla

27
dom/ipc/PColorPicker.ipdl Normal file
View file

@ -0,0 +1,27 @@
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=4 ts=8 et tw=80 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 protocol PBrowser;
namespace mozilla {
namespace dom {
protocol PColorPicker
{
manager PBrowser;
parent:
async Open();
child:
async Update(nsString color);
async __delete__(nsString color);
};
} // namespace dom
} // namespace mozilla

1063
dom/ipc/PContent.ipdl Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,69 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PBlob;
include protocol PBrowser;
include protocol PContent;
include protocol PJavaScript;
include protocol PFileDescriptorSet;
include protocol PSendStream;
include DOMTypes;
include JavaScriptTypes;
include PTabContext;
using class IPC::Principal from "mozilla/dom/PermissionMessageUtils.h";
using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
using mozilla::dom::ContentParentId from "mozilla/dom/ipc/IdType.h";
using class mozilla::dom::MessagePort from "mozilla/dom/MessagePort.h";
using class mozilla::dom::ipc::StructuredCloneData from "mozilla/dom/ipc/StructuredCloneData.h";
namespace mozilla {
namespace dom {
/*
* PContentBridge allows us to represent a parent/child relationship between two
* child processes. When a child process wants to open its own child, it asks
* the root process to create a new process and then bridge them. The first
* child will allocate the PContentBridgeParent, and the newly opened child will
* allocate the PContentBridgeChild. This protocol allows these processes to
* share PBrowsers and send messages to each other.
*/
nested(upto inside_cpow) sync protocol PContentBridge
{
bridges PContent, PContent;
manages PBlob;
manages PBrowser;
manages PFileDescriptorSet;
manages PJavaScript;
manages PSendStream;
parent:
sync SyncMessage(nsString aMessage, ClonedMessageData aData,
CpowEntry[] aCpows, Principal aPrincipal)
returns (StructuredCloneData[] retval);
async PJavaScript();
async PSendStream();
both:
// Both the parent and the child can construct the PBrowser.
// See the comment in PContent::PBrowser().
async PBrowser(TabId tabId, IPCTabContext context, uint32_t chromeFlags,
ContentParentId cpId, bool isForApp, bool isForBrowser);
async PBlob(BlobConstructorParams params);
async PFileDescriptorSet(FileDescriptor fd);
async AsyncMessage(nsString aMessage, CpowEntry[] aCpows,
Principal aPrincipal, ClonedMessageData aData);
};
}
}

View file

@ -0,0 +1,20 @@
/* 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/. */
namespace mozilla {
namespace dom {
struct PermissionRequest {
nsCString type;
nsCString access;
nsString[] options;
};
struct PermissionChoice {
nsCString type;
nsString choice;
};
} // namespace dom
} // namespace mozilla

View file

@ -0,0 +1,28 @@
/* 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 protocol PContent;
include PContentPermission;
namespace mozilla {
namespace dom {
protocol PContentPermissionRequest
{
manager PContent;
parent:
async prompt();
async NotifyVisibility(bool visibility);
async Destroy();
child:
async GetVisibility();
async NotifyResult(bool allow, PermissionChoice[] choices);
async __delete__();
};
} // namespace dom
} // namespace mozilla

View file

@ -0,0 +1,31 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set sw=4 ts=8 et 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 protocol PContent;
include protocol PPluginModule;
include protocol PGMP;
namespace mozilla {
namespace dom {
struct Mapping {
nsCString library_name;
nsCString file_id;
uintptr_t start_address;
size_t mapping_length;
size_t file_offset;
};
async protocol PCrashReporter {
manager PContent or PPluginModule or PGMP;
parent:
async AnnotateCrashReport(nsCString key, nsCString data);
async AppendAppNotes(nsCString data);
async __delete__();
};
}
}

View file

@ -0,0 +1,22 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 protocol PContent;
namespace mozilla {
namespace dom {
protocol PCycleCollectWithLogs {
manager PContent;
parent:
async CloseGCLog();
async CloseCCLog();
async __delete__();
};
}
}

27
dom/ipc/PDatePicker.ipdl Normal file
View file

@ -0,0 +1,27 @@
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=4 ts=8 et tw=80 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 protocol PBrowser;
namespace mozilla {
namespace dom {
protocol PDatePicker
{
manager PBrowser;
parent:
async Open();
child:
async Cancel();
async __delete__(nsString color);
};
} // namespace dom
} // namespace mozilla

View file

@ -0,0 +1,25 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* 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 protocol PBrowser;
include "mozilla/GfxMessageUtils.h";
using nsIntSize from "nsSize.h";
namespace mozilla {
namespace ipc {
protocol PDocumentRenderer
{
manager PBrowser;
parent:
// Returns the width and height, in pixels, of the returned ARGB32 data.
async __delete__(nsIntSize renderedSize, nsCString data);
};
} // namespace ipc
} // namespace mozilla

46
dom/ipc/PFilePicker.ipdl Normal file
View file

@ -0,0 +1,46 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=4 ts=8 et tw=80 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 protocol PBlob;
include protocol PBrowser;
using struct mozilla::void_t from "ipc/IPCMessageUtils.h";
namespace mozilla {
namespace dom {
struct InputBlobs
{
PBlob[] blobs;
};
struct InputDirectory
{
nsString directoryPath;
};
union MaybeInputData
{
InputBlobs;
InputDirectory;
void_t;
};
protocol PFilePicker
{
manager PBrowser;
parent:
async Open(int16_t selectedType, bool addToRecentDocs, nsString defaultFile,
nsString defaultExtension, nsString[] filters, nsString[] filterNames,
nsString displayDirectory, nsString okButtonLabel);
child:
async __delete__(MaybeInputData data, int16_t result);
};
} // namespace dom
} // namespace mozilla

View file

@ -0,0 +1,29 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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 protocol PContent;
namespace mozilla {
namespace dom {
struct MemoryReport {
nsCString process;
nsCString path;
int32_t kind;
int32_t units;
int64_t amount;
nsCString desc;
};
protocol PMemoryReportRequest {
manager PContent;
parent:
async Report(MemoryReport aReport);
async __delete__();
};
}
}

View file

@ -0,0 +1,61 @@
/* 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 protocol PBrowser;
include "mozilla/GfxMessageUtils.h";
using nsIntRect from "nsRect.h";
namespace mozilla {
namespace plugins {
/**
* PPluginWidget - a nsIWidget'ish protocol for windowed plugins in e10s.
* On windows and linux we create native widgets in chrome which we then manage
* from content. On the content side there's PluginWidgetProxy which
* implements nsIWidget. We hand this around layout and plugins code. Anything
* not dealt with via PluginWidgetProxy falls through to PuppetWidget. Native
* widget exists on the chrome side (PluginWidgetParent) attached to the
* browser window as a child. Window management calls are forwarded from
* PluginWidgetProxy to PluginWidgetParent over this interface.
*
* Note lifetime management for PluginWidgetProxy (the plugin widget) and the
* connection (PluginWidgetChild) are separated. PluginWidgetChild will
* be torn down first by the tab, followed by the deref'ing of the nsIWidget
* via layout.
*/
sync protocol PPluginWidget {
manager PBrowser;
parent:
async __delete__();
/**
* Used to set the ID of a scroll capture container from the parent process,
* so that we can create a proxy container in the layer tree.
* @param aScrollCaptureId async container ID of the parent container
* @param aPluginInstanceId plugin ID on which to set the scroll capture ID
*/
sync Create() returns (nsresult aResult, uint64_t aScrollCaptureId,
uintptr_t aPluginInstanceId);
async SetFocus(bool aRaise);
/**
* Returns NS_NATIVE_PLUGIN_PORT and its variants: a sharable native
* window for plugins. On Linux, this returns an XID for a socket widget
* embedded in the chrome side native window. On Windows this returns the
* native HWND of the plugin widget.
*/
sync GetNativePluginPort() returns (uintptr_t value);
/**
* Sends an NS_NATIVE_CHILD_WINDOW to be adopted by the widget's native window
* on the chrome side. This is only currently used on Windows.
*/
sync SetNativeChildWindow(uintptr_t childWindow);
};
}
}

View file

@ -0,0 +1,47 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* vim: sw=2 ts=8 et :
*/
/* 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/. */
using base::ProcessId from "base/process.h";
using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
namespace mozilla {
struct SlowScriptData
{
TabId tabId;
nsCString filename;
uint32_t lineno;
};
struct PluginHangData
{
uint32_t pluginId;
ProcessId contentProcessId;
};
union HangData
{
SlowScriptData;
PluginHangData;
};
protocol PProcessHangMonitor
{
parent:
async HangEvidence(HangData data);
async ClearHang();
child:
async TerminateScript();
async BeginStartingDebugger();
async EndStartingDebugger();
async ForcePaint(TabId tabId, uint64_t aLayerObserverEpoch);
};
} // namespace mozilla

View file

@ -0,0 +1,62 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* 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 protocol PBrowser;
include protocol PContent;
include "mozilla/GfxMessageUtils.h";
using nsIntRect from "nsRect.h";
using mozilla::dom::TabId from "mozilla/dom/ipc/IdType.h";
namespace mozilla {
namespace dom {
struct ScreenDetails {
uint32_t id;
nsIntRect rect;
nsIntRect rectDisplayPix;
nsIntRect availRect;
nsIntRect availRectDisplayPix;
int32_t pixelDepth;
int32_t colorDepth;
double contentsScaleFactor;
};
nested(upto inside_cpow) sync protocol PScreenManager
{
manager PContent;
parent:
nested(inside_sync) sync Refresh()
returns (uint32_t numberOfScreens,
float systemDefaultScale,
bool success);
nested(inside_cpow) sync ScreenRefresh(uint32_t aId)
returns (ScreenDetails screen,
bool success);
nested(inside_sync) sync GetPrimaryScreen()
returns (ScreenDetails screen,
bool success);
nested(inside_sync) sync ScreenForRect(int32_t aLeft,
int32_t aTop,
int32_t aWidth,
int32_t aHeight)
returns (ScreenDetails screen,
bool success);
nested(inside_cpow) sync ScreenForBrowser(TabId aTabId)
returns (ScreenDetails screen,
bool success);
child:
async __delete__();
};
} // namespace dom
} // namespace mozilla

84
dom/ipc/PTabContext.ipdlh Normal file
View file

@ -0,0 +1,84 @@
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=4 ts=8 et tw=80 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 protocol PBrowser;
include PBrowserOrId;
using UIStateChangeType from "nsPIDOMWindow.h";
using mozilla::DocShellOriginAttributes from "mozilla/ipc/BackgroundUtils.h";
namespace mozilla {
namespace dom {
// An IPCTabContext which corresponds to a PBrowser opened by a child when it
// receives window.open().
//
// If isMozBrowserElement is false, this PopupIPCTabContext is either a
// <xul:browser> or an app frame. The frame's app-id and app-frame-owner-app-id
// will be equal to the opener's values. For a <xul:browser>, those app IDs
// will be NO_APP_ID.
//
// If isMozBrowserElement is true, the frame's browserFrameOwnerAppId will be
// equal to the opener's app-id.
//
// It's an error to set isMozBrowserElement == false if opener is a mozbrowser
// element. Such a PopupIPCTabContext should be rejected by code which receives
// it.
struct PopupIPCTabContext
{
PBrowserOrId opener;
bool isMozBrowserElement;
};
// An IPCTabContext which corresponds to an app, browser, or normal frame.
struct FrameIPCTabContext
{
// The originAttributes dictionary.
DocShellOriginAttributes originAttributes;
// The ID of the app containing this app/browser frame, if applicable.
uint32_t frameOwnerAppId;
// Whether this is a mozbrowser frame. <iframe mozbrowser mozapp> and
// <xul:browser> are not considered to be mozbrowser frames.
bool isMozBrowserElement;
// Whether this TabContext should work in prerender mode.
bool isPrerendered;
// The requested presentation URL.
// This value would be empty if the TabContext isn't created for
// presented content.
nsString presentationURL;
// Keyboard indicator state inherited from the parent.
UIStateChangeType showAccelerators;
UIStateChangeType showFocusRings;
};
// XXXcatalinb: This is only used by ServiceWorkerClients::OpenWindow.
// Because service workers don't have an associated TabChild
// we can't satisfy the security constraints on b2g. As such, the parent
// process will accept this tab context only on desktop.
struct UnsafeIPCTabContext
{ };
// IPCTabContext is an analog to mozilla::dom::TabContext. Both specify an
// iframe/PBrowser's own and containing app-ids and tell you whether the
// iframe/PBrowser is a browser frame. But only IPCTabContext is allowed to
// travel over IPC.
//
// We need IPCTabContext (specifically, PopupIPCTabContext) to prevent a
// privilege escalation attack by a compromised child process.
union IPCTabContext
{
PopupIPCTabContext;
FrameIPCTabContext;
UnsafeIPCTabContext;
};
}
}

View file

@ -0,0 +1,69 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "mozilla/dom/PermissionMessageUtils.h"
#include "nsISerializable.h"
#include "nsSerializationHelper.h"
namespace IPC {
void
ParamTraits<Principal>::Write(Message* aMsg, const paramType& aParam) {
bool isNull = !aParam.mPrincipal;
WriteParam(aMsg, isNull);
if (isNull) {
return;
}
bool isSerialized = false;
nsCString principalString;
nsCOMPtr<nsISerializable> serializable = do_QueryInterface(aParam.mPrincipal);
if (serializable) {
nsresult rv = NS_SerializeToString(serializable, principalString);
if (NS_SUCCEEDED(rv)) {
isSerialized = true;
}
}
if (!isSerialized) {
NS_RUNTIMEABORT("Unable to serialize principal.");
return;
}
WriteParam(aMsg, principalString);
}
bool
ParamTraits<Principal>::Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
bool isNull;
if (!ReadParam(aMsg, aIter, &isNull)) {
return false;
}
if (isNull) {
aResult->mPrincipal = nullptr;
return true;
}
nsCString principalString;
if (!ReadParam(aMsg, aIter, &principalString)) {
return false;
}
nsCOMPtr<nsISupports> iSupports;
nsresult rv = NS_DeserializeObject(principalString, getter_AddRefs(iSupports));
NS_ENSURE_SUCCESS(rv, false);
nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(iSupports);
NS_ENSURE_TRUE(principal, false);
principal.swap(aResult->mPrincipal);
return true;
}
} // namespace IPC

View file

@ -0,0 +1,52 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_permission_message_utils_h__
#define mozilla_dom_permission_message_utils_h__
#include "ipc/IPCMessageUtils.h"
#include "nsCOMPtr.h"
#include "nsIPrincipal.h"
namespace IPC {
class Principal
{
friend struct ParamTraits<Principal>;
public:
Principal()
: mPrincipal(nullptr)
{}
explicit Principal(nsIPrincipal* aPrincipal)
: mPrincipal(aPrincipal)
{}
operator nsIPrincipal*() const { return mPrincipal.get(); }
Principal& operator=(const Principal& aOther)
{
mPrincipal = aOther.mPrincipal;
return *this;
}
private:
nsCOMPtr<nsIPrincipal> mPrincipal;
};
template <>
struct ParamTraits<Principal>
{
typedef Principal paramType;
static void Write(Message* aMsg, const paramType& aParam);
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult);
};
} // namespace IPC
#endif // mozilla_dom_permission_message_utils_h__

View file

@ -0,0 +1,252 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "mozilla/PreallocatedProcessManager.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Preferences.h"
#include "mozilla/Unused.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ScriptSettings.h"
#include "nsIPropertyBag2.h"
#include "ProcessPriorityManager.h"
#include "nsServiceManagerUtils.h"
// This number is fairly arbitrary ... the intention is to put off
// launching another app process until the last one has finished
// loading its content, to reduce CPU/memory/IO contention.
#define DEFAULT_ALLOCATE_DELAY 1000
using namespace mozilla;
using namespace mozilla::hal;
using namespace mozilla::dom;
namespace {
/**
* This singleton class implements the static methods on
* PreallocatedProcessManager.
*/
class PreallocatedProcessManagerImpl final
: public nsIObserver
{
public:
static PreallocatedProcessManagerImpl* Singleton();
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
// See comments on PreallocatedProcessManager for these methods.
void AllocateAfterDelay();
void AllocateOnIdle();
void AllocateNow();
already_AddRefed<ContentParent> Take();
private:
static mozilla::StaticRefPtr<PreallocatedProcessManagerImpl> sSingleton;
PreallocatedProcessManagerImpl();
~PreallocatedProcessManagerImpl() {}
DISALLOW_EVIL_CONSTRUCTORS(PreallocatedProcessManagerImpl);
void Init();
void RereadPrefs();
void Enable();
void Disable();
void ObserveProcessShutdown(nsISupports* aSubject);
bool mEnabled;
bool mShutdown;
RefPtr<ContentParent> mPreallocatedAppProcess;
};
/* static */ StaticRefPtr<PreallocatedProcessManagerImpl>
PreallocatedProcessManagerImpl::sSingleton;
/* static */ PreallocatedProcessManagerImpl*
PreallocatedProcessManagerImpl::Singleton()
{
if (!sSingleton) {
sSingleton = new PreallocatedProcessManagerImpl();
sSingleton->Init();
ClearOnShutdown(&sSingleton);
}
return sSingleton;
}
NS_IMPL_ISUPPORTS(PreallocatedProcessManagerImpl, nsIObserver)
PreallocatedProcessManagerImpl::PreallocatedProcessManagerImpl()
:
mEnabled(false)
, mShutdown(false)
{}
void
PreallocatedProcessManagerImpl::Init()
{
Preferences::AddStrongObserver(this, "dom.ipc.processPrelaunch.enabled");
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (os) {
os->AddObserver(this, "ipc:content-shutdown",
/* weakRef = */ false);
os->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
/* weakRef = */ false);
}
{
RereadPrefs();
}
}
NS_IMETHODIMP
PreallocatedProcessManagerImpl::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData)
{
if (!strcmp("ipc:content-shutdown", aTopic)) {
ObserveProcessShutdown(aSubject);
} else if (!strcmp("nsPref:changed", aTopic)) {
// The only other observer we registered was for our prefs.
RereadPrefs();
} else if (!strcmp(NS_XPCOM_SHUTDOWN_OBSERVER_ID, aTopic)) {
mShutdown = true;
} else {
MOZ_ASSERT(false);
}
return NS_OK;
}
void
PreallocatedProcessManagerImpl::RereadPrefs()
{
if (Preferences::GetBool("dom.ipc.processPrelaunch.enabled")) {
Enable();
} else {
Disable();
}
}
already_AddRefed<ContentParent>
PreallocatedProcessManagerImpl::Take()
{
return mPreallocatedAppProcess.forget();
}
void
PreallocatedProcessManagerImpl::Enable()
{
if (mEnabled) {
return;
}
mEnabled = true;
AllocateAfterDelay();
}
void
PreallocatedProcessManagerImpl::AllocateAfterDelay()
{
if (!mEnabled || mPreallocatedAppProcess) {
return;
}
MessageLoop::current()->PostDelayedTask(
NewRunnableMethod(this, &PreallocatedProcessManagerImpl::AllocateOnIdle),
Preferences::GetUint("dom.ipc.processPrelaunch.delayMs",
DEFAULT_ALLOCATE_DELAY));
}
void
PreallocatedProcessManagerImpl::AllocateOnIdle()
{
if (!mEnabled || mPreallocatedAppProcess) {
return;
}
MessageLoop::current()->PostIdleTask(NewRunnableMethod(this, &PreallocatedProcessManagerImpl::AllocateNow));
}
void
PreallocatedProcessManagerImpl::AllocateNow()
{
if (!mEnabled || mPreallocatedAppProcess) {
return;
}
mPreallocatedAppProcess = ContentParent::PreallocateAppProcess();
}
void
PreallocatedProcessManagerImpl::Disable()
{
if (!mEnabled) {
return;
}
mEnabled = false;
if (mPreallocatedAppProcess) {
mPreallocatedAppProcess->Close();
mPreallocatedAppProcess = nullptr;
}
}
void
PreallocatedProcessManagerImpl::ObserveProcessShutdown(nsISupports* aSubject)
{
if (!mPreallocatedAppProcess) {
return;
}
nsCOMPtr<nsIPropertyBag2> props = do_QueryInterface(aSubject);
NS_ENSURE_TRUE_VOID(props);
uint64_t childID = CONTENT_PROCESS_ID_UNKNOWN;
props->GetPropertyAsUint64(NS_LITERAL_STRING("childID"), &childID);
NS_ENSURE_TRUE_VOID(childID != CONTENT_PROCESS_ID_UNKNOWN);
if (childID == mPreallocatedAppProcess->ChildID()) {
mPreallocatedAppProcess = nullptr;
}
}
inline PreallocatedProcessManagerImpl* GetPPMImpl()
{
return PreallocatedProcessManagerImpl::Singleton();
}
} // namespace
namespace mozilla {
/* static */ void
PreallocatedProcessManager::AllocateAfterDelay()
{
GetPPMImpl()->AllocateAfterDelay();
}
/* static */ void
PreallocatedProcessManager::AllocateOnIdle()
{
GetPPMImpl()->AllocateOnIdle();
}
/* static */ void
PreallocatedProcessManager::AllocateNow()
{
GetPPMImpl()->AllocateNow();
}
/* static */ already_AddRefed<ContentParent>
PreallocatedProcessManager::Take()
{
return GetPPMImpl()->Take();
}
} // namespace mozilla

View file

@ -0,0 +1,88 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_PreallocatedProcessManager_h
#define mozilla_PreallocatedProcessManager_h
#include "base/basictypes.h"
#include "nsCOMPtr.h"
#include "nsIObserver.h"
namespace mozilla {
namespace dom {
class ContentParent;
} // namespace dom
/**
* This class manages a ContentParent that it starts up ahead of any particular
* need. You can then call Take() to get this process and use it. Since we
* already started it up, it should be ready for use faster than if you'd
* created the process when you needed it.
*
* This class watches the dom.ipc.processPrelaunch.enabled pref. If it changes
* from false to true, it preallocates a process. If it changes from true to
* false, it kills the preallocated process, if any.
*
* We don't expect this pref to flip between true and false in production, but
* flipping the pref is important for tests.
*
* The static methods here are implemented by forwarding calls on to a
* PreallocatedProcessManagerImpl singleton class, so if you add a new static
* method here, you'll need to write a corresponding public method on the
* singleton.
*/
class PreallocatedProcessManager final
{
typedef mozilla::dom::ContentParent ContentParent;
public:
/**
* Create a process after a delay. We wait for a period of time (specified
* by the dom.ipc.processPrelaunch.delayMs pref), then wait for this process
* to go idle, then allocate the new process.
*
* If the dom.ipc.processPrelaunch.enabled pref is false, or if we already
* have a preallocated process, this function does nothing.
*/
static void AllocateAfterDelay();
/**
* Create a process once this process goes idle.
*
* If the dom.ipc.processPrelaunch.enabled pref is false, or if we already
* have a preallocated process, this function does nothing.
*/
static void AllocateOnIdle();
/**
* Create a process right now.
*
* If the dom.ipc.processPrelaunch.enabled pref is false, or if we already
* have a preallocated process, this function does nothing.
*/
static void AllocateNow();
/**
* Take the preallocated process, if we have one. If we don't have one, this
* returns null.
*
* If you call Take() twice in a row, the second call is guaranteed to return
* null.
*
* After you Take() the preallocated process, you need to call one of the
* Allocate* functions (or change the dom.ipc.processPrelaunch pref from
* false to true) before we'll create a new process.
*/
static already_AddRefed<ContentParent> Take();
private:
PreallocatedProcessManager();
DISALLOW_EVIL_CONSTRUCTORS(PreallocatedProcessManager);
};
} // namespace mozilla
#endif // defined mozilla_PreallocatedProcessManager_h

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,82 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_ProcessHangMonitor_h
#define mozilla_ProcessHangMonitor_h
#include "mozilla/Atomics.h"
#include "nsIObserver.h"
class nsITabChild;
class MessageLoop;
namespace base {
class Thread;
} // namespace base
namespace mozilla {
namespace dom {
class ContentParent;
class TabParent;
} // namespace dom
class PProcessHangMonitorParent;
class ProcessHangMonitor final
: public nsIObserver
{
private:
ProcessHangMonitor();
virtual ~ProcessHangMonitor();
public:
static ProcessHangMonitor* Get() { return sInstance; }
static ProcessHangMonitor* GetOrCreate();
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
static void AddProcess(dom::ContentParent* aContentParent);
static void RemoveProcess(PProcessHangMonitorParent* aParent);
static void ClearHang();
static void ForcePaint(PProcessHangMonitorParent* aParent,
dom::TabParent* aTab,
uint64_t aLayerObserverEpoch);
static void ClearForcePaint();
enum SlowScriptAction {
Continue,
Terminate,
StartDebugger
};
SlowScriptAction NotifySlowScript(nsITabChild* aTabChild,
const char* aFileName,
unsigned aLineNo);
void NotifyPluginHang(uint32_t aPluginId);
bool IsDebuggerStartupComplete();
void InitiateCPOWTimeout();
bool ShouldTimeOutCPOWs();
MessageLoop* MonitorLoop();
private:
static ProcessHangMonitor* sInstance;
Atomic<bool> mCPOWTimeout;
base::Thread* mThread;
};
} // namespace mozilla
#endif // mozilla_ProcessHangMonitor_h

View file

@ -0,0 +1,34 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_ProcessHangMonitorIPC_h
#define mozilla_ProcessHangMonitorIPC_h
#include "base/task.h"
#include "base/thread.h"
#include "mozilla/PProcessHangMonitor.h"
#include "mozilla/PProcessHangMonitorParent.h"
#include "mozilla/PProcessHangMonitorChild.h"
namespace mozilla {
namespace dom {
class ContentParent;
} // namespace dom
PProcessHangMonitorParent*
CreateHangMonitorParent(mozilla::dom::ContentParent* aContentParent,
mozilla::ipc::Transport* aTransport,
base::ProcessId aOtherProcess);
PProcessHangMonitorChild*
CreateHangMonitorChild(mozilla::ipc::Transport* aTransport,
base::ProcessId aOtherProcess);
} // namespace mozilla
#endif // mozilla_ProcessHangMonitorIPC_h

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,84 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_ProcessPriorityManager_h_
#define mozilla_ProcessPriorityManager_h_
#include "mozilla/HalTypes.h"
namespace mozilla {
namespace dom {
class ContentParent;
} // namespace dom
/**
* This class sets the priority of subprocesses in response to explicit
* requests and events in the system.
*
* A process's priority changes e.g. when it goes into the background via
* mozbrowser's setVisible(false). Process priority affects CPU scheduling and
* also which processes get killed when we run out of memory.
*
* After you call Initialize(), the only thing you probably have to do is call
* SetProcessPriority on processes immediately after creating them in order to
* set their initial priority. The ProcessPriorityManager takes care of the
* rest.
*/
class ProcessPriorityManager final
{
public:
/**
* Initialize the ProcessPriorityManager machinery, causing the
* ProcessPriorityManager to actively manage the priorities of all
* subprocesses. You should call this before creating any subprocesses.
*
* You should also call this function even if you're in a child process,
* since it will initialize ProcessPriorityManagerChild.
*/
static void Init();
/**
* Set the process priority of a given ContentParent's process.
*
* Note that because this method takes a ContentParent*, you can only set the
* priority of your subprocesses. In fact, because we don't support nested
* content processes (bug 761935), you can only call this method from the
* main process.
*
* It probably only makes sense to call this function immediately after a
* process is created. At this point, the process priority manager doesn't
* have enough context about the processs to know what its priority should
* be.
*
* Eventually whatever priority you set here can and probably will be
* overwritten by the process priority manager.
*/
static void SetProcessPriority(dom::ContentParent* aContentParent,
hal::ProcessPriority aPriority);
/**
* Returns true iff this process's priority is FOREGROUND*.
*
* Note that because process priorities are set in the main process, it's
* possible for this method to return a stale value. So be careful about
* what you use this for.
*/
static bool CurrentProcessIsForeground();
/**
* Returns true if one or more processes with FOREGROUND_HIGH priority are
* present, false otherwise.
*/
static bool AnyProcessHasHighPriority();
private:
ProcessPriorityManager();
DISALLOW_EVIL_CONSTRUCTORS(ProcessPriorityManager);
};
} // namespace mozilla
#endif

View file

@ -0,0 +1,229 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "mozilla/dom/ContentParent.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/Unused.h"
#include "nsIWidget.h"
#include "nsServiceManagerUtils.h"
#include "ScreenManagerParent.h"
#include "ContentProcessManager.h"
namespace mozilla {
namespace dom {
static const char *sScreenManagerContractID = "@mozilla.org/gfx/screenmanager;1";
ScreenManagerParent::ScreenManagerParent(uint32_t* aNumberOfScreens,
float* aSystemDefaultScale,
bool* aSuccess)
{
mScreenMgr = do_GetService(sScreenManagerContractID);
if (!mScreenMgr) {
MOZ_CRASH("Couldn't get nsIScreenManager from ScreenManagerParent.");
}
Unused << RecvRefresh(aNumberOfScreens, aSystemDefaultScale, aSuccess);
}
bool
ScreenManagerParent::RecvRefresh(uint32_t* aNumberOfScreens,
float* aSystemDefaultScale,
bool* aSuccess)
{
*aSuccess = false;
nsresult rv = mScreenMgr->GetNumberOfScreens(aNumberOfScreens);
if (NS_FAILED(rv)) {
return true;
}
rv = mScreenMgr->GetSystemDefaultScale(aSystemDefaultScale);
if (NS_FAILED(rv)) {
return true;
}
*aSuccess = true;
return true;
}
bool
ScreenManagerParent::RecvScreenRefresh(const uint32_t& aId,
ScreenDetails* aRetVal,
bool* aSuccess)
{
*aSuccess = false;
nsCOMPtr<nsIScreen> screen;
nsresult rv = mScreenMgr->ScreenForId(aId, getter_AddRefs(screen));
if (NS_FAILED(rv)) {
return true;
}
ScreenDetails details;
Unused << ExtractScreenDetails(screen, details);
*aRetVal = details;
*aSuccess = true;
return true;
}
bool
ScreenManagerParent::RecvGetPrimaryScreen(ScreenDetails* aRetVal,
bool* aSuccess)
{
*aSuccess = false;
nsCOMPtr<nsIScreen> screen;
nsresult rv = mScreenMgr->GetPrimaryScreen(getter_AddRefs(screen));
NS_ENSURE_SUCCESS(rv, true);
ScreenDetails details;
if (!ExtractScreenDetails(screen, details)) {
return true;
}
*aRetVal = details;
*aSuccess = true;
return true;
}
bool
ScreenManagerParent::RecvScreenForRect(const int32_t& aLeft,
const int32_t& aTop,
const int32_t& aWidth,
const int32_t& aHeight,
ScreenDetails* aRetVal,
bool* aSuccess)
{
*aSuccess = false;
nsCOMPtr<nsIScreen> screen;
nsresult rv = mScreenMgr->ScreenForRect(aLeft, aTop, aWidth, aHeight, getter_AddRefs(screen));
NS_ENSURE_SUCCESS(rv, true);
ScreenDetails details;
if (!ExtractScreenDetails(screen, details)) {
return true;
}
*aRetVal = details;
*aSuccess = true;
return true;
}
bool
ScreenManagerParent::RecvScreenForBrowser(const TabId& aTabId,
ScreenDetails* aRetVal,
bool* aSuccess)
{
*aSuccess = false;
#ifdef MOZ_VALGRIND
// Zero this so that Valgrind doesn't complain when we send it to another
// process.
memset(aRetVal, 0, sizeof(ScreenDetails));
#endif
// Find the mWidget associated with the tabparent, and then return
// the nsIScreen it's on.
ContentParent* cp = static_cast<ContentParent*>(this->Manager());
ContentProcessManager* cpm = ContentProcessManager::GetSingleton();
RefPtr<TabParent> tabParent =
cpm->GetTopLevelTabParentByProcessAndTabId(cp->ChildID(), aTabId);
if(!tabParent){
return false;
}
nsCOMPtr<nsIWidget> widget = tabParent->GetWidget();
nsCOMPtr<nsIScreen> screen;
if (widget && widget->GetNativeData(NS_NATIVE_WINDOW)) {
mScreenMgr->ScreenForNativeWidget(widget->GetNativeData(NS_NATIVE_WINDOW),
getter_AddRefs(screen));
} else {
nsresult rv = mScreenMgr->GetPrimaryScreen(getter_AddRefs(screen));
if (NS_WARN_IF(NS_FAILED(rv))) {
return true;
}
}
NS_ENSURE_TRUE(screen, true);
ScreenDetails details;
if (!ExtractScreenDetails(screen, details)) {
return true;
}
*aRetVal = details;
*aSuccess = true;
return true;
}
bool
ScreenManagerParent::ExtractScreenDetails(nsIScreen* aScreen, ScreenDetails &aDetails)
{
if (!aScreen) {
return false;
}
uint32_t id;
nsresult rv = aScreen->GetId(&id);
NS_ENSURE_SUCCESS(rv, false);
aDetails.id() = id;
nsIntRect rect;
rv = aScreen->GetRect(&rect.x, &rect.y, &rect.width, &rect.height);
NS_ENSURE_SUCCESS(rv, false);
aDetails.rect() = rect;
nsIntRect rectDisplayPix;
rv = aScreen->GetRectDisplayPix(&rectDisplayPix.x, &rectDisplayPix.y,
&rectDisplayPix.width, &rectDisplayPix.height);
NS_ENSURE_SUCCESS(rv, false);
aDetails.rectDisplayPix() = rectDisplayPix;
nsIntRect availRect;
rv = aScreen->GetAvailRect(&availRect.x, &availRect.y, &availRect.width,
&availRect.height);
NS_ENSURE_SUCCESS(rv, false);
aDetails.availRect() = availRect;
nsIntRect availRectDisplayPix;
rv = aScreen->GetAvailRectDisplayPix(&availRectDisplayPix.x,
&availRectDisplayPix.y,
&availRectDisplayPix.width,
&availRectDisplayPix.height);
NS_ENSURE_SUCCESS(rv, false);
aDetails.availRectDisplayPix() = availRectDisplayPix;
int32_t pixelDepth = 0;
rv = aScreen->GetPixelDepth(&pixelDepth);
NS_ENSURE_SUCCESS(rv, false);
aDetails.pixelDepth() = pixelDepth;
int32_t colorDepth = 0;
rv = aScreen->GetColorDepth(&colorDepth);
NS_ENSURE_SUCCESS(rv, false);
aDetails.colorDepth() = colorDepth;
double contentsScaleFactor = 1.0;
rv = aScreen->GetContentsScaleFactor(&contentsScaleFactor);
NS_ENSURE_SUCCESS(rv, false);
aDetails.contentsScaleFactor() = contentsScaleFactor;
return true;
}
void
ScreenManagerParent::ActorDestroy(ActorDestroyReason why)
{
}
} // namespace dom
} // namespace mozilla

View file

@ -0,0 +1,56 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_ScreenManagerParent_h
#define mozilla_dom_ScreenManagerParent_h
#include "mozilla/dom/PScreenManagerParent.h"
#include "nsIScreenManager.h"
namespace mozilla {
namespace dom {
class ScreenManagerParent : public PScreenManagerParent
{
public:
ScreenManagerParent(uint32_t* aNumberOfScreens,
float* aSystemDefaultScale,
bool* aSuccess);
~ScreenManagerParent() {};
virtual bool RecvRefresh(uint32_t* aNumberOfScreens,
float* aSystemDefaultScale,
bool* aSuccess) override;
virtual bool RecvScreenRefresh(const uint32_t& aId,
ScreenDetails* aRetVal,
bool* aSuccess) override;
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
virtual bool RecvGetPrimaryScreen(ScreenDetails* aRetVal,
bool* aSuccess) override;
virtual bool RecvScreenForRect(const int32_t& aLeft,
const int32_t& aTop,
const int32_t& aWidth,
const int32_t& aHeight,
ScreenDetails* aRetVal,
bool* aSuccess) override;
virtual bool RecvScreenForBrowser(const TabId& aTabId,
ScreenDetails* aRetVal,
bool* aSuccess) override;
private:
bool ExtractScreenDetails(nsIScreen* aScreen, ScreenDetails &aDetails);
nsCOMPtr<nsIScreenManager> mScreenMgr;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ScreenManagerParent_h

View file

@ -0,0 +1,18 @@
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
/* vim: set sw=4 ts=8 et tw=80 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 ServiceWorkerRegistrarTypes;
namespace mozilla {
namespace dom {
struct ServiceWorkerConfiguration
{
ServiceWorkerRegistrationData[] serviceWorkerRegistrations;
};
} // namespace dom
} // namespace mozilla

View file

@ -0,0 +1,133 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "StructuredCloneData.h"
#include "nsIDOMDOMException.h"
#include "nsIMutable.h"
#include "nsIXPConnect.h"
#include "ipc/IPCMessageUtils.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/ToJSValue.h"
#include "nsContentUtils.h"
#include "nsJSEnvironment.h"
#include "MainThreadUtils.h"
#include "StructuredCloneTags.h"
#include "jsapi.h"
namespace mozilla {
namespace dom {
namespace ipc {
bool
StructuredCloneData::Copy(const StructuredCloneData& aData)
{
if (!aData.mInitialized) {
return true;
}
if (aData.SharedData()) {
mSharedData = aData.SharedData();
} else {
mSharedData =
SharedJSAllocatedData::CreateFromExternalData(aData.Data());
NS_ENSURE_TRUE(mSharedData, false);
}
PortIdentifiers().AppendElements(aData.PortIdentifiers());
MOZ_ASSERT(BlobImpls().IsEmpty());
BlobImpls().AppendElements(aData.BlobImpls());
MOZ_ASSERT(GetSurfaces().IsEmpty());
MOZ_ASSERT(WasmModules().IsEmpty());
mInitialized = true;
return true;
}
void
StructuredCloneData::Read(JSContext* aCx,
JS::MutableHandle<JS::Value> aValue,
ErrorResult &aRv)
{
MOZ_ASSERT(mInitialized);
nsIGlobalObject *global = xpc::NativeGlobal(JS::CurrentGlobalOrNull(aCx));
MOZ_ASSERT(global);
ReadFromBuffer(global, aCx, Data(), aValue, aRv);
}
void
StructuredCloneData::Write(JSContext* aCx,
JS::Handle<JS::Value> aValue,
ErrorResult &aRv)
{
Write(aCx, aValue, JS::UndefinedHandleValue, aRv);
}
void
StructuredCloneData::Write(JSContext* aCx,
JS::Handle<JS::Value> aValue,
JS::Handle<JS::Value> aTransfer,
ErrorResult &aRv)
{
MOZ_ASSERT(!mInitialized);
StructuredCloneHolder::Write(aCx, aValue, aTransfer,
JS::CloneDataPolicy().denySharedArrayBuffer(), aRv);
if (NS_WARN_IF(aRv.Failed())) {
return;
}
JSStructuredCloneData data;
mBuffer->abandon();
mBuffer->steal(&data);
mBuffer = nullptr;
mSharedData = new SharedJSAllocatedData(Move(data));
mInitialized = true;
}
void
StructuredCloneData::WriteIPCParams(IPC::Message* aMsg) const
{
WriteParam(aMsg, Data());
}
bool
StructuredCloneData::ReadIPCParams(const IPC::Message* aMsg,
PickleIterator* aIter)
{
MOZ_ASSERT(!mInitialized);
JSStructuredCloneData data;
if (!ReadParam(aMsg, aIter, &data)) {
return false;
}
mSharedData = new SharedJSAllocatedData(Move(data));
mInitialized = true;
return true;
}
bool
StructuredCloneData::CopyExternalData(const char* aData,
size_t aDataLength)
{
MOZ_ASSERT(!mInitialized);
mSharedData = SharedJSAllocatedData::CreateFromExternalData(aData,
aDataLength);
NS_ENSURE_TRUE(mSharedData, false);
mInitialized = true;
return true;
}
} // namespace ipc
} // namespace dom
} // namespace mozilla

View file

@ -0,0 +1,160 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_ipc_StructuredCloneData_h
#define mozilla_dom_ipc_StructuredCloneData_h
#include <algorithm>
#include "mozilla/RefPtr.h"
#include "mozilla/dom/StructuredCloneHolder.h"
#include "nsISupportsImpl.h"
namespace IPC {
class Message;
}
class PickleIterator;
namespace mozilla {
namespace dom {
namespace ipc {
class SharedJSAllocatedData final
{
public:
explicit SharedJSAllocatedData(JSStructuredCloneData&& aData)
: mData(Move(aData))
{ }
static already_AddRefed<SharedJSAllocatedData>
CreateFromExternalData(const char* aData, size_t aDataLength)
{
JSStructuredCloneData buf;
buf.WriteBytes(aData, aDataLength);
RefPtr<SharedJSAllocatedData> sharedData =
new SharedJSAllocatedData(Move(buf));
return sharedData.forget();
}
static already_AddRefed<SharedJSAllocatedData>
CreateFromExternalData(const JSStructuredCloneData& aData)
{
JSStructuredCloneData buf;
auto iter = aData.Iter();
while (!iter.Done()) {
buf.WriteBytes(iter.Data(), iter.RemainingInSegment());
iter.Advance(aData, iter.RemainingInSegment());
}
RefPtr<SharedJSAllocatedData> sharedData =
new SharedJSAllocatedData(Move(buf));
return sharedData.forget();
}
NS_INLINE_DECL_REFCOUNTING(SharedJSAllocatedData)
JSStructuredCloneData& Data() { return mData; }
size_t DataLength() const { return mData.Size(); }
private:
~SharedJSAllocatedData() { }
JSStructuredCloneData mData;
};
class StructuredCloneData : public StructuredCloneHolder
{
public:
StructuredCloneData()
: StructuredCloneHolder(StructuredCloneHolder::CloningSupported,
StructuredCloneHolder::TransferringSupported,
StructuredCloneHolder::StructuredCloneScope::DifferentProcess)
, mInitialized(false)
{}
StructuredCloneData(const StructuredCloneData&) = delete;
StructuredCloneData(StructuredCloneData&& aOther) = default;
~StructuredCloneData()
{}
StructuredCloneData&
operator=(const StructuredCloneData& aOther) = delete;
StructuredCloneData&
operator=(StructuredCloneData&& aOther) = default;
const nsTArray<RefPtr<BlobImpl>>& BlobImpls() const
{
return mBlobImplArray;
}
nsTArray<RefPtr<BlobImpl>>& BlobImpls()
{
return mBlobImplArray;
}
bool Copy(const StructuredCloneData& aData);
void Read(JSContext* aCx,
JS::MutableHandle<JS::Value> aValue,
ErrorResult &aRv);
void Write(JSContext* aCx,
JS::Handle<JS::Value> aValue,
ErrorResult &aRv);
void Write(JSContext* aCx,
JS::Handle<JS::Value> aValue,
JS::Handle<JS::Value> aTransfers,
ErrorResult &aRv);
bool UseExternalData(const JSStructuredCloneData& aData)
{
auto iter = aData.Iter();
bool success = false;
mExternalData =
aData.Borrow<js::SystemAllocPolicy>(iter, aData.Size(), &success);
mInitialized = true;
return success;
}
bool CopyExternalData(const char* aData, size_t aDataLength);
JSStructuredCloneData& Data()
{
return mSharedData ? mSharedData->Data() : mExternalData;
}
const JSStructuredCloneData& Data() const
{
return mSharedData ? mSharedData->Data() : mExternalData;
}
size_t DataLength() const
{
return mSharedData ? mSharedData->DataLength() : mExternalData.Size();
}
SharedJSAllocatedData* SharedData() const
{
return mSharedData;
}
// For IPC serialization
void WriteIPCParams(IPC::Message* aMessage) const;
bool ReadIPCParams(const IPC::Message* aMessage, PickleIterator* aIter);
private:
JSStructuredCloneData mExternalData;
RefPtr<SharedJSAllocatedData> mSharedData;
bool mInitialized;
};
} // namespace ipc
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_ipc_StructuredCloneData_h

3371
dom/ipc/TabChild.cpp Normal file

File diff suppressed because it is too large Load diff

818
dom/ipc/TabChild.h Normal file
View file

@ -0,0 +1,818 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_TabChild_h
#define mozilla_dom_TabChild_h
#include "mozilla/dom/PBrowserChild.h"
#include "nsIWebNavigation.h"
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsIWebBrowserChrome2.h"
#include "nsIEmbeddingSiteWindow.h"
#include "nsIWebBrowserChromeFocus.h"
#include "nsIDOMEventListener.h"
#include "nsIInterfaceRequestor.h"
#include "nsIWindowProvider.h"
#include "nsIDOMWindow.h"
#include "nsIDocShell.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsFrameMessageManager.h"
#include "nsIPresShell.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsWeakReference.h"
#include "nsITabChild.h"
#include "nsITooltipListener.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/TabContext.h"
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/EventDispatcher.h"
#include "mozilla/EventForwards.h"
#include "mozilla/layers/CompositorTypes.h"
#include "mozilla/layers/APZCCallbackHelper.h"
#include "nsIWebBrowserChrome3.h"
#include "mozilla/dom/ipc/IdType.h"
#include "AudioChannelService.h"
#include "PuppetWidget.h"
#include "mozilla/layers/GeckoContentController.h"
#include "nsISHistoryListener.h"
#include "nsIPartialSHistoryListener.h"
class nsIDOMWindowUtils;
class nsIHttpChannel;
namespace mozilla {
namespace layout {
class RenderFrameChild;
} // namespace layout
namespace layers {
class APZChild;
class APZEventState;
class AsyncDragMetrics;
class IAPZCTreeManager;
class ImageCompositeNotification;
} // namespace layers
namespace widget {
struct AutoCacheNativeKeyCommands;
} // namespace widget
namespace plugins {
class PluginWidgetChild;
} // namespace plugins
namespace dom {
class TabChild;
class ClonedMessageData;
class TabChildBase;
class TabChildGlobal : public DOMEventTargetHelper,
public nsIContentFrameMessageManager,
public nsIScriptObjectPrincipal,
public nsIGlobalObject,
public nsSupportsWeakReference
{
public:
explicit TabChildGlobal(TabChildBase* aTabChild);
void Init();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TabChildGlobal, DOMEventTargetHelper)
NS_FORWARD_SAFE_NSIMESSAGELISTENERMANAGER(mMessageManager)
NS_FORWARD_SAFE_NSIMESSAGESENDER(mMessageManager)
NS_FORWARD_SAFE_NSIMESSAGEMANAGERGLOBAL(mMessageManager)
NS_IMETHOD SendSyncMessage(const nsAString& aMessageName,
JS::Handle<JS::Value> aObject,
JS::Handle<JS::Value> aRemote,
nsIPrincipal* aPrincipal,
JSContext* aCx,
uint8_t aArgc,
JS::MutableHandle<JS::Value> aRetval) override
{
return mMessageManager
? mMessageManager->SendSyncMessage(aMessageName, aObject, aRemote,
aPrincipal, aCx, aArgc, aRetval)
: NS_ERROR_NULL_POINTER;
}
NS_IMETHOD SendRpcMessage(const nsAString& aMessageName,
JS::Handle<JS::Value> aObject,
JS::Handle<JS::Value> aRemote,
nsIPrincipal* aPrincipal,
JSContext* aCx,
uint8_t aArgc,
JS::MutableHandle<JS::Value> aRetval) override
{
return mMessageManager
? mMessageManager->SendRpcMessage(aMessageName, aObject, aRemote,
aPrincipal, aCx, aArgc, aRetval)
: NS_ERROR_NULL_POINTER;
}
NS_IMETHOD GetContent(mozIDOMWindowProxy** aContent) override;
NS_IMETHOD GetDocShell(nsIDocShell** aDocShell) override;
nsresult AddEventListener(const nsAString& aType,
nsIDOMEventListener* aListener,
bool aUseCapture)
{
// By default add listeners only for trusted events!
return DOMEventTargetHelper::AddEventListener(aType, aListener,
aUseCapture, false, 2);
}
using DOMEventTargetHelper::AddEventListener;
NS_IMETHOD AddEventListener(const nsAString& aType,
nsIDOMEventListener* aListener,
bool aUseCapture, bool aWantsUntrusted,
uint8_t optional_argc) override
{
return DOMEventTargetHelper::AddEventListener(aType, aListener,
aUseCapture,
aWantsUntrusted,
optional_argc);
}
nsresult
PreHandleEvent(EventChainPreVisitor& aVisitor) override
{
aVisitor.mForceContentDispatch = true;
return NS_OK;
}
virtual nsIPrincipal* GetPrincipal() override;
virtual JSObject* GetGlobalJSObject() override;
virtual JSObject* WrapObject(JSContext* cx, JS::Handle<JSObject*> aGivenProto) override
{
MOZ_CRASH("TabChildGlobal doesn't use DOM bindings!");
}
nsCOMPtr<nsIContentFrameMessageManager> mMessageManager;
RefPtr<TabChildBase> mTabChild;
protected:
~TabChildGlobal();
};
class ContentListener final : public nsIDOMEventListener
{
public:
explicit ContentListener(TabChild* aTabChild) : mTabChild(aTabChild) {}
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMEVENTLISTENER
protected:
~ContentListener() {}
TabChild* mTabChild;
};
/**
* Listens on session history change, and sends NotifySessionHistoryChange to
* parent process.
*/
class TabChildSHistoryListener final : public nsISHistoryListener,
public nsIPartialSHistoryListener,
public nsSupportsWeakReference
{
public:
explicit TabChildSHistoryListener(TabChild* aTabChild) : mTabChild(aTabChild) {}
void ClearTabChild() { mTabChild = nullptr; }
NS_DECL_ISUPPORTS
NS_DECL_NSISHISTORYLISTENER
NS_DECL_NSIPARTIALSHISTORYLISTENER
private:
~TabChildSHistoryListener() {}
TabChild* mTabChild;
};
// This is base clase which helps to share Viewport and touch related
// functionality between b2g/android FF/embedlite clients implementation.
// It make sense to place in this class all helper functions, and functionality
// which could be shared between Cross-process/Cross-thread implmentations.
class TabChildBase : public nsISupports,
public nsMessageManagerScriptExecutor,
public ipc::MessageManagerCallback
{
protected:
typedef mozilla::widget::PuppetWidget PuppetWidget;
public:
TabChildBase();
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(TabChildBase)
virtual nsIWebNavigation* WebNavigation() const = 0;
virtual PuppetWidget* WebWidget() = 0;
nsIPrincipal* GetPrincipal() { return mPrincipal; }
virtual bool DoUpdateZoomConstraints(const uint32_t& aPresShellId,
const mozilla::layers::FrameMetrics::ViewID& aViewId,
const Maybe<mozilla::layers::ZoomConstraints>& aConstraints) = 0;
virtual ScreenIntSize GetInnerSize() = 0;
// Get the Document for the top-level window in this tab.
already_AddRefed<nsIDocument> GetDocument() const;
// Get the pres-shell of the document for the top-level window in this tab.
already_AddRefed<nsIPresShell> GetPresShell() const;
protected:
virtual ~TabChildBase();
// Wraps up a JSON object as a structured clone and sends it to the browser
// chrome script.
//
// XXX/bug 780335: Do the work the browser chrome script does in C++ instead
// so we don't need things like this.
void DispatchMessageManagerMessage(const nsAString& aMessageName,
const nsAString& aJSONData);
void ProcessUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
bool UpdateFrameHandler(const mozilla::layers::FrameMetrics& aFrameMetrics);
protected:
RefPtr<TabChildGlobal> mTabChildGlobal;
nsCOMPtr<nsIWebBrowserChrome3> mWebBrowserChrome;
};
class TabChild final : public TabChildBase,
public PBrowserChild,
public nsIWebBrowserChrome2,
public nsIEmbeddingSiteWindow,
public nsIWebBrowserChromeFocus,
public nsIInterfaceRequestor,
public nsIWindowProvider,
public nsSupportsWeakReference,
public nsITabChild,
public nsIObserver,
public TabContext,
public nsITooltipListener,
public mozilla::ipc::IShmemAllocator
{
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
typedef mozilla::layout::RenderFrameChild RenderFrameChild;
typedef mozilla::layers::APZEventState APZEventState;
typedef mozilla::layers::SetAllowedTouchBehaviorCallback SetAllowedTouchBehaviorCallback;
public:
/**
* Find TabChild of aTabId in the same content process of the
* caller.
*/
static already_AddRefed<TabChild> FindTabChild(const TabId& aTabId);
// Return a list of all active TabChildren.
static nsTArray<RefPtr<TabChild>> GetAll();
public:
/**
* Create a new TabChild object.
*/
TabChild(nsIContentChild* aManager,
const TabId& aTabId,
const TabContext& aContext,
uint32_t aChromeFlags);
nsresult Init();
/**
* This is expected to be called off the critical path to content
* startup. This is an opportunity to load things that are slow
* on the critical path.
*/
static void PreloadSlowThings();
/** Return a TabChild with the given attributes. */
static already_AddRefed<TabChild>
Create(nsIContentChild* aManager, const TabId& aTabId,
const TabContext& aContext, uint32_t aChromeFlags);
// Let managees query if it is safe to send messages.
bool IsDestroyed() const{ return mDestroyed; }
const TabId GetTabId() const
{
MOZ_ASSERT(mUniqueId != 0);
return mUniqueId;
}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIWEBBROWSERCHROME
NS_DECL_NSIWEBBROWSERCHROME2
NS_DECL_NSIEMBEDDINGSITEWINDOW
NS_DECL_NSIWEBBROWSERCHROMEFOCUS
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSIWINDOWPROVIDER
NS_DECL_NSITABCHILD
NS_DECL_NSIOBSERVER
NS_DECL_NSITOOLTIPLISTENER
FORWARD_SHMEM_ALLOCATOR_TO(PBrowserChild)
/**
* MessageManagerCallback methods that we override.
*/
virtual bool DoSendBlockingMessage(JSContext* aCx,
const nsAString& aMessage,
StructuredCloneData& aData,
JS::Handle<JSObject *> aCpows,
nsIPrincipal* aPrincipal,
nsTArray<StructuredCloneData>* aRetVal,
bool aIsSync) override;
virtual nsresult DoSendAsyncMessage(JSContext* aCx,
const nsAString& aMessage,
StructuredCloneData& aData,
JS::Handle<JSObject *> aCpows,
nsIPrincipal* aPrincipal) override;
virtual bool
DoUpdateZoomConstraints(const uint32_t& aPresShellId,
const ViewID& aViewId,
const Maybe<ZoomConstraints>& aConstraints) override;
virtual bool RecvLoadURL(const nsCString& aURI,
const ShowInfo& aInfo) override;
virtual bool
RecvShow(const ScreenIntSize& aSize,
const ShowInfo& aInfo,
const TextureFactoryIdentifier& aTextureFactoryIdentifier,
const uint64_t& aLayersId,
PRenderFrameChild* aRenderFrame,
const bool& aParentIsActive,
const nsSizeMode& aSizeMode) override;
virtual bool
RecvUpdateDimensions(const CSSRect& aRect,
const CSSSize& aSize,
const ScreenOrientationInternal& aOrientation,
const LayoutDeviceIntPoint& aClientOffset,
const LayoutDeviceIntPoint& aChromeDisp) override;
virtual bool
RecvSizeModeChanged(const nsSizeMode& aSizeMode) override;
virtual bool RecvActivate() override;
virtual bool RecvDeactivate() override;
virtual bool RecvMouseEvent(const nsString& aType,
const float& aX,
const float& aY,
const int32_t& aButton,
const int32_t& aClickCount,
const int32_t& aModifiers,
const bool& aIgnoreRootScrollFrame) override;
virtual bool RecvRealMouseMoveEvent(const mozilla::WidgetMouseEvent& aEvent,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId) override;
virtual bool RecvSynthMouseMoveEvent(const mozilla::WidgetMouseEvent& aEvent,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId) override;
virtual bool RecvRealMouseButtonEvent(const mozilla::WidgetMouseEvent& aEvent,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId) override;
virtual bool RecvRealDragEvent(const WidgetDragEvent& aEvent,
const uint32_t& aDragAction,
const uint32_t& aDropEffect) override;
virtual bool
RecvRealKeyEvent(const mozilla::WidgetKeyboardEvent& aEvent,
const MaybeNativeKeyBinding& aBindings) override;
virtual bool RecvMouseWheelEvent(const mozilla::WidgetWheelEvent& aEvent,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId) override;
virtual bool RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId,
const nsEventStatus& aApzResponse) override;
virtual bool
RecvRealTouchMoveEvent(const WidgetTouchEvent& aEvent,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId,
const nsEventStatus& aApzResponse) override;
virtual bool RecvKeyEvent(const nsString& aType,
const int32_t& aKeyCode,
const int32_t& aCharCode,
const int32_t& aModifiers,
const bool& aPreventDefault) override;
virtual bool RecvNativeSynthesisResponse(const uint64_t& aObserverId,
const nsCString& aResponse) override;
virtual bool RecvPluginEvent(const WidgetPluginEvent& aEvent) override;
virtual bool
RecvCompositionEvent(const mozilla::WidgetCompositionEvent& aEvent) override;
virtual bool
RecvSelectionEvent(const mozilla::WidgetSelectionEvent& aEvent) override;
virtual bool
RecvPasteTransferable(const IPCDataTransfer& aDataTransfer,
const bool& aIsPrivateData,
const IPC::Principal& aRequestingPrincipal) override;
virtual bool
RecvActivateFrameEvent(const nsString& aType, const bool& aCapture) override;
virtual bool RecvLoadRemoteScript(const nsString& aURL,
const bool& aRunInGlobalScope) override;
virtual bool RecvAsyncMessage(const nsString& aMessage,
InfallibleTArray<CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
const ClonedMessageData& aData) override;
virtual bool
RecvSwappedWithOtherRemoteLoader(const IPCTabContext& aContext) override;
virtual PDocAccessibleChild*
AllocPDocAccessibleChild(PDocAccessibleChild*, const uint64_t&,
const uint32_t&, const IAccessibleHolder&) override;
virtual bool DeallocPDocAccessibleChild(PDocAccessibleChild*) override;
virtual PDocumentRendererChild*
AllocPDocumentRendererChild(const nsRect& aDocumentRect,
const gfx::Matrix& aTransform,
const nsString& aBggcolor,
const uint32_t& aRenderFlags,
const bool& aFlushLayout,
const nsIntSize& arenderSize) override;
virtual bool
DeallocPDocumentRendererChild(PDocumentRendererChild* aCctor) override;
virtual bool
RecvPDocumentRendererConstructor(PDocumentRendererChild* aActor,
const nsRect& aDocumentRect,
const gfx::Matrix& aTransform,
const nsString& aBgcolor,
const uint32_t& aRenderFlags,
const bool& aFlushLayout,
const nsIntSize& aRenderSize) override;
virtual PColorPickerChild*
AllocPColorPickerChild(const nsString& aTitle,
const nsString& aInitialColor) override;
virtual bool DeallocPColorPickerChild(PColorPickerChild* aActor) override;
virtual PDatePickerChild*
AllocPDatePickerChild(const nsString& title, const nsString& initialDate) override;
virtual bool DeallocPDatePickerChild(PDatePickerChild* actor) override;
virtual PFilePickerChild*
AllocPFilePickerChild(const nsString& aTitle, const int16_t& aMode) override;
virtual bool
DeallocPFilePickerChild(PFilePickerChild* aActor) override;
virtual PIndexedDBPermissionRequestChild*
AllocPIndexedDBPermissionRequestChild(const Principal& aPrincipal) override;
virtual bool
DeallocPIndexedDBPermissionRequestChild(PIndexedDBPermissionRequestChild* aActor) override;
virtual nsIWebNavigation* WebNavigation() const override
{
return mWebNav;
}
virtual PuppetWidget* WebWidget() override { return mPuppetWidget; }
/** Return the DPI of the widget this TabChild draws to. */
void GetDPI(float* aDPI);
void GetDefaultScale(double *aScale);
void GetWidgetRounding(int32_t* aRounding);
bool IsTransparent() const { return mIsTransparent; }
void GetMaxTouchPoints(uint32_t* aTouchPoints);
ScreenOrientationInternal GetOrientation() const { return mOrientation; }
void SetBackgroundColor(const nscolor& aColor);
void NotifyPainted();
void RequestNativeKeyBindings(mozilla::widget::AutoCacheNativeKeyCommands* aAutoCache,
const WidgetKeyboardEvent* aEvent);
/**
* Signal to this TabChild that it should be made visible:
* activated widget, retained layer tree, etc. (Respectively,
* made not visible.)
*/
void MakeVisible();
void MakeHidden();
nsIContentChild* Manager() const { return mManager; }
static inline TabChild*
GetFrom(nsIDocShell* aDocShell)
{
if (!aDocShell) {
return nullptr;
}
nsCOMPtr<nsITabChild> tc = aDocShell->GetTabChild();
return static_cast<TabChild*>(tc.get());
}
static inline TabChild*
GetFrom(mozIDOMWindow* aWindow)
{
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(webNav);
return GetFrom(docShell);
}
static inline TabChild*
GetFrom(mozIDOMWindowProxy* aWindow)
{
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(webNav);
return GetFrom(docShell);
}
static TabChild* GetFrom(nsIPresShell* aPresShell);
static TabChild* GetFrom(uint64_t aLayersId);
uint64_t LayersId() { return mLayersId; }
void DidComposite(uint64_t aTransactionId,
const TimeStamp& aCompositeStart,
const TimeStamp& aCompositeEnd);
void DidRequestComposite(const TimeStamp& aCompositeReqStart,
const TimeStamp& aCompositeReqEnd);
void ClearCachedResources();
void InvalidateLayers();
void ReinitRendering();
void CompositorUpdated(const TextureFactoryIdentifier& aNewIdentifier);
static inline TabChild* GetFrom(nsIDOMWindow* aWindow)
{
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(webNav);
return GetFrom(docShell);
}
virtual bool RecvUIResolutionChanged(const float& aDpi,
const int32_t& aRounding,
const double& aScale) override;
virtual bool
RecvThemeChanged(nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache) override;
virtual bool RecvHandleAccessKey(const WidgetKeyboardEvent& aEvent,
nsTArray<uint32_t>&& aCharCodes,
const int32_t& aModifierMask) override;
virtual bool RecvAudioChannelChangeNotification(const uint32_t& aAudioChannel,
const float& aVolume,
const bool& aMuted) override;
virtual bool RecvSetUseGlobalHistory(const bool& aUse) override;
virtual bool RecvHandledWindowedPluginKeyEvent(
const mozilla::NativeEventData& aKeyEventData,
const bool& aIsConsumed) override;
virtual bool RecvPrint(const uint64_t& aOuterWindowID,
const PrintData& aPrintData) override;
virtual bool RecvUpdateNativeWindowHandle(const uintptr_t& aNewHandle) override;
/**
* Native widget remoting protocol for use with windowed plugins with e10s.
*/
PPluginWidgetChild* AllocPPluginWidgetChild() override;
bool DeallocPPluginWidgetChild(PPluginWidgetChild* aActor) override;
nsresult CreatePluginWidget(nsIWidget* aParent, nsIWidget** aOut);
LayoutDeviceIntPoint GetClientOffset() const { return mClientOffset; }
LayoutDeviceIntPoint GetChromeDisplacement() const { return mChromeDisp; };
bool IPCOpen() const { return mIPCOpen; }
bool ParentIsActive() const
{
return mParentIsActive;
}
bool AsyncPanZoomEnabled() const { return mAsyncPanZoomEnabled; }
virtual ScreenIntSize GetInnerSize() override;
// Call RecvShow(nsIntSize(0, 0)) and block future calls to RecvShow().
void DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
const uint64_t& aLayersId,
PRenderFrameChild* aRenderFrame,
const ShowInfo& aShowInfo);
void ContentReceivedInputBlock(const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId,
bool aPreventDefault) const;
void SetTargetAPZC(uint64_t aInputBlockId,
const nsTArray<ScrollableLayerGuid>& aTargets) const;
bool RecvHandleTap(const layers::GeckoContentController::TapType& aType,
const LayoutDevicePoint& aPoint,
const Modifiers& aModifiers,
const ScrollableLayerGuid& aGuid,
const uint64_t& aInputBlockId) override;
void SetAllowedTouchBehavior(uint64_t aInputBlockId,
const nsTArray<TouchBehaviorFlags>& aFlags) const;
bool UpdateFrame(const FrameMetrics& aFrameMetrics);
bool NotifyAPZStateChange(const ViewID& aViewId,
const layers::GeckoContentController::APZStateChange& aChange,
const int& aArg);
void StartScrollbarDrag(const layers::AsyncDragMetrics& aDragMetrics);
void ZoomToRect(const uint32_t& aPresShellId,
const FrameMetrics::ViewID& aViewId,
const CSSRect& aRect,
const uint32_t& aFlags);
// Request that the docshell be marked as active.
void ForcePaint(uint64_t aLayerObserverEpoch);
#if defined(XP_WIN) && defined(ACCESSIBILITY)
uintptr_t GetNativeWindowHandle() const { return mNativeWindowHandle; }
#endif
bool TakeIsFreshProcess()
{
bool wasFreshProcess = mIsFreshProcess;
mIsFreshProcess = false;
return wasFreshProcess;
}
protected:
virtual ~TabChild();
virtual PRenderFrameChild* AllocPRenderFrameChild() override;
virtual bool DeallocPRenderFrameChild(PRenderFrameChild* aFrame) override;
virtual bool RecvDestroy() override;
virtual bool RecvSetDocShellIsActive(const bool& aIsActive,
const bool& aIsHidden,
const uint64_t& aLayerObserverEpoch) override;
virtual bool RecvNavigateByKey(const bool& aForward,
const bool& aForDocumentNavigation) override;
virtual bool RecvRequestNotifyAfterRemotePaint() override;
virtual bool RecvSuppressDisplayport(const bool& aEnabled) override;
virtual bool RecvParentActivated(const bool& aActivated) override;
virtual bool RecvSetKeyboardIndicators(const UIStateChangeType& aShowAccelerators,
const UIStateChangeType& aShowFocusRings) override;
virtual bool RecvStopIMEStateManagement() override;
virtual bool RecvMenuKeyboardListenerInstalled(
const bool& aInstalled) override;
virtual bool RecvNotifyAttachGroupedSessionHistory(const uint32_t& aOffset) override;
virtual bool RecvNotifyPartialSessionHistoryActive(const uint32_t& aGlobalLength,
const uint32_t& aTargetLocalIndex) override;
virtual bool RecvNotifyPartialSessionHistoryDeactive() override;
virtual bool RecvSetFreshProcess() override;
private:
void HandleDoubleTap(const CSSPoint& aPoint, const Modifiers& aModifiers,
const ScrollableLayerGuid& aGuid);
// Notify others that our TabContext has been updated.
//
// You should call this after calling TabContext::SetTabContext(). We also
// call this during Init().
//
// @param aIsPreallocated true if this is called for Preallocated Tab.
void NotifyTabContextUpdated(bool aIsPreallocated);
// Update the frameType on our docshell.
void UpdateFrameType();
void ActorDestroy(ActorDestroyReason why) override;
enum FrameScriptLoading { DONT_LOAD_SCRIPTS, DEFAULT_LOAD_SCRIPTS };
bool InitTabChildGlobal(FrameScriptLoading aScriptLoading = DEFAULT_LOAD_SCRIPTS);
bool InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
const uint64_t& aLayersId,
PRenderFrameChild* aRenderFrame);
void DestroyWindow();
void SetProcessNameToAppName();
void ApplyShowInfo(const ShowInfo& aInfo);
bool HasValidInnerSize();
void SetTabId(const TabId& aTabId);
ScreenIntRect GetOuterRect();
void SetUnscaledInnerSize(const CSSSize& aSize)
{
mUnscaledInnerSize = aSize;
}
class DelayedDeleteRunnable;
TextureFactoryIdentifier mTextureFactoryIdentifier;
nsCOMPtr<nsIWebNavigation> mWebNav;
RefPtr<PuppetWidget> mPuppetWidget;
nsCOMPtr<nsIURI> mLastURI;
RenderFrameChild* mRemoteFrame;
RefPtr<nsIContentChild> mManager;
RefPtr<TabChildSHistoryListener> mHistoryListener;
uint32_t mChromeFlags;
int32_t mActiveSuppressDisplayport;
uint64_t mLayersId;
CSSRect mUnscaledOuterRect;
nscolor mLastBackgroundColor;
bool mDidFakeShow;
bool mNotified;
bool mTriedBrowserInit;
ScreenOrientationInternal mOrientation;
bool mIgnoreKeyPressEvent;
RefPtr<APZEventState> mAPZEventState;
SetAllowedTouchBehaviorCallback mSetAllowedTouchBehaviorCallback;
bool mHasValidInnerSize;
bool mDestroyed;
// Position of client area relative to the outer window
LayoutDeviceIntPoint mClientOffset;
// Position of tab, relative to parent widget (typically the window)
LayoutDeviceIntPoint mChromeDisp;
TabId mUniqueId;
friend class ContentChild;
float mDPI;
int32_t mRounding;
double mDefaultScale;
bool mIsTransparent;
bool mIPCOpen;
bool mParentIsActive;
bool mAsyncPanZoomEnabled;
CSSSize mUnscaledInnerSize;
bool mDidSetRealShowInfo;
bool mDidLoadURLInit;
bool mIsFreshProcess;
AutoTArray<bool, NUMBER_OF_AUDIO_CHANNELS> mAudioChannelsActive;
RefPtr<layers::IAPZCTreeManager> mApzcTreeManager;
// APZChild clears this pointer from its destructor, so it shouldn't be a
// dangling pointer.
layers::APZChild* mAPZChild;
// The most recently seen layer observer epoch in RecvSetDocShellIsActive.
uint64_t mLayerObserverEpoch;
#if defined(XP_WIN) && defined(ACCESSIBILITY)
// The handle associated with the native window that contains this tab
uintptr_t mNativeWindowHandle;
#endif // defined(XP_WIN)
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_TabChild_h

434
dom/ipc/TabContext.cpp Normal file
View file

@ -0,0 +1,434 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "mozilla/dom/TabContext.h"
#include "mozilla/dom/PTabContext.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/dom/TabChild.h"
#include "nsIAppsService.h"
#include "nsIScriptSecurityManager.h"
#include "nsServiceManagerUtils.h"
#define NO_APP_ID (nsIScriptSecurityManager::NO_APP_ID)
using namespace mozilla::dom::ipc;
using namespace mozilla::layout;
namespace mozilla {
namespace dom {
TabContext::TabContext()
: mIsPrerendered(false)
, mInitialized(false)
, mIsMozBrowserElement(false)
, mContainingAppId(NO_APP_ID)
, mShowAccelerators(UIStateChangeType_NoChange)
, mShowFocusRings(UIStateChangeType_NoChange)
{
}
bool
TabContext::IsMozBrowserElement() const
{
return mIsMozBrowserElement;
}
bool
TabContext::IsIsolatedMozBrowserElement() const
{
return mOriginAttributes.mInIsolatedMozBrowser;
}
bool
TabContext::IsMozBrowserOrApp() const
{
return HasOwnApp() || IsMozBrowserElement();
}
uint32_t
TabContext::OwnAppId() const
{
return mOriginAttributes.mAppId;
}
already_AddRefed<mozIApplication>
TabContext::GetOwnApp() const
{
nsCOMPtr<mozIApplication> ownApp = mOwnApp;
return ownApp.forget();
}
bool
TabContext::HasOwnApp() const
{
nsCOMPtr<mozIApplication> ownApp = GetOwnApp();
return !!ownApp;
}
uint32_t
TabContext::BrowserOwnerAppId() const
{
if (IsMozBrowserElement()) {
return mContainingAppId;
}
return NO_APP_ID;
}
already_AddRefed<mozIApplication>
TabContext::GetBrowserOwnerApp() const
{
nsCOMPtr<mozIApplication> ownerApp;
if (IsMozBrowserElement()) {
ownerApp = mContainingApp;
}
return ownerApp.forget();
}
bool
TabContext::HasBrowserOwnerApp() const
{
nsCOMPtr<mozIApplication> ownerApp = GetBrowserOwnerApp();
return !!ownerApp;
}
uint32_t
TabContext::AppOwnerAppId() const
{
if (HasOwnApp()) {
return mContainingAppId;
}
return NO_APP_ID;
}
already_AddRefed<mozIApplication>
TabContext::GetAppOwnerApp() const
{
nsCOMPtr<mozIApplication> ownerApp;
if (HasOwnApp()) {
ownerApp = mContainingApp;
}
return ownerApp.forget();
}
bool
TabContext::HasAppOwnerApp() const
{
nsCOMPtr<mozIApplication> ownerApp = GetAppOwnerApp();
return !!ownerApp;
}
uint32_t
TabContext::OwnOrContainingAppId() const
{
if (HasOwnApp()) {
return mOriginAttributes.mAppId;
}
return mContainingAppId;
}
already_AddRefed<mozIApplication>
TabContext::GetOwnOrContainingApp() const
{
nsCOMPtr<mozIApplication> ownOrContainingApp;
if (HasOwnApp()) {
ownOrContainingApp = mOwnApp;
} else {
ownOrContainingApp = mContainingApp;
}
return ownOrContainingApp.forget();
}
bool
TabContext::HasOwnOrContainingApp() const
{
nsCOMPtr<mozIApplication> ownOrContainingApp = GetOwnOrContainingApp();
return !!ownOrContainingApp;
}
bool
TabContext::SetTabContext(const TabContext& aContext)
{
NS_ENSURE_FALSE(mInitialized, false);
*this = aContext;
mInitialized = true;
return true;
}
void
TabContext::SetPrivateBrowsingAttributes(bool aIsPrivateBrowsing)
{
mOriginAttributes.SyncAttributesWithPrivateBrowsing(aIsPrivateBrowsing);
}
bool
TabContext::UpdateTabContextAfterSwap(const TabContext& aContext)
{
// This is only used after already initialized.
MOZ_ASSERT(mInitialized);
// The only permissable change is to `mIsMozBrowserElement`. All other fields
// must match for the change to be accepted.
if (aContext.OwnAppId() != OwnAppId() ||
aContext.mContainingAppId != mContainingAppId ||
aContext.mOriginAttributes != mOriginAttributes) {
return false;
}
mIsMozBrowserElement = aContext.mIsMozBrowserElement;
return true;
}
const DocShellOriginAttributes&
TabContext::OriginAttributesRef() const
{
return mOriginAttributes;
}
const nsAString&
TabContext::PresentationURL() const
{
return mPresentationURL;
}
UIStateChangeType
TabContext::ShowAccelerators() const
{
return mShowAccelerators;
}
UIStateChangeType
TabContext::ShowFocusRings() const
{
return mShowFocusRings;
}
bool
TabContext::SetTabContext(bool aIsMozBrowserElement,
bool aIsPrerendered,
mozIApplication* aOwnApp,
mozIApplication* aAppFrameOwnerApp,
UIStateChangeType aShowAccelerators,
UIStateChangeType aShowFocusRings,
const DocShellOriginAttributes& aOriginAttributes,
const nsAString& aPresentationURL)
{
NS_ENSURE_FALSE(mInitialized, false);
// Get ids for both apps and only write to our member variables after we've
// verified that this worked.
uint32_t ownAppId = NO_APP_ID;
if (aOwnApp) {
nsresult rv = aOwnApp->GetLocalId(&ownAppId);
NS_ENSURE_SUCCESS(rv, false);
NS_ENSURE_TRUE(ownAppId != NO_APP_ID, false);
}
uint32_t containingAppId = NO_APP_ID;
if (aAppFrameOwnerApp) {
nsresult rv = aAppFrameOwnerApp->GetLocalId(&containingAppId);
NS_ENSURE_SUCCESS(rv, false);
NS_ENSURE_TRUE(containingAppId != NO_APP_ID, false);
}
// Veryify that app id matches mAppId passed in originAttributes
MOZ_RELEASE_ASSERT((aOwnApp && aOriginAttributes.mAppId == ownAppId) ||
(aAppFrameOwnerApp && aOriginAttributes.mAppId == containingAppId) ||
aOriginAttributes.mAppId == NO_APP_ID);
mInitialized = true;
mIsMozBrowserElement = aIsMozBrowserElement;
mIsPrerendered = aIsPrerendered;
mOriginAttributes = aOriginAttributes;
mContainingAppId = containingAppId;
mOwnApp = aOwnApp;
mContainingApp = aAppFrameOwnerApp;
mPresentationURL = aPresentationURL;
mShowAccelerators = aShowAccelerators;
mShowFocusRings = aShowFocusRings;
return true;
}
IPCTabContext
TabContext::AsIPCTabContext() const
{
return IPCTabContext(FrameIPCTabContext(mOriginAttributes,
mContainingAppId,
mIsMozBrowserElement,
mIsPrerendered,
mPresentationURL,
mShowAccelerators,
mShowFocusRings));
}
static already_AddRefed<mozIApplication>
GetAppForId(uint32_t aAppId)
{
nsCOMPtr<nsIAppsService> appsService = do_GetService(APPS_SERVICE_CONTRACTID);
NS_ENSURE_TRUE(appsService, nullptr);
nsCOMPtr<mozIApplication> app;
appsService->GetAppByLocalId(aAppId, getter_AddRefs(app));
return app.forget();
}
MaybeInvalidTabContext::MaybeInvalidTabContext(const IPCTabContext& aParams)
: mInvalidReason(nullptr)
{
bool isMozBrowserElement = false;
bool isPrerendered = false;
uint32_t containingAppId = NO_APP_ID;
DocShellOriginAttributes originAttributes;
nsAutoString presentationURL;
UIStateChangeType showAccelerators = UIStateChangeType_NoChange;
UIStateChangeType showFocusRings = UIStateChangeType_NoChange;
switch(aParams.type()) {
case IPCTabContext::TPopupIPCTabContext: {
const PopupIPCTabContext &ipcContext = aParams.get_PopupIPCTabContext();
TabContext *context;
if (ipcContext.opener().type() == PBrowserOrId::TPBrowserParent) {
context = TabParent::GetFrom(ipcContext.opener().get_PBrowserParent());
if (!context) {
mInvalidReason = "Child is-browser process tried to "
"open a null tab.";
return;
}
if (context->IsMozBrowserElement() &&
!ipcContext.isMozBrowserElement()) {
// If the TabParent corresponds to a browser element, then it can only
// open other browser elements, for security reasons. We should have
// checked this before calling the TabContext constructor, so this is
// a fatal error.
mInvalidReason = "Child is-browser process tried to "
"open a non-browser tab.";
return;
}
} else if (ipcContext.opener().type() == PBrowserOrId::TPBrowserChild) {
context = static_cast<TabChild*>(ipcContext.opener().get_PBrowserChild());
} else if (ipcContext.opener().type() == PBrowserOrId::TTabId) {
// We should never get here because this PopupIPCTabContext is only
// used for allocating a new tab id, not for allocating a PBrowser.
mInvalidReason = "Child process tried to open an tab without the opener information.";
return;
} else {
// This should be unreachable because PopupIPCTabContext::opener is not a
// nullable field.
mInvalidReason = "PopupIPCTabContext::opener was null (?!).";
return;
}
// Browser elements can't nest other browser elements. So if
// our opener is browser element, we must be a new DOM window
// opened by it. In that case we inherit our containing app ID
// (if any).
//
// Otherwise, we're a new app window and we inherit from our
// opener app.
isMozBrowserElement = ipcContext.isMozBrowserElement();
originAttributes = context->mOriginAttributes;
if (isMozBrowserElement) {
containingAppId = context->OwnOrContainingAppId();
} else {
containingAppId = context->mContainingAppId;
}
break;
}
case IPCTabContext::TFrameIPCTabContext: {
const FrameIPCTabContext &ipcContext =
aParams.get_FrameIPCTabContext();
isMozBrowserElement = ipcContext.isMozBrowserElement();
isPrerendered = ipcContext.isPrerendered();
containingAppId = ipcContext.frameOwnerAppId();
presentationURL = ipcContext.presentationURL();
showAccelerators = ipcContext.showAccelerators();
showFocusRings = ipcContext.showFocusRings();
originAttributes = ipcContext.originAttributes();
break;
}
case IPCTabContext::TUnsafeIPCTabContext: {
// XXXcatalinb: This used *only* by ServiceWorkerClients::OpenWindow.
// It is meant as a temporary solution until service workers can
// provide a TabChild equivalent. Don't allow this on b2g since
// it might be used to escalate privileges.
#ifdef MOZ_B2G
mInvalidReason = "ServiceWorkerClients::OpenWindow is not supported.";
return;
#endif
if (!Preferences::GetBool("dom.serviceWorkers.enabled", false)) {
mInvalidReason = "ServiceWorkers should be enabled.";
return;
}
containingAppId = NO_APP_ID;
break;
}
default: {
MOZ_CRASH();
}
}
nsCOMPtr<mozIApplication> ownApp;
if (!isMozBrowserElement) {
// mAppId corresponds to OwnOrContainingAppId; if isMozBrowserElement is
// false then it's ownApp otherwise it's containingApp
ownApp = GetAppForId(originAttributes.mAppId);
if ((ownApp == nullptr) != (originAttributes.mAppId == NO_APP_ID)) {
mInvalidReason = "Got an ownAppId that didn't correspond to an app.";
return;
}
}
nsCOMPtr<mozIApplication> containingApp = GetAppForId(containingAppId);
if ((containingApp == nullptr) != (containingAppId == NO_APP_ID)) {
mInvalidReason = "Got a containingAppId that didn't correspond to an app.";
return;
}
bool rv;
rv = mTabContext.SetTabContext(isMozBrowserElement,
isPrerendered,
ownApp,
containingApp,
showAccelerators,
showFocusRings,
originAttributes,
presentationURL);
if (!rv) {
mInvalidReason = "Couldn't initialize TabContext.";
}
}
bool
MaybeInvalidTabContext::IsValid()
{
return mInvalidReason == nullptr;
}
const char*
MaybeInvalidTabContext::GetInvalidReason()
{
return mInvalidReason;
}
const TabContext&
MaybeInvalidTabContext::GetTabContext()
{
if (!IsValid()) {
MOZ_CRASH("Can't GetTabContext() if !IsValid().");
}
return mTabContext;
}
} // namespace dom
} // namespace mozilla

337
dom/ipc/TabContext.h Normal file
View file

@ -0,0 +1,337 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_TabContext_h
#define mozilla_dom_TabContext_h
#include "mozIApplication.h"
#include "nsCOMPtr.h"
#include "mozilla/BasePrincipal.h"
#include "nsPIDOMWindow.h"
#include "nsPIWindowRoot.h"
namespace mozilla {
namespace dom {
class IPCTabContext;
/**
* TabContext encapsulates information about an iframe that may be a mozbrowser
* or mozapp. You can ask whether a TabContext corresponds to a mozbrowser or
* mozapp, get the app that contains the browser, and so on.
*
* TabParent and TabChild both inherit from TabContext, and you can also have
* standalone TabContext objects.
*
* This class is immutable except by calling one of the protected
* SetTabContext*() methods (and those methods can only be called once). See
* also MutableTabContext.
*/
class TabContext
{
public:
TabContext();
/* (The implicit copy-constructor and operator= are fine.) */
/**
* Generates IPCTabContext of type BrowserFrameIPCTabContext or
* AppFrameIPCTabContext from this TabContext's information.
*/
IPCTabContext AsIPCTabContext() const;
/**
* Does this TabContext correspond to a mozbrowser?
*
* <iframe mozbrowser mozapp> and <xul:browser> are not considered to be
* mozbrowser elements.
*
* If IsMozBrowserElement() is true, HasOwnApp() and HasAppOwnerApp() are
* guaranteed to be false.
*
* If IsMozBrowserElement() is false, HasBrowserOwnerApp() is guaranteed to be
* false.
*/
bool IsMozBrowserElement() const;
/**
* Does this TabContext correspond to an isolated mozbrowser?
*
* <iframe mozbrowser mozapp> and <xul:browser> are not considered to be
* mozbrowser elements. <iframe mozbrowser noisolation> does not count as
* isolated since isolation is disabled. Isolation can only be disabled by
* chrome pages.
*/
bool IsIsolatedMozBrowserElement() const;
/**
* Does this TabContext correspond to a mozbrowser or mozapp? This is
* equivalent to IsMozBrowserElement() || HasOwnApp(). Returns false for
* <xul:browser>, which is neither a mozbrowser nor a mozapp.
*/
bool IsMozBrowserOrApp() const;
/**
* OwnAppId() returns the id of the app which directly corresponds to this
* context's frame. GetOwnApp() returns the corresponding app object, and
* HasOwnApp() returns true iff GetOwnApp() would return a non-null value.
*
* If HasOwnApp() is true, IsMozBrowserElement() is guaranteed to be
* false.
*/
uint32_t OwnAppId() const;
already_AddRefed<mozIApplication> GetOwnApp() const;
bool HasOwnApp() const;
/**
* BrowserOwnerAppId() gets the ID of the app which contains this browser
* frame. If this is not a mozbrowser frame (if !IsMozBrowserElement()), then
* BrowserOwnerAppId() is guaranteed to return NO_APP_ID.
*
* Even if we are a browser frame, BrowserOwnerAppId() may still return
* NO_APP_ID, if this browser frame is not contained inside an app.
*/
uint32_t BrowserOwnerAppId() const;
already_AddRefed<mozIApplication> GetBrowserOwnerApp() const;
bool HasBrowserOwnerApp() const;
/**
* AppOwnerAppId() gets the ID of the app which contains this app frame. If
* this is not an app frame (i.e., if !HasOwnApp()), then AppOwnerAppId() is
* guaranteed to return NO_APP_ID.
*
* Even if we are an app frame, AppOwnerAppId() may still return NO_APP_ID, if
* this app frame is not contained inside an app.
*/
uint32_t AppOwnerAppId() const;
already_AddRefed<mozIApplication> GetAppOwnerApp() const;
bool HasAppOwnerApp() const;
/**
* OwnOrContainingAppId() gets the ID of this frame, if HasOwnApp(). If this
* frame does not have its own app, it gets the ID of the app which contains
* this frame (i.e., the result of {Browser,App}OwnerAppId(), as applicable).
*/
uint32_t OwnOrContainingAppId() const;
already_AddRefed<mozIApplication> GetOwnOrContainingApp() const;
bool HasOwnOrContainingApp() const;
/**
* OriginAttributesRef() returns the DocShellOriginAttributes of this frame to
* the caller. This is used to store any attribute associated with the frame's
* docshell, such as the AppId.
*/
const DocShellOriginAttributes& OriginAttributesRef() const;
/**
* Returns the presentation URL associated with the tab if this tab is
* created for presented content
*/
const nsAString& PresentationURL() const;
UIStateChangeType ShowAccelerators() const;
UIStateChangeType ShowFocusRings() const;
protected:
friend class MaybeInvalidTabContext;
/**
* These protected mutator methods let you modify a TabContext once. Further
* attempts to modify a given TabContext will fail (the method will return
* false).
*
* These mutators will also fail if the TabContext was created with anything
* other than the no-args constructor.
*/
/**
* Set this TabContext to match the given TabContext.
*/
bool SetTabContext(const TabContext& aContext);
/**
* Set the tab context's origin attributes to a private browsing value.
*/
void SetPrivateBrowsingAttributes(bool aIsPrivateBrowsing);
/**
* Set the TabContext for this frame. This can either be:
* - an app frame (with the given own app) inside the given owner app. Either
* apps can be null.
* - a browser frame inside the given owner app (which may be null).
* - a non-browser, non-app frame. Both own app and owner app should be null.
*/
bool SetTabContext(bool aIsMozBrowserElement,
bool aIsPrerendered,
mozIApplication* aOwnApp,
mozIApplication* aAppFrameOwnerApp,
UIStateChangeType aShowAccelerators,
UIStateChangeType aShowFocusRings,
const DocShellOriginAttributes& aOriginAttributes,
const nsAString& aPresentationURL);
/**
* Modify this TabContext to match the given TabContext. This is a special
* case triggered by nsFrameLoader::SwapWithOtherRemoteLoader which may have
* caused the owner content to change.
*
* This special case only allows the field `mIsMozBrowserElement` to be
* changed. If any other fields have changed, the update is ignored and
* returns false.
*/
bool UpdateTabContextAfterSwap(const TabContext& aContext);
/**
* Whether this TabContext is in prerender mode.
*/
bool mIsPrerendered;
private:
/**
* Has this TabContext been initialized? If so, mutator methods will fail.
*/
bool mInitialized;
/**
* Whether this TabContext corresponds to a mozbrowser.
*
* <iframe mozbrowser mozapp> and <xul:browser> are not considered to be
* mozbrowser elements.
*/
bool mIsMozBrowserElement;
/**
* This TabContext's own app. If this is non-null, then this
* TabContext corresponds to an app, and mIsMozBrowserElement must be false.
*/
nsCOMPtr<mozIApplication> mOwnApp;
/**
* This TabContext's containing app. If mIsMozBrowserElement, this
* corresponds to the app which contains the browser frame; otherwise, this
* corresponds to the app which contains the app frame.
*/
nsCOMPtr<mozIApplication> mContainingApp;
/*
* Cache of mContainingApp->GetLocalId().
*/
uint32_t mContainingAppId;
/**
* DocShellOriginAttributes of the top level tab docShell
*/
DocShellOriginAttributes mOriginAttributes;
/**
* The requested presentation URL.
*/
nsString mPresentationURL;
/**
* Keyboard indicator state (focus rings, accelerators).
*/
UIStateChangeType mShowAccelerators;
UIStateChangeType mShowFocusRings;
};
/**
* MutableTabContext is the same as MaybeInvalidTabContext, except the mutation
* methods are public instead of protected. You can still only call these
* mutation methods once on a given object.
*/
class MutableTabContext : public TabContext
{
public:
bool SetTabContext(const TabContext& aContext)
{
return TabContext::SetTabContext(aContext);
}
bool
SetTabContext(bool aIsMozBrowserElement,
bool aIsPrerendered,
mozIApplication* aOwnApp,
mozIApplication* aAppFrameOwnerApp,
UIStateChangeType aShowAccelerators,
UIStateChangeType aShowFocusRings,
const DocShellOriginAttributes& aOriginAttributes,
const nsAString& aPresentationURL = EmptyString())
{
return TabContext::SetTabContext(aIsMozBrowserElement,
aIsPrerendered,
aOwnApp,
aAppFrameOwnerApp,
aShowAccelerators,
aShowFocusRings,
aOriginAttributes,
aPresentationURL);
}
};
/**
* MaybeInvalidTabContext is a simple class that lets you transform an
* IPCTabContext into a TabContext.
*
* The issue is that an IPCTabContext is not necessarily valid; for example, it
* might specify an app-id which doesn't exist. So to convert an IPCTabContext
* into a TabContext, you construct a MaybeInvalidTabContext, check whether it's
* valid, and, if so, read out your TabContext.
*
* Example usage:
*
* void UseTabContext(const TabContext& aTabContext);
*
* void CreateTab(const IPCTabContext& aContext) {
* MaybeInvalidTabContext tc(aContext);
* if (!tc.IsValid()) {
* NS_ERROR(nsPrintfCString("Got an invalid IPCTabContext: %s",
* tc.GetInvalidReason()));
* return;
* }
* UseTabContext(tc.GetTabContext());
* }
*/
class MaybeInvalidTabContext
{
public:
/**
* This constructor copies the information in aContext and sets IsValid() as
* appropriate.
*/
explicit MaybeInvalidTabContext(const IPCTabContext& aContext);
/**
* Was the IPCTabContext we received in our constructor valid?
*/
bool IsValid();
/**
* If IsValid(), this function returns null. Otherwise, it returns a
* human-readable string indicating why the IPCTabContext passed to our
* constructor was not valid.
*/
const char* GetInvalidReason();
/**
* If IsValid(), this function returns a reference to a TabContext
* corresponding to the IPCTabContext passed to our constructor. If
* !IsValid(), this function crashes.
*/
const TabContext& GetTabContext();
private:
MaybeInvalidTabContext(const MaybeInvalidTabContext&) = delete;
MaybeInvalidTabContext& operator=(const MaybeInvalidTabContext&) = delete;
const char* mInvalidReason;
MutableTabContext mTabContext;
};
} // namespace dom
} // namespace mozilla
#endif

View file

@ -0,0 +1,30 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "mozilla/EventDispatcher.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/TabMessageUtils.h"
#include "nsCOMPtr.h"
namespace mozilla {
namespace dom {
bool
ReadRemoteEvent(const IPC::Message* aMsg, PickleIterator* aIter,
RemoteDOMEvent* aResult)
{
aResult->mEvent = nullptr;
nsString type;
NS_ENSURE_TRUE(ReadParam(aMsg, aIter, &type), false);
aResult->mEvent = EventDispatcher::CreateEvent(nullptr, nullptr, nullptr,
type);
return aResult->mEvent->Deserialize(aMsg, aIter);
}
} // namespace dom
} // namespace mozilla

117
dom/ipc/TabMessageUtils.h Normal file
View file

@ -0,0 +1,117 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 TABMESSAGE_UTILS_H
#define TABMESSAGE_UTILS_H
#include "ipc/IPCMessageUtils.h"
#include "mozilla/dom/AudioChannelBinding.h"
#include "nsIDOMEvent.h"
#include "nsPIDOMWindow.h"
#include "nsCOMPtr.h"
#ifdef MOZ_CRASHREPORTER
#include "nsExceptionHandler.h"
#endif
namespace mozilla {
namespace dom {
struct RemoteDOMEvent
{
// Make sure to set the owner after deserializing.
nsCOMPtr<nsIDOMEvent> mEvent;
};
bool ReadRemoteEvent(const IPC::Message* aMsg, PickleIterator* aIter,
mozilla::dom::RemoteDOMEvent* aResult);
#ifdef MOZ_CRASHREPORTER
typedef CrashReporter::ThreadId NativeThreadId;
#else
// unused in this case
typedef int32_t NativeThreadId;
#endif
} // namespace dom
} // namespace mozilla
namespace IPC {
template<>
struct ParamTraits<mozilla::dom::RemoteDOMEvent>
{
typedef mozilla::dom::RemoteDOMEvent paramType;
static void Write(Message* aMsg, const paramType& aParam)
{
aParam.mEvent->Serialize(aMsg, true);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
return mozilla::dom::ReadRemoteEvent(aMsg, aIter, aResult);
}
static void Log(const paramType& aParam, std::wstring* aLog)
{
}
};
template<>
struct ParamTraits<mozilla::dom::AudioChannel>
{
typedef mozilla::dom::AudioChannel paramType;
static bool IsLegalValue(const paramType &aValue)
{
return aValue <= mozilla::dom::AudioChannel::Publicnotification;
}
static void Write(Message* aMsg, const paramType& aValue)
{
MOZ_ASSERT(IsLegalValue(aValue));
WriteParam(aMsg, (uint32_t)aValue);
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
{
uint32_t value;
if(!ReadParam(aMsg, aIter, &value) ||
!IsLegalValue(paramType(value))) {
return false;
}
*aResult = paramType(value);
return true;
}
static void Log(const paramType& aParam, std::wstring* aLog)
{}
};
template <>
struct ParamTraits<nsEventStatus>
: public ContiguousEnumSerializer<nsEventStatus,
nsEventStatus_eIgnore,
nsEventStatus_eSentinel>
{};
template<>
struct ParamTraits<nsSizeMode>
: public ContiguousEnumSerializer<nsSizeMode,
nsSizeMode_Normal,
nsSizeMode_Invalid>
{};
template<>
struct ParamTraits<UIStateChangeType>
: public ContiguousEnumSerializer<UIStateChangeType,
UIStateChangeType_NoChange,
UIStateChangeType_Invalid>
{ };
} // namespace IPC
#endif // TABMESSAGE_UTILS_H

3306
dom/ipc/TabParent.cpp Normal file

File diff suppressed because it is too large Load diff

813
dom/ipc/TabParent.h Normal file
View file

@ -0,0 +1,813 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_tabs_TabParent_h
#define mozilla_tabs_TabParent_h
#include "js/TypeDecls.h"
#include "mozilla/ContentCache.h"
#include "mozilla/dom/AudioChannelBinding.h"
#include "mozilla/dom/ipc/IdType.h"
#include "mozilla/dom/PBrowserParent.h"
#include "mozilla/dom/PContent.h"
#include "mozilla/dom/PFilePickerParent.h"
#include "mozilla/dom/TabContext.h"
#include "mozilla/EventForwards.h"
#include "mozilla/dom/File.h"
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/RefPtr.h"
#include "mozilla/Move.h"
#include "nsCOMPtr.h"
#include "nsIAuthPromptProvider.h"
#include "nsIBrowserDOMWindow.h"
#include "nsIDOMEventListener.h"
#include "nsIKeyEventInPluginCallback.h"
#include "nsISecureBrowserUI.h"
#include "nsITabParent.h"
#include "nsIWebBrowserPersistable.h"
#include "nsIXULBrowserWindow.h"
#include "nsRefreshDriver.h"
#include "nsWeakReference.h"
#include "Units.h"
#include "nsIWidget.h"
#include "nsIPartialSHistory.h"
class nsFrameLoader;
class nsIFrameLoader;
class nsIContent;
class nsIPrincipal;
class nsIURI;
class nsILoadContext;
class nsIDocShell;
namespace mozilla {
namespace a11y {
class DocAccessibleParent;
}
namespace jsipc {
class CpowHolder;
} // namespace jsipc
namespace layers {
struct TextureFactoryIdentifier;
} // namespace layers
namespace layout {
class RenderFrameParent;
} // namespace layout
namespace widget {
struct IMENotification;
} // namespace widget
namespace gfx {
class SourceSurface;
class DataSourceSurface;
} // namespace gfx
namespace dom {
class ClonedMessageData;
class nsIContentParent;
class Element;
class DataTransfer;
namespace ipc {
class StructuredCloneData;
} // ipc namespace
class TabParent final : public PBrowserParent
, public nsIDOMEventListener
, public nsITabParent
, public nsIAuthPromptProvider
, public nsISecureBrowserUI
, public nsIKeyEventInPluginCallback
, public nsSupportsWeakReference
, public TabContext
, public nsAPostRefreshObserver
, public nsIWebBrowserPersistable
{
typedef mozilla::dom::ClonedMessageData ClonedMessageData;
virtual ~TabParent();
public:
// Helper class for ContentParent::RecvCreateWindow.
struct AutoUseNewTab;
// nsITabParent
NS_DECL_NSITABPARENT
// nsIDOMEventListener interfaces
NS_DECL_NSIDOMEVENTLISTENER
TabParent(nsIContentParent* aManager,
const TabId& aTabId,
const TabContext& aContext,
uint32_t aChromeFlags);
Element* GetOwnerElement() const { return mFrameElement; }
already_AddRefed<nsPIDOMWindowOuter> GetParentWindowOuter();
void SetOwnerElement(Element* aElement);
void CacheFrameLoader(nsFrameLoader* aFrameLoader);
/**
* Get the mozapptype attribute from this TabParent's owner DOM element.
*/
void GetAppType(nsAString& aOut);
/**
* Returns true iff this TabParent's nsIFrameLoader is visible.
*
* The frameloader's visibility can be independent of e.g. its docshell's
* visibility.
*/
bool IsVisible() const;
nsIBrowserDOMWindow *GetBrowserDOMWindow() const { return mBrowserDOMWindow; }
void SetBrowserDOMWindow(nsIBrowserDOMWindow* aBrowserDOMWindow)
{
mBrowserDOMWindow = aBrowserDOMWindow;
}
void SetHasContentOpener(bool aHasContentOpener);
void SwapFrameScriptsFrom(nsTArray<FrameScriptInfo>& aFrameScripts)
{
aFrameScripts.SwapElements(mDelayedFrameScripts);
}
already_AddRefed<nsILoadContext> GetLoadContext();
already_AddRefed<nsIWidget> GetTopLevelWidget();
nsIXULBrowserWindow* GetXULBrowserWindow();
void Destroy();
void RemoveWindowListeners();
void AddWindowListeners();
void DidRefresh() override;
virtual bool RecvMoveFocus(const bool& aForward,
const bool& aForDocumentNavigation) override;
virtual bool RecvSizeShellTo(const uint32_t& aFlags,
const int32_t& aWidth,
const int32_t& aHeight,
const int32_t& aShellItemWidth,
const int32_t& aShellItemHeight) override;
virtual bool RecvDropLinks(nsTArray<nsString>&& aLinks) override;
virtual bool RecvEvent(const RemoteDOMEvent& aEvent) override;
virtual bool RecvReplyKeyEvent(const WidgetKeyboardEvent& aEvent) override;
virtual bool
RecvDispatchAfterKeyboardEvent(const WidgetKeyboardEvent& aEvent) override;
virtual bool
RecvAccessKeyNotHandled(const WidgetKeyboardEvent& aEvent) override;
virtual bool RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
PRenderFrameParent* aRenderFrame,
const nsString& aURL,
const nsString& aName,
const nsString& aFeatures,
bool* aOutWindowOpened,
TextureFactoryIdentifier* aTextureFactoryIdentifier,
uint64_t* aLayersId) override;
virtual bool
RecvSyncMessage(const nsString& aMessage,
const ClonedMessageData& aData,
InfallibleTArray<CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
nsTArray<ipc::StructuredCloneData>* aRetVal) override;
virtual bool
RecvRpcMessage(const nsString& aMessage,
const ClonedMessageData& aData,
InfallibleTArray<CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
nsTArray<ipc::StructuredCloneData>* aRetVal) override;
virtual bool RecvAsyncMessage(const nsString& aMessage,
InfallibleTArray<CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
const ClonedMessageData& aData) override;
virtual bool
RecvNotifyIMEFocus(const ContentCache& aContentCache,
const widget::IMENotification& aEventMessage,
nsIMEUpdatePreference* aPreference) override;
virtual bool
RecvNotifyIMETextChange(const ContentCache& aContentCache,
const widget::IMENotification& aEventMessage) override;
virtual bool
RecvNotifyIMECompositionUpdate(const ContentCache& aContentCache,
const widget::IMENotification& aEventMessage) override;
virtual bool
RecvNotifyIMESelection(const ContentCache& aContentCache,
const widget::IMENotification& aEventMessage) override;
virtual bool
RecvUpdateContentCache(const ContentCache& aContentCache) override;
virtual bool
RecvNotifyIMEMouseButtonEvent(const widget::IMENotification& aEventMessage,
bool* aConsumedByIME) override;
virtual bool
RecvNotifyIMEPositionChange(const ContentCache& aContentCache,
const widget::IMENotification& aEventMessage) override;
virtual bool
RecvOnEventNeedingAckHandled(const EventMessage& aMessage) override;
virtual bool
RecvRequestIMEToCommitComposition(const bool& aCancel,
bool* aIsCommitted,
nsString* aCommittedString) override;
virtual bool
RecvStartPluginIME(const WidgetKeyboardEvent& aKeyboardEvent,
const int32_t& aPanelX,
const int32_t& aPanelY,
nsString* aCommitted) override;
virtual bool RecvSetPluginFocused(const bool& aFocused) override;
virtual bool RecvSetCandidateWindowForPlugin(
const widget::CandidateWindowPosition& aPosition) override;
virtual bool
RecvDefaultProcOfPluginEvent(const WidgetPluginEvent& aEvent) override;
virtual bool RecvGetInputContext(int32_t* aIMEEnabled,
int32_t* aIMEOpen) override;
virtual bool RecvSetInputContext(const int32_t& aIMEEnabled,
const int32_t& aIMEOpen,
const nsString& aType,
const nsString& aInputmode,
const nsString& aActionHint,
const int32_t& aCause,
const int32_t& aFocusChange) override;
// See nsIKeyEventInPluginCallback
virtual void HandledWindowedPluginKeyEvent(
const NativeEventData& aKeyEventData,
bool aIsConsumed) override;
virtual bool RecvOnWindowedPluginKeyEvent(
const NativeEventData& aKeyEventData) override;
virtual bool RecvRequestFocus(const bool& aCanRaise) override;
virtual bool RecvLookUpDictionary(
const nsString& aText,
nsTArray<mozilla::FontRange>&& aFontRangeArray,
const bool& aIsVertical,
const LayoutDeviceIntPoint& aPoint) override;
virtual bool
RecvEnableDisableCommands(const nsString& aAction,
nsTArray<nsCString>&& aEnabledCommands,
nsTArray<nsCString>&& aDisabledCommands) override;
virtual bool
RecvSetCursor(const uint32_t& aValue, const bool& aForce) override;
virtual bool RecvSetCustomCursor(const nsCString& aUri,
const uint32_t& aWidth,
const uint32_t& aHeight,
const uint32_t& aStride,
const uint8_t& aFormat,
const uint32_t& aHotspotX,
const uint32_t& aHotspotY,
const bool& aForce) override;
virtual bool RecvSetStatus(const uint32_t& aType,
const nsString& aStatus) override;
virtual bool RecvIsParentWindowMainWidgetVisible(bool* aIsVisible) override;
virtual bool RecvShowTooltip(const uint32_t& aX,
const uint32_t& aY,
const nsString& aTooltip,
const nsString& aDirection) override;
virtual bool RecvHideTooltip() override;
virtual bool RecvGetDPI(float* aValue) override;
virtual bool RecvGetDefaultScale(double* aValue) override;
virtual bool RecvGetWidgetRounding(int32_t* aValue) override;
virtual bool RecvGetMaxTouchPoints(uint32_t* aTouchPoints) override;
virtual bool RecvGetWidgetNativeData(WindowsHandle* aValue) override;
virtual bool RecvSetNativeChildOfShareableWindow(const uintptr_t& childWindow) override;
virtual bool RecvDispatchFocusToTopLevelWindow() override;
virtual bool RecvRespondStartSwipeEvent(const uint64_t& aInputBlockId,
const bool& aStartSwipe) override;
virtual bool
RecvDispatchWheelEvent(const mozilla::WidgetWheelEvent& aEvent) override;
virtual bool
RecvDispatchMouseEvent(const mozilla::WidgetMouseEvent& aEvent) override;
virtual bool
RecvDispatchKeyboardEvent(const mozilla::WidgetKeyboardEvent& aEvent) override;
virtual PColorPickerParent*
AllocPColorPickerParent(const nsString& aTitle,
const nsString& aInitialColor) override;
virtual bool
DeallocPColorPickerParent(PColorPickerParent* aColorPicker) override;
virtual PDatePickerParent*
AllocPDatePickerParent(const nsString& aTitle, const nsString& aInitialDate) override;
virtual bool DeallocPDatePickerParent(PDatePickerParent* aDatePicker) override;
virtual PDocAccessibleParent*
AllocPDocAccessibleParent(PDocAccessibleParent*, const uint64_t&,
const uint32_t&, const IAccessibleHolder&) override;
virtual bool DeallocPDocAccessibleParent(PDocAccessibleParent*) override;
virtual bool
RecvPDocAccessibleConstructor(PDocAccessibleParent* aDoc,
PDocAccessibleParent* aParentDoc,
const uint64_t& aParentID,
const uint32_t& aMsaaID,
const IAccessibleHolder& aDocCOMProxy) override;
/**
* Return the top level doc accessible parent for this tab.
*/
a11y::DocAccessibleParent* GetTopLevelDocAccessible() const;
void LoadURL(nsIURI* aURI);
// XXX/cjones: it's not clear what we gain by hiding these
// message-sending functions under a layer of indirection and
// eating the return values
void Show(const ScreenIntSize& aSize, bool aParentIsActive);
void UpdateDimensions(const nsIntRect& aRect, const ScreenIntSize& aSize);
void SizeModeChanged(const nsSizeMode& aSizeMode);
void UIResolutionChanged();
void ThemeChanged();
void HandleAccessKey(const WidgetKeyboardEvent& aEvent,
nsTArray<uint32_t>& aCharCodes,
const int32_t& aModifierMask);
void Activate();
void Deactivate();
bool MapEventCoordinatesForChildProcess(mozilla::WidgetEvent* aEvent);
void MapEventCoordinatesForChildProcess(const LayoutDeviceIntPoint& aOffset,
mozilla::WidgetEvent* aEvent);
LayoutDeviceToCSSScale GetLayoutDeviceToCSSScale();
virtual bool
RecvRequestNativeKeyBindings(const mozilla::WidgetKeyboardEvent& aEvent,
MaybeNativeKeyBinding* aBindings) override;
virtual bool
RecvSynthesizeNativeKeyEvent(const int32_t& aNativeKeyboardLayout,
const int32_t& aNativeKeyCode,
const uint32_t& aModifierFlags,
const nsString& aCharacters,
const nsString& aUnmodifiedCharacters,
const uint64_t& aObserverId) override;
virtual bool
RecvSynthesizeNativeMouseEvent(const LayoutDeviceIntPoint& aPoint,
const uint32_t& aNativeMessage,
const uint32_t& aModifierFlags,
const uint64_t& aObserverId) override;
virtual bool
RecvSynthesizeNativeMouseMove(const LayoutDeviceIntPoint& aPoint,
const uint64_t& aObserverId) override;
virtual bool
RecvSynthesizeNativeMouseScrollEvent(const LayoutDeviceIntPoint& aPoint,
const uint32_t& aNativeMessage,
const double& aDeltaX,
const double& aDeltaY,
const double& aDeltaZ,
const uint32_t& aModifierFlags,
const uint32_t& aAdditionalFlags,
const uint64_t& aObserverId) override;
virtual bool
RecvSynthesizeNativeTouchPoint(const uint32_t& aPointerId,
const TouchPointerState& aPointerState,
const LayoutDeviceIntPoint& aPoint,
const double& aPointerPressure,
const uint32_t& aPointerOrientation,
const uint64_t& aObserverId) override;
virtual bool
RecvSynthesizeNativeTouchTap(const LayoutDeviceIntPoint& aPoint,
const bool& aLongTap,
const uint64_t& aObserverId) override;
virtual bool
RecvClearNativeTouchSequence(const uint64_t& aObserverId) override;
void SendMouseEvent(const nsAString& aType, float aX, float aY,
int32_t aButton, int32_t aClickCount,
int32_t aModifiers, bool aIgnoreRootScrollFrame);
void SendKeyEvent(const nsAString& aType, int32_t aKeyCode,
int32_t aCharCode, int32_t aModifiers,
bool aPreventDefault);
bool SendRealMouseEvent(mozilla::WidgetMouseEvent& event);
bool SendRealDragEvent(mozilla::WidgetDragEvent& aEvent,
uint32_t aDragAction,
uint32_t aDropEffect);
bool SendMouseWheelEvent(mozilla::WidgetWheelEvent& event);
bool SendRealKeyEvent(mozilla::WidgetKeyboardEvent& event);
bool SendRealTouchEvent(WidgetTouchEvent& event);
bool SendHandleTap(TapType aType,
const LayoutDevicePoint& aPoint,
Modifiers aModifiers,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId);
virtual PDocumentRendererParent*
AllocPDocumentRendererParent(const nsRect& documentRect,
const gfx::Matrix& transform,
const nsString& bgcolor,
const uint32_t& renderFlags,
const bool& flushLayout,
const nsIntSize& renderSize) override;
virtual bool
DeallocPDocumentRendererParent(PDocumentRendererParent* actor) override;
virtual PFilePickerParent*
AllocPFilePickerParent(const nsString& aTitle,
const int16_t& aMode) override;
virtual bool DeallocPFilePickerParent(PFilePickerParent* actor) override;
virtual PIndexedDBPermissionRequestParent*
AllocPIndexedDBPermissionRequestParent(const Principal& aPrincipal) override;
virtual bool
RecvPIndexedDBPermissionRequestConstructor(
PIndexedDBPermissionRequestParent* aActor,
const Principal& aPrincipal)
override;
virtual bool
DeallocPIndexedDBPermissionRequestParent(
PIndexedDBPermissionRequestParent* aActor)
override;
bool GetGlobalJSObject(JSContext* cx, JSObject** globalp);
NS_DECL_ISUPPORTS
NS_DECL_NSIAUTHPROMPTPROVIDER
NS_DECL_NSISECUREBROWSERUI
NS_DECL_NSIWEBBROWSERPERSISTABLE
bool HandleQueryContentEvent(mozilla::WidgetQueryContentEvent& aEvent);
bool SendCompositionEvent(mozilla::WidgetCompositionEvent& event);
bool SendSelectionEvent(mozilla::WidgetSelectionEvent& event);
bool SendPasteTransferable(const IPCDataTransfer& aDataTransfer,
const bool& aIsPrivateData,
const IPC::Principal& aRequestingPrincipal);
static TabParent* GetFrom(nsFrameLoader* aFrameLoader);
static TabParent* GetFrom(nsIFrameLoader* aFrameLoader);
static TabParent* GetFrom(nsITabParent* aTabParent);
static TabParent* GetFrom(PBrowserParent* aTabParent);
static TabParent* GetFrom(nsIContent* aContent);
static TabId GetTabIdFrom(nsIDocShell* docshell);
nsIContentParent* Manager() const { return mManager; }
/**
* Let managees query if Destroy() is already called so they don't send out
* messages when the PBrowser actor is being destroyed.
*/
bool IsDestroyed() const { return mIsDestroyed; }
already_AddRefed<nsIWidget> GetWidget() const;
const TabId GetTabId() const
{
return mTabId;
}
LayoutDeviceIntPoint GetChildProcessOffset();
LayoutDevicePoint AdjustTapToChildWidget(const LayoutDevicePoint& aPoint);
/**
* Native widget remoting protocol for use with windowed plugins with e10s.
*/
virtual PPluginWidgetParent* AllocPPluginWidgetParent() override;
virtual bool
DeallocPPluginWidgetParent(PPluginWidgetParent* aActor) override;
void SetInitedByParent() { mInitedByParent = true; }
bool IsInitedByParent() const { return mInitedByParent; }
static TabParent* GetNextTabParent();
bool SendLoadRemoteScript(const nsString& aURL,
const bool& aRunInGlobalScope);
void LayerTreeUpdate(uint64_t aEpoch, bool aActive);
virtual bool
RecvInvokeDragSession(nsTArray<IPCDataTransfer>&& aTransfers,
const uint32_t& aAction,
const OptionalShmem& aVisualDnDData,
const uint32_t& aStride, const uint8_t& aFormat,
const LayoutDeviceIntRect& aDragRect) override;
void AddInitialDnDDataTo(DataTransfer* aDataTransfer);
bool TakeDragVisualization(RefPtr<mozilla::gfx::SourceSurface>& aSurface,
LayoutDeviceIntRect* aDragRect);
layout::RenderFrameParent* GetRenderFrame();
void AudioChannelChangeNotification(nsPIDOMWindowOuter* aWindow,
AudioChannel aAudioChannel,
float aVolume,
bool aMuted);
bool SetRenderFrame(PRenderFrameParent* aRFParent);
bool GetRenderFrameInfo(TextureFactoryIdentifier* aTextureFactoryIdentifier,
uint64_t* aLayersId);
bool RecvEnsureLayersConnected() override;
protected:
bool ReceiveMessage(const nsString& aMessage,
bool aSync,
ipc::StructuredCloneData* aData,
mozilla::jsipc::CpowHolder* aCpows,
nsIPrincipal* aPrincipal,
nsTArray<ipc::StructuredCloneData>* aJSONRetVal = nullptr);
virtual bool RecvAsyncAuthPrompt(const nsCString& aUri,
const nsString& aRealm,
const uint64_t& aCallbackId) override;
virtual bool Recv__delete__() override;
virtual void ActorDestroy(ActorDestroyReason why) override;
Element* mFrameElement;
nsCOMPtr<nsIBrowserDOMWindow> mBrowserDOMWindow;
virtual PRenderFrameParent* AllocPRenderFrameParent() override;
virtual bool DeallocPRenderFrameParent(PRenderFrameParent* aFrame) override;
virtual bool RecvRemotePaintIsReady() override;
virtual bool RecvForcePaintNoOp(const uint64_t& aLayerObserverEpoch) override;
virtual bool RecvSetDimensions(const uint32_t& aFlags,
const int32_t& aX, const int32_t& aY,
const int32_t& aCx, const int32_t& aCy) override;
virtual bool RecvGetTabCount(uint32_t* aValue) override;
virtual bool RecvAudioChannelActivityNotification(const uint32_t& aAudioChannel,
const bool& aActive) override;
virtual bool RecvNotifySessionHistoryChange(const uint32_t& aCount) override;
virtual bool RecvRequestCrossBrowserNavigation(const uint32_t& aGlobalIndex) override;
ContentCacheInParent mContentCache;
nsIntRect mRect;
ScreenIntSize mDimensions;
ScreenOrientationInternal mOrientation;
float mDPI;
int32_t mRounding;
CSSToLayoutDeviceScale mDefaultScale;
bool mUpdatedDimensions;
nsSizeMode mSizeMode;
LayoutDeviceIntPoint mClientOffset;
LayoutDeviceIntPoint mChromeOffset;
private:
void DestroyInternal();
already_AddRefed<nsFrameLoader>
GetFrameLoader(bool aUseCachedFrameLoaderAfterDestroy = false) const;
RefPtr<nsIContentParent> mManager;
void TryCacheDPIAndScale();
nsresult UpdatePosition();
bool AsyncPanZoomEnabled() const;
// Cached value indicating the docshell active state of the remote browser.
bool mDocShellIsActive;
// Update state prior to routing an APZ-aware event to the child process.
// |aOutTargetGuid| will contain the identifier
// of the APZC instance that handled the event. aOutTargetGuid may be null.
// |aOutInputBlockId| will contain the identifier of the input block
// that this event was added to, if there was one. aOutInputBlockId may be null.
// |aOutApzResponse| will contain the response that the APZ gave when processing
// the input block; this is used for generating appropriate pointercancel events.
void ApzAwareEventRoutingToChild(ScrollableLayerGuid* aOutTargetGuid,
uint64_t* aOutInputBlockId,
nsEventStatus* aOutApzResponse);
// When true, we've initiated normal shutdown and notified our managing PContent.
bool mMarkedDestroying;
// When true, the TabParent is invalid and we should not send IPC messages anymore.
bool mIsDestroyed;
uint32_t mChromeFlags;
nsTArray<nsTArray<IPCDataTransferItem>> mInitialDataTransferItems;
RefPtr<gfx::DataSourceSurface> mDnDVisualization;
bool mDragValid;
LayoutDeviceIntRect mDragRect;
// When true, the TabParent is initialized without child side's request.
// When false, the TabParent is initialized by window.open() from child side.
bool mInitedByParent;
nsCOMPtr<nsILoadContext> mLoadContext;
// We keep a strong reference to the frameloader after we've sent the
// Destroy message and before we've received __delete__. This allows us to
// dispatch message manager messages during this time.
RefPtr<nsFrameLoader> mFrameLoader;
TabId mTabId;
// When loading a new tab or window via window.open, the child process sends
// a new PBrowser to use. We store that tab in sNextTabParent and then
// proceed through the browser's normal paths to create a new
// window/tab. When it comes time to create a new TabParent, we instead use
// sNextTabParent.
static TabParent* sNextTabParent;
// When loading a new tab or window via window.open, the child is
// responsible for loading the URL it wants into the new TabChild. When the
// parent receives the CreateWindow message, though, it sends a LoadURL
// message, usually for about:blank. It's important for the about:blank load
// to get processed because the Firefox frontend expects every new window to
// immediately start loading something (see bug 1123090). However, we want
// the child to process the LoadURL message before it returns from
// ProvideWindow so that the URL sent from the parent doesn't override the
// child's URL. This is not possible using our IPC mechanisms. To solve the
// problem, we skip sending the LoadURL message in the parent and instead
// return the URL as a result from CreateWindow. The child simulates
// receiving a LoadURL message before returning from ProvideWindow.
//
// The mCreatingWindow flag is set while dispatching CreateWindow. During
// that time, any LoadURL calls are skipped and the URL is stored in
// mSkippedURL.
bool mCreatingWindow;
nsCString mDelayedURL;
// When loading a new tab or window via window.open, we want to ensure that
// frame scripts for that tab are loaded before any scripts start to run in
// the window. We can't load the frame scripts the normal way, using
// separate IPC messages, since they won't be processed by the child until
// returning to the event loop, which is too late. Instead, we queue up
// frame scripts that we intend to load and send them as part of the
// CreateWindow response. Then TabChild loads them immediately.
nsTArray<FrameScriptInfo> mDelayedFrameScripts;
// Cached cursor setting from TabChild. When the cursor is over the tab,
// it should take this appearance.
nsCursor mCursor;
nsCOMPtr<imgIContainer> mCustomCursor;
uint32_t mCustomCursorHotspotX, mCustomCursorHotspotY;
// True if the cursor changes from the TabChild should change the widget
// cursor. This happens whenever the cursor is in the tab's region.
bool mTabSetsCursor;
RefPtr<nsIPresShell> mPresShellWithRefreshListener;
bool mHasContentOpener;
#ifdef DEBUG
int32_t mActiveSupressDisplayportCount;
#endif
ShowInfo GetShowInfo();
private:
// This is used when APZ needs to find the TabParent associated with a layer
// to dispatch events.
typedef nsDataHashtable<nsUint64HashKey, TabParent*> LayerToTabParentTable;
static LayerToTabParentTable* sLayerToTabParentTable;
static void AddTabParentToTable(uint64_t aLayersId, TabParent* aTabParent);
static void RemoveTabParentFromTable(uint64_t aLayersId);
uint64_t mLayerTreeEpoch;
// If this flag is set, then the tab's layers will be preserved even when
// the tab's docshell is inactive.
bool mPreserveLayers;
public:
static TabParent* GetTabParentFromLayersId(uint64_t aLayersId);
};
struct MOZ_STACK_CLASS TabParent::AutoUseNewTab final
{
public:
AutoUseNewTab(TabParent* aNewTab, bool* aWindowIsNew, nsCString* aURLToLoad)
: mNewTab(aNewTab), mWindowIsNew(aWindowIsNew), mURLToLoad(aURLToLoad)
{
MOZ_ASSERT(!TabParent::sNextTabParent);
MOZ_ASSERT(!aNewTab->mCreatingWindow);
TabParent::sNextTabParent = aNewTab;
aNewTab->mCreatingWindow = true;
aNewTab->mDelayedURL.Truncate();
}
~AutoUseNewTab()
{
mNewTab->mCreatingWindow = false;
*mURLToLoad = mNewTab->mDelayedURL;
if (TabParent::sNextTabParent) {
MOZ_ASSERT(TabParent::sNextTabParent == mNewTab);
TabParent::sNextTabParent = nullptr;
*mWindowIsNew = false;
}
}
private:
TabParent* mNewTab;
bool* mWindowIsNew;
nsCString* mURLToLoad;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_tabs_TabParent_h

17
dom/ipc/extensions.js Normal file
View file

@ -0,0 +1,17 @@
/* 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/. */
"use strict";
function debug(msg) {
// dump("extensions - " + msg + "\n");
}
debug("loaded");
ExtensionContent.init(this);
addEventListener("unload", () => {
ExtensionContent.uninit(this);
});

13
dom/ipc/jar.mn Normal file
View file

@ -0,0 +1,13 @@
# 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/.
toolkit.jar:
content/global/test-ipc.xul (test.xul)
content/global/remote-test-ipc.js (remote-test.js)
content/global/BrowserElementChild.js (../browser-element/BrowserElementChild.js)
content/global/BrowserElementChildPreload.js (../browser-element/BrowserElementChildPreload.js)
content/global/BrowserElementCopyPaste.js (../browser-element/BrowserElementCopyPaste.js)
content/global/extensions.js (extensions.js)
content/global/manifestMessages.js (manifestMessages.js)
content/global/preload.js (preload.js)

108
dom/ipc/manifestMessages.js Normal file
View file

@ -0,0 +1,108 @@
/* 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/.*/
/*
* Manifest obtainer frame script implementation of:
* http://www.w3.org/TR/appmanifest/#obtaining
*
* It searches a top-level browsing context for
* a <link rel=manifest> element. Then fetches
* and processes the linked manifest.
*
* BUG: https://bugzilla.mozilla.org/show_bug.cgi?id=1083410
*/
/*globals Task, ManifestObtainer, ManifestFinder, content, sendAsyncMessage, addMessageListener, Components*/
"use strict";
const {
utils: Cu,
} = Components;
Cu.import("resource://gre/modules/ManifestObtainer.jsm");
Cu.import("resource://gre/modules/ManifestFinder.jsm");
Cu.import("resource://gre/modules/Task.jsm");
const MessageHandler = {
registerListeners() {
addMessageListener(
"DOM:WebManifest:hasManifestLink",
this.hasManifestLink.bind(this)
);
addMessageListener(
"DOM:ManifestObtainer:Obtain",
this.obtainManifest.bind(this)
);
addMessageListener(
"DOM:Manifest:FireAppInstalledEvent",
this.fireAppInstalledEvent.bind(this)
);
},
/**
* Check if the content document includes a link to a web manifest.
* @param {Object} aMsg The IPC message, which is destructured to just
* get the id.
*/
hasManifestLink({data: {id}}) {
const response = makeMsgResponse(id);
response.result = ManifestFinder.contentHasManifestLink(content);
response.success = true;
sendAsyncMessage("DOM:WebManifest:hasManifestLink", response);
},
/**
* Asynchronously obtains a web manifest from content by using the
* ManifestObtainer and messages back the result.
* @param {Object} aMsg The IPC message, which is destructured to just
* get the id.
*/
obtainManifest: Task.async(function* ({data: {id}}) {
const response = makeMsgResponse(id);
try {
response.result = yield ManifestObtainer.contentObtainManifest(content);
response.success = true;
} catch (err) {
response.result = serializeError(err);
}
sendAsyncMessage("DOM:ManifestObtainer:Obtain", response);
}),
fireAppInstalledEvent({data: {id}}){
const ev = new Event("appinstalled");
const response = makeMsgResponse(id);
if (!content || content.top !== content) {
const msg = "Can only dispatch install event on top-level browsing contexts.";
response.result = serializeError(new Error(msg));
} else {
response.success = true;
content.dispatchEvent(ev);
}
sendAsyncMessage("DOM:Manifest:FireAppInstalledEvent", response);
}
};
/**
* Utility function to Serializes an JS Error, so it can be transferred over
* the message channel.
* FIX ME: https://bugzilla.mozilla.org/show_bug.cgi?id=1172586
* @param {Error} aError The error to serialize.
* @return {Object} The serialized object.
*/
function serializeError(aError) {
const clone = {
"fileName": aError.fileName,
"lineNumber": aError.lineNumber,
"columnNumber": aError.columnNumber,
"stack": aError.stack,
"message": aError.message,
"name": aError.name
};
return clone;
}
function makeMsgResponse(aId) {
return {
id: aId,
success: false,
result: undefined
};
}
MessageHandler.registerListeners();

179
dom/ipc/moz.build Normal file
View file

@ -0,0 +1,179 @@
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# 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/.
XPIDL_SOURCES += [
'nsIHangReport.idl',
]
XPIDL_MODULE = 'dom'
EXPORTS.mozilla.dom.ipc += [
'BlobChild.h',
'BlobParent.h',
'IdType.h',
'nsIRemoteBlob.h',
'StructuredCloneData.h',
]
EXPORTS.mozilla.dom += [
'ContentBridgeChild.h',
'ContentBridgeParent.h',
'ContentChild.h',
'ContentParent.h',
'ContentProcess.h',
'ContentProcessManager.h',
'CPOWManagerGetter.h',
'CrashReporterChild.h',
'CrashReporterParent.h',
'FilePickerParent.h',
'nsIContentChild.h',
'nsIContentParent.h',
'PermissionMessageUtils.h',
'TabChild.h',
'TabContext.h',
'TabMessageUtils.h',
'TabParent.h',
]
EXPORTS.mozilla += [
'AppProcessChecker.h',
'PreallocatedProcessManager.h',
'ProcessHangMonitor.h',
'ProcessHangMonitorIPC.h',
'ProcessPriorityManager.h',
]
UNIFIED_SOURCES += [
'AppProcessChecker.cpp',
'ColorPickerParent.cpp',
'ContentBridgeChild.cpp',
'ContentBridgeParent.cpp',
'ContentParent.cpp',
'ContentProcess.cpp',
'ContentProcessManager.cpp',
'CrashReporterParent.cpp',
'DatePickerParent.cpp',
'FilePickerParent.cpp',
'nsIContentChild.cpp',
'nsIContentParent.cpp',
'PermissionMessageUtils.cpp',
'PreallocatedProcessManager.cpp',
'ProcessPriorityManager.cpp',
'ScreenManagerParent.cpp',
'StructuredCloneData.cpp',
'TabChild.cpp',
'TabContext.cpp',
'TabMessageUtils.cpp',
'TabParent.cpp',
]
# Blob.cpp cannot be compiled in unified mode because it triggers a fatal gcc warning.
# CrashReporterChild.cpp cannot be compiled in unified mode because of name clashes
# in OS X headers.
# ContentChild.cpp cannot be compiled in unified mode on linux due to Time conflict
SOURCES += [
'Blob.cpp',
'ContentChild.cpp',
'CrashReporterChild.cpp',
'ProcessHangMonitor.cpp',
]
IPDL_SOURCES += [
'BlobTypes.ipdlh',
'DOMTypes.ipdlh',
'PBlob.ipdl',
'PBlobStream.ipdl',
'PBrowser.ipdl',
'PBrowserOrId.ipdlh',
'PColorPicker.ipdl',
'PContent.ipdl',
'PContentBridge.ipdl',
'PContentPermission.ipdlh',
'PContentPermissionRequest.ipdl',
'PCrashReporter.ipdl',
'PCycleCollectWithLogs.ipdl',
'PDatePicker.ipdl',
'PDocumentRenderer.ipdl',
'PFilePicker.ipdl',
'PMemoryReportRequest.ipdl',
'PPluginWidget.ipdl',
'PProcessHangMonitor.ipdl',
'PScreenManager.ipdl',
'PTabContext.ipdlh',
'ServiceWorkerConfiguration.ipdlh',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_TARGET'] == 'Darwin':
USE_LIBS += [
'mozsandbox',
]
if CONFIG['MOZ_CONTENT_SANDBOX'] and CONFIG['OS_ARCH'] == 'Linux':
USE_LIBS += [
'mozsandbox',
]
LOCAL_INCLUDES += [
'/caps',
'/chrome',
'/docshell/base',
'/dom/base',
'/dom/events',
'/dom/filesystem',
'/dom/geolocation',
'/dom/media/webspeech/synth/ipc',
'/dom/security',
'/dom/storage',
'/dom/workers',
'/embedding/components/printingui/ipc',
'/extensions/cookie',
'/extensions/spellcheck/src',
'/gfx/2d',
'/hal/sandbox',
'/layout/base',
'/media/webrtc',
'/netwerk/base',
'/toolkit/crashreporter',
'/toolkit/xre',
'/uriloader/exthandler',
'/widget',
'/xpcom/base',
'/xpcom/threads',
]
if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_ARCH'] == 'WINNT':
LOCAL_INCLUDES += [
'/security/sandbox/chromium',
'/security/sandbox/chromium-shim',
]
if CONFIG['OS_ARCH'] != 'WINNT':
LOCAL_INCLUDES += [
'/modules/libjar',
]
DEFINES['BIN_SUFFIX'] = '"%s"' % CONFIG['BIN_SUFFIX']
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android', 'gtk2', 'gonk'):
DEFINES['MOZ_ENABLE_FREETYPE'] = True
if CONFIG['MOZ_TOOLKIT_SEARCH']:
DEFINES['MOZ_TOOLKIT_SEARCH'] = True
JAR_MANIFESTS += ['jar.mn']
BROWSER_CHROME_MANIFESTS += ['tests/browser.ini']
MOCHITEST_CHROME_MANIFESTS += ['tests/chrome.ini']
MOCHITEST_MANIFESTS += ['tests/mochitest.ini']
CXXFLAGS += CONFIG['TK_CFLAGS']
if CONFIG['GNU_CXX']:
CXXFLAGS += ['-Wno-error=shadow']

159
dom/ipc/nsIContentChild.cpp Normal file
View file

@ -0,0 +1,159 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "nsIContentChild.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/dom/DOMTypes.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/TabChild.h"
#include "mozilla/dom/ipc/BlobChild.h"
#include "mozilla/dom/ipc/StructuredCloneData.h"
#include "mozilla/ipc/FileDescriptorSetChild.h"
#include "mozilla/ipc/InputStreamUtils.h"
#include "mozilla/ipc/SendStream.h"
#include "nsPrintfCString.h"
#include "xpcpublic.h"
using namespace mozilla::ipc;
using namespace mozilla::jsipc;
namespace mozilla {
namespace dom {
PJavaScriptChild*
nsIContentChild::AllocPJavaScriptChild()
{
return NewJavaScriptChild();
}
bool
nsIContentChild::DeallocPJavaScriptChild(PJavaScriptChild* aChild)
{
ReleaseJavaScriptChild(aChild);
return true;
}
PBrowserChild*
nsIContentChild::AllocPBrowserChild(const TabId& aTabId,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const ContentParentId& aCpID,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
// We'll happily accept any kind of IPCTabContext here; we don't need to
// check that it's of a certain type for security purposes, because we
// believe whatever the parent process tells us.
MaybeInvalidTabContext tc(aContext);
if (!tc.IsValid()) {
NS_ERROR(nsPrintfCString("Received an invalid TabContext from "
"the parent process. (%s) Crashing...",
tc.GetInvalidReason()).get());
MOZ_CRASH("Invalid TabContext received from the parent process.");
}
RefPtr<TabChild> child =
TabChild::Create(this, aTabId, tc.GetTabContext(), aChromeFlags);
// The ref here is released in DeallocPBrowserChild.
return child.forget().take();
}
bool
nsIContentChild::DeallocPBrowserChild(PBrowserChild* aIframe)
{
TabChild* child = static_cast<TabChild*>(aIframe);
NS_RELEASE(child);
return true;
}
PBlobChild*
nsIContentChild::AllocPBlobChild(const BlobConstructorParams& aParams)
{
return BlobChild::Create(this, aParams);
}
bool
nsIContentChild::DeallocPBlobChild(PBlobChild* aActor)
{
BlobChild::Destroy(aActor);
return true;
}
BlobChild*
nsIContentChild::GetOrCreateActorForBlob(Blob* aBlob)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aBlob);
RefPtr<BlobImpl> blobImpl = aBlob->Impl();
MOZ_ASSERT(blobImpl);
return GetOrCreateActorForBlobImpl(blobImpl);
}
BlobChild*
nsIContentChild::GetOrCreateActorForBlobImpl(BlobImpl* aImpl)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aImpl);
BlobChild* actor = BlobChild::GetOrCreate(this, aImpl);
NS_ENSURE_TRUE(actor, nullptr);
return actor;
}
PSendStreamChild*
nsIContentChild::AllocPSendStreamChild()
{
MOZ_CRASH("PSendStreamChild actors should be manually constructed!");
}
bool
nsIContentChild::DeallocPSendStreamChild(PSendStreamChild* aActor)
{
delete aActor;
return true;
}
PFileDescriptorSetChild*
nsIContentChild::AllocPFileDescriptorSetChild(const FileDescriptor& aFD)
{
return new FileDescriptorSetChild(aFD);
}
bool
nsIContentChild::DeallocPFileDescriptorSetChild(PFileDescriptorSetChild* aActor)
{
delete static_cast<FileDescriptorSetChild*>(aActor);
return true;
}
bool
nsIContentChild::RecvAsyncMessage(const nsString& aMsg,
InfallibleTArray<CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
const ClonedMessageData& aData)
{
RefPtr<nsFrameMessageManager> cpm = nsFrameMessageManager::GetChildProcessManager();
if (cpm) {
ipc::StructuredCloneData data;
ipc::UnpackClonedMessageDataForChild(aData, data);
CrossProcessCpowHolder cpows(this, aCpows);
cpm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(cpm.get()), nullptr,
aMsg, false, &data, &cpows, aPrincipal, nullptr);
}
return true;
}
} // namespace dom
} // namespace mozilla

118
dom/ipc/nsIContentChild.h Normal file
View file

@ -0,0 +1,118 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_nsIContentChild_h
#define mozilla_dom_nsIContentChild_h
#include "mozilla/dom/ipc/IdType.h"
#include "nsISupports.h"
#include "nsTArrayForwardDeclare.h"
#include "mozilla/dom/CPOWManagerGetter.h"
#include "mozilla/ipc/Shmem.h"
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
#define NS_ICONTENTCHILD_IID \
{ 0x4eed2e73, 0x94ba, 0x48a8, \
{ 0xa2, 0xd1, 0xa5, 0xed, 0x86, 0xd7, 0xbb, 0xe4 } }
class nsString;
namespace IPC {
class Principal;
} // namespace IPC
namespace mozilla {
namespace ipc {
class FileDescriptor;
class PFileDescriptorSetChild;
class PSendStreamChild;
class Shmem;
} // namespace ipc
namespace jsipc {
class PJavaScriptChild;
class CpowEntry;
} // namespace jsipc
namespace dom {
class Blob;
class BlobChild;
class BlobImpl;
class BlobConstructorParams;
class ClonedMessageData;
class IPCTabContext;
class PBlobChild;
class PBrowserChild;
class nsIContentChild : public nsISupports
, public CPOWManagerGetter
, public mozilla::ipc::IShmemAllocator
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENTCHILD_IID)
BlobChild* GetOrCreateActorForBlob(Blob* aBlob);
BlobChild* GetOrCreateActorForBlobImpl(BlobImpl* aImpl);
virtual PBlobChild*
SendPBlobConstructor(PBlobChild* aActor,
const BlobConstructorParams& aParams) = 0;
virtual bool
SendPBrowserConstructor(PBrowserChild* aActor,
const TabId& aTabId,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const ContentParentId& aCpID,
const bool& aIsForApp,
const bool& aIsForBrowser) = 0;
virtual mozilla::ipc::PFileDescriptorSetChild*
SendPFileDescriptorSetConstructor(const mozilla::ipc::FileDescriptor&) = 0;
virtual mozilla::ipc::PSendStreamChild*
SendPSendStreamConstructor(mozilla::ipc::PSendStreamChild*) = 0;
protected:
virtual jsipc::PJavaScriptChild* AllocPJavaScriptChild();
virtual bool DeallocPJavaScriptChild(jsipc::PJavaScriptChild*);
virtual PBrowserChild* AllocPBrowserChild(const TabId& aTabId,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const ContentParentId& aCpId,
const bool& aIsForApp,
const bool& aIsForBrowser);
virtual bool DeallocPBrowserChild(PBrowserChild*);
virtual PBlobChild* AllocPBlobChild(const BlobConstructorParams& aParams);
virtual bool DeallocPBlobChild(PBlobChild* aActor);
virtual mozilla::ipc::PSendStreamChild* AllocPSendStreamChild();
virtual bool DeallocPSendStreamChild(mozilla::ipc::PSendStreamChild* aActor);
virtual mozilla::ipc::PFileDescriptorSetChild*
AllocPFileDescriptorSetChild(const mozilla::ipc::FileDescriptor& aFD);
virtual bool
DeallocPFileDescriptorSetChild(mozilla::ipc::PFileDescriptorSetChild* aActor);
virtual bool RecvAsyncMessage(const nsString& aMsg,
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
const ClonedMessageData& aData);
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentChild, NS_ICONTENTCHILD_IID)
} // namespace dom
} // namespace mozilla
#endif /* mozilla_dom_nsIContentChild_h */

View file

@ -0,0 +1,328 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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 "nsIContentParent.h"
#include "mozilla/AppProcessChecker.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/ContentBridgeParent.h"
#include "mozilla/dom/PTabContext.h"
#include "mozilla/dom/PermissionMessageUtils.h"
#include "mozilla/dom/TabParent.h"
#include "mozilla/dom/ipc/BlobParent.h"
#include "mozilla/dom/ipc/StructuredCloneData.h"
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
#include "mozilla/ipc/FileDescriptorSetParent.h"
#include "mozilla/ipc/PFileDescriptorSetParent.h"
#include "mozilla/ipc/SendStreamAlloc.h"
#include "mozilla/Unused.h"
#include "nsFrameMessageManager.h"
#include "nsIWebBrowserChrome.h"
#include "nsPrintfCString.h"
#include "xpcpublic.h"
using namespace mozilla::jsipc;
// XXX need another bug to move this to a common header.
#ifdef DISABLE_ASSERTS_FOR_FUZZING
#define ASSERT_UNLESS_FUZZING(...) do { } while (0)
#else
#define ASSERT_UNLESS_FUZZING(...) MOZ_ASSERT(false, __VA_ARGS__)
#endif
namespace mozilla {
namespace dom {
nsIContentParent::nsIContentParent()
{
mMessageManager = nsFrameMessageManager::NewProcessMessageManager(true);
}
ContentParent*
nsIContentParent::AsContentParent()
{
MOZ_ASSERT(IsContentParent());
return static_cast<ContentParent*>(this);
}
ContentBridgeParent*
nsIContentParent::AsContentBridgeParent()
{
MOZ_ASSERT(IsContentBridgeParent());
return static_cast<ContentBridgeParent*>(this);
}
PJavaScriptParent*
nsIContentParent::AllocPJavaScriptParent()
{
return NewJavaScriptParent();
}
bool
nsIContentParent::DeallocPJavaScriptParent(PJavaScriptParent* aParent)
{
ReleaseJavaScriptParent(aParent);
return true;
}
bool
nsIContentParent::CanOpenBrowser(const IPCTabContext& aContext)
{
// (PopupIPCTabContext lets the child process prove that it has access to
// the app it's trying to open.)
// On e10s we also allow UnsafeTabContext to allow service workers to open
// windows. This is enforced in MaybeInvalidTabContext.
if (aContext.type() != IPCTabContext::TPopupIPCTabContext &&
aContext.type() != IPCTabContext::TUnsafeIPCTabContext) {
ASSERT_UNLESS_FUZZING("Unexpected IPCTabContext type. Aborting AllocPBrowserParent.");
return false;
}
if (aContext.type() == IPCTabContext::TPopupIPCTabContext) {
const PopupIPCTabContext& popupContext = aContext.get_PopupIPCTabContext();
if (popupContext.opener().type() != PBrowserOrId::TPBrowserParent) {
ASSERT_UNLESS_FUZZING("Unexpected PopupIPCTabContext type. Aborting AllocPBrowserParent.");
return false;
}
auto opener = TabParent::GetFrom(popupContext.opener().get_PBrowserParent());
if (!opener) {
ASSERT_UNLESS_FUZZING("Got null opener from child; aborting AllocPBrowserParent.");
return false;
}
// Popup windows of isMozBrowserElement frames must be isMozBrowserElement if
// the parent isMozBrowserElement. Allocating a !isMozBrowserElement frame with
// same app ID would allow the content to access data it's not supposed to.
if (!popupContext.isMozBrowserElement() && opener->IsMozBrowserElement()) {
ASSERT_UNLESS_FUZZING("Child trying to escalate privileges! Aborting AllocPBrowserParent.");
return false;
}
}
MaybeInvalidTabContext tc(aContext);
if (!tc.IsValid()) {
NS_ERROR(nsPrintfCString("Child passed us an invalid TabContext. (%s) "
"Aborting AllocPBrowserParent.",
tc.GetInvalidReason()).get());
return false;
}
return true;
}
PBrowserParent*
nsIContentParent::AllocPBrowserParent(const TabId& aTabId,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const ContentParentId& aCpId,
const bool& aIsForApp,
const bool& aIsForBrowser)
{
Unused << aCpId;
Unused << aIsForApp;
Unused << aIsForBrowser;
if (!CanOpenBrowser(aContext)) {
return nullptr;
}
uint32_t chromeFlags = aChromeFlags;
if (aContext.type() == IPCTabContext::TPopupIPCTabContext) {
// CanOpenBrowser has ensured that the IPCTabContext is of
// type PopupIPCTabContext, and that the opener TabParent is
// reachable.
const PopupIPCTabContext& popupContext = aContext.get_PopupIPCTabContext();
auto opener = TabParent::GetFrom(popupContext.opener().get_PBrowserParent());
// We must ensure that the private browsing and remoteness flags
// match those of the opener.
nsCOMPtr<nsILoadContext> loadContext = opener->GetLoadContext();
if (!loadContext) {
return nullptr;
}
bool isPrivate;
loadContext->GetUsePrivateBrowsing(&isPrivate);
if (isPrivate) {
chromeFlags |= nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
}
}
// And because we're allocating a remote browser, of course the
// window is remote.
chromeFlags |= nsIWebBrowserChrome::CHROME_REMOTE_WINDOW;
MaybeInvalidTabContext tc(aContext);
MOZ_ASSERT(tc.IsValid());
TabParent* parent = new TabParent(this, aTabId, tc.GetTabContext(), chromeFlags);
// We release this ref in DeallocPBrowserParent()
NS_ADDREF(parent);
return parent;
}
bool
nsIContentParent::DeallocPBrowserParent(PBrowserParent* aFrame)
{
TabParent* parent = TabParent::GetFrom(aFrame);
NS_RELEASE(parent);
return true;
}
PBlobParent*
nsIContentParent::AllocPBlobParent(const BlobConstructorParams& aParams)
{
return BlobParent::Create(this, aParams);
}
bool
nsIContentParent::DeallocPBlobParent(PBlobParent* aActor)
{
BlobParent::Destroy(aActor);
return true;
}
BlobParent*
nsIContentParent::GetOrCreateActorForBlob(Blob* aBlob)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aBlob);
RefPtr<BlobImpl> blobImpl = aBlob->Impl();
MOZ_ASSERT(blobImpl);
return GetOrCreateActorForBlobImpl(blobImpl);
}
BlobParent*
nsIContentParent::GetOrCreateActorForBlobImpl(BlobImpl* aImpl)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aImpl);
BlobParent* actor = BlobParent::GetOrCreate(this, aImpl);
NS_ENSURE_TRUE(actor, nullptr);
return actor;
}
bool
nsIContentParent::RecvSyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,
InfallibleTArray<CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
nsTArray<ipc::StructuredCloneData>* aRetvals)
{
// FIXME Permission check in Content process
nsIPrincipal* principal = aPrincipal;
if (IsContentParent()) {
ContentParent* parent = AsContentParent();
if (!ContentParent::IgnoreIPCPrincipal() &&
parent && principal && !AssertAppPrincipal(parent, principal)) {
return false;
}
}
RefPtr<nsFrameMessageManager> ppm = mMessageManager;
if (ppm) {
ipc::StructuredCloneData data;
ipc::UnpackClonedMessageDataForParent(aData, data);
CrossProcessCpowHolder cpows(this, aCpows);
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
aMsg, true, &data, &cpows, aPrincipal, aRetvals);
}
return true;
}
bool
nsIContentParent::RecvRpcMessage(const nsString& aMsg,
const ClonedMessageData& aData,
InfallibleTArray<CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
nsTArray<ipc::StructuredCloneData>* aRetvals)
{
// FIXME Permission check in Content process
nsIPrincipal* principal = aPrincipal;
if (IsContentParent()) {
ContentParent* parent = AsContentParent();
if (!ContentParent::IgnoreIPCPrincipal() &&
parent && principal && !AssertAppPrincipal(parent, principal)) {
return false;
}
}
RefPtr<nsFrameMessageManager> ppm = mMessageManager;
if (ppm) {
ipc::StructuredCloneData data;
ipc::UnpackClonedMessageDataForParent(aData, data);
CrossProcessCpowHolder cpows(this, aCpows);
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
aMsg, true, &data, &cpows, aPrincipal, aRetvals);
}
return true;
}
PFileDescriptorSetParent*
nsIContentParent::AllocPFileDescriptorSetParent(const FileDescriptor& aFD)
{
return new FileDescriptorSetParent(aFD);
}
bool
nsIContentParent::DeallocPFileDescriptorSetParent(PFileDescriptorSetParent* aActor)
{
delete static_cast<FileDescriptorSetParent*>(aActor);
return true;
}
PSendStreamParent*
nsIContentParent::AllocPSendStreamParent()
{
return mozilla::ipc::AllocPSendStreamParent();
}
bool
nsIContentParent::DeallocPSendStreamParent(PSendStreamParent* aActor)
{
delete aActor;
return true;
}
bool
nsIContentParent::RecvAsyncMessage(const nsString& aMsg,
InfallibleTArray<CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
const ClonedMessageData& aData)
{
// FIXME Permission check in Content process
nsIPrincipal* principal = aPrincipal;
if (IsContentParent()) {
ContentParent* parent = AsContentParent();
if (!ContentParent::IgnoreIPCPrincipal() &&
parent && principal && !AssertAppPrincipal(parent, principal)) {
return false;
}
}
RefPtr<nsFrameMessageManager> ppm = mMessageManager;
if (ppm) {
ipc::StructuredCloneData data;
ipc::UnpackClonedMessageDataForParent(aData, data);
CrossProcessCpowHolder cpows(this, aCpows);
ppm->ReceiveMessage(static_cast<nsIContentFrameMessageManager*>(ppm.get()), nullptr,
aMsg, false, &data, &cpows, aPrincipal, nullptr);
}
return true;
}
} // namespace dom
} // namespace mozilla

145
dom/ipc/nsIContentParent.h Normal file
View file

@ -0,0 +1,145 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_nsIContentParent_h
#define mozilla_dom_nsIContentParent_h
#include "mozilla/Attributes.h"
#include "mozilla/dom/ipc/IdType.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "nsFrameMessageManager.h"
#include "nsISupports.h"
#include "mozilla/dom/CPOWManagerGetter.h"
#define NS_ICONTENTPARENT_IID \
{ 0xeeec9ebf, 0x8ecf, 0x4e38, \
{ 0x81, 0xda, 0xb7, 0x34, 0x13, 0x7e, 0xac, 0xf3 } }
namespace IPC {
class Principal;
} // namespace IPC
namespace mozilla {
namespace jsipc {
class PJavaScriptParent;
class CpowEntry;
} // namespace jsipc
namespace ipc {
class PFileDescriptorSetParent;
class PSendStreamParent;
}
namespace dom {
class Blob;
class BlobConstructorParams;
class BlobImpl;
class BlobParent;
class ContentParent;
class ContentBridgeParent;
class IPCTabContext;
class PBlobParent;
class PBrowserParent;
class nsIContentParent : public nsISupports
, public mozilla::dom::ipc::MessageManagerCallback
, public CPOWManagerGetter
, public mozilla::ipc::IShmemAllocator
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENTPARENT_IID)
nsIContentParent();
BlobParent* GetOrCreateActorForBlob(Blob* aBlob);
BlobParent* GetOrCreateActorForBlobImpl(BlobImpl* aImpl);
virtual ContentParentId ChildID() const = 0;
virtual bool IsForApp() const = 0;
virtual bool IsForBrowser() const = 0;
MOZ_MUST_USE virtual PBlobParent*
SendPBlobConstructor(PBlobParent* aActor,
const BlobConstructorParams& aParams) = 0;
MOZ_MUST_USE virtual PBrowserParent*
SendPBrowserConstructor(PBrowserParent* actor,
const TabId& aTabId,
const IPCTabContext& context,
const uint32_t& chromeFlags,
const ContentParentId& aCpId,
const bool& aIsForApp,
const bool& aIsForBrowser) = 0;
virtual bool IsContentParent() const { return false; }
ContentParent* AsContentParent();
virtual bool IsContentBridgeParent() const { return false; }
ContentBridgeParent* AsContentBridgeParent();
nsFrameMessageManager* GetMessageManager() const { return mMessageManager; }
virtual int32_t Pid() const = 0;
protected: // methods
bool CanOpenBrowser(const IPCTabContext& aContext);
protected: // IPDL methods
virtual mozilla::jsipc::PJavaScriptParent* AllocPJavaScriptParent();
virtual bool DeallocPJavaScriptParent(mozilla::jsipc::PJavaScriptParent*);
virtual PBrowserParent* AllocPBrowserParent(const TabId& aTabId,
const IPCTabContext& aContext,
const uint32_t& aChromeFlags,
const ContentParentId& aCpId,
const bool& aIsForApp,
const bool& aIsForBrowser);
virtual bool DeallocPBrowserParent(PBrowserParent* frame);
virtual PBlobParent* AllocPBlobParent(const BlobConstructorParams& aParams);
virtual bool DeallocPBlobParent(PBlobParent* aActor);
virtual mozilla::ipc::PFileDescriptorSetParent*
AllocPFileDescriptorSetParent(const mozilla::ipc::FileDescriptor& aFD);
virtual bool
DeallocPFileDescriptorSetParent(mozilla::ipc::PFileDescriptorSetParent* aActor);
virtual mozilla::ipc::PSendStreamParent* AllocPSendStreamParent();
virtual bool DeallocPSendStreamParent(mozilla::ipc::PSendStreamParent* aActor);
virtual bool RecvSyncMessage(const nsString& aMsg,
const ClonedMessageData& aData,
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
nsTArray<ipc::StructuredCloneData>* aRetvals);
virtual bool RecvRpcMessage(const nsString& aMsg,
const ClonedMessageData& aData,
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
nsTArray<ipc::StructuredCloneData>* aRetvals);
virtual bool RecvAsyncMessage(const nsString& aMsg,
InfallibleTArray<jsipc::CpowEntry>&& aCpows,
const IPC::Principal& aPrincipal,
const ClonedMessageData& aData);
protected: // members
RefPtr<nsFrameMessageManager> mMessageManager;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentParent, NS_ICONTENTPARENT_IID)
} // namespace dom
} // namespace mozilla
#endif /* mozilla_dom_nsIContentParent_h */

66
dom/ipc/nsIHangReport.idl Normal file
View file

@ -0,0 +1,66 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:set ts=2 sw=2 sts=2 et cindent: */
/* 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 nsIDOMElement;
interface nsIFrameLoader;
/**
* When a content process hangs, Gecko notifies "process-hang-report" observers
* and passes an nsIHangReport for the subject parameter. There is at most one
* nsIHangReport associated with a given content process. As long as the content
* process stays stuck, the "process-hang-report" observer will continue to be
* notified at regular intervals (approximately once per second). The content
* process will continue to run uninhibitedly during this time.
*/
[scriptable, uuid(5fcffbb9-be62-49b1-b8a1-36e820787a74)]
interface nsIHangReport : nsISupports
{
const unsigned long SLOW_SCRIPT = 1;
const unsigned long PLUGIN_HANG = 2;
// The type of hang being reported: SLOW_SCRIPT or PLUGIN_HANG.
readonly attribute unsigned long hangType;
// For SLOW_SCRIPT reports, these fields contain information about the
// slow script.
// Only valid for SLOW_SCRIPT reports.
readonly attribute nsIDOMElement scriptBrowser;
readonly attribute ACString scriptFileName;
readonly attribute unsigned long scriptLineNo;
// For PLUGIN_HANGs, this field contains information about the plugin.
// Only valid for PLUGIN_HANG reports.
readonly attribute ACString pluginName;
// Called by front end code when user ignores or cancels
// the notification.
void userCanceled();
// Terminate the slow script if it is still running.
// Only valid for SLOW_SCRIPT reports.
void terminateScript();
// Terminate the plugin if it is still hung.
// Only valid for PLUGIN_HANG reports.
void terminatePlugin();
// Ask the content process to start up the slow script debugger.
// Only valid for SLOW_SCRIPT reports.
void beginStartingDebugger();
// Inform the content process that the slow script debugger has finished
// spinning up. The content process will run a nested event loop until this
// method is called.
// Only valid for SLOW_SCRIPT reports.
void endStartingDebugger();
// Inquire whether the report is for a content process loaded by the given
// frameloader.
bool isReportForBrowser(in nsIFrameLoader aFrameLoader);
};

45
dom/ipc/nsIRemoteBlob.h Normal file
View file

@ -0,0 +1,45 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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_ipc_nsIRemoteBlob_h
#define mozilla_dom_ipc_nsIRemoteBlob_h
#include "nsISupports.h"
#ifndef NS_NO_VTABLE
#define NS_NO_VTABLE
#endif
#define NS_IREMOTEBLOB_IID \
{0x0b8b0091, 0xb315, 0x48a2, {0x90, 0xf1, 0x60, 0x0e, 0x78, 0x35, 0xf7, 0x2d}}
namespace mozilla {
namespace dom {
class BlobChild;
class BlobParent;
} // namespace dom
} // namespace mozilla
class NS_NO_VTABLE nsIRemoteBlob : public nsISupports
{
public:
typedef mozilla::dom::BlobChild BlobChild;
typedef mozilla::dom::BlobParent BlobParent;
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IREMOTEBLOB_IID)
virtual BlobChild*
GetBlobChild() = 0;
virtual BlobParent*
GetBlobParent() = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIRemoteBlob, NS_IREMOTEBLOB_IID)
#endif // mozilla_dom_ipc_nsIRemoteBlob_h

130
dom/ipc/preload.js Normal file
View file

@ -0,0 +1,130 @@
/* 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/. */
// Preload some things, in an attempt to make app startup faster.
//
// This script is run when the preallocated process starts. It is injected as
// a frame script.
var BrowserElementIsPreloaded = true;
var DoPreloadPostfork = function(aCallback) {
Services.obs.addObserver({
_callback: aCallback,
observe: function() {
this._callback();
Services.obs.removeObserver(this, "preload-postfork");
}
}, "preload-postfork", false);
};
(function (global) {
"use strict";
let Cu = Components.utils;
let Cc = Components.classes;
let Ci = Components.interfaces;
Cu.import("resource://gre/modules/AppsUtils.jsm");
Cu.import("resource://gre/modules/BrowserElementPromptService.jsm");
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
Cu.import("resource://gre/modules/Geometry.jsm");
Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/SettingsDB.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cc["@mozilla.org/appshell/appShellService;1"].getService(Ci["nsIAppShellService"]);
Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci["nsIWindowMediator"]);
Cc["@mozilla.org/base/telemetry;1"].getService(Ci["nsITelemetry"]);
Cc["@mozilla.org/categorymanager;1"].getService(Ci["nsICategoryManager"]);
Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci["nsIMessageSender"]);
Cc["@mozilla.org/consoleservice;1"].getService(Ci["nsIConsoleService"]);
Cc["@mozilla.org/docshell/urifixup;1"].getService(Ci["nsIURIFixup"]);
Cc["@mozilla.org/dom/dom-request-service;1"].getService(Ci["nsIDOMRequestService"]);
Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci["nsIPromptService"]);
Cc["@mozilla.org/embedcomp/window-watcher;1"].getService(Ci["nsIWindowWatcher"]);
Cc["@mozilla.org/eventlistenerservice;1"].getService(Ci["nsIEventListenerService"]);
Cc["@mozilla.org/focus-manager;1"].getService(Ci["nsIFocusManager"]);
Cc["@mozilla.org/intl/nslocaleservice;1"].getService(Ci["nsILocaleService"]);
Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci["nsIStringBundleService"]);
Cc["@mozilla.org/layout/content-policy;1"].getService(Ci["nsIContentPolicy"]);
Cc["@mozilla.org/message-loop;1"].getService(Ci["nsIMessageLoop"]);
Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci["mozIJSSubScriptLoader"]);
Cc["@mozilla.org/network/application-cache-service;1"].getService(Ci["nsIApplicationCacheService"]);
Cc["@mozilla.org/network/dns-service;1"].getService(Ci["nsIDNSService"]);
Cc["@mozilla.org/network/effective-tld-service;1"].getService(Ci["nsIEffectiveTLDService"]);
Cc["@mozilla.org/network/idn-service;1"].getService(Ci["nsIIDNService"]);
Cc["@mozilla.org/network/io-service;1"].getService(Ci["nsIIOService2"]);
Cc["@mozilla.org/network/mime-hdrparam;1"].getService(Ci["nsIMIMEHeaderParam"]);
Cc["@mozilla.org/network/socket-transport-service;1"].getService(Ci["nsISocketTransportService"]);
Cc["@mozilla.org/network/stream-transport-service;1"].getService(Ci["nsIStreamTransportService"]);
Cc["@mozilla.org/network/url-parser;1?auth=maybe"].getService(Ci["nsIURLParser"]);
Cc["@mozilla.org/network/url-parser;1?auth=no"].getService(Ci["nsIURLParser"]);
Cc["@mozilla.org/network/url-parser;1?auth=yes"].getService(Ci["nsIURLParser"]);
Cc["@mozilla.org/observer-service;1"].getService(Ci["nsIObserverService"]);
Cc["@mozilla.org/preferences-service;1"].getService(Ci["nsIPrefBranch"]);
Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci["nsIScriptSecurityManager"]);
Cc["@mozilla.org/storage/service;1"].getService(Ci["mozIStorageService"]);
Cc["@mozilla.org/system-info;1"].getService(Ci["nsIPropertyBag2"]);
Cc["@mozilla.org/thread-manager;1"].getService(Ci["nsIThreadManager"]);
Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci["nsIAppStartup"]);
Cc["@mozilla.org/uriloader;1"].getService(Ci["nsIURILoader"]);
Cc["@mozilla.org/cspcontext;1"].createInstance(Ci["nsIContentSecurityPolicy"]);
Cc["@mozilla.org/settingsManager;1"].createInstance(Ci["nsISupports"]);
/* Applications Specific Helper */
try {
if (Services.prefs.getBoolPref("dom.sysmsg.enabled")) {
Cc["@mozilla.org/system-message-manager;1"].getService(Ci["nsIDOMNavigatorSystemMessages"]);
}
} catch(e) {
}
try {
if (Services.prefs.getBoolPref("dom.mozInputMethod.enabled")) {
Services.scriptloader.loadSubScript("chrome://global/content/forms.js", global);
}
} catch (e) {
}
Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementCopyPaste.js", global);
Services.scriptloader.loadSubScript("chrome://global/content/BrowserElementChildPreload.js", global);
Services.io.getProtocolHandler("app");
Services.io.getProtocolHandler("default");
// Register an observer for topic "preload_postfork" after we fork a content
// process.
DoPreloadPostfork(function () {
// Load AppsServiceChild.jsm after fork since it sends an async message to
// the chrome process in its init() function.
Cu.import("resource://gre/modules/AppsServiceChild.jsm");
// Load nsIAppsService after fork since its implementation loads
// AppsServiceChild.jsm
Cc["@mozilla.org/AppsService;1"].getService(Ci["nsIAppsService"]);
// Load nsICookieService after fork since it sends an IPC constructor
// message to the chrome process.
Cc["@mozilla.org/cookieService;1"].getService(Ci["nsICookieService"]);
// Load nsIPermissionManager after fork since it sends a message to the
// chrome process to read permissions.
Cc["@mozilla.org/permissionmanager;1"].getService(Ci["nsIPermissionManager"]);
// Load nsIProtocolProxyService after fork since it asynchronously accesses
// the "Proxy Resolution" thread after it's frozen.
Cc["@mozilla.org/network/protocol-proxy-service;1"].getService(Ci["nsIProtocolProxyService"]);
// Call docShell.createAboutBlankContentViewer() after fork since it has IPC
// activity in the PCompositor protocol.
docShell.createAboutBlankContentViewer(null);
docShell.isActive = false;
});
})(this);

54
dom/ipc/remote-test.js Normal file
View file

@ -0,0 +1,54 @@
/* 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/. */
dump("Loading remote script!\n");
dump(content + "\n");
var cpm = Components.classes["@mozilla.org/childprocessmessagemanager;1"]
.getService(Components.interfaces.nsISyncMessageSender);
cpm.addMessageListener("cpm-async",
function(m) {
cpm.sendSyncMessage("ppm-sync");
dump(content.document.documentElement);
cpm.sendAsyncMessage("ppm-async");
});
var Cc = Components.classes;
var Ci = Components.interfaces;
var dshell = content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIDocShell);
addEventListener("click",
function(e) {
dump(e.target + "\n");
if (e.target instanceof Components.interfaces.nsIDOMHTMLAnchorElement &&
dshell == docShell) {
var retval = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsIContentFrameMessageManager).
sendSyncMessage("linkclick", { href: e.target.href });
dump(uneval(retval[0]) + "\n");
// Test here also that both retvals are the same
sendAsyncMessage("linkclick-reply-object", uneval(retval[0]) == uneval(retval[1]) ? retval[0] : "");
}
},
true);
addMessageListener("chrome-message",
function(m) {
dump(uneval(m.json) + "\n");
sendAsyncMessage("chrome-message-reply", m.json);
});
addMessageListener("speed-test-start",
function(m) {
while (sendSyncMessage("speed-test")[0].message != "done");
});
addMessageListener("async-echo", function(m) {
sendAsyncMessage(m.name);
});

274
dom/ipc/test.xul Normal file
View file

@ -0,0 +1,274 @@
<?xml version="1.0"?>
<!-- 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/. -->
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
width="800" height="800" orient="vertical" onload="initRemoteFrameScript();">
<script>
function dumpClientRect(r) {
dump(r.left + "," + r.top + "," + r.right + "," +
r.bottom + "," + r.width + "," + r.height + "\n");
}
function handleMozAfterPaint(e) {
return;
dump(e.type + "\n")
var rects = e.clientRects;
var i;
dump("\tclientRects:\n");
for (i = 0; i &lt; rects.length; ++i) {
var r = rects.item(i);
dump("\t\t");
dumpClientRect(rects.item(i));
}
dump("\tboundingClientRect\n\t\t");
dumpClientRect(e.boundingClientRect);
var paintRequests = e.paintRequests;
dump("\tpaintRequests\n");
for (i = 0; i &lt; paintRequests.length; ++i) {
var pr = paintRequests.item(i);
dump("\t\t");
dumpClientRect(pr.clientRect);
if (pr.reason)
dump("\t\t" + pr.reason + "\n");
}
}
function handleMozScrolledAreaChanged(e) {
return;
dump(e.type + "\n");
dump("\t" + e.x + "," + e.y + "," + e.width + "," + e.height + "\n");
}
function restart() {
var y = document.getElementById('page');
var p = y.parentNode;
p.removeChild(y);
p.appendChild(y);
var fl = y.QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
fl.activateFrameEvent("MozAfterPaint", true);
fl.activateFrameEvent("MozScrolledAreaChanged", true);
y.addEventListener("MozAfterPaint", handleMozAfterPaint, true);
y.addEventListener("MozScrolledAreaChanged", handleMozScrolledAreaChanged, true);
}
function loadURL(url) {
document.getElementById('page').setAttribute('src', url);
}
function randomClick() {
// First focus the remote frame, then dispatch click. This way remote frame gets focus before
// mouse event.
document.getElementById('page').focus();
var frameLoader = document.getElementById('page').QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
var x = parseInt(Math.random() * 100);
var y = parseInt(Math.random() * 100);
frameLoader.sendCrossProcessMouseEvent("mousedown", x, y, 0, 1, 0, false);
frameLoader.sendCrossProcessMouseEvent("mouseup", x, y, 0, 1, 0, false);
}
function keyPress() {
// First focus the remote frame, then dispatch click. This way remote frame gets focus before
// mouse event.
document.getElementById('page').focus();
var frameLoader = document.getElementById('page').QueryInterface(Components.interfaces.nsIFrameLoaderOwner).frameLoader;
var keyCode = Components.interfaces.nsIDOMKeyEvent.DOM_VK_A;
frameLoader.sendCrossProcessKeyEvent("keydown", keyCode, 0, 0);
frameLoader.sendCrossProcessKeyEvent("keypress", keyCode, 0, 0);
frameLoader.sendCrossProcessKeyEvent("keyup", keyCode, 0, 0);
}
function openWindow() {
window.open('chrome://global/content/test-ipc.xul', '_blank', 'chrome,resizable,width=800,height=800');
}
function closeWindow() {
window.close();
}
function initRemoteFrameScript() {
// 1. Test that loading a script works, and that accessing process level mm and
// global mm works.
var ppm = Components.classes["@mozilla.org/parentprocessmessagemanager;1"]
.getService(Components.interfaces.nsIMessageBroadcaster);
var gm = Components.classes["@mozilla.org/globalmessagemanager;1"]
.getService(Components.interfaces.nsIMessageBroadcaster);
var cpm = Components.classes["@mozilla.org/childprocessmessagemanager;1"]
.getService(Components.interfaces.nsISyncMessageSender);
if (ppm.childCount != 2) {
alert("Should have two child processes!");
}
var childprocessmm = ppm.getChildAt(1); // 0 is the in-process child process mm
childprocessmm.addMessageListener("ppm-sync",
function(m) {
if (m.target != childprocessmm) alert("Wrong target!");
document.getElementById("messageLog").value += "[SYNC1 PPM]";
}
);
ppm.addMessageListener("ppm-sync",
function(m) {
// Check that global process message manager gets the per-process mm as target.
if (m.target != childprocessmm) alert("Wrong target!");
document.getElementById("messageLog").value += "[SYNC2 PPM]";
}
);
childprocessmm.addMessageListener("ppm-async",
function(m) {
if (m.target != childprocessmm) alert("Wrong target!");
document.getElementById("messageLog").value += "[ASYNC1 PPM]";
}
);
ppm.addMessageListener("ppm-async",
function(m) {
// Check that global process message manager gets the per-process mm as target.
if (m.target != childprocessmm) alert("Wrong target!");
document.getElementById("messageLog").value += "[ASYNC2 PPM]";
}
);
messageManager.loadFrameScript("chrome://global/content/remote-test-ipc.js", true);
ppm.sendAsyncMessage("cpm-async");
// 2. Test that adding message listener works, and that receiving a sync message works.
messageManager.addMessageListener("linkclick",
function(m) {
// This checks that json sending works in sync messages.
document.getElementById("messageLog").value = m.name + ": " + m.json.href;
return { message: "linkclick-received" };
});
// 3. Test that returning multiple json results works.
messageManager.addMessageListener("linkclick",
function(m) {
return { message: "linkclick-received" };
});
// 4. Test that receiving an async message works.
// Test also that sending async message to content works.
// Test also that { receiveMessage: function(m) {} } works.
messageManager.addMessageListener("linkclick-reply-object",
{ foobarObjectVar: true,
receiveMessage: function(m) {
var s = (m.json.message == "linkclick-received") &amp;&amp;
(this.foobarObjectVar) ? "PASS" : "FAIL";
messageManager.broadcastAsyncMessage("chrome-message", { ok : s } );
}
}
);
// 5. Final test to check that everything went ok.
messageManager.addMessageListener("chrome-message-reply",
function(m) {
// Check that 'this' and .target values are handled correctly
if (m.target == document.getElementById("page") &amp;&amp;
this == messageManager) {
// Check that the message properties are enumerable.
var hasName = false;
var hasSync = false;
var hasJSON = false;
for (i in m) {
if (i == "name") {
hasName = true;
} else if (i == "sync") {
hasSync = true;
} else if (i == "json") {
hasJSON = true;
}
}
if (hasName &amp;&amp; hasSync &amp;&amp; hasJSON) {
document.getElementById("messageLog").value += ", " + m.json.ok;
}
}
});
}
var speedTestStartTime = 0;
var speedTestCount = 0;
function messageSpeed() {
speedTestCount = 0;
messageManager.addMessageListener("speed-test", speedHandler);
messageManager.broadcastAsyncMessage("speed-test-start");
}
function speedHandler() {
if (!speedTestCount) {
speedTestStartTime = new Date().getTime();
}
if (++speedTestCount == 1000) {
setTimeout("alert('" + speedTestCount + " in " + (new Date().getTime() - speedTestStartTime) + "ms')", 0);
return { message: "done" };
}
return { message: "continue" };
}
var addRemoveTestCount = 0;
function echoListener() {
if (++addRemoveTestCount == 1) {
alert("Expected echo message");
messageManager.removeMessageListener("async-echo", echoListener);
messageManager.broadcastAsyncMessage("async-echo");
return;
}
alert("Unexpected echo message");
}
function listenerAddRemove() {
addRemoveTestCount = 0;
messageManager.addMessageListener("async-echo", echoListener);
messageManager.broadcastAsyncMessage("async-echo");
}
var MozAfterPaintCount = 0;
function enableMozAfterPaint() {
messageManager.addMessageListener("MozAfterPaint",
function(m) {
document.getElementById("messageLog").value = m.name + "[" + (++MozAfterPaintCount) + "]";
});
messageManager.loadFrameScript("data:,addEventListener('MozAfterPaint', function(e) { sendAsyncMessage('MozAfterPaint'); },true);", false);
}
var Ci = Components.interfaces;
var Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
</script>
<toolbar id="controls">
<toolbarbutton label="Back"/>
<toolbarbutton label="Forward"/>
<textbox onchange="loadURL(this.value)" flex="1" id="URL"/>
</toolbar>
<toolbar>
<toolbarbutton onclick="restart()" label="Recover"/>
<toolbarbutton onclick="randomClick()" label="random click"/>
<toolbarbutton onclick="keyPress()" label="key press"/>
<toolbarbutton onclick="messageSpeed()" label="test message handling speed"/>
<toolbarbutton onclick="listenerAddRemove()" label="test listener add/remove"/>
<toolbarbutton onclick="enableMozAfterPaint()" label="MozAfterPaint"/>
<toolbarbutton onclick="openWindow()" label="open new window"/>
<toolbarbutton onclick="closeWindow()" label="close this window"/>
</toolbar>
<toolbar><label value="Load a script (URL) to content process:"/>
<textbox flex="1" id="script"/><button
label="send" oncommand="document.getElementById('page')
.QueryInterface(Components.interfaces.nsIFrameLoaderOwner)
.frameLoader.messageManager
.loadFrameScript(this.previousSibling.value, false);"/>
</toolbar>
<toolbar>
<label value="Eval script in chrome context"/>
<textbox flex="1"/><button label="run" oncommand="eval(this.previousSibling.value);"/>
</toolbar>
<browser type="content" src="http://www.google.com/" flex="1" id="page" remote="true"/>
<label id="messageLog" value="" crop="center"/>
</window>

View file

@ -0,0 +1,20 @@
const CC = Components.Constructor;
const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1",
"nsIBinaryInputStream",
"setInputStream");
const BinaryOutputStream = CC("@mozilla.org/binaryoutputstream;1",
"nsIBinaryOutputStream",
"setOutputStream");
function handleRequest(request, response) {
var bodyStream = new BinaryInputStream(request.bodyInputStream);
var bodyBytes = [];
while ((bodyAvail = bodyStream.available()) > 0)
Array.prototype.push.apply(bodyBytes, bodyStream.readByteArray(bodyAvail));
var bos = new BinaryOutputStream(response.bodyOutputStream);
response.processAsync();
bos.writeByteArray(bodyBytes, bodyBytes.length);
response.finish();
}

View file

@ -0,0 +1,6 @@
[DEFAULT]
support-files =
file_disableScript.html
file_domainPolicy_base.html
[browser_domainPolicy.js]

View file

@ -0,0 +1,240 @@
var policy; // To make sure we never leave up an activated domain policy after a failed test, let's make this global.
function activateDomainPolicy() {
const ssm = Services.scriptSecurityManager;
policy = ssm.activateDomainPolicy();
}
function deactivateDomainPolicy() {
if (policy) {
policy.deactivate();
policy = null;
}
}
function* test_domainPolicy() {
XPCOMUtils.defineLazyModuleGetter(this, "Promise", "resource://gre/modules/Promise.jsm");
let deferred = Promise.defer();
let currentTask = deferred.promise;
SpecialPowers.pushPrefEnv(
{set: [["dom.ipc.browser_frames.oop_by_default", false],
["browser.pagethumbnails.capturing_disabled", false],
["dom.mozBrowserFramesEnabled", false]]},
() => { return deferred.resolve()});
yield currentTask;
// Create tab
let tab;
// Init test
function initProcess() {
tab = gBrowser.addTab();
gBrowser.selectedTab = tab;
let initPromise = ContentTask.spawn(tab.linkedBrowser, null, function() {
Cu.import("resource://gre/modules/PromiseUtils.jsm");
function loadBase() {
let deferred = PromiseUtils.defer();
let listener = (event) => {
removeEventListener("DOMDocElementInserted", listener, true);
let listener2 = (event) => {
content.removeEventListener('load', listener2);
deferred.resolve();
}
content.addEventListener('load', listener2);
};
addEventListener("DOMDocElementInserted", listener, true);
return deferred.promise;
}
return loadBase();
});
tab.linkedBrowser.loadURI("http://mochi.test:8888/browser/dom/ipc/tests/file_domainPolicy_base.html");
return initPromise;
}
// We use ContentTask for the tests, but we also want to pass some data and some helper functions too.
// To do that, we serialize an input object via JSON |ipcArgs| and some shared helper functions |initUtils|
// and eval them in the content process.
var ipcArgs = {};
function initUtils(obj) {
obj.checkScriptEnabled = function(win, expectEnabled) {
win.wrappedJSObject.gFiredOnclick = false;
win.document.body.dispatchEvent(new win.Event('click'));
return { passed: win.wrappedJSObject.gFiredOnclick == expectEnabled,
msg: `Checking script-enabled for ${win.name} (${win.location})`};
}
obj.navigateFrame = function(ifr, src) {
let deferred = PromiseUtils.defer();
function onload() {
ifr.removeEventListener('load', onload);
deferred.resolve();
}
ifr.addEventListener('load', onload, false);
ifr.setAttribute('src', src);
return deferred.promise;
}
};
function runTest(test) {
return ContentTask.spawn(tab.linkedBrowser,
'ipcArgs = ' + JSON.stringify(ipcArgs) + '; (' + initUtils.toSource() + ')(utils)', test);
}
function checkAndCleanup(result) {
result = [].concat(result);
for (var i in result)
ok(result[i].passed, result[i].msg);
gBrowser.removeTab(tab);
deactivateDomainPolicy();
ipcArgs = {};
}
function testDomain(domain) {
ipcArgs.domain = domain;
return (aUtils) => {
Cu.import("resource://gre/modules/PromiseUtils.jsm");
var ipcArgs;
var utils = {};
eval(aUtils);
let path = '/browser/dom/ipc/tests/file_disableScript.html';
let deferred = PromiseUtils.defer();
var rootFrame = content.document.getElementById('root');
utils.navigateFrame(rootFrame, ipcArgs.domain + path).then(() => {
deferred.resolve(utils.checkScriptEnabled(rootFrame.contentWindow, false));
});
return deferred.promise;
}
}
info("Testing simple blacklist policy");
info("Creating child process first, activating domainPolicy after");
currentTask = initProcess();
yield currentTask;
activateDomainPolicy();
var bl = policy.blacklist;
bl.add(Services.io.newURI('http://example.com', null, null));
currentTask = runTest(testDomain("http://example.com"));
checkAndCleanup(yield currentTask);
info("Activating domainPolicy first, creating child process after");
activateDomainPolicy();
var bl = policy.blacklist;
bl.add(Services.io.newURI('http://example.com', null, null));
currentTask = initProcess();
yield currentTask;
currentTask = runTest(testDomain("http://example.com"));
checkAndCleanup(yield currentTask);
function testList(expectEnabled, list) {
ipcArgs.expectEnabled = expectEnabled;
ipcArgs.list = list;
return (aUtils) => {
Cu.import("resource://gre/modules/PromiseUtils.jsm");
var ipcArgs;
var utils = {};
eval(aUtils);
var results = [];
var testListInternal = function(expectEnabled, list, idx) {
idx = idx || 0;
let deferred = PromiseUtils.defer();
let path = '/browser/dom/ipc/tests/file_disableScript.html';
let target = list[idx] + path;
var rootFrame = content.document.getElementById('root');
utils.navigateFrame(rootFrame, target).then(function() {
results.push(utils.checkScriptEnabled(rootFrame.contentWindow, expectEnabled));
if (idx == list.length - 1)
deferred.resolve(results);
else
testListInternal(expectEnabled, list, idx + 1).then(function(retArg) { deferred.resolve(retArg); });
});
return deferred.promise;
}
return testListInternal(ipcArgs.expectEnabled, ipcArgs.list);
}
}
let testPolicy = {
exceptions: ['http://test1.example.com', 'http://example.com'],
superExceptions: ['http://test2.example.org', 'https://test1.example.com'],
exempt: ['http://test1.example.com', 'http://example.com',
'http://test2.example.org', 'http://sub1.test2.example.org',
'https://sub1.test1.example.com'],
notExempt: ['http://test2.example.com', 'http://sub1.test1.example.com',
'http://www.example.com', 'https://test2.example.com',
'https://example.com', 'http://test1.example.org'],
};
function activate(isBlack, exceptions, superExceptions) {
activateDomainPolicy();
let set = isBlack ? policy.blacklist : policy.whitelist;
let superSet = isBlack ? policy.superBlacklist : policy.superWhitelist;
for (var e of exceptions)
set.add(makeURI(e));
for (var e of superExceptions)
superSet.add(makeURI(e));
};
info("Testing Blacklist-style Domain Policy");
info("Activating domainPolicy first, creating child process after");
activate(true, testPolicy.exceptions, testPolicy.superExceptions);
currentTask = initProcess();
yield currentTask;
let results = [];
currentTask = runTest(testList(true, testPolicy.notExempt));
results = results.concat(yield currentTask);
currentTask = runTest(testList(false, testPolicy.exempt));
results = results.concat(yield currentTask);
checkAndCleanup(results);
info("Creating child process first, activating domainPolicy after");
currentTask = initProcess();
yield currentTask;
activate(true, testPolicy.exceptions, testPolicy.superExceptions);
results = [];
currentTask = runTest(testList(true, testPolicy.notExempt));
results = results.concat(yield currentTask);
currentTask = runTest(testList(false, testPolicy.exempt));
results = results.concat(yield currentTask);
checkAndCleanup(results);
info("Testing Whitelist-style Domain Policy");
deferred = Promise.defer();
currentTask = deferred.promise;
SpecialPowers.pushPrefEnv({set:[["javascript.enabled", false]]}, () => { return deferred.resolve()});
yield currentTask;
info("Activating domainPolicy first, creating child process after");
activate(false, testPolicy.exceptions, testPolicy.superExceptions);
currentTask = initProcess();
yield currentTask;
results = [];
currentTask = runTest(testList(false, testPolicy.notExempt));
results = results.concat(yield currentTask);
currentTask = runTest(testList(true, testPolicy.exempt));
results = results.concat(yield currentTask);
checkAndCleanup(results);
info("Creating child process first, activating domainPolicy after");
currentTask = initProcess();
yield currentTask;
activate(false, testPolicy.exceptions, testPolicy.superExceptions);
results = [];
currentTask = runTest(testList(false, testPolicy.notExempt));
results = results.concat(yield currentTask);
currentTask = runTest(testList(true, testPolicy.exempt));
results = results.concat(yield currentTask);
checkAndCleanup(results);
finish();
}
add_task(test_domainPolicy);
registerCleanupFunction(()=>{
deactivateDomainPolicy();
})

8
dom/ipc/tests/chrome.ini Normal file
View file

@ -0,0 +1,8 @@
[DEFAULT]
skip-if = os == 'android'
support-files =
process_error.xul
process_error_contentscript.js
[test_process_error.xul]
skip-if = !crashreporter

View file

@ -0,0 +1,16 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1086684
-->
<head>
<title>Test for Bug 1086684</title>
<meta charset="UTF-8">
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1086684">Mozilla Bug 1086684</a>
<div id="content">
<input type="file" id="f">
</div>
</body>
</html>

View file

@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<script>
var gFiredOnload = false;
var gFiredOnclick = false;
</script>
</head>
<body onload="gFiredOnload = true;" onclick="gFiredOnclick = true;">
</body>
</html>

View file

@ -0,0 +1,8 @@
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<iframe id="root" name="root"/>
</body>
</html>

View file

@ -0,0 +1,22 @@
[DEFAULT]
support-files =
file_bug1086684.html
[test_blob_sliced_from_child_process.html]
# This test is only supposed to run in the main process.
skip-if = e10s
[test_blob_sliced_from_parent_process.html]
# This test is only supposed to run in the main process.
skip-if = e10s
[test_bug1086684.html]
# This test is only supposed to run in the main process
skip-if = e10s || toolkit == 'android'
[test_cpow_cookies.html]
[test_child_docshell.html]
skip-if = toolkit == 'cocoa' # disabled due to hangs, see changeset 6852e7c47edf
[test_CrashService_crash.html]
skip-if = !(crashreporter && !e10s && (toolkit == 'gtk2' || toolkit == 'gtk3' || toolkit == 'cocoa' || toolkit == 'windows'))
[test_temporaryfile_stream.html]
support-files =
blob_verify.sjs
!/dom/canvas/test/captureStream_common.js

View file

@ -0,0 +1,58 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
orient="vertical">
<browser id="thebrowser" type="content" remote="true" />
<script type="application/javascript"><![CDATA[
Components.utils.import("resource://gre/modules/Services.jsm");
const ok = window.opener.wrappedJSObject.ok;
const is = window.opener.wrappedJSObject.is;
const done = window.opener.wrappedJSObject.done;
const SimpleTest = window.opener.wrappedJSObject.SimpleTest;
function getMinidumpDirectory() {
var dir = Services.dirsvc.get('ProfD', Components.interfaces.nsIFile);
dir.append("minidumps");
return dir;
}
function removeFile(directory, filename) {
var file = directory.clone();
file.append(filename);
if (file.exists()) {
file.remove(false);
}
}
function crashObserver(subject, topic, data) {
is(topic, 'ipc:content-shutdown', 'Received correct observer topic.');
ok(subject instanceof Components.interfaces.nsIPropertyBag2,
'Subject implements nsIPropertyBag2.');
var dumpID;
if ('nsICrashReporter' in Components.interfaces) {
dumpID = subject.getPropertyAsAString('dumpID');
ok(dumpID, "dumpID is present and not an empty string");
}
if (dumpID) {
var minidumpDirectory = getMinidumpDirectory();
removeFile(minidumpDirectory, dumpID + '.dmp');
removeFile(minidumpDirectory, dumpID + '.extra');
}
Services.obs.removeObserver(crashObserver, 'ipc:content-shutdown');
done();
}
Services.obs.addObserver(crashObserver, 'ipc:content-shutdown', false);
document.getElementById('thebrowser')
.QueryInterface(Components.interfaces.nsIFrameLoaderOwner)
.frameLoader.messageManager
.loadFrameScript('chrome://mochitests/content/chrome/dom/ipc/tests/process_error_contentscript.js', true);
]]></script>
</window>

View file

@ -0,0 +1,7 @@
Components.utils.import("resource://gre/modules/ctypes.jsm");
privateNoteIntentionalCrash();
var zero = new ctypes.intptr_t(8);
var badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t));
var crash = badptr.contents;

View file

@ -0,0 +1,95 @@
<!DOCTYPE HTML>
<html>
<!--
Ensures that content crashes are reported to the crash service
(nsICrashService and CrashManager.jsm).
-->
<head>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.7">
"use strict";
SimpleTest.waitForExplicitFinish();
SimpleTest.requestFlakyTimeout("untriaged");
SpecialPowers.addPermission("browser", true, document);
SpecialPowers.pushPrefEnv({'set':[
["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true],
["dom.ipc.tabs.disabled", false]
]}, function () {
var iframe = document.createElementNS('http://www.w3.org/1999/xhtml', 'iframe');
iframe.setAttribute("remote", "true");
SpecialPowers.wrap(iframe).mozbrowser = true;
document.documentElement.appendChild(iframe);
SimpleTest.expectChildProcessCrash();
var crashMan =
SpecialPowers.Cu.import("resource://gre/modules/Services.jsm").
Services.crashmanager;
// First, clear the crash record store.
info("Waiting for pruneOldCrashes");
var future = new Date(Date.now() + 1000 * 60 * 60 * 24);
crashMan.pruneOldCrashes(future).then(function () {
var crashDateMS = Date.now();
// Inject a frame script that crashes the content process.
var mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
mm.loadFrameScript('data:,new ' + function ContentScriptScope() {
let Cu = Components.utils;
Cu.import("resource://gre/modules/ctypes.jsm");
let crash = function() {
let zero = new ctypes.intptr_t(8);
let badptr = ctypes.cast(zero, ctypes.PointerType(ctypes.int32_t));
badptr.contents;
};
privateNoteIntentionalCrash();
crash();
}, false);
// Finally, poll for the new crash record.
function tryGetCrash() {
info("Waiting for getCrashes");
crashMan.getCrashes().then(SpecialPowers.wrapCallback(function (crashes) {
if (crashes.length) {
is(crashes.length, 1, "There should be only one record");
var crash = crashes[0];
ok(crash.isOfType(crashMan.PROCESS_TYPE_CONTENT,
crashMan.CRASH_TYPE_CRASH),
"Record should be a content crash");
ok(!!crash.id, "Record should have an ID");
ok(!!crash.crashDate, "Record should have a crash date");
var dateMS = crash.crashDate.valueOf();
var twoMin = 1000 * 60 * 2;
ok(crashDateMS - twoMin <= dateMS &&
dateMS <= crashDateMS + twoMin,
"Record's crash date should be nowish: " +
"now=" + crashDateMS + " recordDate=" + dateMS);
SimpleTest.finish();
}
else {
setTimeout(tryGetCrash, 1000);
}
}), function (err) {
ok(false, "Error getting crashes: " + err);
SimpleTest.finish();
});
}
setTimeout(tryGetCrash, 1000);
}, function () {
ok(false, "pruneOldCrashes error");
SimpleTest.finish();
});
});
</script>
</body>
</html>

View file

@ -0,0 +1,185 @@
<!DOCTYPE html>
<html>
<head>
<title>Test for slicing blobs that originated in a child process</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
</script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body onload="setup();">
<script type="application/javascript;version=1.7">
"use strict";
function childFrameScript() {
"use strict";
Components.utils.importGlobalProperties(["Blob"]);
const messageName = "test:blob-slice-test";
const blobData = ["So", " ", "many", " ", "blobs!"];
const blobText = blobData.join("");
const blobType = "text/plain";
let blob = new Blob(blobData, { type: blobType });
let sliceText = blobData[2][1] + blobData[2][2];
let sliceIndex = blobText.indexOf(sliceText);
let firstSliceStart = blobData[0].length + blobData[1].length;
let firstSliceEnd = firstSliceStart + blobData[2].length;
let slice = blob.slice(firstSliceStart, firstSliceEnd, blobType);
let secondSliceStart = blobData[2].indexOf("a");
let secondSliceEnd = secondSliceStart + 2;
slice = slice.slice(secondSliceStart, secondSliceEnd, blobType);
sendAsyncMessage(messageName, { blob: blob });
sendAsyncMessage(messageName, { slice: slice });
}
function parentFrameScript(mm) {
const messageName = "test:blob-slice-test";
const blobData = ["So", " ", "many", " ", "blobs!"];
const blobText = blobData.join("");
const blobType = "text/plain";
const sliceText = "an";
let receivedBlob = false;
let receivedSlice = false;
let finishedTestingBlob = false;
let finishedTestingSlice = false;
mm.addMessageListener(messageName, function(message) {
if ("blob" in message.data) {
is(receivedBlob, false, "Have not yet received Blob");
is(receivedSlice, false, "Have not yet received Slice");
is(finishedTestingBlob, false, "Have not yet finished testing Blob");
is(finishedTestingSlice, false, "Have not yet finished testing Slice");
receivedBlob = true;
let blob = message.data.blob;
ok(blob instanceof Blob, "Received a Blob");
is(blob.size, blobText.length, "Blob has correct size");
is(blob.type, blobType, "Blob has correct type");
let slice = blob.slice(blobText.length -
blobData[blobData.length - 1].length,
blob.size,
blobType);
ok(slice instanceof Blob, "Slice returned a Blob");
is(slice.size,
blobData[blobData.length - 1].length,
"Slice has correct size");
is(slice.type, blobType, "Slice has correct type");
let reader = new FileReader();
reader.onload = function() {
is(reader.result,
blobData[blobData.length - 1],
"Slice has correct data");
finishedTestingBlob = true;
if (finishedTestingSlice) {
SimpleTest.finish();
}
};
reader.readAsText(slice);
return;
}
if ("slice" in message.data) {
is(receivedBlob, true, "Already received Blob");
is(receivedSlice, false, "Have not yet received Slice");
is(finishedTestingSlice, false, "Have not yet finished testing Slice");
receivedSlice = true;
let slice = message.data.slice;
ok(slice instanceof Blob, "Received a Blob for slice");
is(slice.size, sliceText.length, "Slice has correct size");
is(slice.type, blobType, "Slice has correct type");
let reader = new FileReader();
reader.onload = function() {
is(reader.result, sliceText, "Slice has correct data");
let slice2 = slice.slice(1, 2, blobType);
ok(slice2 instanceof Blob, "Slice returned a Blob");
is(slice2.size, 1, "Slice has correct size");
is(slice2.type, blobType, "Slice has correct type");
let reader2 = new FileReader();
reader2.onload = function() {
is(reader2.result, sliceText[1], "Slice has correct data");
finishedTestingSlice = true;
if (finishedTestingBlob) {
SimpleTest.finish();
}
};
reader2.readAsText(slice2);
};
reader.readAsText(slice);
return;
}
ok(false, "Received a bad message: " + JSON.stringify(message.data));
});
mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();",
false);
}
function setup() {
info("Got load event");
SpecialPowers.pushPrefEnv(
{ set: [ ["dom.ipc.browser_frames.oop_by_default", true],
["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true],
["browser.pagethumbnails.capturing_disabled", true] ] },
function() {
info("Prefs set");
SpecialPowers.pushPermissions(
[ { type: "browser", allow: true, context: document } ],
function() {
info("Permissions set");
let iframe = document.createElement("iframe");
SpecialPowers.wrap(iframe).mozbrowser = true;
iframe.id = "iframe";
iframe.src =
"data:text/html,<!DOCTYPE HTML><html><body></body></html>";
iframe.addEventListener("mozbrowserloadend", function() {
info("Starting tests");
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe)
parentFrameScript(mm);
});
document.body.appendChild(iframe);
}
);
}
);
}
SimpleTest.waitForExplicitFinish();
</script>
</body>
</html>

View file

@ -0,0 +1,213 @@
<!DOCTYPE html>
<html>
<head>
<title>Test for slicing blobs that originated in a parent process</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
</script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body onload="setup();">
<script type="application/javascript;version=1.7">
"use strict";
function childFrameScript() {
"use strict";
const { classes: Cc, interfaces: Ci } = Components;
const messageName = "test:blob-slice-test";
const blobData = ["So", " ", "many", " ", "blobs!"];
const blobText = blobData.join("");
const blobType = "text/plain";
const sliceText = "an";
function info(msg) {
sendAsyncMessage(messageName, { op: "info", msg: msg });
}
function ok(condition, name, diag) {
sendAsyncMessage(messageName,
{ op: "ok",
condition: condition,
name: name,
diag: diag });
}
function is(a, b, name) {
let pass = a == b;
let diag = pass ? "" : "got " + a + ", expected " + b;
ok(pass, name, diag);
}
function finish(result) {
sendAsyncMessage(messageName, { op: "done", result: result });
}
function grabAndContinue(arg) {
testGenerator.send(arg);
}
function testSteps() {
addMessageListener(messageName, grabAndContinue);
let message = yield undefined;
let blob = message.data;
ok(blob instanceof Ci.nsIDOMBlob, "Received a Blob");
is(blob.size, blobText.length, "Blob has correct length");
is(blob.type, blobType, "Blob has correct type");
info("Reading blob");
let reader = new FileReader();
reader.addEventListener("load", grabAndContinue);
reader.readAsText(blob);
yield undefined;
is(reader.result, blobText, "Blob has correct data");
let firstSliceStart = blobData[0].length + blobData[1].length;
let firstSliceEnd = firstSliceStart + blobData[2].length;
let slice = blob.slice(firstSliceStart, firstSliceEnd, blobType);
ok(slice instanceof Ci.nsIDOMBlob, "Slice returned a Blob");
is(slice.size, blobData[2].length, "Slice has correct length");
is(slice.type, blobType, "Slice has correct type");
info("Reading slice");
reader = new FileReader();
reader.addEventListener("load", grabAndContinue);
reader.readAsText(slice);
yield undefined;
is(reader.result, blobData[2], "Slice has correct data");
let secondSliceStart = blobData[2].indexOf("a");
let secondSliceEnd = secondSliceStart + sliceText.length;
slice = slice.slice(secondSliceStart, secondSliceEnd, blobType);
ok(slice instanceof Ci.nsIDOMBlob, "Second slice returned a Blob");
is(slice.size, sliceText.length, "Second slice has correct length");
is(slice.type, blobType, "Second slice has correct type");
info("Sending second slice");
finish(slice);
yield undefined;
}
let testGenerator = testSteps();
testGenerator.next();
}
function parentFrameScript(mm) {
const messageName = "test:blob-slice-test";
const blobData = ["So", " ", "many", " ", "blobs!"];
const blobText = blobData.join("");
const blobType = "text/plain";
const sliceText = "an";
function grabAndContinue(arg) {
testGenerator.send(arg);
}
function testSteps() {
let slice = yield undefined;
ok(slice instanceof Blob, "Received a Blob");
is(slice.size, sliceText.length, "Slice has correct size");
is(slice.type, blobType, "Slice has correct type");
let reader = new FileReader();
reader.onload = grabAndContinue;
reader.readAsText(slice);
yield undefined;
is(reader.result, sliceText, "Slice has correct data");
SimpleTest.finish();
yield undefined;
}
let testGenerator = testSteps();
testGenerator.next();
mm.addMessageListener(messageName, function(message) {
let data = message.data;
switch (data.op) {
case "info": {
info(data.msg);
break;
}
case "ok": {
ok(data.condition, data.name, data.diag);
break;
}
case "done": {
testGenerator.send(data.result);
break;
}
default: {
ok(false, "Unknown op: " + data.op);
SimpleTest.finish();
}
}
});
mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();",
false);
let blob = new Blob(blobData, { type: blobType });
mm.sendAsyncMessage(messageName, blob);
}
function setup() {
info("Got load event");
SpecialPowers.pushPrefEnv(
{ set: [ ["dom.ipc.browser_frames.oop_by_default", true],
["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true],
["browser.pagethumbnails.capturing_disabled", true] ] },
function() {
info("Prefs set");
SpecialPowers.pushPermissions(
[ { type: "browser", allow: true, context: document } ],
function() {
info("Permissions set");
let iframe = document.createElement("iframe");
SpecialPowers.wrap(iframe).mozbrowser = true;
iframe.id = "iframe";
iframe.src =
"data:text/html,<!DOCTYPE HTML><html><body></body></html>";
iframe.addEventListener("mozbrowserloadend", function() {
info("Starting tests");
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe)
parentFrameScript(mm);
});
document.body.appendChild(iframe);
}
);
}
);
}
SimpleTest.waitForExplicitFinish();
</script>
</body>
</html>

View file

@ -0,0 +1,107 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for recursive CPOW-getting-cookie bug</title>
<script type="application/javascript"
src="/tests/SimpleTest/SimpleTest.js">
</script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.8">
"use strict";
SimpleTest.waitForExplicitFinish();
const childFrameURL =
"http://mochi.test:8888/tests/dom/ipc/tests/file_bug1086684.html";
function childFrameScript() {
"use strict";
let { MockFilePicker } =
Components.utils.import("chrome://specialpowers/content/MockFilePicker.jsm", {});
function parentReady(message) {
MockFilePicker.init(content);
MockFilePicker.returnFiles = [message.data.file];
MockFilePicker.returnValue = MockFilePicker.returnOK;
let input = content.document.getElementById("f");
input.addEventListener("change", () => {
MockFilePicker.cleanup();
let value = input.value;
message.target.sendAsyncMessage("testBug1086684:childDone", { value });
});
input.focus();
input.click();
}
addMessageListener("testBug1086684:parentReady", function(message) {
parentReady(message);
});
}
let test;
function* testStructure(mm) {
let value;
function testDone(msg) {
test.next(msg.data.value);
}
mm.addMessageListener("testBug1086684:childDone", testDone);
let blob = new Blob([]);
let file = new File([blob], "helloworld.txt", { type: "text/plain" });
mm.sendAsyncMessage("testBug1086684:parentReady", { file });
value = yield;
// Note that the "helloworld.txt" passed in above doesn't affect the
// 'value' getter. Because we're mocking a file using a blob, we ask the
// blob for its path, which is the empty string.
is(value, "", "got the right answer and didn't crash");
SimpleTest.finish();
}
function runTests() {
info("Browser prefs set.");
let iframe = document.createElement("iframe");
SpecialPowers.wrap(iframe).mozbrowser = true;
iframe.id = "iframe";
iframe.src = childFrameURL;
iframe.addEventListener("mozbrowserloadend", function() {
info("Got iframe load event.");
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
mm.loadFrameScript("data:,(" + encodeURI(childFrameScript.toString()) + ")();",
false);
test = testStructure(mm);
test.next();
});
document.body.appendChild(iframe);
}
addEventListener("load", function() {
info("Got load event.");
SpecialPowers.addPermission("browser", true, document);
SpecialPowers.pushPrefEnv({
"set": [
["dom.ipc.browser_frames.oop_by_default", true],
["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true],
["browser.pagethumbnails.capturing_disabled", true]
]
}, runTests);
});
</script>
</body>
</html>

View file

@ -0,0 +1,86 @@
<!DOCTYPE HTML>
<html>
<!--
-->
<head>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<script type="application/javascript;version=1.7">
"use strict";
SimpleTest.waitForExplicitFinish();
SpecialPowers.addPermission("browser", true, document);
SpecialPowers.pushPrefEnv({'set':[
["dom.mozBrowserFramesEnabled", true],
["network.disable.ipc.security", true],
["dom.ipc.tabs.disabled", false]
]}, function () {
var iframe = document.createElementNS('http://www.w3.org/1999/xhtml', 'iframe');
iframe.setAttribute("remote", "true");
SpecialPowers.wrap(iframe).mozbrowser = true;
document.documentElement.appendChild(iframe);
var mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
mm.addMessageListener("chromeEventHandler", function (msg) {
msg = SpecialPowers.wrap(msg);
var result = msg.json;
is(result.processType, SpecialPowers.Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT,
"The frame script is running in a real distinct child process");
ok(result.hasCorrectInterface,
"docshell.chromeEventHandler has nsIDOMEventTarget interface");
});
mm.addMessageListener("DOMWindowCreatedReceived", function (msg) {
msg = SpecialPowers.wrap(msg);
ok(true, "the chrome event handler looks functional");
var result = msg.json;
ok(result.stableChromeEventHandler, "docShell.chromeEventHandler is stable");
ok(result.iframeHasNewDocShell, "iframe spawns a new docShell");
ok(result.iframeHasSameChromeEventHandler, "but iframe has the same chrome event handler");
SimpleTest.finish();
});
// Inject a frame script in the child process:
mm.loadFrameScript('data:,new ' + function ContentScriptScope() {
var processType = Components.classes["@mozilla.org/xre/runtime;1"]
.getService(Components.interfaces.nsIXULRuntime)
.processType;
var chromeEventHandler = docShell.chromeEventHandler;
sendAsyncMessage("chromeEventHandler", {
processType: Services.appinfo.processType,
hasCorrectInterface: chromeEventHandler instanceof Components.interfaces.nsIDOMEventTarget
});
/*
Ensure that this chromeEventHandler actually works,
by creating a new window and listening for its DOMWindowCreated event
*/
chromeEventHandler.addEventListener("DOMWindowCreated", function listener(evt) {
if (evt.target == content.document) {
return;
}
chromeEventHandler.removeEventListener("DOMWindowCreated", listener);
let new_win = evt.target.defaultView;
let new_docShell = new_win.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
sendAsyncMessage("DOMWindowCreatedReceived", {
stableChromeEventHandler: chromeEventHandler === docShell.chromeEventHandler,
iframeHasNewDocShell: new_docShell !== docShell,
iframeHasSameChromeEventHandler: new_docShell.chromeEventHandler === chromeEventHandler
});
});
let i = content.document.createElement("iframe");
i.setAttribute("src", "data:text/html,foo");
content.document.documentElement.appendChild(i);
}, false);
});
</script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show more