gecko-dev/dom/ipc/BrowserParent.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

3829 lines
128 KiB
C++
Raw Normal View History

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
2012-05-21 11:12:37 +00:00
/* 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 "base/basictypes.h"
#include "BrowserParent.h"
#ifdef ACCESSIBILITY
# include "mozilla/a11y/DocAccessibleParent.h"
# include "nsAccessibilityService.h"
#endif
#include "mozilla/BrowserElementParent.h"
#include "mozilla/dom/CancelContentJSOptionsBinding.h"
#include "mozilla/dom/ChromeMessageSender.h"
#include "mozilla/dom/ContentParent.h"
#include "mozilla/dom/DataTransfer.h"
#include "mozilla/dom/DataTransferItemList.h"
#include "mozilla/dom/Event.h"
#include "mozilla/dom/indexedDB/ActorsParent.h"
#include "mozilla/dom/PaymentRequestParent.h"
#include "mozilla/dom/BrowserBridgeParent.h"
#include "mozilla/dom/RemoteDragStartData.h"
#include "mozilla/dom/RemoteWebProgress.h"
#include "mozilla/dom/RemoteWebProgressRequest.h"
#include "mozilla/dom/SessionStoreUtilsBinding.h"
#include "mozilla/EventStateManager.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/DataSurfaceHelpers.h"
#include "mozilla/gfx/GPUProcessManager.h"
#include "mozilla/Hal.h"
#include "mozilla/IMEStateManager.h"
#include "mozilla/jsipc/CrossProcessObjectWrappers.h"
#include "mozilla/layers/AsyncDragMetrics.h"
#include "mozilla/layers/InputAPZContext.h"
#include "mozilla/layout/RemoteLayerTreeOwner.h"
#include "mozilla/plugins/PPluginWidgetParent.h"
#include "mozilla/LookAndFeel.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/net/NeckoChild.h"
#include "mozilla/Preferences.h"
#include "mozilla/PresShell.h"
#include "mozilla/ProcessHangMonitor.h"
#include "mozilla/StaticPrefs.h"
#include "mozilla/TextEvents.h"
#include "mozilla/TouchEvents.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Unused.h"
#include "nsCOMPtr.h"
#include "nsContentUtils.h"
#include "nsDebug.h"
#include "nsFocusManager.h"
#include "nsFrameLoader.h"
#include "nsFrameLoaderOwner.h"
#include "nsFrameManager.h"
#include "nsIBaseWindow.h"
#include "nsIBrowser.h"
#include "nsIContent.h"
#include "nsIDocShell.h"
#include "nsIDocShellTreeOwner.h"
#include "nsIDOMWindow.h"
#include "nsIDOMWindowUtils.h"
#include "nsImportModule.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsILoadInfo.h"
#include "nsIPromptFactory.h"
#include "nsITransportSecurityInfo.h"
#include "nsIURI.h"
#include "nsIWindowWatcher.h"
#include "nsIWebBrowserChrome.h"
Bug 1499092 - rename/move code from 'feeds' and 'web content' to more appropriate/obvious versions for registerProtocolHandler, r=nika Differential Revision: https://phabricator.services.mozilla.com/D13699 --HG-- rename : browser/components/feeds/WebContentConverter.js => browser/components/protocolhandler/WebProtocolHandlerRegistrar.js rename : browser/components/feeds/moz.build => browser/components/protocolhandler/moz.build rename : browser/components/feeds/test/.eslintrc.js => browser/components/protocolhandler/test/.eslintrc.js rename : browser/components/feeds/test/browser/.eslintrc.js => browser/components/protocolhandler/test/browser/.eslintrc.js rename : browser/components/feeds/test/browser/browser.ini => browser/components/protocolhandler/test/browser/browser.ini rename : browser/components/feeds/test/browser/browser_registerProtocolHandler_notification.html => browser/components/protocolhandler/test/browser/browser_registerProtocolHandler_notification.html rename : browser/components/feeds/test/browser/browser_registerProtocolHandler_notification.js => browser/components/protocolhandler/test/browser/browser_registerProtocolHandler_notification.js rename : browser/components/feeds/test/mochitest.ini => browser/components/protocolhandler/test/mochitest.ini rename : browser/components/feeds/test/test_registerHandler.html => browser/components/protocolhandler/test/test_registerHandler.html rename : browser/components/feeds/test/test_registerHandler_disabled.html => browser/components/protocolhandler/test/test_registerHandler_disabled.html rename : dom/interfaces/sidebar/nsIWebContentHandlerRegistrar.idl => dom/interfaces/sidebar/nsIWebProtocolHandlerRegistrar.idl extra : moz-landing-system : lando
2018-12-13 13:34:11 +00:00
#include "nsIWebProtocolHandlerRegistrar.h"
#include "nsIXULBrowserWindow.h"
#include "nsIXULWindow.h"
#include "nsViewManager.h"
#include "nsVariant.h"
#include "nsIWidget.h"
#include "nsNetUtil.h"
#ifndef XP_WIN
# include "nsJARProtocolHandler.h"
#endif
#include "nsPIDOMWindow.h"
#include "nsPrintfCString.h"
#include "nsQueryObject.h"
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
#include "PermissionMessageUtils.h"
#include "StructuredCloneData.h"
#include "ColorPickerParent.h"
#include "FilePickerParent.h"
#include "BrowserChild.h"
#include "LoadContext.h"
#include "nsNetCID.h"
#include "nsIAuthInformation.h"
#include "nsIAuthPromptCallback.h"
#include "nsAuthInformationHolder.h"
#include "nsICancelable.h"
#include "gfxUtils.h"
#include "nsILoginManagerPrompter.h"
#include "nsPIWindowRoot.h"
#include "nsIAuthPrompt2.h"
#include "gfxDrawable.h"
#include "ImageOps.h"
#include "UnitTransforms.h"
#include <algorithm>
#include "mozilla/NullPrincipal.h"
#include "mozilla/WebBrowserPersistDocumentParent.h"
#include "ProcessPriorityManager.h"
#include "nsString.h"
#include "IHistory.h"
#include "mozilla/dom/WindowGlobalParent.h"
#include "mozilla/dom/CanonicalBrowsingContext.h"
#include "MMPrinter.h"
#include "SessionStoreFunctions.h"
#ifdef XP_WIN
# include "mozilla/plugins/PluginWidgetParent.h"
#endif
#if defined(XP_WIN) && defined(ACCESSIBILITY)
# include "mozilla/a11y/AccessibleWrap.h"
# include "mozilla/a11y/Compatibility.h"
# include "mozilla/a11y/nsWinUtils.h"
#endif
#ifdef MOZ_ANDROID_HISTORY
# include "GeckoViewHistory.h"
#endif
using namespace mozilla::dom;
using namespace mozilla::ipc;
using namespace mozilla::layers;
using namespace mozilla::layout;
using namespace mozilla::services;
using namespace mozilla::widget;
using namespace mozilla::jsipc;
using namespace mozilla::gfx;
using mozilla::LazyLogModule;
using mozilla::StaticAutoPtr;
using mozilla::Unused;
LazyLogModule gBrowserFocusLog("BrowserFocus");
#define LOGBROWSERFOCUS(args) \
MOZ_LOG(gBrowserFocusLog, mozilla::LogLevel::Debug, args)
/* static */
StaticAutoPtr<nsTArray<BrowserParent*>> BrowserParent::sFocusStack;
// The flags passed by the webProgress notifications are 16 bits shifted
// from the ones registered by webProgressListeners.
#define NOTIFY_FLAG_SHIFT 16
namespace mozilla {
namespace dom {
BrowserParent::LayerToBrowserParentTable*
BrowserParent::sLayerToBrowserParentTable = nullptr;
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(BrowserParent)
NS_INTERFACE_MAP_ENTRY(nsIAuthPromptProvider)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEventListener)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION(BrowserParent, mFrameElement, mBrowserDOMWindow,
mLoadContext, mFrameLoader, mBrowsingContext)
NS_IMPL_CYCLE_COLLECTING_ADDREF(BrowserParent)
NS_IMPL_CYCLE_COLLECTING_RELEASE(BrowserParent)
BrowserParent::BrowserParent(ContentParent* aManager, const TabId& aTabId,
const TabContext& aContext,
CanonicalBrowsingContext* aBrowsingContext,
uint32_t aChromeFlags)
: TabContext(aContext),
mTabId(aTabId),
mManager(aManager),
mBrowsingContext(aBrowsingContext),
mLoadContext(nullptr),
mFrameElement(nullptr),
mBrowserDOMWindow(nullptr),
mFrameLoader(nullptr),
mChromeFlags(aChromeFlags),
mBrowserBridgeParent(nullptr),
mBrowserHost(nullptr),
mContentCache(*this),
mRemoteLayerTreeOwner{},
mLayerTreeEpoch{1},
mChildToParentConversionMatrix{},
mRect(0, 0, 0, 0),
mDimensions(0, 0),
mOrientation(0),
mDPI(0),
mRounding(0),
mDefaultScale(0),
mUpdatedDimensions(false),
mSizeMode(nsSizeMode_Normal),
mClientOffset{},
mChromeOffset{},
mCreatingWindow(false),
mDelayedURL{},
mDelayedFrameScripts{},
mCursor(eCursorInvalid),
mCustomCursor{},
mCustomCursorHotspotX(0),
mCustomCursorHotspotY(0),
mVerifyDropLinks{},
mDocShellIsActive(false),
mMarkedDestroying(false),
mIsDestroyed(false),
mTabSetsCursor(false),
mHasContentOpener(false),
mPreserveLayers(false),
mRenderLayers(true),
mActiveInPriorityManager(false),
mHasLayers(false),
mHasPresented(false),
mIsReadyToHandleInputEvents(false),
mIsMouseEnterIntoWidgetEventSuppressed(false),
mIsActiveRecordReplayTab(false) {
MOZ_ASSERT(aManager);
// When the input event queue is disabled, we don't need to handle the case
// that some input events are dispatched before PBrowserConstructor.
mIsReadyToHandleInputEvents = !ContentParent::IsInputEventQueueSupported();
}
BrowserParent::~BrowserParent() {}
/* static */
void BrowserParent::InitializeStatics() {
MOZ_ASSERT(XRE_IsParentProcess());
sFocusStack = new nsTArray<BrowserParent*>();
ClearOnShutdown(&sFocusStack);
}
/* static */
BrowserParent* BrowserParent::GetFocused() {
if (!sFocusStack) {
return nullptr;
}
if (sFocusStack->IsEmpty()) {
return nullptr;
}
return sFocusStack->LastElement();
}
/*static*/
BrowserParent* BrowserParent::GetFrom(nsFrameLoader* aFrameLoader) {
if (!aFrameLoader) {
return nullptr;
}
return aFrameLoader->GetBrowserParent();
}
/*static*/
BrowserParent* BrowserParent::GetFrom(PBrowserParent* aBrowserParent) {
return static_cast<BrowserParent*>(aBrowserParent);
}
/*static*/
BrowserParent* BrowserParent::GetFrom(nsIContent* aContent) {
RefPtr<nsFrameLoaderOwner> loaderOwner = do_QueryObject(aContent);
if (!loaderOwner) {
return nullptr;
}
RefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
return GetFrom(frameLoader);
}
/* static */
BrowserParent* BrowserParent::GetBrowserParentFromLayersId(
layers::LayersId aLayersId) {
if (!sLayerToBrowserParentTable) {
return nullptr;
}
return sLayerToBrowserParentTable->Get(uint64_t(aLayersId));
}
/*static*/
TabId BrowserParent::GetTabIdFrom(nsIDocShell* docShell) {
nsCOMPtr<nsIBrowserChild> browserChild(BrowserChild::GetFrom(docShell));
if (browserChild) {
return static_cast<BrowserChild*>(browserChild.get())->GetTabId();
}
return TabId(0);
}
void BrowserParent::AddBrowserParentToTable(layers::LayersId aLayersId,
BrowserParent* aBrowserParent) {
if (!sLayerToBrowserParentTable) {
sLayerToBrowserParentTable = new LayerToBrowserParentTable();
}
sLayerToBrowserParentTable->Put(uint64_t(aLayersId), aBrowserParent);
}
void BrowserParent::RemoveBrowserParentFromTable(layers::LayersId aLayersId) {
if (!sLayerToBrowserParentTable) {
return;
}
sLayerToBrowserParentTable->Remove(uint64_t(aLayersId));
if (sLayerToBrowserParentTable->Count() == 0) {
delete sLayerToBrowserParentTable;
sLayerToBrowserParentTable = nullptr;
}
}
already_AddRefed<nsILoadContext> BrowserParent::GetLoadContext() {
nsCOMPtr<nsILoadContext> loadContext;
if (mLoadContext) {
loadContext = mLoadContext;
} else {
bool isPrivate = mChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
SetPrivateBrowsingAttributes(isPrivate);
bool useTrackingProtection = false;
nsCOMPtr<nsIDocShell> docShell = mFrameElement->OwnerDoc()->GetDocShell();
if (docShell) {
docShell->GetUseTrackingProtection(&useTrackingProtection);
}
loadContext = new LoadContext(
GetOwnerElement(), true /* aIsContent */, isPrivate,
mChromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW,
mChromeFlags & nsIWebBrowserChrome::CHROME_FISSION_WINDOW,
useTrackingProtection, OriginAttributesRef());
mLoadContext = loadContext;
}
return loadContext.forget();
}
/**
* Will return nullptr if there is no outer window available for the
* document hosting the owner element of this BrowserParent. Also will return
* nullptr if that outer window is in the process of closing.
*/
already_AddRefed<nsPIDOMWindowOuter> BrowserParent::GetParentWindowOuter() {
nsCOMPtr<nsIContent> frame = GetOwnerElement();
if (!frame) {
return nullptr;
}
nsCOMPtr<nsPIDOMWindowOuter> parent = frame->OwnerDoc()->GetWindow();
if (!parent || parent->Closed()) {
return nullptr;
}
return parent.forget();
}
already_AddRefed<nsIWidget> BrowserParent::GetTopLevelWidget() {
if (RefPtr<Element> element = mFrameElement) {
if (PresShell* presShell = element->OwnerDoc()->GetPresShell()) {
nsViewManager* vm = presShell->GetViewManager();
nsCOMPtr<nsIWidget> widget;
vm->GetRootWidget(getter_AddRefs(widget));
return widget.forget();
}
}
return nullptr;
}
already_AddRefed<nsIWidget> BrowserParent::GetWidget() const {
if (!mFrameElement) {
return nullptr;
}
nsCOMPtr<nsIWidget> widget = nsContentUtils::WidgetForContent(mFrameElement);
if (!widget) {
widget = nsContentUtils::WidgetForDocument(mFrameElement->OwnerDoc());
}
return widget.forget();
}
already_AddRefed<nsIWidget> BrowserParent::GetDocWidget() const {
if (!mFrameElement) {
return nullptr;
}
return do_AddRef(
nsContentUtils::WidgetForDocument(mFrameElement->OwnerDoc()));
}
nsIXULBrowserWindow* BrowserParent::GetXULBrowserWindow() {
if (!mFrameElement) {
return nullptr;
}
nsCOMPtr<nsIDocShell> docShell = mFrameElement->OwnerDoc()->GetDocShell();
if (!docShell) {
return nullptr;
}
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
docShell->GetTreeOwner(getter_AddRefs(treeOwner));
if (!treeOwner) {
return nullptr;
}
nsCOMPtr<nsIXULWindow> window = do_GetInterface(treeOwner);
if (!window) {
return nullptr;
}
nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow;
window->GetXULBrowserWindow(getter_AddRefs(xulBrowserWindow));
return xulBrowserWindow;
}
uint32_t BrowserParent::GetMaxTouchPoints(Element* aElement) {
if (!aElement) {
return 0;
}
if (StaticPrefs::dom_maxtouchpoints_testing_value() >= 0) {
return StaticPrefs::dom_maxtouchpoints_testing_value();
}
nsIWidget* widget = nsContentUtils::WidgetForDocument(aElement->OwnerDoc());
return widget ? widget->GetMaxTouchPoints() : 0;
}
a11y::DocAccessibleParent* BrowserParent::GetTopLevelDocAccessible() const {
#ifdef ACCESSIBILITY
// XXX Consider managing non top level PDocAccessibles with their parent
// document accessible.
const ManagedContainer<PDocAccessibleParent>& docs =
ManagedPDocAccessibleParent();
for (auto iter = docs.ConstIter(); !iter.Done(); iter.Next()) {
auto doc = static_cast<a11y::DocAccessibleParent*>(iter.Get()->GetKey());
// We want the document for this BrowserParent even if it's for an
// embedded out-of-process iframe. Therefore, we use
// IsTopLevelInContentProcess. In contrast, using IsToplevel would only
// include documents that aren't embedded; e.g. tab documents.
if (doc->IsTopLevelInContentProcess()) {
return doc;
}
}
MOZ_ASSERT(docs.Count() == 0,
"If there isn't a top level accessible doc "
"there shouldn't be an accessible doc at all!");
#endif
return nullptr;
}
LayersId BrowserParent::GetLayersId() const {
if (!mRemoteLayerTreeOwner.IsInitialized()) {
return LayersId{};
}
return mRemoteLayerTreeOwner.GetLayersId();
}
BrowserBridgeParent* BrowserParent::GetBrowserBridgeParent() const {
return mBrowserBridgeParent;
}
BrowserHost* BrowserParent::GetBrowserHost() const { return mBrowserHost; }
ShowInfo BrowserParent::GetShowInfo() {
TryCacheDPIAndScale();
if (mFrameElement) {
nsAutoString name;
mFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
bool allowFullscreen =
mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) ||
mFrameElement->HasAttr(kNameSpaceID_None,
nsGkAtoms::mozallowfullscreen);
bool isPrivate = mFrameElement->HasAttr(kNameSpaceID_None,
nsGkAtoms::mozprivatebrowsing);
bool isTransparent =
nsContentUtils::IsChromeDoc(mFrameElement->OwnerDoc()) &&
mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::transparent);
return ShowInfo(name, allowFullscreen, isPrivate, false, isTransparent,
mDPI, mRounding, mDefaultScale.scale);
}
return ShowInfo(EmptyString(), false, false, false, false, mDPI, mRounding,
mDefaultScale.scale);
}
void BrowserParent::SetOwnerElement(Element* aElement) {
// If we held previous content then unregister for its events.
RemoveWindowListeners();
// If we change top-level documents then we need to change our
// registration with them.
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 05:24:48 +00:00
RefPtr<nsPIWindowRoot> curTopLevelWin, newTopLevelWin;
if (mFrameElement) {
curTopLevelWin = nsContentUtils::GetWindowRoot(mFrameElement->OwnerDoc());
}
if (aElement) {
newTopLevelWin = nsContentUtils::GetWindowRoot(aElement->OwnerDoc());
}
bool isSameTopLevelWin = curTopLevelWin == newTopLevelWin;
if (mBrowserHost && curTopLevelWin && !isSameTopLevelWin) {
curTopLevelWin->RemoveBrowser(mBrowserHost);
}
// Update to the new content, and register to listen for events from it.
mFrameElement = aElement;
if (mBrowserHost && newTopLevelWin && !isSameTopLevelWin) {
newTopLevelWin->AddBrowser(mBrowserHost);
}
if (mFrameElement) {
bool useGlobalHistory = !mFrameElement->HasAttr(
kNameSpaceID_None, nsGkAtoms::disableglobalhistory);
Unused << SendSetUseGlobalHistory(useGlobalHistory);
}
#if defined(XP_WIN) && defined(ACCESSIBILITY)
if (!mIsDestroyed) {
uintptr_t newWindowHandle = 0;
if (nsCOMPtr<nsIWidget> widget = GetWidget()) {
newWindowHandle =
reinterpret_cast<uintptr_t>(widget->GetNativeData(NS_NATIVE_WINDOW));
}
Unused << SendUpdateNativeWindowHandle(newWindowHandle);
a11y::DocAccessibleParent* doc = GetTopLevelDocAccessible();
if (doc) {
HWND hWnd = reinterpret_cast<HWND>(doc->GetEmulatedWindowHandle());
if (hWnd) {
HWND parentHwnd = reinterpret_cast<HWND>(newWindowHandle);
if (parentHwnd != ::GetParent(hWnd)) {
::SetParent(hWnd, parentHwnd);
}
}
}
}
#endif
AddWindowListeners();
TryCacheDPIAndScale();
// Try to send down WidgetNativeData, now that this BrowserParent is
// associated with a widget.
nsCOMPtr<nsIWidget> widget = GetTopLevelWidget();
if (widget) {
WindowsHandle widgetNativeData = reinterpret_cast<WindowsHandle>(
widget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW));
if (widgetNativeData) {
Unused << SendSetWidgetNativeData(widgetNativeData);
}
}
Bug 1500257 part 7 - Modify RenderFrame to hold onto TabParent instead of nsFrameLoader. r=aosmond A TabParent for a remote subframe will have the same owner content as the top-level remote browser. This means that 'TabParent::GetFrameLoader()' will return the frame loader of the top-level remote browser. This is fine for getting the layer manager and compositor for connecting layer trees, but the frame loader is also used to acquire a TabParent for its process ID. This is incorrect in the remote subframe case, and will lead to the compositor rejecting layer transactions for the remote subframe because it will only accept them from the top-level remote browser's process. This commit switches RenderFrame to just hold on to TabParent, and acquire the nsFrameLoader as necessary. Another change is to RenderFrame::SetOwnerContent. Previously this method would take the new owner content and check an assertion. I don't see much value in the assertion, so I've removed it. Additionally, now that we acquire the owner content, and therefore the layer manager, from TabParent, we need to ensure that RenderFrame::SetOwnerContent is ran after the TabParent has had it's owner content updated. So the callsite has been moved into TabParent. This resolved a test failure with frame loader swapping. Differential Revision: https://phabricator.services.mozilla.com/D17447 --HG-- extra : source : 4c85fb68f2ed297828bf4646301c2d80d1c8e0a1 extra : intermediate-source : 62ad54fb95eb76f88865f43da1a5d556421e7884 extra : histedit_source : 6b7085118bca83433b26fcec3983a385bd536672
2019-01-23 15:52:30 +00:00
if (mRemoteLayerTreeOwner.IsInitialized()) {
mRemoteLayerTreeOwner.OwnerContentChanged();
Bug 1500257 part 7 - Modify RenderFrame to hold onto TabParent instead of nsFrameLoader. r=aosmond A TabParent for a remote subframe will have the same owner content as the top-level remote browser. This means that 'TabParent::GetFrameLoader()' will return the frame loader of the top-level remote browser. This is fine for getting the layer manager and compositor for connecting layer trees, but the frame loader is also used to acquire a TabParent for its process ID. This is incorrect in the remote subframe case, and will lead to the compositor rejecting layer transactions for the remote subframe because it will only accept them from the top-level remote browser's process. This commit switches RenderFrame to just hold on to TabParent, and acquire the nsFrameLoader as necessary. Another change is to RenderFrame::SetOwnerContent. Previously this method would take the new owner content and check an assertion. I don't see much value in the assertion, so I've removed it. Additionally, now that we acquire the owner content, and therefore the layer manager, from TabParent, we need to ensure that RenderFrame::SetOwnerContent is ran after the TabParent has had it's owner content updated. So the callsite has been moved into TabParent. This resolved a test failure with frame loader swapping. Differential Revision: https://phabricator.services.mozilla.com/D17447 --HG-- extra : source : 4c85fb68f2ed297828bf4646301c2d80d1c8e0a1 extra : intermediate-source : 62ad54fb95eb76f88865f43da1a5d556421e7884 extra : histedit_source : 6b7085118bca83433b26fcec3983a385bd536672
2019-01-23 15:52:30 +00:00
}
// Set our BrowsingContext's embedder if we're not embedded within a
// BrowserBridgeParent.
if (!GetBrowserBridgeParent() && mBrowsingContext && mFrameElement) {
mBrowsingContext->SetEmbedderElement(mFrameElement);
}
VisitChildren([aElement](BrowserBridgeParent* aBrowser) {
if (auto* browserParent = aBrowser->GetBrowserParent()) {
browserParent->SetOwnerElement(aElement);
}
});
}
void BrowserParent::CacheFrameLoader(nsFrameLoader* aFrameLoader) {
mFrameLoader = aFrameLoader;
}
void BrowserParent::AddWindowListeners() {
if (mFrameElement) {
if (nsCOMPtr<nsPIDOMWindowOuter> window =
mFrameElement->OwnerDoc()->GetWindow()) {
nsCOMPtr<EventTarget> eventTarget = window->GetTopWindowRoot();
if (eventTarget) {
eventTarget->AddEventListener(NS_LITERAL_STRING("MozUpdateWindowPos"),
this, false, false);
eventTarget->AddEventListener(NS_LITERAL_STRING("fullscreenchange"),
this, false, false);
}
}
}
}
void BrowserParent::RemoveWindowListeners() {
if (mFrameElement && mFrameElement->OwnerDoc()->GetWindow()) {
nsCOMPtr<nsPIDOMWindowOuter> window =
mFrameElement->OwnerDoc()->GetWindow();
nsCOMPtr<EventTarget> eventTarget = window->GetTopWindowRoot();
if (eventTarget) {
eventTarget->RemoveEventListener(NS_LITERAL_STRING("MozUpdateWindowPos"),
this, false);
eventTarget->RemoveEventListener(NS_LITERAL_STRING("fullscreenchange"),
this, false);
}
}
}
void BrowserParent::DestroyInternal() {
PopFocus(this);
RemoveWindowListeners();
#ifdef ACCESSIBILITY
if (a11y::DocAccessibleParent* tabDoc = GetTopLevelDocAccessible()) {
tabDoc->Destroy();
}
#endif
// If this fails, it's most likely due to a content-process crash,
// and auto-cleanup will kick in. Otherwise, the child side will
// destroy itself and send back __delete__().
Unused << SendDestroy();
#ifdef XP_WIN
// Let all PluginWidgets know we are tearing down. Prevents
// these objects from sending async events after the child side
// is shut down.
const ManagedContainer<PPluginWidgetParent>& kids =
ManagedPPluginWidgetParent();
for (auto iter = kids.ConstIter(); !iter.Done(); iter.Next()) {
static_cast<mozilla::plugins::PluginWidgetParent*>(iter.Get()->GetKey())
->ParentDestroy();
}
#endif
SetIsActiveRecordReplayTab(false);
}
void BrowserParent::Destroy() {
// Aggressively release the window to avoid leaking the world in shutdown
// corner cases.
mBrowserDOMWindow = nullptr;
if (mIsDestroyed) {
return;
}
DestroyInternal();
mIsDestroyed = true;
ContentParent::NotifyTabDestroying(this->GetTabId(), Manager()->ChildID());
mMarkedDestroying = true;
}
mozilla::ipc::IPCResult BrowserParent::RecvEnsureLayersConnected(
CompositorOptions* aCompositorOptions) {
if (mRemoteLayerTreeOwner.IsInitialized()) {
mRemoteLayerTreeOwner.EnsureLayersConnected(aCompositorOptions);
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::Recv__delete__() {
MOZ_RELEASE_ASSERT(XRE_IsParentProcess());
ContentParent::UnregisterRemoteFrame(mTabId, Manager()->ChildID(),
mMarkedDestroying);
return IPC_OK();
}
void BrowserParent::ActorDestroy(ActorDestroyReason why) {
if (mRemoteLayerTreeOwner.IsInitialized()) {
// It's important to unmap layers after the remote browser has been
// destroyed, otherwise it may still send messages to the compositor which
// will reject them, causing assertions.
RemoveBrowserParentFromTable(mRemoteLayerTreeOwner.GetLayersId());
mRemoteLayerTreeOwner.Destroy();
}
// Even though BrowserParent::Destroy calls this, we need to do it here too in
// case of a crash.
BrowserParent::PopFocus(this);
// Prevent executing ContentParent::NotifyTabDestroying in
// BrowserParent::Destroy() called by frameLoader->DestroyComplete() below
// when tab crashes in contentprocess because ContentParent::ActorDestroy()
// in main process will be triggered before this function
// and remove the process information that
// ContentParent::NotifyTabDestroying need from mContentParentMap.
// When tab crashes in content process,
// there is no need to call ContentParent::NotifyTabDestroying
// because the jobs in ContentParent::NotifyTabDestroying
// will be done by ContentParent::ActorDestroy.
if (XRE_IsContentProcess() && why == AbnormalShutdown && !mIsDestroyed) {
DestroyInternal();
mIsDestroyed = true;
}
// Tell our embedder that the tab is now going away unless we're an
// out-of-process iframe.
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 05:24:48 +00:00
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader(true);
if (frameLoader) {
ReceiveMessage(CHILD_PROCESS_SHUTDOWN_MESSAGE, false, nullptr, nullptr,
nullptr);
if (!mBrowsingContext->GetParent()) {
// If this is a top-level BrowsingContext, tell the frameloader it's time
// to go away. Otherwise, this is a subframe crash, and we can keep the
// frameloader around.
frameLoader->DestroyComplete();
}
// If this was a crash, tell our nsFrameLoader to fire crash events.
if (why == AbnormalShutdown) {
frameLoader->MaybeNotifyCrashed(mBrowsingContext, GetIPCChannel());
}
}
mFrameLoader = nullptr;
}
mozilla::ipc::IPCResult BrowserParent::RecvMoveFocus(
const bool& aForward, const bool& aForDocumentNavigation) {
LOGBROWSERFOCUS(("RecvMoveFocus %p, aForward: %d, aForDocumentNavigation: %d",
this, aForward, aForDocumentNavigation));
BrowserBridgeParent* bridgeParent = GetBrowserBridgeParent();
if (bridgeParent) {
mozilla::Unused << bridgeParent->SendMoveFocus(aForward,
aForDocumentNavigation);
return IPC_OK();
}
nsCOMPtr<nsIFocusManager> fm = nsFocusManager::GetFocusManager();
if (fm) {
RefPtr<Element> dummy;
uint32_t type =
aForward
? (aForDocumentNavigation
? static_cast<uint32_t>(
nsIFocusManager::MOVEFOCUS_FORWARDDOC)
: static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_FORWARD))
: (aForDocumentNavigation
? static_cast<uint32_t>(
nsIFocusManager::MOVEFOCUS_BACKWARDDOC)
: static_cast<uint32_t>(
nsIFocusManager::MOVEFOCUS_BACKWARD));
fm->MoveFocus(nullptr, mFrameElement, type, nsIFocusManager::FLAG_BYKEY,
getter_AddRefs(dummy));
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvSizeShellTo(
const uint32_t& aFlags, const int32_t& aWidth, const int32_t& aHeight,
const int32_t& aShellItemWidth, const int32_t& aShellItemHeight) {
NS_ENSURE_TRUE(mFrameElement, IPC_OK());
nsCOMPtr<nsIDocShell> docShell = mFrameElement->OwnerDoc()->GetDocShell();
NS_ENSURE_TRUE(docShell, IPC_OK());
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
nsresult rv = docShell->GetTreeOwner(getter_AddRefs(treeOwner));
NS_ENSURE_SUCCESS(rv, IPC_OK());
int32_t width = aWidth;
int32_t height = aHeight;
if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_CX) {
width = mDimensions.width;
}
if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_CY) {
height = mDimensions.height;
}
nsCOMPtr<nsIXULWindow> xulWin(do_GetInterface(treeOwner));
NS_ENSURE_TRUE(xulWin, IPC_OK());
xulWin->SizeShellToWithLimit(width, height, aShellItemWidth,
aShellItemHeight);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvDropLinks(
nsTArray<nsString>&& aLinks) {
nsCOMPtr<nsIBrowser> browser =
mFrameElement ? mFrameElement->AsBrowser() : nullptr;
if (browser) {
// Verify that links have not been modified by the child. If links have
// not been modified then it's safe to load those links using the
// SystemPrincipal. If they have been modified by web content, then
// we use a NullPrincipal which still allows to load web links.
bool loadUsingSystemPrincipal = true;
if (aLinks.Length() != mVerifyDropLinks.Length()) {
loadUsingSystemPrincipal = false;
}
for (uint32_t i = 0; i < aLinks.Length(); i++) {
if (loadUsingSystemPrincipal) {
if (!aLinks[i].Equals(mVerifyDropLinks[i])) {
loadUsingSystemPrincipal = false;
}
}
}
mVerifyDropLinks.Clear();
nsCOMPtr<nsIPrincipal> triggeringPrincipal;
if (loadUsingSystemPrincipal) {
triggeringPrincipal = nsContentUtils::GetSystemPrincipal();
} else {
triggeringPrincipal = NullPrincipal::CreateWithoutOriginAttributes();
}
browser->DropLinks(aLinks, triggeringPrincipal);
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvEvent(const RemoteDOMEvent& aEvent) {
RefPtr<Event> event = aEvent.mEvent;
NS_ENSURE_TRUE(event, IPC_OK());
RefPtr<EventTarget> target = mFrameElement;
NS_ENSURE_TRUE(target, IPC_OK());
event->SetOwner(target);
target->DispatchEvent(*event);
return IPC_OK();
}
bool BrowserParent::SendLoadRemoteScript(const nsString& aURL,
const bool& aRunInGlobalScope) {
if (mCreatingWindow) {
mDelayedFrameScripts.AppendElement(
FrameScriptInfo(aURL, aRunInGlobalScope));
return true;
}
MOZ_ASSERT(mDelayedFrameScripts.IsEmpty());
return PBrowserParent::SendLoadRemoteScript(aURL, aRunInGlobalScope);
}
void BrowserParent::LoadURL(nsIURI* aURI) {
MOZ_ASSERT(aURI);
if (mIsDestroyed) {
return;
}
nsCString spec;
aURI->GetSpec(spec);
if (mCreatingWindow) {
// Don't send the message if the child wants to load its own URL.
MOZ_ASSERT(mDelayedURL.IsEmpty());
mDelayedURL = spec;
return;
}
Unused << SendLoadURL(spec, GetShowInfo());
}
void BrowserParent::ResumeLoad(uint64_t aPendingSwitchID) {
MOZ_ASSERT(aPendingSwitchID != 0);
if (NS_WARN_IF(mIsDestroyed)) {
return;
}
Unused << SendResumeLoad(aPendingSwitchID, GetShowInfo());
}
void BrowserParent::InitRendering() {
if (mRemoteLayerTreeOwner.IsInitialized()) {
return;
}
mRemoteLayerTreeOwner.Initialize(this);
layers::LayersId layersId = mRemoteLayerTreeOwner.GetLayersId();
AddBrowserParentToTable(layersId, this);
TextureFactoryIdentifier textureFactoryIdentifier;
mRemoteLayerTreeOwner.GetTextureFactoryIdentifier(&textureFactoryIdentifier);
Unused << SendInitRendering(textureFactoryIdentifier, layersId,
mRemoteLayerTreeOwner.GetCompositorOptions(),
mRemoteLayerTreeOwner.IsLayersConnected());
}
bool BrowserParent::AttachLayerManager() {
return !!mRemoteLayerTreeOwner.AttachLayerManager();
}
void BrowserParent::MaybeShowFrame() {
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
if (!frameLoader) {
return;
}
frameLoader->MaybeShowFrame();
}
bool BrowserParent::Show(const ScreenIntSize& size, bool aParentIsActive) {
mDimensions = size;
if (mIsDestroyed) {
return false;
}
MOZ_ASSERT(mRemoteLayerTreeOwner.IsInitialized());
if (!mRemoteLayerTreeOwner.AttachLayerManager()) {
return false;
}
nsCOMPtr<nsISupports> container = mFrameElement->OwnerDoc()->GetContainer();
nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(container);
nsCOMPtr<nsIWidget> mainWidget;
baseWindow->GetMainWidget(getter_AddRefs(mainWidget));
mSizeMode = mainWidget ? mainWidget->SizeMode() : nsSizeMode_Normal;
Unused << SendShow(size, GetShowInfo(), aParentIsActive, mSizeMode);
return true;
}
mozilla::ipc::IPCResult BrowserParent::RecvSetDimensions(const uint32_t& aFlags,
const int32_t& aX,
const int32_t& aY,
const int32_t& aCx,
const int32_t& aCy) {
MOZ_ASSERT(!(aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER),
"We should never see DIM_FLAGS_SIZE_INNER here!");
NS_ENSURE_TRUE(mFrameElement, IPC_OK());
nsCOMPtr<nsIDocShell> docShell = mFrameElement->OwnerDoc()->GetDocShell();
NS_ENSURE_TRUE(docShell, IPC_OK());
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
docShell->GetTreeOwner(getter_AddRefs(treeOwner));
nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = do_QueryInterface(treeOwner);
NS_ENSURE_TRUE(treeOwnerAsWin, IPC_OK());
// We only care about the parameters that actually changed, see more
// details in BrowserChild::SetDimensions.
int32_t unused;
int32_t x = aX;
if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_X) {
treeOwnerAsWin->GetPosition(&x, &unused);
}
int32_t y = aY;
if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_Y) {
treeOwnerAsWin->GetPosition(&unused, &y);
}
int32_t cx = aCx;
if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_CX) {
treeOwnerAsWin->GetSize(&cx, &unused);
}
int32_t cy = aCy;
if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_CY) {
treeOwnerAsWin->GetSize(&unused, &cy);
}
if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION &&
aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER) {
treeOwnerAsWin->SetPositionAndSize(x, y, cx, cy, nsIBaseWindow::eRepaint);
return IPC_OK();
}
if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION) {
treeOwnerAsWin->SetPosition(x, y);
mUpdatedDimensions = false;
UpdatePosition();
return IPC_OK();
}
if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER) {
treeOwnerAsWin->SetSize(cx, cy, true);
return IPC_OK();
}
MOZ_ASSERT(false, "Unknown flags!");
return IPC_FAIL_NO_REASON(this);
}
nsresult BrowserParent::UpdatePosition() {
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 05:24:48 +00:00
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
if (!frameLoader) {
return NS_OK;
}
nsIntRect windowDims;
NS_ENSURE_SUCCESS(frameLoader->GetWindowDimensions(windowDims),
NS_ERROR_FAILURE);
UpdateDimensions(windowDims, mDimensions);
return NS_OK;
}
void BrowserParent::UpdateDimensions(const nsIntRect& rect,
const ScreenIntSize& size) {
if (mIsDestroyed) {
return;
}
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
NS_WARNING("No widget found in BrowserParent::UpdateDimensions");
return;
}
hal::ScreenConfiguration config;
hal::GetCurrentScreenConfiguration(&config);
hal::ScreenOrientation orientation = config.orientation();
LayoutDeviceIntPoint clientOffset = GetClientOffset();
LayoutDeviceIntPoint chromeOffset = -GetChildProcessOffset();
if (!mUpdatedDimensions || mOrientation != orientation ||
mDimensions != size || !mRect.IsEqualEdges(rect) ||
clientOffset != mClientOffset || chromeOffset != mChromeOffset) {
mUpdatedDimensions = true;
mRect = rect;
mDimensions = size;
mOrientation = orientation;
mClientOffset = clientOffset;
mChromeOffset = chromeOffset;
Unused << SendUpdateDimensions(GetDimensionInfo());
}
}
DimensionInfo BrowserParent::GetDimensionInfo() {
nsCOMPtr<nsIWidget> widget = GetWidget();
MOZ_ASSERT(widget);
CSSToLayoutDeviceScale widgetScale = widget->GetDefaultScale();
LayoutDeviceIntRect devicePixelRect = ViewAs<LayoutDevicePixel>(
mRect, PixelCastJustification::LayoutDeviceIsScreenForTabDims);
LayoutDeviceIntSize devicePixelSize = ViewAs<LayoutDevicePixel>(
mDimensions, PixelCastJustification::LayoutDeviceIsScreenForTabDims);
CSSRect unscaledRect = devicePixelRect / widgetScale;
CSSSize unscaledSize = devicePixelSize / widgetScale;
DimensionInfo di(unscaledRect, unscaledSize, mOrientation, mClientOffset,
mChromeOffset);
return di;
}
void BrowserParent::SizeModeChanged(const nsSizeMode& aSizeMode) {
if (!mIsDestroyed && aSizeMode != mSizeMode) {
mSizeMode = aSizeMode;
Unused << SendSizeModeChanged(aSizeMode);
}
}
void BrowserParent::ThemeChanged() {
if (!mIsDestroyed) {
// The theme has changed, and any cached values we had sent down
// to the child have been invalidated. When this method is called,
// LookAndFeel should have the up-to-date values, which we now
// send down to the child. We do this for every remote tab for now,
// but bug 1156934 has been filed to do it once per content process.
Unused << SendThemeChanged(LookAndFeel::GetIntCache());
}
}
void BrowserParent::HandleAccessKey(const WidgetKeyboardEvent& aEvent,
nsTArray<uint32_t>& aCharCodes) {
if (!mIsDestroyed) {
// Note that we don't need to mark aEvent is posted to a remote process
// because the event may be dispatched to it as normal keyboard event.
// Therefore, we should use local copy to send it.
WidgetKeyboardEvent localEvent(aEvent);
Unused << SendHandleAccessKey(localEvent, aCharCodes);
}
}
void BrowserParent::Activate() {
LOGBROWSERFOCUS(("Activate %p", this));
if (!mIsDestroyed) {
PushFocus(this); // Intentionally inside "if"
Unused << Manager()->SendActivate(this);
}
}
void BrowserParent::Deactivate(bool aWindowLowering) {
LOGBROWSERFOCUS(("Deactivate %p", this));
if (!aWindowLowering) {
PopFocus(this); // Intentionally outside the next "if"
}
if (!mIsDestroyed) {
Unused << Manager()->SendDeactivate(this);
}
}
a11y::PDocAccessibleParent* BrowserParent::AllocPDocAccessibleParent(
PDocAccessibleParent* aParent, const uint64_t&, const uint32_t&,
const IAccessibleHolder&) {
#ifdef ACCESSIBILITY
// Reference freed in DeallocPDocAccessibleParent.
return do_AddRef(new a11y::DocAccessibleParent()).take();
#else
return nullptr;
#endif
}
bool BrowserParent::DeallocPDocAccessibleParent(PDocAccessibleParent* aParent) {
#ifdef ACCESSIBILITY
// Free reference from AllocPDocAccessibleParent.
static_cast<a11y::DocAccessibleParent*>(aParent)->Release();
#endif
return true;
}
mozilla::ipc::IPCResult BrowserParent::RecvPDocAccessibleConstructor(
PDocAccessibleParent* aDoc, PDocAccessibleParent* aParentDoc,
const uint64_t& aParentID, const uint32_t& aMsaaID,
const IAccessibleHolder& aDocCOMProxy) {
#ifdef ACCESSIBILITY
auto doc = static_cast<a11y::DocAccessibleParent*>(aDoc);
// If this tab is already shutting down just mark the new actor as shutdown
// and ignore it. When the tab actor is destroyed it will be too.
if (mIsDestroyed) {
doc->MarkAsShutdown();
return IPC_OK();
}
if (aParentDoc) {
// A document should never directly be the parent of another document.
// There should always be an outer doc accessible child of the outer
// document containing the child.
MOZ_ASSERT(aParentID);
if (!aParentID) {
return IPC_FAIL_NO_REASON(this);
}
auto parentDoc = static_cast<a11y::DocAccessibleParent*>(aParentDoc);
mozilla::ipc::IPCResult added = parentDoc->AddChildDoc(doc, aParentID);
if (!added) {
# ifdef DEBUG
return added;
# else
return IPC_OK();
# endif
}
# ifdef XP_WIN
MOZ_ASSERT(aDocCOMProxy.IsNull());
a11y::WrapperFor(doc)->SetID(aMsaaID);
if (a11y::nsWinUtils::IsWindowEmulationStarted()) {
doc->SetEmulatedWindowHandle(parentDoc->GetEmulatedWindowHandle());
}
# endif
return IPC_OK();
}
a11y::DocAccessibleParent* embedderDoc;
uint64_t embedderID;
Tie(embedderDoc, embedderID) = doc->GetRemoteEmbedder();
if (embedderDoc) {
// Iframe document rendered in a different process to its embedder.
// In this case, we don't get aParentDoc and aParentID.
MOZ_ASSERT(!aParentDoc && !aParentID);
MOZ_ASSERT(embedderID);
doc->SetTopLevelInContentProcess();
# ifdef XP_WIN
MOZ_ASSERT(!aDocCOMProxy.IsNull());
RefPtr<IAccessible> proxy(aDocCOMProxy.Get());
doc->SetCOMInterface(proxy);
# endif
mozilla::ipc::IPCResult added = embedderDoc->AddChildDoc(doc, embedderID);
if (!added) {
# ifdef DEBUG
return added;
# else
return IPC_OK();
# endif
}
# ifdef XP_WIN
// This *must* be called after AddChildDoc because AddChildDoc
// calls ProxyCreated and WrapperFor will fail before that.
a11y::AccessibleWrap* wrapper = a11y::WrapperFor(doc);
MOZ_ASSERT(wrapper);
wrapper->SetID(aMsaaID);
# endif
return IPC_OK();
} else {
// null aParentDoc means this document is at the top level in the child
// process. That means it makes no sense to get an id for an accessible
// that is its parent.
MOZ_ASSERT(!aParentID);
if (aParentID) {
return IPC_FAIL_NO_REASON(this);
}
doc->SetTopLevel();
a11y::DocManager::RemoteDocAdded(doc);
# ifdef XP_WIN
a11y::WrapperFor(doc)->SetID(aMsaaID);
MOZ_ASSERT(!aDocCOMProxy.IsNull());
RefPtr<IAccessible> proxy(aDocCOMProxy.Get());
doc->SetCOMInterface(proxy);
doc->MaybeInitWindowEmulation();
if (a11y::Accessible* outerDoc = doc->OuterDocOfRemoteBrowser()) {
doc->SendParentCOMProxy(outerDoc);
}
# endif
}
#endif
return IPC_OK();
}
PFilePickerParent* BrowserParent::AllocPFilePickerParent(const nsString& aTitle,
const int16_t& aMode) {
return new FilePickerParent(aTitle, aMode);
}
bool BrowserParent::DeallocPFilePickerParent(PFilePickerParent* actor) {
delete actor;
return true;
}
IPCResult BrowserParent::RecvIndexedDBPermissionRequest(
nsIPrincipal* aPrincipal, IndexedDBPermissionRequestResolver&& aResolve) {
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIPrincipal> principal(aPrincipal);
if (!principal) {
return IPC_FAIL_NO_REASON(this);
}
if (NS_WARN_IF(!mFrameElement)) {
return IPC_FAIL_NO_REASON(this);
}
RefPtr<indexedDB::PermissionRequestHelper> actor =
new indexedDB::PermissionRequestHelper(mFrameElement, principal,
aResolve);
indexedDB::PermissionRequestBase::PermissionValue permission;
nsresult rv = actor->PromptIfNeeded(&permission);
if (NS_FAILED(rv)) {
return IPC_FAIL_NO_REASON(this);
}
if (permission != indexedDB::PermissionRequestBase::kPermissionPrompt) {
aResolve(permission);
}
return IPC_OK();
}
IPCResult BrowserParent::RecvPWindowGlobalConstructor(
PWindowGlobalParent* aActor, const WindowGlobalInit& aInit) {
static_cast<WindowGlobalParent*>(aActor)->Init(aInit);
return IPC_OK();
}
PWindowGlobalParent* BrowserParent::AllocPWindowGlobalParent(
const WindowGlobalInit& aInit) {
// Reference freed in DeallocPWindowGlobalParent.
return do_AddRef(new WindowGlobalParent(aInit, /* inproc */ false)).take();
}
bool BrowserParent::DeallocPWindowGlobalParent(PWindowGlobalParent* aActor) {
// Free reference from AllocPWindowGlobalParent.
static_cast<WindowGlobalParent*>(aActor)->Release();
return true;
}
IPCResult BrowserParent::RecvPBrowserBridgeConstructor(
PBrowserBridgeParent* aActor, const nsString& aName,
const nsString& aRemoteType, BrowsingContext* aBrowsingContext,
const uint32_t& aChromeFlags, const TabId& aTabId) {
nsresult rv = static_cast<BrowserBridgeParent*>(aActor)->Init(
aName, aRemoteType, CanonicalBrowsingContext::Cast(aBrowsingContext),
aChromeFlags, aTabId);
if (NS_FAILED(rv)) {
return IPC_FAIL(this, "Failed to construct BrowserBridgeParent");
}
return IPC_OK();
}
PBrowserBridgeParent* BrowserParent::AllocPBrowserBridgeParent(
const nsString& aName, const nsString& aRemoteType,
BrowsingContext* aBrowsingContext, const uint32_t& aChromeFlags,
const TabId& aTabId) {
// Reference freed in DeallocPBrowserBridgeParent.
return do_AddRef(new BrowserBridgeParent()).take();
}
bool BrowserParent::DeallocPBrowserBridgeParent(PBrowserBridgeParent* aActor) {
// Free reference from AllocPBrowserBridgeParent.
static_cast<BrowserBridgeParent*>(aActor)->Release();
return true;
}
void BrowserParent::SendMouseEvent(const nsAString& aType, float aX, float aY,
int32_t aButton, int32_t aClickCount,
int32_t aModifiers,
bool aIgnoreRootScrollFrame) {
if (!mIsDestroyed) {
Unused << PBrowserParent::SendMouseEvent(nsString(aType), aX, aY, aButton,
aClickCount, aModifiers,
aIgnoreRootScrollFrame);
}
}
void BrowserParent::SendRealMouseEvent(WidgetMouseEvent& aEvent) {
if (mIsDestroyed) {
return;
}
aEvent.mRefPoint = TransformParentToChild(aEvent.mRefPoint);
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
// When we mouseenter the tab, the tab's cursor should
// become the current cursor. When we mouseexit, we stop.
if (eMouseEnterIntoWidget == aEvent.mMessage) {
mTabSetsCursor = true;
if (mCursor != eCursorInvalid) {
widget->SetCursor(mCursor, mCustomCursor, mCustomCursorHotspotX,
mCustomCursorHotspotY);
}
} else if (eMouseExitFromWidget == aEvent.mMessage) {
mTabSetsCursor = false;
}
}
if (!mIsReadyToHandleInputEvents) {
if (eMouseEnterIntoWidget == aEvent.mMessage) {
mIsMouseEnterIntoWidgetEventSuppressed = true;
} else if (eMouseExitFromWidget == aEvent.mMessage) {
mIsMouseEnterIntoWidgetEventSuppressed = false;
}
return;
}
ScrollableLayerGuid guid;
uint64_t blockId;
ApzAwareEventRoutingToChild(&guid, &blockId, nullptr);
bool isInputPriorityEventEnabled = Manager()->IsInputPriorityEventEnabled();
if (mIsMouseEnterIntoWidgetEventSuppressed) {
// In the case that the BrowserParent suppressed the eMouseEnterWidget event
// due to its corresponding BrowserChild wasn't ready to handle it, we have
// to resend it when the BrowserChild is ready.
mIsMouseEnterIntoWidgetEventSuppressed = false;
WidgetMouseEvent localEvent(aEvent);
localEvent.mMessage = eMouseEnterIntoWidget;
DebugOnly<bool> ret =
isInputPriorityEventEnabled
? SendRealMouseButtonEvent(localEvent, guid, blockId)
: SendNormalPriorityRealMouseButtonEvent(localEvent, guid, blockId);
NS_WARNING_ASSERTION(
ret, "SendRealMouseButtonEvent(eMouseEnterIntoWidget) failed");
MOZ_ASSERT(!ret || localEvent.HasBeenPostedToRemoteProcess());
}
if (eMouseMove == aEvent.mMessage) {
if (aEvent.mReason == WidgetMouseEvent::eSynthesized) {
DebugOnly<bool> ret =
isInputPriorityEventEnabled
? SendSynthMouseMoveEvent(aEvent, guid, blockId)
: SendNormalPrioritySynthMouseMoveEvent(aEvent, guid, blockId);
NS_WARNING_ASSERTION(ret, "SendSynthMouseMoveEvent() failed");
MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
return;
}
DebugOnly<bool> ret =
isInputPriorityEventEnabled
? SendRealMouseMoveEvent(aEvent, guid, blockId)
: SendNormalPriorityRealMouseMoveEvent(aEvent, guid, blockId);
NS_WARNING_ASSERTION(ret, "SendRealMouseMoveEvent() failed");
MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
return;
}
DebugOnly<bool> ret =
isInputPriorityEventEnabled
? SendRealMouseButtonEvent(aEvent, guid, blockId)
: SendNormalPriorityRealMouseButtonEvent(aEvent, guid, blockId);
NS_WARNING_ASSERTION(ret, "SendRealMouseButtonEvent() failed");
MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
}
LayoutDeviceToCSSScale BrowserParent::GetLayoutDeviceToCSSScale() {
Document* doc = (mFrameElement ? mFrameElement->OwnerDoc() : nullptr);
nsPresContext* ctx = (doc ? doc->GetPresContext() : nullptr);
return LayoutDeviceToCSSScale(
ctx ? (float)ctx->AppUnitsPerDevPixel() / AppUnitsPerCSSPixel() : 0.0f);
}
bool BrowserParent::QueryDropLinksForVerification() {
// Before sending the dragEvent, we query the links being dragged and
// store them on the parent, to make sure the child can not modify links.
nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
if (!dragSession) {
NS_WARNING("No dragSession to query links for verification");
return false;
}
RefPtr<DataTransfer> initialDataTransfer = dragSession->GetDataTransfer();
if (!initialDataTransfer) {
NS_WARNING("No initialDataTransfer to query links for verification");
return false;
}
nsCOMPtr<nsIDroppedLinkHandler> dropHandler =
do_GetService("@mozilla.org/content/dropped-link-handler;1");
if (!dropHandler) {
NS_WARNING("No dropHandler to query links for verification");
return false;
}
// No more than one drop event can happen simultaneously; reset the link
// verification array and store all links that are being dragged.
mVerifyDropLinks.Clear();
nsTArray<RefPtr<nsIDroppedLinkItem>> droppedLinkItems;
dropHandler->QueryLinks(initialDataTransfer, droppedLinkItems);
// Since the entire event is cancelled if one of the links is invalid,
// we can store all links on the parent side without any prior
// validation checks.
nsresult rv = NS_OK;
for (nsIDroppedLinkItem* item : droppedLinkItems) {
nsString tmp;
rv = item->GetUrl(tmp);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to query url for verification");
break;
}
mVerifyDropLinks.AppendElement(tmp);
rv = item->GetName(tmp);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to query name for verification");
break;
}
mVerifyDropLinks.AppendElement(tmp);
rv = item->GetType(tmp);
if (NS_FAILED(rv)) {
NS_WARNING("Failed to query type for verification");
break;
}
mVerifyDropLinks.AppendElement(tmp);
}
if (NS_FAILED(rv)) {
mVerifyDropLinks.Clear();
return false;
}
return true;
}
void BrowserParent::SendRealDragEvent(WidgetDragEvent& aEvent,
uint32_t aDragAction,
uint32_t aDropEffect,
nsIPrincipal* aPrincipal) {
if (mIsDestroyed || !mIsReadyToHandleInputEvents) {
return;
}
MOZ_ASSERT(!Manager()->IsInputPriorityEventEnabled());
aEvent.mRefPoint = TransformParentToChild(aEvent.mRefPoint);
if (aEvent.mMessage == eDrop) {
if (!QueryDropLinksForVerification()) {
return;
}
}
DebugOnly<bool> ret = PBrowserParent::SendRealDragEvent(
aEvent, aDragAction, aDropEffect, aPrincipal);
NS_WARNING_ASSERTION(ret, "PBrowserParent::SendRealDragEvent() failed");
MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
}
void BrowserParent::SendMouseWheelEvent(WidgetWheelEvent& aEvent) {
if (mIsDestroyed || !mIsReadyToHandleInputEvents) {
return;
}
ScrollableLayerGuid guid;
uint64_t blockId;
ApzAwareEventRoutingToChild(&guid, &blockId, nullptr);
aEvent.mRefPoint = TransformParentToChild(aEvent.mRefPoint);
DebugOnly<bool> ret =
Manager()->IsInputPriorityEventEnabled()
? PBrowserParent::SendMouseWheelEvent(aEvent, guid, blockId)
: PBrowserParent::SendNormalPriorityMouseWheelEvent(aEvent, guid,
blockId);
NS_WARNING_ASSERTION(ret, "PBrowserParent::SendMouseWheelEvent() failed");
MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
}
mozilla::ipc::IPCResult BrowserParent::RecvDispatchWheelEvent(
const mozilla::WidgetWheelEvent& aEvent) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return IPC_OK();
}
WidgetWheelEvent localEvent(aEvent);
localEvent.mWidget = widget;
localEvent.mRefPoint = TransformChildToParent(localEvent.mRefPoint);
widget->DispatchInputEvent(&localEvent);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvDispatchMouseEvent(
const mozilla::WidgetMouseEvent& aEvent) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return IPC_OK();
}
WidgetMouseEvent localEvent(aEvent);
localEvent.mWidget = widget;
localEvent.mRefPoint = TransformChildToParent(localEvent.mRefPoint);
widget->DispatchInputEvent(&localEvent);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvDispatchKeyboardEvent(
const mozilla::WidgetKeyboardEvent& aEvent) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return IPC_OK();
}
WidgetKeyboardEvent localEvent(aEvent);
localEvent.mWidget = widget;
localEvent.mRefPoint = TransformChildToParent(localEvent.mRefPoint);
widget->DispatchInputEvent(&localEvent);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvRequestNativeKeyBindings(
const uint32_t& aType, const WidgetKeyboardEvent& aEvent,
nsTArray<CommandInt>* aCommands) {
MOZ_ASSERT(aCommands);
MOZ_ASSERT(aCommands->IsEmpty());
nsIWidget::NativeKeyBindingsType keyBindingsType =
static_cast<nsIWidget::NativeKeyBindingsType>(aType);
switch (keyBindingsType) {
case nsIWidget::NativeKeyBindingsForSingleLineEditor:
case nsIWidget::NativeKeyBindingsForMultiLineEditor:
case nsIWidget::NativeKeyBindingsForRichTextEditor:
break;
default:
return IPC_FAIL(this, "Invalid aType value");
}
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return IPC_OK();
}
WidgetKeyboardEvent localEvent(aEvent);
localEvent.mWidget = widget;
if (NS_FAILED(widget->AttachNativeKeyEvent(localEvent))) {
return IPC_OK();
}
localEvent.InitEditCommandsFor(keyBindingsType);
*aCommands = localEvent.EditCommandsConstRef(keyBindingsType);
return IPC_OK();
}
class SynthesizedEventObserver : public nsIObserver {
NS_DECL_ISUPPORTS
public:
SynthesizedEventObserver(BrowserParent* aBrowserParent,
const uint64_t& aObserverId)
: mBrowserParent(aBrowserParent), mObserverId(aObserverId) {
MOZ_ASSERT(mBrowserParent);
}
NS_IMETHOD Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) override {
if (!mBrowserParent || !mObserverId) {
// We already sent the notification, or we don't actually need to
// send any notification at all.
return NS_OK;
}
if (mBrowserParent->IsDestroyed()) {
// If this happens it's probably a bug in the test that's triggering this.
NS_WARNING(
"BrowserParent was unexpectedly destroyed during event "
"synthesization!");
} else if (!mBrowserParent->SendNativeSynthesisResponse(
mObserverId, nsCString(aTopic))) {
NS_WARNING("Unable to send native event synthesization response!");
}
// Null out browserParent to indicate we already sent the response
mBrowserParent = nullptr;
return NS_OK;
}
private:
virtual ~SynthesizedEventObserver() {}
RefPtr<BrowserParent> mBrowserParent;
uint64_t mObserverId;
};
NS_IMPL_ISUPPORTS(SynthesizedEventObserver, nsIObserver)
class MOZ_STACK_CLASS AutoSynthesizedEventResponder {
public:
AutoSynthesizedEventResponder(BrowserParent* aBrowserParent,
const uint64_t& aObserverId, const char* aTopic)
: mObserver(new SynthesizedEventObserver(aBrowserParent, aObserverId)),
mTopic(aTopic) {}
~AutoSynthesizedEventResponder() {
// This may be a no-op if the observer already sent a response.
mObserver->Observe(nullptr, mTopic, nullptr);
}
nsIObserver* GetObserver() { return mObserver; }
private:
nsCOMPtr<nsIObserver> mObserver;
const char* mTopic;
};
mozilla::ipc::IPCResult BrowserParent::RecvSynthesizeNativeKeyEvent(
const int32_t& aNativeKeyboardLayout, const int32_t& aNativeKeyCode,
const uint32_t& aModifierFlags, const nsString& aCharacters,
const nsString& aUnmodifiedCharacters, const uint64_t& aObserverId) {
AutoSynthesizedEventResponder responder(this, aObserverId, "keyevent");
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
widget->SynthesizeNativeKeyEvent(
aNativeKeyboardLayout, aNativeKeyCode, aModifierFlags, aCharacters,
aUnmodifiedCharacters, responder.GetObserver());
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvSynthesizeNativeMouseEvent(
const LayoutDeviceIntPoint& aPoint, const uint32_t& aNativeMessage,
const uint32_t& aModifierFlags, const uint64_t& aObserverId) {
AutoSynthesizedEventResponder responder(this, aObserverId, "mouseevent");
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
widget->SynthesizeNativeMouseEvent(aPoint, aNativeMessage, aModifierFlags,
responder.GetObserver());
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvSynthesizeNativeMouseMove(
const LayoutDeviceIntPoint& aPoint, const uint64_t& aObserverId) {
AutoSynthesizedEventResponder responder(this, aObserverId, "mousemove");
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
widget->SynthesizeNativeMouseMove(aPoint, responder.GetObserver());
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::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) {
AutoSynthesizedEventResponder responder(this, aObserverId,
"mousescrollevent");
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
widget->SynthesizeNativeMouseScrollEvent(
aPoint, aNativeMessage, aDeltaX, aDeltaY, aDeltaZ, aModifierFlags,
aAdditionalFlags, responder.GetObserver());
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvSynthesizeNativeTouchPoint(
const uint32_t& aPointerId, const TouchPointerState& aPointerState,
const LayoutDeviceIntPoint& aPoint, const double& aPointerPressure,
const uint32_t& aPointerOrientation, const uint64_t& aObserverId) {
AutoSynthesizedEventResponder responder(this, aObserverId, "touchpoint");
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
widget->SynthesizeNativeTouchPoint(aPointerId, aPointerState, aPoint,
aPointerPressure, aPointerOrientation,
responder.GetObserver());
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvSynthesizeNativeTouchTap(
const LayoutDeviceIntPoint& aPoint, const bool& aLongTap,
const uint64_t& aObserverId) {
AutoSynthesizedEventResponder responder(this, aObserverId, "touchtap");
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
widget->SynthesizeNativeTouchTap(aPoint, aLongTap, responder.GetObserver());
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvClearNativeTouchSequence(
const uint64_t& aObserverId) {
AutoSynthesizedEventResponder responder(this, aObserverId, "cleartouch");
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
widget->ClearNativeTouchSequence(responder.GetObserver());
}
return IPC_OK();
}
mozilla::ipc::IPCResult
BrowserParent::RecvSetPrefersReducedMotionOverrideForTest(const bool& aValue) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
widget->SetPrefersReducedMotionOverrideForTest(aValue);
}
return IPC_OK();
}
mozilla::ipc::IPCResult
BrowserParent::RecvResetPrefersReducedMotionOverrideForTest() {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
widget->ResetPrefersReducedMotionOverrideForTest();
}
return IPC_OK();
}
void BrowserParent::SendRealKeyEvent(WidgetKeyboardEvent& aEvent) {
if (mIsDestroyed || !mIsReadyToHandleInputEvents) {
return;
}
aEvent.mRefPoint = TransformParentToChild(aEvent.mRefPoint);
if (aEvent.mMessage == eKeyPress) {
// XXX Should we do this only when input context indicates an editor having
// focus and the key event won't cause inputting text?
aEvent.InitAllEditCommands();
} else {
aEvent.PreventNativeKeyBindings();
}
DebugOnly<bool> ret =
Manager()->IsInputPriorityEventEnabled()
? PBrowserParent::SendRealKeyEvent(aEvent)
: PBrowserParent::SendNormalPriorityRealKeyEvent(aEvent);
NS_WARNING_ASSERTION(ret, "PBrowserParent::SendRealKeyEvent() failed");
MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
}
void BrowserParent::SendRealTouchEvent(WidgetTouchEvent& aEvent) {
if (mIsDestroyed || !mIsReadyToHandleInputEvents) {
return;
}
// PresShell::HandleEventInternal adds touches on touch end/cancel. This
// confuses remote content and the panning and zooming logic into thinking
// that the added touches are part of the touchend/cancel, when actually
// they're not.
if (aEvent.mMessage == eTouchEnd || aEvent.mMessage == eTouchCancel) {
for (int i = aEvent.mTouches.Length() - 1; i >= 0; i--) {
if (!aEvent.mTouches[i]->mChanged) {
aEvent.mTouches.RemoveElementAt(i);
}
}
}
ScrollableLayerGuid guid;
uint64_t blockId;
nsEventStatus apzResponse;
ApzAwareEventRoutingToChild(&guid, &blockId, &apzResponse);
if (mIsDestroyed) {
return;
}
for (uint32_t i = 0; i < aEvent.mTouches.Length(); i++) {
aEvent.mTouches[i]->mRefPoint =
TransformParentToChild(aEvent.mTouches[i]->mRefPoint);
}
bool inputPriorityEventEnabled = Manager()->IsInputPriorityEventEnabled();
if (aEvent.mMessage == eTouchMove) {
DebugOnly<bool> ret =
inputPriorityEventEnabled
? PBrowserParent::SendRealTouchMoveEvent(aEvent, guid, blockId,
apzResponse)
: PBrowserParent::SendNormalPriorityRealTouchMoveEvent(
aEvent, guid, blockId, apzResponse);
NS_WARNING_ASSERTION(ret,
"PBrowserParent::SendRealTouchMoveEvent() failed");
MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
return;
}
DebugOnly<bool> ret = inputPriorityEventEnabled
? PBrowserParent::SendRealTouchEvent(
aEvent, guid, blockId, apzResponse)
: PBrowserParent::SendNormalPriorityRealTouchEvent(
aEvent, guid, blockId, apzResponse);
NS_WARNING_ASSERTION(ret, "PBrowserParent::SendRealTouchEvent() failed");
MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
}
void BrowserParent::SendPluginEvent(WidgetPluginEvent& aEvent) {
DebugOnly<bool> ret = PBrowserParent::SendPluginEvent(aEvent);
NS_WARNING_ASSERTION(ret, "PBrowserParent::SendPluginEvent() failed");
MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
}
bool BrowserParent::SendHandleTap(TapType aType,
const LayoutDevicePoint& aPoint,
Modifiers aModifiers,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId) {
if (mIsDestroyed || !mIsReadyToHandleInputEvents) {
return false;
}
if ((aType == TapType::eSingleTap || aType == TapType::eSecondTap)) {
nsIFocusManager* fm = nsFocusManager::GetFocusManager();
if (fm) {
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
if (frameLoader) {
RefPtr<Element> element = frameLoader->GetOwnerContent();
if (element) {
fm->SetFocus(element, nsIFocusManager::FLAG_BYMOUSE |
nsIFocusManager::FLAG_BYTOUCH |
nsIFocusManager::FLAG_NOSCROLL);
}
}
}
}
return Manager()->IsInputPriorityEventEnabled()
? PBrowserParent::SendHandleTap(aType,
TransformParentToChild(aPoint),
aModifiers, aGuid, aInputBlockId)
: PBrowserParent::SendNormalPriorityHandleTap(
aType, TransformParentToChild(aPoint), aModifiers, aGuid,
aInputBlockId);
}
mozilla::ipc::IPCResult BrowserParent::RecvSyncMessage(
const nsString& aMessage, const ClonedMessageData& aData,
nsTArray<CpowEntry>&& aCpows, nsIPrincipal* aPrincipal,
nsTArray<StructuredCloneData>* aRetVal) {
AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING("BrowserParent::RecvSyncMessage",
OTHER, aMessage);
MMPrinter::Print("BrowserParent::RecvSyncMessage", aMessage, aData);
StructuredCloneData data;
ipc::UnpackClonedMessageDataForParent(aData, data);
CrossProcessCpowHolder cpows(Manager(), aCpows);
if (!ReceiveMessage(aMessage, true, &data, &cpows, aPrincipal, aRetVal)) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvRpcMessage(
const nsString& aMessage, const ClonedMessageData& aData,
nsTArray<CpowEntry>&& aCpows, nsIPrincipal* aPrincipal,
nsTArray<StructuredCloneData>* aRetVal) {
AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING("BrowserParent::RecvRpcMessage",
OTHER, aMessage);
MMPrinter::Print("BrowserParent::RecvRpcMessage", aMessage, aData);
StructuredCloneData data;
ipc::UnpackClonedMessageDataForParent(aData, data);
CrossProcessCpowHolder cpows(Manager(), aCpows);
if (!ReceiveMessage(aMessage, true, &data, &cpows, aPrincipal, aRetVal)) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvAsyncMessage(
const nsString& aMessage, nsTArray<CpowEntry>&& aCpows,
nsIPrincipal* aPrincipal, const ClonedMessageData& aData) {
AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING("BrowserParent::RecvAsyncMessage",
OTHER, aMessage);
MMPrinter::Print("BrowserParent::RecvAsyncMessage", aMessage, aData);
StructuredCloneData data;
ipc::UnpackClonedMessageDataForParent(aData, data);
CrossProcessCpowHolder cpows(Manager(), aCpows);
if (!ReceiveMessage(aMessage, false, &data, &cpows, aPrincipal, nullptr)) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvSetCursor(
const nsCursor& aCursor, const bool& aHasCustomCursor,
const nsCString& aCursorData, const uint32_t& aWidth,
const uint32_t& aHeight, const uint32_t& aStride,
const gfx::SurfaceFormat& aFormat, const uint32_t& aHotspotX,
const uint32_t& aHotspotY, const bool& aForce) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return IPC_OK();
}
if (aForce) {
widget->ClearCachedCursor();
}
if (!mTabSetsCursor) {
return IPC_OK();
}
nsCOMPtr<imgIContainer> cursorImage;
if (aHasCustomCursor) {
if (aHeight * aStride != aCursorData.Length() ||
aStride < aWidth * gfx::BytesPerPixel(aFormat)) {
return IPC_FAIL(this, "Invalid custom cursor data");
}
const gfx::IntSize size(aWidth, aHeight);
RefPtr<gfx::DataSourceSurface> customCursor =
gfx::CreateDataSourceSurfaceFromData(
size, aFormat,
reinterpret_cast<const uint8_t*>(aCursorData.BeginReading()),
aStride);
RefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(customCursor, size);
cursorImage = image::ImageOps::CreateFromDrawable(drawable);
}
widget->SetCursor(aCursor, cursorImage, aHotspotX, aHotspotY);
mCursor = aCursor;
mCustomCursor = cursorImage;
mCustomCursorHotspotX = aHotspotX;
mCustomCursorHotspotY = aHotspotY;
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvSetStatus(const uint32_t& aType,
const nsString& aStatus) {
nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow = GetXULBrowserWindow();
if (!xulBrowserWindow) {
return IPC_OK();
}
switch (aType) {
case nsIWebBrowserChrome::STATUS_LINK:
xulBrowserWindow->SetOverLink(aStatus, nullptr);
break;
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvShowTooltip(
const uint32_t& aX, const uint32_t& aY, const nsString& aTooltip,
const nsString& aDirection) {
nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow = GetXULBrowserWindow();
if (!xulBrowserWindow) {
return IPC_OK();
}
// ShowTooltip will end up accessing XULElement properties in JS (specifically
// BoxObject). However, to get it to JS, we need to make sure we're a
// nsFrameLoaderOwner, which implies we're a XULFrameElement. We can then
// safely pass Element into JS.
RefPtr<nsFrameLoaderOwner> flo = do_QueryObject(mFrameElement);
if (!flo) return IPC_OK();
nsCOMPtr<Element> el = do_QueryInterface(flo);
if (!el) return IPC_OK();
xulBrowserWindow->ShowTooltip(aX, aY, aTooltip, aDirection, el);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvHideTooltip() {
nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow = GetXULBrowserWindow();
if (!xulBrowserWindow) {
return IPC_OK();
}
xulBrowserWindow->HideTooltip();
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvNotifyIMEFocus(
const ContentCache& aContentCache, const IMENotification& aIMENotification,
NotifyIMEFocusResolver&& aResolve) {
if (mIsDestroyed) {
return IPC_OK();
}
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
aResolve(IMENotificationRequests());
return IPC_OK();
}
mContentCache.AssignContent(aContentCache, widget, &aIMENotification);
IMEStateManager::NotifyIME(aIMENotification, widget, this);
IMENotificationRequests requests;
if (aIMENotification.mMessage == NOTIFY_IME_OF_FOCUS) {
requests = widget->IMENotificationRequestsRef();
}
aResolve(requests);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvNotifyIMETextChange(
const ContentCache& aContentCache,
const IMENotification& aIMENotification) {
nsCOMPtr<nsIWidget> widget = GetDocWidget();
if (!widget || !IMEStateManager::DoesBrowserParentHaveIMEFocus(this)) {
return IPC_OK();
}
mContentCache.AssignContent(aContentCache, widget, &aIMENotification);
mContentCache.MaybeNotifyIME(widget, aIMENotification);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvNotifyIMECompositionUpdate(
const ContentCache& aContentCache,
const IMENotification& aIMENotification) {
nsCOMPtr<nsIWidget> widget = GetDocWidget();
if (!widget || !IMEStateManager::DoesBrowserParentHaveIMEFocus(this)) {
return IPC_OK();
}
mContentCache.AssignContent(aContentCache, widget, &aIMENotification);
mContentCache.MaybeNotifyIME(widget, aIMENotification);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvNotifyIMESelection(
const ContentCache& aContentCache,
const IMENotification& aIMENotification) {
nsCOMPtr<nsIWidget> widget = GetDocWidget();
if (!widget || !IMEStateManager::DoesBrowserParentHaveIMEFocus(this)) {
return IPC_OK();
}
mContentCache.AssignContent(aContentCache, widget, &aIMENotification);
mContentCache.MaybeNotifyIME(widget, aIMENotification);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvUpdateContentCache(
const ContentCache& aContentCache) {
nsCOMPtr<nsIWidget> widget = GetDocWidget();
if (!widget || !IMEStateManager::DoesBrowserParentHaveIMEFocus(this)) {
return IPC_OK();
}
mContentCache.AssignContent(aContentCache, widget);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvNotifyIMEMouseButtonEvent(
const IMENotification& aIMENotification, bool* aConsumedByIME) {
nsCOMPtr<nsIWidget> widget = GetDocWidget();
if (!widget || !IMEStateManager::DoesBrowserParentHaveIMEFocus(this)) {
*aConsumedByIME = false;
return IPC_OK();
}
nsresult rv = IMEStateManager::NotifyIME(aIMENotification, widget, this);
*aConsumedByIME = rv == NS_SUCCESS_EVENT_CONSUMED;
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvNotifyIMEPositionChange(
const ContentCache& aContentCache,
const IMENotification& aIMENotification) {
nsCOMPtr<nsIWidget> widget = GetDocWidget();
if (!widget || !IMEStateManager::DoesBrowserParentHaveIMEFocus(this)) {
return IPC_OK();
}
mContentCache.AssignContent(aContentCache, widget, &aIMENotification);
mContentCache.MaybeNotifyIME(widget, aIMENotification);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvOnEventNeedingAckHandled(
const EventMessage& aMessage) {
// This is called when the child process receives WidgetCompositionEvent or
// WidgetSelectionEvent.
// FYI: Don't check if widget is nullptr here because it's more important to
// notify mContentCahce of this than handling something in it.
nsCOMPtr<nsIWidget> widget = GetDocWidget();
// While calling OnEventNeedingAckHandled(), BrowserParent *might* be
// destroyed since it may send notifications to IME.
RefPtr<BrowserParent> kungFuDeathGrip(this);
mContentCache.OnEventNeedingAckHandled(widget, aMessage);
return IPC_OK();
}
void BrowserParent::HandledWindowedPluginKeyEvent(
const NativeEventData& aKeyEventData, bool aIsConsumed) {
DebugOnly<bool> ok =
SendHandledWindowedPluginKeyEvent(aKeyEventData, aIsConsumed);
NS_WARNING_ASSERTION(ok, "SendHandledWindowedPluginKeyEvent failed");
}
mozilla::ipc::IPCResult BrowserParent::RecvOnWindowedPluginKeyEvent(
const NativeEventData& aKeyEventData) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (NS_WARN_IF(!widget)) {
// Notifies the plugin process of the key event being not consumed by us.
HandledWindowedPluginKeyEvent(aKeyEventData, false);
return IPC_OK();
}
nsresult rv = widget->OnWindowedPluginKeyEvent(aKeyEventData, this);
if (NS_WARN_IF(NS_FAILED(rv))) {
// Notifies the plugin process of the key event being not consumed by us.
HandledWindowedPluginKeyEvent(aKeyEventData, false);
return IPC_OK();
}
// If the key event is posted to another process, we need to wait a call
// of HandledWindowedPluginKeyEvent(). So, nothing to do here in this case.
if (rv == NS_SUCCESS_EVENT_HANDLED_ASYNCHRONOUSLY) {
return IPC_OK();
}
// Otherwise, the key event is handled synchronously. Let's notify the
// plugin process of the key event's result.
bool consumed = (rv == NS_SUCCESS_EVENT_CONSUMED);
HandledWindowedPluginKeyEvent(aKeyEventData, consumed);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvRequestFocus(const bool& aCanRaise) {
LOGBROWSERFOCUS(("RecvRequestFocus %p, aCanRaise: %d", this, aCanRaise));
if (BrowserBridgeParent* bridgeParent = GetBrowserBridgeParent()) {
mozilla::Unused << bridgeParent->SendRequestFocus(aCanRaise);
return IPC_OK();
}
if (!mFrameElement) {
return IPC_OK();
}
nsContentUtils::RequestFrameFocus(*mFrameElement, aCanRaise);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvEnableDisableCommands(
const nsString& aAction, nsTArray<nsCString>&& aEnabledCommands,
nsTArray<nsCString>&& aDisabledCommands) {
nsCOMPtr<nsIBrowser> browser =
mFrameElement ? mFrameElement->AsBrowser() : nullptr;
bool isRemoteBrowser = false;
if (browser) {
browser->GetIsRemoteBrowser(&isRemoteBrowser);
}
if (isRemoteBrowser) {
browser->EnableDisableCommandsRemoteOnly(aAction, aEnabledCommands,
aDisabledCommands);
}
return IPC_OK();
}
LayoutDeviceIntPoint BrowserParent::TransformPoint(
const LayoutDeviceIntPoint& aPoint,
const LayoutDeviceToLayoutDeviceMatrix4x4& aMatrix) {
LayoutDevicePoint floatPoint(aPoint);
LayoutDevicePoint floatTransformed = TransformPoint(floatPoint, aMatrix);
// The next line loses precision if an out-of-process iframe
// has been scaled or rotated.
return RoundedToInt(floatTransformed);
}
LayoutDevicePoint BrowserParent::TransformPoint(
const LayoutDevicePoint& aPoint,
const LayoutDeviceToLayoutDeviceMatrix4x4& aMatrix) {
return aMatrix.TransformPoint(aPoint);
}
LayoutDeviceIntPoint BrowserParent::TransformParentToChild(
const LayoutDeviceIntPoint& aPoint) {
LayoutDeviceToLayoutDeviceMatrix4x4 matrix =
GetChildToParentConversionMatrix();
if (!matrix.Invert()) {
return LayoutDeviceIntPoint(0, 0);
}
return TransformPoint(aPoint, matrix);
}
LayoutDevicePoint BrowserParent::TransformParentToChild(
const LayoutDevicePoint& aPoint) {
LayoutDeviceToLayoutDeviceMatrix4x4 matrix =
GetChildToParentConversionMatrix();
if (!matrix.Invert()) {
return LayoutDevicePoint(0.0, 0.0);
}
return TransformPoint(aPoint, matrix);
}
LayoutDeviceIntPoint BrowserParent::TransformChildToParent(
const LayoutDeviceIntPoint& aPoint) {
return TransformPoint(aPoint, GetChildToParentConversionMatrix());
}
LayoutDevicePoint BrowserParent::TransformChildToParent(
const LayoutDevicePoint& aPoint) {
return TransformPoint(aPoint, GetChildToParentConversionMatrix());
}
LayoutDeviceIntRect BrowserParent::TransformChildToParent(
const LayoutDeviceIntRect& aRect) {
LayoutDeviceToLayoutDeviceMatrix4x4 matrix =
GetChildToParentConversionMatrix();
LayoutDeviceRect floatRect(aRect);
// The outcome is not ideal if an out-of-process iframe has been rotated
LayoutDeviceRect floatTransformed = matrix.TransformBounds(floatRect);
// The next line loses precision if an out-of-process iframe
// has been scaled or rotated.
return RoundedToInt(floatTransformed);
}
LayoutDeviceToLayoutDeviceMatrix4x4
BrowserParent::GetChildToParentConversionMatrix() {
if (mChildToParentConversionMatrix) {
return *mChildToParentConversionMatrix;
}
LayoutDevicePoint offset(-GetChildProcessOffset());
return LayoutDeviceToLayoutDeviceMatrix4x4::Translation(offset);
}
void BrowserParent::SetChildToParentConversionMatrix(
const LayoutDeviceToLayoutDeviceMatrix4x4& aMatrix) {
mChildToParentConversionMatrix = Some(aMatrix);
if (mIsDestroyed) {
return;
}
mozilla::Unused << SendChildToParentMatrix(aMatrix.ToUnknownMatrix());
}
LayoutDeviceIntPoint BrowserParent::GetChildProcessOffset() {
// The "toplevel widget" in child processes is always at position
// 0,0. Map the event coordinates to match that.
LayoutDeviceIntPoint offset(0, 0);
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 05:24:48 +00:00
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
if (!frameLoader) {
return offset;
}
nsIFrame* targetFrame = frameLoader->GetPrimaryFrameOfOwningContent();
if (!targetFrame) {
return offset;
}
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return offset;
}
nsPresContext* presContext = targetFrame->PresContext();
nsIFrame* rootFrame = presContext->PresShell()->GetRootFrame();
nsView* rootView = rootFrame ? rootFrame->GetView() : nullptr;
if (!rootView) {
return offset;
}
// Note that we don't want to take into account transforms here:
#if 0
nsPoint pt(0, 0);
nsLayoutUtils::TransformPoint(targetFrame, rootFrame, pt);
#endif
// In practice, when transforms are applied to this frameLoader, we currently
// get the wrong results whether we take transforms into account here or not.
// But applying transforms here gives us the wrong results in all
// circumstances when transforms are applied, unless they're purely
// translational. It also gives us the wrong results whenever CSS transitions
// are used to apply transforms, since the offeets aren't updated as the
// transition is animated.
//
// What we actually need to do is apply the transforms to the coordinates of
// any events we send to the child, and reverse them for any screen
// coordinates that we retrieve from the child.
nsPoint pt = targetFrame->GetOffsetTo(rootFrame);
return -nsLayoutUtils::TranslateViewToWidget(presContext, rootView, pt,
widget);
}
LayoutDeviceIntPoint BrowserParent::GetClientOffset() {
nsCOMPtr<nsIWidget> widget = GetWidget();
nsCOMPtr<nsIWidget> docWidget = GetDocWidget();
if (widget == docWidget) {
return widget->GetClientOffset();
}
return (docWidget->GetClientOffset() +
nsLayoutUtils::WidgetToWidgetOffset(widget, docWidget));
}
void BrowserParent::StopIMEStateManagement() {
if (mIsDestroyed) {
return;
}
Unused << SendStopIMEStateManagement();
}
mozilla::ipc::IPCResult BrowserParent::RecvReplyKeyEvent(
const WidgetKeyboardEvent& aEvent) {
NS_ENSURE_TRUE(mFrameElement, IPC_OK());
WidgetKeyboardEvent localEvent(aEvent);
localEvent.MarkAsHandledInRemoteProcess();
// Here we convert the WidgetEvent that we received to an Event
// to be able to dispatch it to the <browser> element as the target element.
Document* doc = mFrameElement->OwnerDoc();
nsPresContext* presContext = doc->GetPresContext();
NS_ENSURE_TRUE(presContext, IPC_OK());
AutoHandlingUserInputStatePusher userInpStatePusher(localEvent.IsTrusted(),
&localEvent);
Bug 1333459 - part2-2: EventStateManager should check if it needs to wait reply from remote content before handling access keys r=smaug Currently, access key is handled in EventStateManager::PreHandleEvent() with eKeyPress event, i.e., before dispatching it into the DOM tree, if the access key is registered in EventStateManager. So, the main process does not check if the preceding eKeyDown event is consumed in focused remote process. When preceding eKeyDown event is consumed in the main process, eKeyPress event won't be dispatched by widget. However, if remote process has focus, it's impossible widget to stop dispatching eKeyPress event because preceding eKeyDown event hasn't been handled in the focused remote process yet. Therefore, main process needs to post eKeyPress event to check if preceding eKeyDown event was consumed. When eKeyPress event is marked as "waiting reply from remote process", TabChild sends it back to the main process only when preceding eKeyDown event wasn't consumed. So, only when eKeyPress event is back to the main process, main process should handle accesskey with it. This patch makes EventStateManager::PreHandleEvent() check if a remote target has focus before handling accesskey. If a remote process has accesskey and there is an accesskey matching with eKeyPress event, it marks the event as "waiting reply from remote content" and stop propagation in the process. Finally, when eKeyPress event is sent back to TabParent, TabParent::RecvReplyKeyEvent() calls EventStateManager::HandleAccessKey() before dispatching the reply event into the DOM tree. MozReview-Commit-ID: KsOkakaIVzb --HG-- extra : rebase_source : 7e0c6966a1bde085e34d45bca4b0166b9fc2f3f1
2017-07-22 01:50:41 +00:00
nsEventStatus status = nsEventStatus_eIgnore;
// Handle access key in this process before dispatching reply event because
// ESM handles it before dispatching the event to the DOM tree.
if (localEvent.mMessage == eKeyPress &&
(localEvent.ModifiersMatchWithAccessKey(AccessKeyType::eChrome) ||
localEvent.ModifiersMatchWithAccessKey(AccessKeyType::eContent))) {
RefPtr<EventStateManager> esm = presContext->EventStateManager();
AutoTArray<uint32_t, 10> accessCharCodes;
localEvent.GetAccessKeyCandidates(accessCharCodes);
if (esm->HandleAccessKey(&localEvent, presContext, accessCharCodes)) {
status = nsEventStatus_eConsumeNoDefault;
}
}
EventDispatcher::Dispatch(mFrameElement, presContext, &localEvent, nullptr,
&status);
if (!localEvent.DefaultPrevented() &&
!localEvent.mFlags.mIsSynthesizedForTests) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
widget->PostHandleKeyEvent(&localEvent);
localEvent.StopPropagation();
}
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvAccessKeyNotHandled(
const WidgetKeyboardEvent& aEvent) {
NS_ENSURE_TRUE(mFrameElement, IPC_OK());
Bug 1333459 - part2-2: EventStateManager should check if it needs to wait reply from remote content before handling access keys r=smaug Currently, access key is handled in EventStateManager::PreHandleEvent() with eKeyPress event, i.e., before dispatching it into the DOM tree, if the access key is registered in EventStateManager. So, the main process does not check if the preceding eKeyDown event is consumed in focused remote process. When preceding eKeyDown event is consumed in the main process, eKeyPress event won't be dispatched by widget. However, if remote process has focus, it's impossible widget to stop dispatching eKeyPress event because preceding eKeyDown event hasn't been handled in the focused remote process yet. Therefore, main process needs to post eKeyPress event to check if preceding eKeyDown event was consumed. When eKeyPress event is marked as "waiting reply from remote process", TabChild sends it back to the main process only when preceding eKeyDown event wasn't consumed. So, only when eKeyPress event is back to the main process, main process should handle accesskey with it. This patch makes EventStateManager::PreHandleEvent() check if a remote target has focus before handling accesskey. If a remote process has accesskey and there is an accesskey matching with eKeyPress event, it marks the event as "waiting reply from remote content" and stop propagation in the process. Finally, when eKeyPress event is sent back to TabParent, TabParent::RecvReplyKeyEvent() calls EventStateManager::HandleAccessKey() before dispatching the reply event into the DOM tree. MozReview-Commit-ID: KsOkakaIVzb --HG-- extra : rebase_source : 7e0c6966a1bde085e34d45bca4b0166b9fc2f3f1
2017-07-22 01:50:41 +00:00
// This is called only when this process had focus and HandleAccessKey
// message was posted to all remote process and each remote process didn't
// execute any content access keys.
// XXX If there were two or more remote processes, this may be called
// twice or more for a keyboard event, that must be a bug. But how to
// detect if received event has already been handled?
MOZ_ASSERT(aEvent.mMessage == eKeyPress);
WidgetKeyboardEvent localEvent(aEvent);
localEvent.MarkAsHandledInRemoteProcess();
localEvent.mMessage = eAccessKeyNotFound;
// Here we convert the WidgetEvent that we received to an Event
// to be able to dispatch it to the <browser> element as the target element.
Document* doc = mFrameElement->OwnerDoc();
PresShell* presShell = doc->GetPresShell();
NS_ENSURE_TRUE(presShell, IPC_OK());
if (presShell->CanDispatchEvent()) {
nsPresContext* presContext = presShell->GetPresContext();
NS_ENSURE_TRUE(presContext, IPC_OK());
EventDispatcher::Dispatch(mFrameElement, presContext, &localEvent);
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvRegisterProtocolHandler(
const nsString& aScheme, nsIURI* aHandlerURI, const nsString& aTitle,
nsIURI* aDocURI) {
Bug 1499092 - rename/move code from 'feeds' and 'web content' to more appropriate/obvious versions for registerProtocolHandler, r=nika Differential Revision: https://phabricator.services.mozilla.com/D13699 --HG-- rename : browser/components/feeds/WebContentConverter.js => browser/components/protocolhandler/WebProtocolHandlerRegistrar.js rename : browser/components/feeds/moz.build => browser/components/protocolhandler/moz.build rename : browser/components/feeds/test/.eslintrc.js => browser/components/protocolhandler/test/.eslintrc.js rename : browser/components/feeds/test/browser/.eslintrc.js => browser/components/protocolhandler/test/browser/.eslintrc.js rename : browser/components/feeds/test/browser/browser.ini => browser/components/protocolhandler/test/browser/browser.ini rename : browser/components/feeds/test/browser/browser_registerProtocolHandler_notification.html => browser/components/protocolhandler/test/browser/browser_registerProtocolHandler_notification.html rename : browser/components/feeds/test/browser/browser_registerProtocolHandler_notification.js => browser/components/protocolhandler/test/browser/browser_registerProtocolHandler_notification.js rename : browser/components/feeds/test/mochitest.ini => browser/components/protocolhandler/test/mochitest.ini rename : browser/components/feeds/test/test_registerHandler.html => browser/components/protocolhandler/test/test_registerHandler.html rename : browser/components/feeds/test/test_registerHandler_disabled.html => browser/components/protocolhandler/test/test_registerHandler_disabled.html rename : dom/interfaces/sidebar/nsIWebContentHandlerRegistrar.idl => dom/interfaces/sidebar/nsIWebProtocolHandlerRegistrar.idl extra : moz-landing-system : lando
2018-12-13 13:34:11 +00:00
nsCOMPtr<nsIWebProtocolHandlerRegistrar> registrar =
do_GetService(NS_WEBPROTOCOLHANDLERREGISTRAR_CONTRACTID);
if (registrar) {
registrar->RegisterProtocolHandler(aScheme, aHandlerURI, aTitle, aDocURI,
mFrameElement);
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvOnStateChange(
const Maybe<WebProgressData>& aWebProgressData,
const RequestData& aRequestData, const uint32_t aStateFlags,
const nsresult aStatus,
const Maybe<WebProgressStateChangeData>& aStateChangeData) {
nsCOMPtr<nsIBrowser> browser;
nsCOMPtr<nsIWebProgress> manager;
nsCOMPtr<nsIWebProgressListener> managerAsListener;
if (!GetWebProgressListener(getter_AddRefs(browser), getter_AddRefs(manager),
getter_AddRefs(managerAsListener))) {
return IPC_OK();
}
nsCOMPtr<nsIWebProgress> webProgress;
nsCOMPtr<nsIRequest> request;
ReconstructWebProgressAndRequest(manager, aWebProgressData, aRequestData,
getter_AddRefs(webProgress),
getter_AddRefs(request));
if (aWebProgressData && aWebProgressData->isTopLevel()) {
Unused << browser->SetIsNavigating(aStateChangeData->isNavigating());
Unused << browser->SetMayEnableCharacterEncodingMenu(
aStateChangeData->mayEnableCharacterEncodingMenu());
Unused << browser->SetCharsetAutodetected(
aStateChangeData->charsetAutodetected());
Unused << browser->UpdateForStateChange(aStateChangeData->charset(),
aStateChangeData->documentURI(),
aStateChangeData->contentType());
} else if (aStateChangeData.isSome()) {
return IPC_FAIL(
this,
"Unexpected WebProgressStateChangeData for non-top-level WebProgress");
}
Unused << managerAsListener->OnStateChange(webProgress, request, aStateFlags,
aStatus);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvOnProgressChange(
const Maybe<WebProgressData>& aWebProgressData,
const RequestData& aRequestData, const int32_t aCurSelfProgress,
const int32_t aMaxSelfProgress, const int32_t aCurTotalProgress,
const int32_t aMaxTotalProgress) {
nsCOMPtr<nsIBrowser> browser;
nsCOMPtr<nsIWebProgress> manager;
nsCOMPtr<nsIWebProgressListener> managerAsListener;
if (!GetWebProgressListener(getter_AddRefs(browser), getter_AddRefs(manager),
getter_AddRefs(managerAsListener))) {
return IPC_OK();
}
nsCOMPtr<nsIWebProgress> webProgress;
nsCOMPtr<nsIRequest> request;
ReconstructWebProgressAndRequest(manager, aWebProgressData, aRequestData,
getter_AddRefs(webProgress),
getter_AddRefs(request));
Unused << managerAsListener->OnProgressChange(
webProgress, request, aCurSelfProgress, aMaxSelfProgress,
aCurTotalProgress, aMaxTotalProgress);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvOnLocationChange(
const Maybe<WebProgressData>& aWebProgressData,
const RequestData& aRequestData, nsIURI* aLocation, const uint32_t aFlags,
const bool aCanGoBack, const bool aCanGoForward,
const Maybe<WebProgressLocationChangeData>& aLocationChangeData) {
nsCOMPtr<nsIBrowser> browser;
nsCOMPtr<nsIWebProgress> manager;
nsCOMPtr<nsIWebProgressListener> managerAsListener;
if (!GetWebProgressListener(getter_AddRefs(browser), getter_AddRefs(manager),
getter_AddRefs(managerAsListener))) {
return IPC_OK();
}
nsCOMPtr<nsIWebProgress> webProgress;
nsCOMPtr<nsIRequest> request;
ReconstructWebProgressAndRequest(manager, aWebProgressData, aRequestData,
getter_AddRefs(webProgress),
getter_AddRefs(request));
Unused << browser->UpdateWebNavigationForLocationChange(aCanGoBack,
aCanGoForward);
if (aWebProgressData && aWebProgressData->isTopLevel()) {
nsCOMPtr<nsIContentSecurityPolicy> csp;
if (aLocationChangeData->csp().isSome()) {
csp = CSPInfoToCSP(aLocationChangeData->csp().ref(), nullptr, nullptr);
}
nsCOMPtr<nsIPrincipal> contentPrincipal =
PrincipalInfoToPrincipal(aLocationChangeData->contentPrincipal());
nsCOMPtr<nsIPrincipal> contentStoragePrincipal = PrincipalInfoToPrincipal(
aLocationChangeData->contentStoragePrincipal());
Unused << browser->SetIsNavigating(aLocationChangeData->isNavigating());
Unused << browser->UpdateForLocationChange(
aLocation, aLocationChangeData->charset(),
aLocationChangeData->mayEnableCharacterEncodingMenu(),
aLocationChangeData->charsetAutodetected(),
aLocationChangeData->documentURI(), aLocationChangeData->title(),
contentPrincipal, contentStoragePrincipal, csp,
aLocationChangeData->isSyntheticDocument(),
aWebProgressData->innerDOMWindowID(),
aLocationChangeData->requestContextID().isSome(),
aLocationChangeData->requestContextID().valueOr(0),
aLocationChangeData->contentType());
}
Unused << managerAsListener->OnLocationChange(webProgress, request, aLocation,
aFlags);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvOnStatusChange(
const Maybe<WebProgressData>& aWebProgressData,
const RequestData& aRequestData, const nsresult aStatus,
const nsString& aMessage) {
nsCOMPtr<nsIBrowser> browser;
nsCOMPtr<nsIWebProgress> manager;
nsCOMPtr<nsIWebProgressListener> managerAsListener;
if (!GetWebProgressListener(getter_AddRefs(browser), getter_AddRefs(manager),
getter_AddRefs(managerAsListener))) {
return IPC_OK();
}
nsCOMPtr<nsIWebProgress> webProgress;
nsCOMPtr<nsIRequest> request;
ReconstructWebProgressAndRequest(manager, aWebProgressData, aRequestData,
getter_AddRefs(webProgress),
getter_AddRefs(request));
Unused << managerAsListener->OnStatusChange(webProgress, request, aStatus,
aMessage.get());
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvOnContentBlockingEvent(
const Maybe<WebProgressData>& aWebProgressData,
const RequestData& aRequestData, const uint32_t& aEvent) {
nsCOMPtr<nsIBrowser> browser;
nsCOMPtr<nsIWebProgress> manager;
nsCOMPtr<nsIWebProgressListener> managerAsListener;
if (!GetWebProgressListener(getter_AddRefs(browser), getter_AddRefs(manager),
getter_AddRefs(managerAsListener))) {
return IPC_OK();
}
nsCOMPtr<nsIWebProgress> webProgress;
nsCOMPtr<nsIRequest> request;
ReconstructWebProgressAndRequest(manager, aWebProgressData, aRequestData,
getter_AddRefs(webProgress),
getter_AddRefs(request));
Unused << managerAsListener->OnContentBlockingEvent(webProgress, request,
aEvent);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvNavigationFinished() {
nsCOMPtr<nsIBrowser> browser =
mFrameElement ? mFrameElement->AsBrowser() : nullptr;
if (browser) {
browser->SetIsNavigating(false);
}
return IPC_OK();
}
bool BrowserParent::GetWebProgressListener(
nsIBrowser** aOutBrowser, nsIWebProgress** aOutManager,
nsIWebProgressListener** aOutListener) {
MOZ_ASSERT(aOutBrowser);
MOZ_ASSERT(aOutManager);
MOZ_ASSERT(aOutListener);
nsCOMPtr<nsIBrowser> browser;
RefPtr<Element> currentElement = mFrameElement;
// In Responsive Design Mode, mFrameElement will be the <iframe mozbrowser>,
// but we want the <xul:browser> that it is embedded in.
while (currentElement) {
browser = currentElement->AsBrowser();
if (browser) {
break;
}
BrowsingContext* browsingContext =
currentElement->OwnerDoc()->GetBrowsingContext();
currentElement =
browsingContext ? browsingContext->GetEmbedderElement() : nullptr;
}
if (!browser) {
return false;
}
nsCOMPtr<nsIWebProgress> manager;
nsresult rv = browser->GetRemoteWebProgressManager(getter_AddRefs(manager));
if (NS_FAILED(rv)) {
return false;
}
nsCOMPtr<nsIWebProgressListener> listener = do_QueryInterface(manager);
if (!listener) {
// We are no longer remote so we cannot forward this event.
return false;
}
browser.forget(aOutBrowser);
manager.forget(aOutManager);
listener.forget(aOutListener);
return true;
}
void BrowserParent::ReconstructWebProgressAndRequest(
nsIWebProgress* aManager, const Maybe<WebProgressData>& aWebProgressData,
const RequestData& aRequestData, nsIWebProgress** aOutWebProgress,
nsIRequest** aOutRequest) {
MOZ_DIAGNOSTIC_ASSERT(aOutWebProgress,
"aOutWebProgress should never be null");
MOZ_DIAGNOSTIC_ASSERT(aOutRequest, "aOutRequest should never be null");
nsCOMPtr<nsIWebProgress> webProgress;
if (aWebProgressData) {
webProgress = new RemoteWebProgress(
aManager, aWebProgressData->outerDOMWindowID(),
aWebProgressData->innerDOMWindowID(), aWebProgressData->loadType(),
aWebProgressData->isLoadingDocument(), aWebProgressData->isTopLevel());
} else {
webProgress = new RemoteWebProgress(aManager, 0, 0, 0, false, false);
}
webProgress.forget(aOutWebProgress);
if (aRequestData.requestURI()) {
nsCOMPtr<nsIRequest> request = MakeAndAddRef<RemoteWebProgressRequest>(
aRequestData.requestURI(), aRequestData.originalRequestURI(),
aRequestData.matchedList(), aRequestData.elapsedLoadTimeMS());
request.forget(aOutRequest);
} else {
*aOutRequest = nullptr;
}
}
mozilla::ipc::IPCResult BrowserParent::RecvSessionStoreUpdate(
const Maybe<nsCString>& aDocShellCaps, const Maybe<bool>& aPrivatedMode,
const nsTArray<nsCString>&& aPositions,
const nsTArray<int32_t>&& aPositionDescendants, const uint32_t& aFlushId,
const bool& aIsFinal, const uint32_t& aEpoch) {
UpdateSessionStoreData data;
if (aDocShellCaps.isSome()) {
data.mDocShellCaps.Construct() = aDocShellCaps.value();
}
if (aPrivatedMode.isSome()) {
data.mIsPrivate.Construct() = aPrivatedMode.value();
}
if (aPositions.Length() != 0) {
data.mPositions.Construct().Assign(std::move(aPositions));
data.mPositionDescendants.Construct().Assign(
std::move(aPositionDescendants));
}
nsCOMPtr<nsISessionStoreFunctions> funcs =
do_ImportModule("resource://gre/modules/SessionStoreFunctions.jsm");
NS_ENSURE_TRUE(funcs, IPC_OK());
nsCOMPtr<nsIXPConnectWrappedJS> wrapped = do_QueryInterface(funcs);
AutoJSAPI jsapi;
MOZ_ALWAYS_TRUE(jsapi.Init(wrapped->GetJSObjectGlobal()));
JS::Rooted<JS::Value> dataVal(jsapi.cx());
bool ok = ToJSValue(jsapi.cx(), data, &dataVal);
NS_ENSURE_TRUE(ok, IPC_OK());
nsresult rv = funcs->UpdateSessionStore(mFrameElement, aFlushId, aIsFinal,
aEpoch, dataVal);
NS_ENSURE_SUCCESS(rv, IPC_OK());
return IPC_OK();
}
bool BrowserParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return true;
}
if (NS_WARN_IF(!mContentCache.HandleQueryContentEvent(aEvent, widget)) ||
NS_WARN_IF(!aEvent.mSucceeded)) {
return true;
}
switch (aEvent.mMessage) {
case eQueryTextRect:
case eQueryCaretRect:
case eQueryEditorRect: {
nsCOMPtr<nsIWidget> widget = GetWidget();
nsCOMPtr<nsIWidget> docWidget = GetDocWidget();
if (widget != docWidget) {
aEvent.mReply.mRect +=
nsLayoutUtils::WidgetToWidgetOffset(widget, docWidget);
}
aEvent.mReply.mRect = TransformChildToParent(aEvent.mReply.mRect);
break;
}
default:
break;
}
return true;
}
bool BrowserParent::SendCompositionEvent(WidgetCompositionEvent& aEvent) {
if (mIsDestroyed) {
return false;
}
if (!mContentCache.OnCompositionEvent(aEvent)) {
return true;
}
bool ret = Manager()->IsInputPriorityEventEnabled()
? PBrowserParent::SendCompositionEvent(aEvent)
: PBrowserParent::SendNormalPriorityCompositionEvent(aEvent);
if (NS_WARN_IF(!ret)) {
return false;
}
MOZ_ASSERT(aEvent.HasBeenPostedToRemoteProcess());
return true;
}
bool BrowserParent::SendSelectionEvent(WidgetSelectionEvent& aEvent) {
if (mIsDestroyed) {
return false;
}
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return true;
}
mContentCache.OnSelectionEvent(aEvent);
bool ret = Manager()->IsInputPriorityEventEnabled()
? PBrowserParent::SendSelectionEvent(aEvent)
: PBrowserParent::SendNormalPrioritySelectionEvent(aEvent);
if (NS_WARN_IF(!ret)) {
return false;
}
MOZ_ASSERT(aEvent.HasBeenPostedToRemoteProcess());
aEvent.mSucceeded = true;
return true;
}
bool BrowserParent::SendPasteTransferable(const IPCDataTransfer& aDataTransfer,
const bool& aIsPrivateData,
nsIPrincipal* aRequestingPrincipal,
const uint32_t& aContentPolicyType) {
return PBrowserParent::SendPasteTransferable(
aDataTransfer, aIsPrivateData, aRequestingPrincipal, aContentPolicyType);
}
/* static */
void BrowserParent::PushFocus(BrowserParent* aBrowserParent) {
if (!sFocusStack) {
MOZ_ASSERT_UNREACHABLE("PushFocus when not initialized");
return;
}
if (!aBrowserParent->GetBrowserBridgeParent()) {
// top-level Web content
// When a new native window is created, we spin a nested event loop.
// As a result, unlike when raising an existing window, we get
// PushFocus for content in the new window before we get the PopFocus
// for content in the old one. Hence, if the stack isn't empty when
// pushing top-level Web content, first pop everything off the stack.
PopFocusAll();
MOZ_ASSERT(sFocusStack->IsEmpty());
} else {
// out-of-process iframe
// Considering that we can get top-level pushes out of order, let's
// ignore trailing out-of-process iframe pushes for the previous top-level
// Web content.
if (sFocusStack->IsEmpty()) {
LOGBROWSERFOCUS(
("PushFocus for out-of-process iframe ignored with empty stack %p",
aBrowserParent));
return;
}
nsCOMPtr<nsIWidget> webRootWidget = sFocusStack->ElementAt(0)->GetWidget();
nsCOMPtr<nsIWidget> iframeWigdet = aBrowserParent->GetWidget();
if (webRootWidget != iframeWigdet) {
LOGBROWSERFOCUS(
("PushFocus for out-of-process iframe ignored with mismatching "
"top-level content %p",
aBrowserParent));
return;
}
}
if (sFocusStack->Contains(aBrowserParent)) {
MOZ_ASSERT_UNREACHABLE(
"Trying to push a BrowserParent that is already on the stack");
return;
}
BrowserParent* old = GetFocused();
sFocusStack->AppendElement(aBrowserParent);
MOZ_ASSERT(GetFocused() == aBrowserParent);
LOGBROWSERFOCUS(("PushFocus changed focus to %p", aBrowserParent));
IMEStateManager::OnFocusMovedBetweenBrowsers(old, aBrowserParent);
}
/* static */
void BrowserParent::PopFocus(BrowserParent* aBrowserParent) {
if (!sFocusStack) {
MOZ_ASSERT_UNREACHABLE("PopFocus when not initialized");
return;
}
// When focus is in an out-of-process iframe and the whole window
// or tab loses focus, we first receive a pop for the top-level Web
// content process and only then for its out-of-process iframes.
// Hence, we do all the popping up front and then ignore the
// pop requests for the out-of-process iframes that we already
// popped.
auto pos = sFocusStack->LastIndexOf(aBrowserParent);
if (pos == nsTArray<BrowserParent*>::NoIndex) {
LOGBROWSERFOCUS(("PopFocus not on stack %p", aBrowserParent));
return;
}
auto len = sFocusStack->Length();
auto itemsToPop = len - pos;
LOGBROWSERFOCUS(("PopFocus pops %zu items %p", itemsToPop, aBrowserParent));
while (pos < sFocusStack->Length()) {
BrowserParent* popped = sFocusStack->PopLastElement();
BrowserParent* focused = GetFocused();
LOGBROWSERFOCUS(("PopFocus changed focus to %p", focused));
IMEStateManager::OnFocusMovedBetweenBrowsers(popped, focused);
}
}
/* static */
void BrowserParent::PopFocusAll() {
if (!sFocusStack->IsEmpty()) {
LOGBROWSERFOCUS(("PopFocusAll pops items"));
PopFocus(sFocusStack->ElementAt(0));
} else {
LOGBROWSERFOCUS(("PopFocusAll does nothing"));
}
}
mozilla::ipc::IPCResult BrowserParent::RecvRequestIMEToCommitComposition(
const bool& aCancel, bool* aIsCommitted, nsString* aCommittedString) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
*aIsCommitted = false;
return IPC_OK();
}
*aIsCommitted = mContentCache.RequestIMEToCommitComposition(
widget, aCancel, *aCommittedString);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvStartPluginIME(
const WidgetKeyboardEvent& aKeyboardEvent, const int32_t& aPanelX,
const int32_t& aPanelY, nsString* aCommitted) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return IPC_OK();
}
Unused << widget->StartPluginIME(aKeyboardEvent, (int32_t&)aPanelX,
(int32_t&)aPanelY, *aCommitted);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvSetPluginFocused(
const bool& aFocused) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return IPC_OK();
}
widget->SetPluginFocused((bool&)aFocused);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvSetCandidateWindowForPlugin(
const CandidateWindowPosition& aPosition) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return IPC_OK();
}
widget->SetCandidateWindowForPlugin(aPosition);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvEnableIMEForPlugin(
const bool& aEnable) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return IPC_OK();
}
widget->EnableIMEForPlugin(aEnable);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvDefaultProcOfPluginEvent(
const WidgetPluginEvent& aEvent) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return IPC_OK();
}
widget->DefaultProcOfPluginEvent(aEvent);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvGetInputContext(
widget::IMEState* aState) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
*aState = widget::IMEState(IMEState::DISABLED,
IMEState::OPEN_STATE_NOT_SUPPORTED);
return IPC_OK();
}
*aState = widget->GetInputContext().mIMEState;
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvSetInputContext(
const InputContext& aContext, const InputContextAction& aAction) {
IMEStateManager::SetInputContextForChildProcess(this, aContext, aAction);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvSetNativeChildOfShareableWindow(
const uintptr_t& aChildWindow) {
#if defined(XP_WIN)
nsCOMPtr<nsIWidget> widget = GetTopLevelWidget();
if (widget) {
// Note that this call will probably cause a sync native message to the
// process that owns the child window.
widget->SetNativeData(NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW, aChildWindow);
}
return IPC_OK();
#else
MOZ_ASSERT_UNREACHABLE(
"BrowserParent::RecvSetNativeChildOfShareableWindow not implemented!");
return IPC_FAIL_NO_REASON(this);
#endif
}
mozilla::ipc::IPCResult BrowserParent::RecvDispatchFocusToTopLevelWindow() {
if (nsCOMPtr<nsIWidget> widget = GetTopLevelWidget()) {
widget->SetFocus(nsIWidget::Raise::No);
}
return IPC_OK();
}
bool BrowserParent::ReceiveMessage(const nsString& aMessage, bool aSync,
StructuredCloneData* aData,
CpowHolder* aCpows, nsIPrincipal* aPrincipal,
nsTArray<StructuredCloneData>* aRetVal) {
// If we're for an oop iframe, don't deliver messages to the wrong place.
if (mBrowserBridgeParent) {
return true;
}
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 05:24:48 +00:00
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader(true);
if (frameLoader && frameLoader->GetFrameMessageManager()) {
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 05:24:48 +00:00
RefPtr<nsFrameMessageManager> manager =
frameLoader->GetFrameMessageManager();
manager->ReceiveMessage(mFrameElement, frameLoader, aMessage, aSync, aData,
aCpows, aPrincipal, aRetVal, IgnoreErrors());
}
return true;
}
// nsIAuthPromptProvider
// This method is largely copied from nsDocShell::GetAuthPrompt
NS_IMETHODIMP
BrowserParent::GetAuthPrompt(uint32_t aPromptReason, const nsIID& iid,
void** aResult) {
// we're either allowing auth, or it's a proxy request
nsresult rv;
nsCOMPtr<nsIPromptFactory> wwatch =
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsPIDOMWindowOuter> window;
RefPtr<Element> frame = mFrameElement;
if (frame) window = frame->OwnerDoc()->GetWindow();
// Get an auth prompter for our window so that the parenting
// of the dialogs works as it should when using tabs.
nsCOMPtr<nsISupports> prompt;
rv = wwatch->GetPrompt(window, iid, getter_AddRefs(prompt));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsILoginManagerPrompter> prompter = do_QueryInterface(prompt);
if (prompter) {
prompter->SetBrowser(mFrameElement);
}
*aResult = prompt.forget().take();
return NS_OK;
}
PColorPickerParent* BrowserParent::AllocPColorPickerParent(
const nsString& aTitle, const nsString& aInitialColor) {
return new ColorPickerParent(aTitle, aInitialColor);
}
bool BrowserParent::DeallocPColorPickerParent(PColorPickerParent* actor) {
delete actor;
return true;
}
already_AddRefed<nsFrameLoader> BrowserParent::GetFrameLoader(
bool aUseCachedFrameLoaderAfterDestroy) const {
if (mIsDestroyed && !aUseCachedFrameLoaderAfterDestroy) {
return nullptr;
}
if (mFrameLoader) {
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 05:24:48 +00:00
RefPtr<nsFrameLoader> fl = mFrameLoader;
return fl.forget();
}
RefPtr<Element> frameElement(mFrameElement);
RefPtr<nsFrameLoaderOwner> frameLoaderOwner = do_QueryObject(frameElement);
return frameLoaderOwner ? frameLoaderOwner->GetFrameLoader() : nullptr;
}
void BrowserParent::TryCacheDPIAndScale() {
if (mDPI > 0) {
return;
}
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
mDPI = widget->GetDPI();
mRounding = widget->RoundsWidgetCoordinatesTo();
mDefaultScale = widget->GetDefaultScale();
}
}
void BrowserParent::ApzAwareEventRoutingToChild(
ScrollableLayerGuid* aOutTargetGuid, uint64_t* aOutInputBlockId,
nsEventStatus* aOutApzResponse) {
// Let the widget know that the event will be sent to the child process,
// which will (hopefully) send a confirmation notice back to APZ.
// Do this even if APZ is off since we need it for swipe gesture support on
// OS X without APZ.
InputAPZContext::SetRoutedToChildProcess();
if (AsyncPanZoomEnabled()) {
if (aOutTargetGuid) {
*aOutTargetGuid = InputAPZContext::GetTargetLayerGuid();
// There may be cases where the APZ hit-testing code came to a different
// conclusion than the main-thread hit-testing code as to where the event
// is destined. In such cases the layersId of the APZ result may not match
// the layersId of this RemoteLayerTreeOwner. In such cases the
// main-thread hit- testing code "wins" so we need to update the guid to
// reflect this.
if (mRemoteLayerTreeOwner.IsInitialized()) {
if (aOutTargetGuid->mLayersId != mRemoteLayerTreeOwner.GetLayersId()) {
*aOutTargetGuid =
ScrollableLayerGuid(mRemoteLayerTreeOwner.GetLayersId(), 0,
ScrollableLayerGuid::NULL_SCROLL_ID);
}
}
}
if (aOutInputBlockId) {
*aOutInputBlockId = InputAPZContext::GetInputBlockId();
}
if (aOutApzResponse) {
*aOutApzResponse = InputAPZContext::GetApzResponse();
}
} else {
if (aOutInputBlockId) {
*aOutInputBlockId = 0;
}
if (aOutApzResponse) {
*aOutApzResponse = nsEventStatus_eIgnore;
}
}
}
mozilla::ipc::IPCResult BrowserParent::RecvBrowserFrameOpenWindow(
PBrowserParent* aOpener, const nsString& aURL, const nsString& aName,
bool aForceNoReferrer, const nsString& aFeatures,
BrowserFrameOpenWindowResolver&& aResolve) {
CreatedWindowInfo cwi;
cwi.rv() = NS_OK;
cwi.maxTouchPoints() = 0;
BrowserElementParent::OpenWindowResult opened =
BrowserElementParent::OpenWindowOOP(BrowserParent::GetFrom(aOpener), this,
aURL, aName, aForceNoReferrer,
aFeatures);
cwi.windowOpened() = (opened == BrowserElementParent::OPEN_WINDOW_ADDED);
cwi.maxTouchPoints() = GetMaxTouchPoints();
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
cwi.dimensions() = GetDimensionInfo();
}
// Resolve the request with the information we collected.
aResolve(cwi);
if (!cwi.windowOpened()) {
Destroy();
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvRespondStartSwipeEvent(
const uint64_t& aInputBlockId, const bool& aStartSwipe) {
if (nsCOMPtr<nsIWidget> widget = GetWidget()) {
widget->ReportSwipeStarted(aInputBlockId, aStartSwipe);
}
return IPC_OK();
}
bool BrowserParent::GetDocShellIsActive() { return mDocShellIsActive; }
void BrowserParent::SetDocShellIsActive(bool isActive) {
mDocShellIsActive = isActive;
SetRenderLayers(isActive);
Unused << SendSetDocShellIsActive(isActive);
// update active accessible documents on windows
#if defined(XP_WIN) && defined(ACCESSIBILITY)
if (a11y::Compatibility::IsDolphin()) {
if (a11y::DocAccessibleParent* tabDoc = GetTopLevelDocAccessible()) {
HWND window = tabDoc->GetEmulatedWindowHandle();
MOZ_ASSERT(window);
if (window) {
if (isActive) {
a11y::nsWinUtils::ShowNativeWindow(window);
} else {
a11y::nsWinUtils::HideNativeWindow(window);
}
}
}
}
#endif
// Keep track of how many active recording/replaying tabs there are.
if (Manager()->IsRecordingOrReplaying()) {
SetIsActiveRecordReplayTab(isActive);
}
}
bool BrowserParent::GetHasPresented() { return mHasPresented; }
bool BrowserParent::GetHasLayers() { return mHasLayers; }
bool BrowserParent::GetRenderLayers() { return mRenderLayers; }
void BrowserParent::SetRenderLayers(bool aEnabled) {
if (mActiveInPriorityManager != aEnabled) {
mActiveInPriorityManager = aEnabled;
// Let's inform the priority manager. This operation can end up with the
// changing of the process priority.
ProcessPriorityManager::TabActivityChanged(this, aEnabled);
}
if (aEnabled == mRenderLayers) {
if (aEnabled && mHasLayers && mPreserveLayers) {
// RenderLayers might be called when we've been preserving layers,
// and already had layers uploaded. In that case, the MozLayerTreeReady
// event will not naturally arrive, which can confuse the front-end
// layer. So we fire the event here.
RefPtr<BrowserParent> self = this;
LayersObserverEpoch epoch = mLayerTreeEpoch;
NS_DispatchToMainThread(NS_NewRunnableFunction(
"dom::BrowserParent::RenderLayers", [self, epoch]() {
MOZ_ASSERT(NS_IsMainThread());
self->LayerTreeUpdate(epoch, true);
}));
}
return;
}
// Preserve layers means that attempts to stop rendering layers
// will be ignored.
if (!aEnabled && mPreserveLayers) {
return;
}
mRenderLayers = aEnabled;
SetRenderLayersInternal(aEnabled, false /* aForceRepaint */);
}
void BrowserParent::SetRenderLayersInternal(bool aEnabled, bool aForceRepaint) {
// Increment the epoch so that layer tree updates from previous
// RenderLayers requests are ignored.
mLayerTreeEpoch = mLayerTreeEpoch.Next();
Unused << SendRenderLayers(aEnabled, aForceRepaint, mLayerTreeEpoch);
// Ask the child to repaint using the PHangMonitor channel/thread (which may
// be less congested).
if (aEnabled) {
Manager()->PaintTabWhileInterruptingJS(this, aForceRepaint,
mLayerTreeEpoch);
}
}
void BrowserParent::PreserveLayers(bool aPreserveLayers) {
mPreserveLayers = aPreserveLayers;
}
void BrowserParent::ForceRepaint() {
if (!mActiveInPriorityManager) {
// If a tab is left and then returned to very rapidly, it can be
// deprioritized without losing its loaded status. In this case we won't
// go through SetRenderLayers.
mActiveInPriorityManager = true;
ProcessPriorityManager::TabActivityChanged(this, true);
}
SetRenderLayersInternal(true /* aEnabled */, true /* aForceRepaint */);
}
void BrowserParent::NotifyResolutionChanged() {
if (!mIsDestroyed) {
// TryCacheDPIAndScale()'s cache is keyed off of
// mDPI being greater than 0, so this invalidates it.
mDPI = -1;
TryCacheDPIAndScale();
// If mDPI was set to -1 to invalidate it and then TryCacheDPIAndScale
// fails to cache the values, then mDefaultScale.scale might be invalid.
// We don't want to send that value to content. Just send -1 for it too in
// that case.
Unused << SendUIResolutionChanged(mDPI, mRounding,
mDPI < 0 ? -1.0 : mDefaultScale.scale);
}
}
void BrowserParent::Deprioritize() {
if (mActiveInPriorityManager) {
ProcessPriorityManager::TabActivityChanged(this, false);
mActiveInPriorityManager = false;
}
}
bool BrowserParent::GetHasContentOpener() { return mHasContentOpener; }
void BrowserParent::SetHasContentOpener(bool aHasContentOpener) {
mHasContentOpener = aHasContentOpener;
}
bool BrowserParent::StartApzAutoscroll(float aAnchorX, float aAnchorY,
nsViewID aScrollId,
uint32_t aPresShellId) {
if (!AsyncPanZoomEnabled()) {
return false;
}
bool success = false;
if (mRemoteLayerTreeOwner.IsInitialized()) {
layers::LayersId layersId = mRemoteLayerTreeOwner.GetLayersId();
if (nsCOMPtr<nsIWidget> widget = GetWidget()) {
SLGuidAndRenderRoot guid(layersId, aPresShellId, aScrollId,
gfxUtils::GetContentRenderRoot());
// The anchor coordinates that are passed in are relative to the origin
// of the screen, but we are sending them to APZ which only knows about
// coordinates relative to the widget, so convert them accordingly.
CSSPoint anchorCss{aAnchorX, aAnchorY};
LayoutDeviceIntPoint anchor =
RoundedToInt(anchorCss * widget->GetDefaultScale());
anchor -= widget->WidgetToScreenOffset();
success = widget->StartAsyncAutoscroll(
ViewAs<ScreenPixel>(
anchor, PixelCastJustification::LayoutDeviceIsScreenForBounds),
guid);
}
}
return success;
}
void BrowserParent::StopApzAutoscroll(nsViewID aScrollId,
uint32_t aPresShellId) {
if (!AsyncPanZoomEnabled()) {
return;
}
if (mRemoteLayerTreeOwner.IsInitialized()) {
layers::LayersId layersId = mRemoteLayerTreeOwner.GetLayersId();
if (nsCOMPtr<nsIWidget> widget = GetWidget()) {
SLGuidAndRenderRoot guid(layersId, aPresShellId, aScrollId,
gfxUtils::GetContentRenderRoot());
widget->StopAsyncAutoscroll(guid);
}
}
}
void BrowserParent::SuppressDisplayport(bool aEnabled) {
if (IsDestroyed()) {
return;
}
#ifdef DEBUG
if (aEnabled) {
mActiveSupressDisplayportCount++;
} else {
mActiveSupressDisplayportCount--;
}
MOZ_ASSERT(mActiveSupressDisplayportCount >= 0);
#endif
Unused << SendSuppressDisplayport(aEnabled);
}
void BrowserParent::NavigateByKey(bool aForward, bool aForDocumentNavigation) {
Unused << SendNavigateByKey(aForward, aForDocumentNavigation);
}
void BrowserParent::LayerTreeUpdate(const LayersObserverEpoch& aEpoch,
bool aActive) {
// Ignore updates from old epochs. They might tell us that layers are
// available when we've already sent a message to clear them. We can't trust
// the update in that case since layers could disappear anytime after that.
if (aEpoch != mLayerTreeEpoch || mIsDestroyed) {
return;
}
RefPtr<EventTarget> target = mFrameElement;
if (!target) {
NS_WARNING("Could not locate target for layer tree message.");
return;
}
mHasLayers = aActive;
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 05:24:48 +00:00
RefPtr<Event> event = NS_NewDOMEvent(mFrameElement, nullptr, nullptr);
if (aActive) {
mHasPresented = true;
event->InitEvent(NS_LITERAL_STRING("MozLayerTreeReady"), true, false);
} else {
event->InitEvent(NS_LITERAL_STRING("MozLayerTreeCleared"), true, false);
}
event->SetTrusted(true);
event->WidgetEventPtr()->mFlags.mOnlyChromeDispatch = true;
mFrameElement->DispatchEvent(*event);
}
mozilla::ipc::IPCResult BrowserParent::RecvPaintWhileInterruptingJSNoOp(
const LayersObserverEpoch& aEpoch) {
// We sent a PaintWhileInterruptingJS message when layers were already
// visible. In this case, we should act as if an update occurred even though
// we already have the layers.
LayerTreeUpdate(aEpoch, true);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvRemotePaintIsReady() {
RefPtr<EventTarget> target = mFrameElement;
if (!target) {
NS_WARNING("Could not locate target for MozAfterRemotePaint message.");
return IPC_OK();
}
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 05:24:48 +00:00
RefPtr<Event> event = NS_NewDOMEvent(mFrameElement, nullptr, nullptr);
event->InitEvent(NS_LITERAL_STRING("MozAfterRemotePaint"), false, false);
event->SetTrusted(true);
event->WidgetEventPtr()->mFlags.mOnlyChromeDispatch = true;
mFrameElement->DispatchEvent(*event);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvNotifyCompositorTransaction() {
RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
if (!frameLoader) {
return IPC_OK();
}
nsIFrame* docFrame = frameLoader->GetPrimaryFrameOfOwningContent();
if (!docFrame) {
// Bad, but nothing we can do about it (XXX/cjones: or is there?
// maybe bug 589337?). When the new frame is created, we'll
// probably still be the current render frame and will get to draw
// our content then. Or, we're shutting down and this update goes
// to /dev/null.
return IPC_OK();
}
docFrame->InvalidateLayer(DisplayItemType::TYPE_REMOTE);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvRemoteIsReadyToHandleInputEvents() {
// When enabling input event prioritization, input events may preempt other
// normal priority IPC messages. To prevent the input events preempt
// PBrowserConstructor, we use an IPC 'RemoteIsReadyToHandleInputEvents' to
// notify the parent that BrowserChild is created and ready to handle input
// events.
SetReadyToHandleInputEvents();
return IPC_OK();
}
mozilla::plugins::PPluginWidgetParent*
BrowserParent::AllocPPluginWidgetParent() {
#ifdef XP_WIN
return new mozilla::plugins::PluginWidgetParent();
#else
MOZ_ASSERT_UNREACHABLE("AllocPPluginWidgetParent only supports Windows");
return nullptr;
#endif
}
bool BrowserParent::DeallocPPluginWidgetParent(
mozilla::plugins::PPluginWidgetParent* aActor) {
delete aActor;
return true;
}
PPaymentRequestParent* BrowserParent::AllocPPaymentRequestParent() {
RefPtr<PaymentRequestParent> actor = new PaymentRequestParent();
return actor.forget().take();
}
bool BrowserParent::DeallocPPaymentRequestParent(
PPaymentRequestParent* aActor) {
RefPtr<PaymentRequestParent> actor =
dont_AddRef(static_cast<PaymentRequestParent*>(aActor));
return true;
}
nsresult BrowserParent::HandleEvent(Event* aEvent) {
if (mIsDestroyed) {
return NS_OK;
}
nsAutoString eventType;
aEvent->GetType(eventType);
if (eventType.EqualsLiteral("MozUpdateWindowPos") ||
eventType.EqualsLiteral("fullscreenchange")) {
// Events that signify the window moving are used to update the position
// and notify the BrowserChild.
return UpdatePosition();
}
return NS_OK;
}
class FakeChannel final : public nsIChannel,
public nsIAuthPromptCallback,
public nsIInterfaceRequestor,
public nsILoadContext {
public:
FakeChannel(const nsCString& aUri, uint64_t aCallbackId, Element* aElement)
: mCallbackId(aCallbackId), mElement(aElement) {
NS_NewURI(getter_AddRefs(mUri), aUri);
}
NS_DECL_ISUPPORTS
#define NO_IMPL \
override { return NS_ERROR_NOT_IMPLEMENTED; }
NS_IMETHOD GetName(nsACString&) NO_IMPL;
NS_IMETHOD IsPending(bool*) NO_IMPL;
NS_IMETHOD GetStatus(nsresult*) NO_IMPL;
NS_IMETHOD Cancel(nsresult) NO_IMPL;
NS_IMETHOD Suspend() NO_IMPL;
NS_IMETHOD Resume() NO_IMPL;
NS_IMETHOD GetLoadGroup(nsILoadGroup**) NO_IMPL;
NS_IMETHOD SetLoadGroup(nsILoadGroup*) NO_IMPL;
NS_IMETHOD SetLoadFlags(nsLoadFlags) NO_IMPL;
NS_IMETHOD GetLoadFlags(nsLoadFlags*) NO_IMPL;
NS_IMETHOD GetIsDocument(bool*) NO_IMPL;
NS_IMETHOD GetOriginalURI(nsIURI**) NO_IMPL;
NS_IMETHOD SetOriginalURI(nsIURI*) NO_IMPL;
NS_IMETHOD GetURI(nsIURI** aUri) override {
nsCOMPtr<nsIURI> copy = mUri;
copy.forget(aUri);
return NS_OK;
}
NS_IMETHOD GetOwner(nsISupports**) NO_IMPL;
NS_IMETHOD SetOwner(nsISupports*) NO_IMPL;
NS_IMETHOD GetLoadInfo(nsILoadInfo** aLoadInfo) override {
nsCOMPtr<nsILoadInfo> copy = mLoadInfo;
copy.forget(aLoadInfo);
return NS_OK;
}
NS_IMETHOD SetLoadInfo(nsILoadInfo* aLoadInfo) override {
mLoadInfo = aLoadInfo;
return NS_OK;
}
NS_IMETHOD GetNotificationCallbacks(
nsIInterfaceRequestor** aRequestor) override {
NS_ADDREF(*aRequestor = this);
return NS_OK;
}
NS_IMETHOD SetNotificationCallbacks(nsIInterfaceRequestor*) NO_IMPL;
NS_IMETHOD GetSecurityInfo(nsISupports**) NO_IMPL;
NS_IMETHOD GetContentType(nsACString&) NO_IMPL;
NS_IMETHOD SetContentType(const nsACString&) NO_IMPL;
NS_IMETHOD GetContentCharset(nsACString&) NO_IMPL;
NS_IMETHOD SetContentCharset(const nsACString&) NO_IMPL;
NS_IMETHOD GetContentLength(int64_t*) NO_IMPL;
NS_IMETHOD SetContentLength(int64_t) NO_IMPL;
NS_IMETHOD Open(nsIInputStream**) NO_IMPL;
NS_IMETHOD AsyncOpen(nsIStreamListener*) NO_IMPL;
NS_IMETHOD GetContentDisposition(uint32_t*) NO_IMPL;
NS_IMETHOD SetContentDisposition(uint32_t) NO_IMPL;
NS_IMETHOD GetContentDispositionFilename(nsAString&) NO_IMPL;
NS_IMETHOD SetContentDispositionFilename(const nsAString&) NO_IMPL;
NS_IMETHOD GetContentDispositionHeader(nsACString&) NO_IMPL;
NS_IMETHOD OnAuthAvailable(nsISupports* aContext,
nsIAuthInformation* aAuthInfo) override;
NS_IMETHOD OnAuthCancelled(nsISupports* aContext, bool userCancel) override;
NS_IMETHOD GetInterface(const nsIID& uuid, void** result) override {
return QueryInterface(uuid, result);
}
NS_IMETHOD GetAssociatedWindow(mozIDOMWindowProxy**) NO_IMPL;
NS_IMETHOD GetTopWindow(mozIDOMWindowProxy**) NO_IMPL;
NS_IMETHOD GetTopFrameElement(Element** aElement) override {
RefPtr<Element> elem = mElement;
elem.forget(aElement);
return NS_OK;
}
NS_IMETHOD GetNestedFrameId(uint64_t*) NO_IMPL;
NS_IMETHOD GetIsContent(bool*) NO_IMPL;
NS_IMETHOD GetUsePrivateBrowsing(bool*) NO_IMPL;
NS_IMETHOD SetUsePrivateBrowsing(bool) NO_IMPL;
NS_IMETHOD SetPrivateBrowsing(bool) NO_IMPL;
NS_IMETHOD GetIsInIsolatedMozBrowserElement(bool*) NO_IMPL;
NS_IMETHOD GetScriptableOriginAttributes(JSContext*,
JS::MutableHandleValue) NO_IMPL;
NS_IMETHOD_(void)
GetOriginAttributes(mozilla::OriginAttributes& aAttrs) override {}
NS_IMETHOD GetUseRemoteTabs(bool*) NO_IMPL;
NS_IMETHOD SetRemoteTabs(bool) NO_IMPL;
NS_IMETHOD GetUseRemoteSubframes(bool*) NO_IMPL;
NS_IMETHOD SetRemoteSubframes(bool) NO_IMPL;
NS_IMETHOD GetUseTrackingProtection(bool*) NO_IMPL;
NS_IMETHOD SetUseTrackingProtection(bool) NO_IMPL;
#undef NO_IMPL
protected:
~FakeChannel() {}
nsCOMPtr<nsIURI> mUri;
uint64_t mCallbackId;
RefPtr<Element> mElement;
nsCOMPtr<nsILoadInfo> mLoadInfo;
};
NS_IMPL_ISUPPORTS(FakeChannel, nsIChannel, nsIAuthPromptCallback, nsIRequest,
nsIInterfaceRequestor, nsILoadContext);
mozilla::ipc::IPCResult BrowserParent::RecvAsyncAuthPrompt(
const nsCString& aUri, const nsString& aRealm,
const uint64_t& aCallbackId) {
nsCOMPtr<nsIAuthPrompt2> authPrompt;
GetAuthPrompt(nsIAuthPromptProvider::PROMPT_NORMAL,
NS_GET_IID(nsIAuthPrompt2), getter_AddRefs(authPrompt));
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 05:24:48 +00:00
RefPtr<FakeChannel> channel =
new FakeChannel(aUri, aCallbackId, mFrameElement);
uint32_t promptFlags = nsIAuthInformation::AUTH_HOST;
Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat The bulk of this commit was generated with a script, executed at the top level of a typical source code checkout. The only non-machine-generated part was modifying MFBT's moz.build to reflect the new naming. CLOSED TREE makes big refactorings like this a piece of cake. # The main substitution. find . -name '*.cpp' -o -name '*.cc' -o -name '*.h' -o -name '*.mm' -o -name '*.idl'| \ xargs perl -p -i -e ' s/nsRefPtr\.h/RefPtr\.h/g; # handle includes s/nsRefPtr ?</RefPtr</g; # handle declarations and variables ' # Handle a special friend declaration in gfx/layers/AtomicRefCountedWithFinalize.h. perl -p -i -e 's/::nsRefPtr;/::RefPtr;/' gfx/layers/AtomicRefCountedWithFinalize.h # Handle nsRefPtr.h itself, a couple places that define constructors # from nsRefPtr, and code generators specially. We do this here, rather # than indiscriminantly s/nsRefPtr/RefPtr/, because that would rename # things like nsRefPtrHashtable. perl -p -i -e 's/nsRefPtr/RefPtr/g' \ mfbt/nsRefPtr.h \ xpcom/glue/nsCOMPtr.h \ xpcom/base/OwningNonNull.h \ ipc/ipdl/ipdl/lower.py \ ipc/ipdl/ipdl/builtin.py \ dom/bindings/Codegen.py \ python/lldbutils/lldbutils/utils.py # In our indiscriminate substitution above, we renamed # nsRefPtrGetterAddRefs, the class behind getter_AddRefs. Fix that up. find . -name '*.cpp' -o -name '*.h' -o -name '*.idl' | \ xargs perl -p -i -e 's/nsRefPtrGetterAddRefs/RefPtrGetterAddRefs/g' if [ -d .git ]; then git mv mfbt/nsRefPtr.h mfbt/RefPtr.h else hg mv mfbt/nsRefPtr.h mfbt/RefPtr.h fi --HG-- rename : mfbt/nsRefPtr.h => mfbt/RefPtr.h
2015-10-18 05:24:48 +00:00
RefPtr<nsAuthInformationHolder> holder =
new nsAuthInformationHolder(promptFlags, aRealm, EmptyCString());
uint32_t level = nsIAuthPrompt2::LEVEL_NONE;
nsCOMPtr<nsICancelable> dummy;
nsresult rv = authPrompt->AsyncPromptAuth(channel, channel, nullptr, level,
holder, getter_AddRefs(dummy));
if (NS_FAILED(rv)) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvInvokeDragSession(
nsTArray<IPCDataTransfer>&& aTransfers, const uint32_t& aAction,
Maybe<Shmem>&& aVisualDnDData, const uint32_t& aStride,
const gfx::SurfaceFormat& aFormat, const LayoutDeviceIntRect& aDragRect,
nsIPrincipal* aPrincipal) {
PresShell* presShell = mFrameElement->OwnerDoc()->GetPresShell();
if (!presShell) {
Unused << Manager()->SendEndDragSession(true, true, LayoutDeviceIntPoint(),
0);
// Continue sending input events with input priority when stopping the dnd
// session.
Manager()->SetInputPriorityEventEnabled(true);
return IPC_OK();
}
RefPtr<RemoteDragStartData> dragStartData = new RemoteDragStartData(
this, std::move(aTransfers), aDragRect, aPrincipal);
if (!aVisualDnDData.isNothing() && aVisualDnDData.ref().IsReadable() &&
aVisualDnDData.ref().Size<char>() >= aDragRect.height * aStride) {
dragStartData->SetVisualization(gfx::CreateDataSourceSurfaceFromData(
gfx::IntSize(aDragRect.width, aDragRect.height), aFormat,
aVisualDnDData.ref().get<uint8_t>(), aStride));
}
nsCOMPtr<nsIDragService> dragService =
do_GetService("@mozilla.org/widget/dragservice;1");
if (dragService) {
dragService->MaybeAddChildProcess(Manager());
}
presShell->GetPresContext()
->EventStateManager()
->BeginTrackingRemoteDragGesture(mFrameElement, dragStartData);
if (aVisualDnDData.isSome()) {
Unused << DeallocShmem(aVisualDnDData.ref());
}
return IPC_OK();
}
bool BrowserParent::AsyncPanZoomEnabled() const {
nsCOMPtr<nsIWidget> widget = GetWidget();
return widget && widget->AsyncPanZoomEnabled();
}
void BrowserParent::StartPersistence(
uint64_t aOuterWindowID, nsIWebBrowserPersistDocumentReceiver* aRecv,
ErrorResult& aRv) {
auto* actor = new WebBrowserPersistDocumentParent();
actor->SetOnReady(aRecv);
bool ok = Manager()->SendPWebBrowserPersistDocumentConstructor(
actor, this, aOuterWindowID);
if (!ok) {
aRv.Throw(NS_ERROR_FAILURE);
}
// (The actor will be destroyed on constructor failure.)
}
mozilla::ipc::IPCResult BrowserParent::RecvLookUpDictionary(
const nsString& aText, nsTArray<FontRange>&& aFontRangeArray,
const bool& aIsVertical, const LayoutDeviceIntPoint& aPoint) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (!widget) {
return IPC_OK();
}
widget->LookUpDictionary(aText, aFontRangeArray, aIsVertical,
TransformChildToParent(aPoint));
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvShowCanvasPermissionPrompt(
const nsCString& aOrigin, const bool& aHideDoorHanger) {
nsCOMPtr<nsIBrowser> browser =
mFrameElement ? mFrameElement->AsBrowser() : nullptr;
if (!browser) {
// If the tab is being closed, the browser may not be available.
// In this case we can ignore the request.
return IPC_OK();
}
nsCOMPtr<nsIObserverService> os = services::GetObserverService();
if (!os) {
return IPC_FAIL_NO_REASON(this);
}
nsresult rv = os->NotifyObservers(
browser,
aHideDoorHanger ? "canvas-permissions-prompt-hide-doorhanger"
: "canvas-permissions-prompt",
NS_ConvertUTF8toUTF16(aOrigin).get());
if (NS_FAILED(rv)) {
return IPC_FAIL_NO_REASON(this);
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvVisitURI(
const URIParams& aURI, const Maybe<URIParams>& aLastVisitedURI,
const uint32_t& aFlags) {
nsCOMPtr<nsIURI> ourURI = DeserializeURI(aURI);
if (!ourURI) {
return IPC_FAIL_NO_REASON(this);
}
nsCOMPtr<nsIURI> ourLastVisitedURI = DeserializeURI(aLastVisitedURI);
RefPtr<nsIWidget> widget = GetWidget();
if (NS_WARN_IF(!widget)) {
return IPC_OK();
}
nsCOMPtr<IHistory> history = services::GetHistoryService();
if (history) {
Unused << history->VisitURI(widget, ourURI, ourLastVisitedURI, aFlags);
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvQueryVisitedState(
nsTArray<URIParams>&& aURIs) {
#ifdef MOZ_ANDROID_HISTORY
nsCOMPtr<IHistory> history = services::GetHistoryService();
if (NS_WARN_IF(!history)) {
return IPC_OK();
}
RefPtr<nsIWidget> widget = GetWidget();
if (NS_WARN_IF(!widget)) {
return IPC_OK();
}
nsTArray<nsCOMPtr<nsIURI>> uris(aURIs.Length());
for (size_t i = 0; i < aURIs.Length(); ++i) {
nsCOMPtr<nsIURI> uri = DeserializeURI(aURIs[i]);
if (NS_WARN_IF(!uri)) {
continue;
}
uris.AppendElement(uri);
}
GeckoViewHistory* gvHistory = static_cast<GeckoViewHistory*>(history.get());
gvHistory->QueryVisitedState(widget, uris);
return IPC_OK();
#else
return IPC_FAIL(this, "QueryVisitedState is Android-only");
#endif
}
void BrowserParent::LiveResizeStarted() { SuppressDisplayport(true); }
void BrowserParent::LiveResizeStopped() { SuppressDisplayport(false); }
void BrowserParent::SetBrowserBridgeParent(BrowserBridgeParent* aBrowser) {
// We should either be clearing out our reference to a browser bridge, or not
// have either a browser bridge, browser host, or owner content yet.
MOZ_ASSERT(!aBrowser ||
(!mBrowserBridgeParent && !mBrowserHost && !mFrameElement));
mBrowserBridgeParent = aBrowser;
}
void BrowserParent::SetBrowserHost(BrowserHost* aBrowser) {
// We should either be clearing out our reference to a browser host, or not
// have either a browser bridge, browser host, or owner content yet.
MOZ_ASSERT(!aBrowser ||
(!mBrowserBridgeParent && !mBrowserHost && !mFrameElement));
mBrowserHost = aBrowser;
}
/* static */
size_t BrowserParent::gNumActiveRecordReplayTabs;
void BrowserParent::SetIsActiveRecordReplayTab(bool aIsActive) {
if (aIsActive != mIsActiveRecordReplayTab) {
gNumActiveRecordReplayTabs += aIsActive ? 1 : -1;
mIsActiveRecordReplayTab = aIsActive;
}
}
mozilla::ipc::IPCResult BrowserParent::RecvSetSystemFont(
const nsCString& aFontName) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
widget->SetSystemFont(aFontName);
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvGetSystemFont(nsCString* aFontName) {
nsCOMPtr<nsIWidget> widget = GetWidget();
if (widget) {
widget->GetSystemFont(*aFontName);
}
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvFireFrameLoadEvent(bool aIsTrusted) {
BrowserBridgeParent* bridge = GetBrowserBridgeParent();
if (!bridge) {
NS_WARNING("Received `load` event on unbridged BrowserParent!");
return IPC_OK();
}
Unused << bridge->SendFireFrameLoadEvent(aIsTrusted);
return IPC_OK();
}
mozilla::ipc::IPCResult BrowserParent::RecvScrollRectIntoView(
const nsRect& aRect, const ScrollAxis& aVertical,
const ScrollAxis& aHorizontal, const ScrollFlags& aScrollFlags,
const int32_t& aAppUnitsPerDevPixel) {
BrowserBridgeParent* bridge = GetBrowserBridgeParent();
if (!bridge || !bridge->CanSend()) {
return IPC_OK();
}
Unused << bridge->SendScrollRectIntoView(aRect, aVertical, aHorizontal,
aScrollFlags, aAppUnitsPerDevPixel);
return IPC_OK();
}
NS_IMETHODIMP
FakeChannel::OnAuthAvailable(nsISupports* aContext,
nsIAuthInformation* aAuthInfo) {
nsAuthInformationHolder* holder =
static_cast<nsAuthInformationHolder*>(aAuthInfo);
if (!net::gNeckoChild->SendOnAuthAvailable(
mCallbackId, holder->User(), holder->Password(), holder->Domain())) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
FakeChannel::OnAuthCancelled(nsISupports* aContext, bool userCancel) {
if (!net::gNeckoChild->SendOnAuthCancelled(mCallbackId, userCancel)) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
} // namespace dom
} // namespace mozilla