LCOV - code coverage report
Current view: top level - dom/ipc - TabChild.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 480 1577 30.4 %
Date: 2017-07-14 16:53:18 Functions: 72 233 30.9 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #include "base/basictypes.h"
       8             : 
       9             : #include "TabChild.h"
      10             : 
      11             : #include "gfxPrefs.h"
      12             : #ifdef ACCESSIBILITY
      13             : #include "mozilla/a11y/DocAccessibleChild.h"
      14             : #endif
      15             : #include "Layers.h"
      16             : #include "ContentChild.h"
      17             : #include "TabParent.h"
      18             : #include "mozilla/Preferences.h"
      19             : #include "mozilla/BrowserElementParent.h"
      20             : #include "mozilla/ClearOnShutdown.h"
      21             : #include "mozilla/EventListenerManager.h"
      22             : #include "mozilla/dom/indexedDB/PIndexedDBPermissionRequestChild.h"
      23             : #include "mozilla/dom/PaymentRequestChild.h"
      24             : #include "mozilla/dom/TelemetryScrollProbe.h"
      25             : #include "mozilla/IMEStateManager.h"
      26             : #include "mozilla/ipc/DocumentRendererChild.h"
      27             : #include "mozilla/ipc/URIUtils.h"
      28             : #include "mozilla/layers/APZChild.h"
      29             : #include "mozilla/layers/APZCCallbackHelper.h"
      30             : #include "mozilla/layers/APZCTreeManager.h"
      31             : #include "mozilla/layers/APZCTreeManagerChild.h"
      32             : #include "mozilla/layers/APZEventState.h"
      33             : #include "mozilla/layers/ContentProcessController.h"
      34             : #include "mozilla/layers/CompositorBridgeChild.h"
      35             : #include "mozilla/layers/DoubleTapToZoom.h"
      36             : #include "mozilla/layers/IAPZCTreeManager.h"
      37             : #include "mozilla/layers/ImageBridgeChild.h"
      38             : #include "mozilla/layers/InputAPZContext.h"
      39             : #include "mozilla/layers/PLayerTransactionChild.h"
      40             : #include "mozilla/layers/ShadowLayers.h"
      41             : #include "mozilla/layers/WebRenderLayerManager.h"
      42             : #include "mozilla/layout/RenderFrameChild.h"
      43             : #include "mozilla/layout/RenderFrameParent.h"
      44             : #include "mozilla/plugins/PPluginWidgetChild.h"
      45             : #include "mozilla/LookAndFeel.h"
      46             : #include "mozilla/MouseEvents.h"
      47             : #include "mozilla/Move.h"
      48             : #include "mozilla/PresShell.h"
      49             : #include "mozilla/ProcessHangMonitor.h"
      50             : #include "mozilla/ScopeExit.h"
      51             : #include "mozilla/Services.h"
      52             : #include "mozilla/StaticPtr.h"
      53             : #include "mozilla/TextEvents.h"
      54             : #include "mozilla/TouchEvents.h"
      55             : #include "mozilla/Unused.h"
      56             : #include "nsContentUtils.h"
      57             : #include "nsCSSFrameConstructor.h"
      58             : #include "nsDocShell.h"
      59             : #include "nsEmbedCID.h"
      60             : #include "nsGlobalWindow.h"
      61             : #include <algorithm>
      62             : #ifdef MOZ_CRASHREPORTER
      63             : #include "nsExceptionHandler.h"
      64             : #endif
      65             : #include "nsFilePickerProxy.h"
      66             : #include "mozilla/dom/Element.h"
      67             : #include "nsGlobalWindow.h"
      68             : #include "nsIBaseWindow.h"
      69             : #include "nsIBrowserDOMWindow.h"
      70             : #include "nsIDocumentInlines.h"
      71             : #include "nsIDocShellTreeOwner.h"
      72             : #include "nsIDOMChromeWindow.h"
      73             : #include "nsIDOMDocument.h"
      74             : #include "nsIDOMEvent.h"
      75             : #include "nsIDOMWindow.h"
      76             : #include "nsIDOMWindowUtils.h"
      77             : #include "nsFocusManager.h"
      78             : #include "EventStateManager.h"
      79             : #include "nsIDocShell.h"
      80             : #include "nsIFrame.h"
      81             : #include "nsIURI.h"
      82             : #include "nsIURIFixup.h"
      83             : #include "nsCDefaultURIFixup.h"
      84             : #include "nsIWebBrowser.h"
      85             : #include "nsIWebBrowserFocus.h"
      86             : #include "nsIWebBrowserSetup.h"
      87             : #include "nsIWebProgress.h"
      88             : #include "nsIXULRuntime.h"
      89             : #include "nsPIDOMWindow.h"
      90             : #include "nsPIWindowRoot.h"
      91             : #include "nsLayoutUtils.h"
      92             : #include "nsPrintfCString.h"
      93             : #include "nsThreadUtils.h"
      94             : #include "nsViewManager.h"
      95             : #include "nsWeakReference.h"
      96             : #include "nsWindowWatcher.h"
      97             : #include "PermissionMessageUtils.h"
      98             : #include "PuppetWidget.h"
      99             : #include "StructuredCloneData.h"
     100             : #include "nsViewportInfo.h"
     101             : #include "nsILoadContext.h"
     102             : #include "ipc/nsGUIEventIPC.h"
     103             : #include "mozilla/gfx/Matrix.h"
     104             : #include "UnitTransforms.h"
     105             : #include "ClientLayerManager.h"
     106             : #include "LayersLogging.h"
     107             : #include "nsDOMClassInfoID.h"
     108             : #include "nsColorPickerProxy.h"
     109             : #include "nsContentPermissionHelper.h"
     110             : #include "nsNetUtil.h"
     111             : #include "nsIPermissionManager.h"
     112             : #include "nsIURILoader.h"
     113             : #include "nsIScriptError.h"
     114             : #include "mozilla/EventForwards.h"
     115             : #include "nsDeviceContext.h"
     116             : #include "nsSandboxFlags.h"
     117             : #include "FrameLayerBuilder.h"
     118             : #include "VRManagerChild.h"
     119             : #include "nsICommandParams.h"
     120             : #include "nsISHistory.h"
     121             : #include "nsQueryObject.h"
     122             : #include "GroupedSHistory.h"
     123             : #include "nsIHttpChannel.h"
     124             : #include "mozilla/dom/DocGroup.h"
     125             : #include "nsString.h"
     126             : #include "nsISupportsPrimitives.h"
     127             : #include "mozilla/Telemetry.h"
     128             : 
     129             : #ifdef XP_WIN
     130             : #include "mozilla/plugins/PluginWidgetChild.h"
     131             : #endif
     132             : 
     133             : #ifdef NS_PRINTING
     134             : #include "nsIPrintSession.h"
     135             : #include "nsIPrintSettings.h"
     136             : #include "nsIPrintSettingsService.h"
     137             : #include "nsIWebBrowserPrint.h"
     138             : #endif
     139             : 
     140             : #define BROWSER_ELEMENT_CHILD_SCRIPT \
     141             :     NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js")
     142             : 
     143             : #define TABC_LOG(...)
     144             : // #define TABC_LOG(...) printf_stderr("TABC: " __VA_ARGS__)
     145             : 
     146             : using namespace mozilla;
     147             : using namespace mozilla::dom;
     148             : using namespace mozilla::dom::ipc;
     149             : using namespace mozilla::dom::workers;
     150             : using namespace mozilla::ipc;
     151             : using namespace mozilla::layers;
     152             : using namespace mozilla::layout;
     153             : using namespace mozilla::docshell;
     154             : using namespace mozilla::widget;
     155             : using namespace mozilla::jsipc;
     156             : using mozilla::layers::GeckoContentController;
     157             : 
     158           0 : NS_IMPL_ISUPPORTS(ContentListener, nsIDOMEventListener)
     159           0 : NS_IMPL_ISUPPORTS(TabChildSHistoryListener,
     160             :                   nsISHistoryListener,
     161             :                   nsIPartialSHistoryListener,
     162             :                   nsISupportsWeakReference)
     163             : 
     164             : static const char BEFORE_FIRST_PAINT[] = "before-first-paint";
     165             : 
     166             : typedef nsDataHashtable<nsUint64HashKey, TabChild*> TabChildMap;
     167             : static TabChildMap* sTabChildren;
     168           3 : StaticMutex sTabChildrenMutex;
     169             : 
     170           1 : TabChildBase::TabChildBase()
     171           1 :   : mTabChildGlobal(nullptr)
     172             : {
     173           1 :   mozilla::HoldJSObjects(this);
     174           1 : }
     175             : 
     176           0 : TabChildBase::~TabChildBase()
     177             : {
     178           0 :   mAnonymousGlobalScopes.Clear();
     179           0 :   mozilla::DropJSObjects(this);
     180           0 : }
     181             : 
     182             : NS_IMPL_CYCLE_COLLECTION_CLASS(TabChildBase)
     183             : 
     184           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(TabChildBase)
     185           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mTabChildGlobal)
     186           0 :   tmp->nsMessageManagerScriptExecutor::Unlink();
     187           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mWebBrowserChrome)
     188           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     189             : 
     190           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(TabChildBase)
     191           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTabChildGlobal)
     192           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWebBrowserChrome)
     193           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     194             : 
     195           0 : NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(TabChildBase)
     196           0 :   tmp->nsMessageManagerScriptExecutor::Trace(aCallbacks, aClosure);
     197           0 : NS_IMPL_CYCLE_COLLECTION_TRACE_END
     198             : 
     199          22 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TabChildBase)
     200          20 :   NS_INTERFACE_MAP_ENTRY(nsISupports)
     201          19 : NS_INTERFACE_MAP_END
     202             : 
     203         208 : NS_IMPL_CYCLE_COLLECTING_ADDREF(TabChildBase)
     204         198 : NS_IMPL_CYCLE_COLLECTING_RELEASE(TabChildBase)
     205             : 
     206             : already_AddRefed<nsIDocument>
     207           7 : TabChildBase::GetDocument() const
     208             : {
     209          14 :   nsCOMPtr<nsIDOMDocument> domDoc;
     210           7 :   WebNavigation()->GetDocument(getter_AddRefs(domDoc));
     211          14 :   nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
     212          14 :   return doc.forget();
     213             : }
     214             : 
     215             : already_AddRefed<nsIPresShell>
     216           2 : TabChildBase::GetPresShell() const
     217             : {
     218           4 :   nsCOMPtr<nsIPresShell> result;
     219           4 :   if (nsCOMPtr<nsIDocument> doc = GetDocument()) {
     220           2 :     result = doc->GetShell();
     221             :   }
     222           4 :   return result.forget();
     223             : }
     224             : 
     225             : void
     226           0 : TabChildBase::DispatchMessageManagerMessage(const nsAString& aMessageName,
     227             :                                             const nsAString& aJSONData)
     228             : {
     229           0 :     AutoSafeJSContext cx;
     230           0 :     JS::Rooted<JS::Value> json(cx, JS::NullValue());
     231           0 :     dom::ipc::StructuredCloneData data;
     232           0 :     if (JS_ParseJSON(cx,
     233           0 :                       static_cast<const char16_t*>(aJSONData.BeginReading()),
     234             :                       aJSONData.Length(),
     235             :                       &json)) {
     236           0 :         ErrorResult rv;
     237           0 :         data.Write(cx, json, rv);
     238           0 :         if (NS_WARN_IF(rv.Failed())) {
     239           0 :             rv.SuppressException();
     240           0 :             return;
     241             :         }
     242             :     }
     243             : 
     244           0 :     JS::Rooted<JSObject*> kungFuDeathGrip(cx, GetGlobal());
     245             :     // Let the BrowserElementScrolling helper (if it exists) for this
     246             :     // content manipulate the frame state.
     247             :     RefPtr<nsFrameMessageManager> mm =
     248           0 :       static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
     249           0 :     mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal), nullptr,
     250           0 :                        aMessageName, false, &data, nullptr, nullptr, nullptr);
     251             : }
     252             : 
     253             : bool
     254           0 : TabChildBase::UpdateFrameHandler(const FrameMetrics& aFrameMetrics)
     255             : {
     256           0 :   MOZ_ASSERT(aFrameMetrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID);
     257             : 
     258           0 :   if (aFrameMetrics.IsRootContent()) {
     259           0 :     if (nsCOMPtr<nsIPresShell> shell = GetPresShell()) {
     260             :       // Guard against stale updates (updates meant for a pres shell which
     261             :       // has since been torn down and destroyed).
     262           0 :       if (aFrameMetrics.GetPresShellId() == shell->GetPresShellId()) {
     263           0 :         ProcessUpdateFrame(aFrameMetrics);
     264           0 :         return true;
     265             :       }
     266             :     }
     267             :   } else {
     268             :     // aFrameMetrics.mIsRoot is false, so we are trying to update a subframe.
     269             :     // This requires special handling.
     270           0 :     FrameMetrics newSubFrameMetrics(aFrameMetrics);
     271           0 :     APZCCallbackHelper::UpdateSubFrame(newSubFrameMetrics);
     272           0 :     return true;
     273             :   }
     274           0 :   return true;
     275             : }
     276             : 
     277             : void
     278           0 : TabChildBase::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics)
     279             : {
     280           0 :     if (!mGlobal || !mTabChildGlobal) {
     281           0 :         return;
     282             :     }
     283             : 
     284           0 :     FrameMetrics newMetrics = aFrameMetrics;
     285           0 :     APZCCallbackHelper::UpdateRootFrame(newMetrics);
     286             : }
     287             : 
     288             : NS_IMETHODIMP
     289           0 : ContentListener::HandleEvent(nsIDOMEvent* aEvent)
     290             : {
     291           0 :   RemoteDOMEvent remoteEvent;
     292           0 :   remoteEvent.mEvent = do_QueryInterface(aEvent);
     293           0 :   NS_ENSURE_STATE(remoteEvent.mEvent);
     294           0 :   mTabChild->SendEvent(remoteEvent);
     295           0 :   return NS_OK;
     296             : }
     297             : 
     298             : class TabChild::DelayedDeleteRunnable final
     299             :   : public Runnable
     300             : {
     301             :     RefPtr<TabChild> mTabChild;
     302             : 
     303             : public:
     304           0 :     explicit DelayedDeleteRunnable(TabChild* aTabChild)
     305           0 :       : Runnable("TabChild::DelayedDeleteRunnable")
     306           0 :       , mTabChild(aTabChild)
     307             :     {
     308           0 :         MOZ_ASSERT(NS_IsMainThread());
     309           0 :         MOZ_ASSERT(aTabChild);
     310           0 :     }
     311             : 
     312             : private:
     313           0 :     ~DelayedDeleteRunnable()
     314           0 :     {
     315           0 :         MOZ_ASSERT(NS_IsMainThread());
     316           0 :         MOZ_ASSERT(!mTabChild);
     317           0 :     }
     318             : 
     319             :     NS_IMETHOD
     320           0 :     Run() override
     321             :     {
     322           0 :         MOZ_ASSERT(NS_IsMainThread());
     323           0 :         MOZ_ASSERT(mTabChild);
     324             : 
     325             :         // Check in case ActorDestroy was called after RecvDestroy message.
     326           0 :         if (mTabChild->IPCOpen()) {
     327           0 :             Unused << PBrowserChild::Send__delete__(mTabChild);
     328             :         }
     329             : 
     330           0 :         mTabChild = nullptr;
     331           0 :         return NS_OK;
     332             :     }
     333             : };
     334             : 
     335             : namespace {
     336             : std::map<TabId, RefPtr<TabChild>>&
     337           7 : NestedTabChildMap()
     338             : {
     339           7 :   MOZ_ASSERT(NS_IsMainThread());
     340           7 :   static std::map<TabId, RefPtr<TabChild>> sNestedTabChildMap;
     341           7 :   return sNestedTabChildMap;
     342             : }
     343             : } // namespace
     344             : 
     345             : already_AddRefed<TabChild>
     346           2 : TabChild::FindTabChild(const TabId& aTabId)
     347             : {
     348           2 :   auto iter = NestedTabChildMap().find(aTabId);
     349           2 :   if (iter == NestedTabChildMap().end()) {
     350           1 :     return nullptr;
     351             :   }
     352           2 :   RefPtr<TabChild> tabChild = iter->second;
     353           1 :   return tabChild.forget();
     354             : }
     355             : 
     356             : /*static*/ already_AddRefed<TabChild>
     357           1 : TabChild::Create(nsIContentChild* aManager,
     358             :                  const TabId& aTabId,
     359             :                  const TabId& aSameTabGroupAs,
     360             :                  const TabContext &aContext,
     361             :                  uint32_t aChromeFlags)
     362             : {
     363           2 :   RefPtr<TabChild> groupChild = FindTabChild(aSameTabGroupAs);
     364           1 :   dom::TabGroup* group = groupChild ? groupChild->TabGroup() : nullptr;
     365             :   RefPtr<TabChild> iframe = new TabChild(aManager, aTabId, group,
     366           2 :                                          aContext, aChromeFlags);
     367           2 :   return iframe.forget();
     368             : }
     369             : 
     370           1 : TabChild::TabChild(nsIContentChild* aManager,
     371             :                    const TabId& aTabId,
     372             :                    dom::TabGroup* aTabGroup,
     373             :                    const TabContext& aContext,
     374           1 :                    uint32_t aChromeFlags)
     375             :   : TabContext(aContext)
     376             :   , mTabGroup(aTabGroup)
     377             :   , mRemoteFrame(nullptr)
     378             :   , mManager(aManager)
     379             :   , mChromeFlags(aChromeFlags)
     380             :   , mMaxTouchPoints(0)
     381             :   , mActiveSuppressDisplayport(0)
     382             :   , mLayersId(0)
     383             :   , mBeforeUnloadListeners(0)
     384             :   , mLayersConnected(true)
     385             :   , mDidFakeShow(false)
     386             :   , mNotified(false)
     387             :   , mTriedBrowserInit(false)
     388             :   , mOrientation(eScreenOrientation_PortraitPrimary)
     389             :   , mIgnoreKeyPressEvent(false)
     390             :   , mHasValidInnerSize(false)
     391             :   , mDestroyed(false)
     392             :   , mUniqueId(aTabId)
     393             :   , mDPI(0)
     394             :   , mRounding(0)
     395             :   , mDefaultScale(0)
     396             :   , mIsTransparent(false)
     397             :   , mIPCOpen(false)
     398             :   , mParentIsActive(false)
     399             :   , mDidSetRealShowInfo(false)
     400             :   , mDidLoadURLInit(false)
     401             :   , mAwaitingLA(false)
     402             :   , mSkipKeyPress(false)
     403             :   , mLayerObserverEpoch(0)
     404             : #if defined(XP_WIN) && defined(ACCESSIBILITY)
     405             :   , mNativeWindowHandle(0)
     406             : #endif
     407             : #if defined(ACCESSIBILITY)
     408             :   , mTopLevelDocAccessibleChild(nullptr)
     409             : #endif
     410             :   , mPendingDocShellIsActive(false)
     411             :   , mPendingDocShellPreserveLayers(false)
     412             :   , mPendingDocShellReceivedMessage(false)
     413             :   , mPendingDocShellBlockers(0)
     414           1 :   , mWidgetNativeData(0)
     415             : {
     416           2 :   nsWeakPtr weakPtrThis(do_GetWeakReference(static_cast<nsITabChild*>(this)));  // for capture by the lambda
     417           4 :   mSetAllowedTouchBehaviorCallback = [weakPtrThis](uint64_t aInputBlockId,
     418           0 :                                                    const nsTArray<TouchBehaviorFlags>& aFlags)
     419             :   {
     420           0 :     if (nsCOMPtr<nsITabChild> tabChild = do_QueryReferent(weakPtrThis)) {
     421           0 :       static_cast<TabChild*>(tabChild.get())->SetAllowedTouchBehavior(aInputBlockId, aFlags);
     422             :     }
     423           1 :   };
     424             : 
     425             :   // preloaded TabChild should not be added to child map
     426           1 :   if (mUniqueId) {
     427           1 :     MOZ_ASSERT(NestedTabChildMap().find(mUniqueId) == NestedTabChildMap().end());
     428           1 :     NestedTabChildMap()[mUniqueId] = this;
     429             :   }
     430           1 : }
     431             : 
     432             : bool
     433          17 : TabChild::AsyncPanZoomEnabled() const
     434             : {
     435             :   // This might get called by the TouchEvent::PrefEnabled code before we have
     436             :   // mCompositorOptions populated (bug 1370089). In that case we just assume
     437             :   // APZ is enabled because we're in a content process (because TabChild) and
     438             :   // APZ is probably going to be enabled here since e10s is enabled.
     439          17 :   return mCompositorOptions ? mCompositorOptions->UseAPZ() : true;
     440             : }
     441             : 
     442             : NS_IMETHODIMP
     443           1 : TabChild::Observe(nsISupports *aSubject,
     444             :                   const char *aTopic,
     445             :                   const char16_t *aData)
     446             : {
     447           1 :   if (!strcmp(aTopic, BEFORE_FIRST_PAINT)) {
     448           1 :     if (AsyncPanZoomEnabled()) {
     449           2 :       nsCOMPtr<nsIDocument> subject(do_QueryInterface(aSubject));
     450           2 :       nsCOMPtr<nsIDocument> doc(GetDocument());
     451             : 
     452           1 :       if (SameCOMIdentity(subject, doc)) {
     453           2 :         nsCOMPtr<nsIPresShell> shell(doc->GetShell());
     454           1 :         if (shell) {
     455           1 :           shell->SetIsFirstPaint(true);
     456             :         }
     457             : 
     458           1 :         APZCCallbackHelper::InitializeRootDisplayport(shell);
     459             :       }
     460             :     }
     461             :   }
     462             : 
     463           1 :   return NS_OK;
     464             : }
     465             : 
     466             : void
     467           0 : TabChild::ContentReceivedInputBlock(const ScrollableLayerGuid& aGuid,
     468             :                                     uint64_t aInputBlockId,
     469             :                                     bool aPreventDefault) const
     470             : {
     471           0 :   if (mApzcTreeManager) {
     472           0 :     mApzcTreeManager->ContentReceivedInputBlock(aInputBlockId, aPreventDefault);
     473             :   }
     474           0 : }
     475             : 
     476             : void
     477           0 : TabChild::SetTargetAPZC(uint64_t aInputBlockId,
     478             :                         const nsTArray<ScrollableLayerGuid>& aTargets) const
     479             : {
     480           0 :   if (mApzcTreeManager) {
     481           0 :     mApzcTreeManager->SetTargetAPZC(aInputBlockId, aTargets);
     482             :   }
     483           0 : }
     484             : 
     485             : void
     486           0 : TabChild::SetAllowedTouchBehavior(uint64_t aInputBlockId,
     487             :                                   const nsTArray<TouchBehaviorFlags>& aTargets) const
     488             : {
     489           0 :   if (mApzcTreeManager) {
     490           0 :     mApzcTreeManager->SetAllowedTouchBehavior(aInputBlockId, aTargets);
     491             :   }
     492           0 : }
     493             : 
     494             : bool
     495           1 : TabChild::DoUpdateZoomConstraints(const uint32_t& aPresShellId,
     496             :                                   const ViewID& aViewId,
     497             :                                   const Maybe<ZoomConstraints>& aConstraints)
     498             : {
     499           1 :   if (!mApzcTreeManager) {
     500           0 :     return false;
     501             :   }
     502             : 
     503           2 :   ScrollableLayerGuid guid = ScrollableLayerGuid(mLayersId, aPresShellId, aViewId);
     504             : 
     505           1 :   mApzcTreeManager->UpdateZoomConstraints(guid, aConstraints);
     506           1 :   return true;
     507             : }
     508             : 
     509             : nsresult
     510           1 : TabChild::Init()
     511             : {
     512           1 :   if (!mTabGroup) {
     513           1 :     mTabGroup = TabGroup::GetFromActor(this);
     514             :   }
     515             : 
     516           2 :   nsCOMPtr<nsIWebBrowser> webBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID);
     517           1 :   if (!webBrowser) {
     518           0 :     NS_ERROR("Couldn't create a nsWebBrowser?");
     519           0 :     return NS_ERROR_FAILURE;
     520             :   }
     521             : 
     522           1 :   webBrowser->SetContainerWindow(this);
     523           1 :   webBrowser->SetOriginAttributes(OriginAttributesRef());
     524           1 :   mWebNav = do_QueryInterface(webBrowser);
     525           1 :   NS_ASSERTION(mWebNav, "nsWebBrowser doesn't implement nsIWebNavigation?");
     526             : 
     527           2 :   nsCOMPtr<nsIDocShellTreeItem> docShellItem(do_QueryInterface(WebNavigation()));
     528           1 :   docShellItem->SetItemType(nsIDocShellTreeItem::typeContentWrapper);
     529             : 
     530           2 :   nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(WebNavigation());
     531           1 :   if (!baseWindow) {
     532           0 :     NS_ERROR("mWebNav doesn't QI to nsIBaseWindow");
     533           0 :     return NS_ERROR_FAILURE;
     534             :   }
     535             : 
     536           2 :   nsCOMPtr<nsIWidget> widget = nsIWidget::CreatePuppetWidget(this);
     537           1 :   mPuppetWidget = static_cast<PuppetWidget*>(widget.get());
     538           1 :   if (!mPuppetWidget) {
     539           0 :     NS_ERROR("couldn't create fake widget");
     540           0 :     return NS_ERROR_FAILURE;
     541             :   }
     542           1 :   mPuppetWidget->InfallibleCreate(
     543             :     nullptr, 0,              // no parents
     544           2 :     LayoutDeviceIntRect(0, 0, 0, 0),
     545             :     nullptr                  // HandleWidgetEvent
     546           1 :   );
     547             : 
     548           1 :   baseWindow->InitWindow(0, mPuppetWidget, 0, 0, 0, 0);
     549           1 :   baseWindow->Create();
     550             : 
     551             :   // Set the tab context attributes then pass to docShell
     552           1 :   NotifyTabContextUpdated(false);
     553             : 
     554             :   // IPC uses a WebBrowser object for which DNS prefetching is turned off
     555             :   // by default. But here we really want it, so enable it explicitly
     556             :   nsCOMPtr<nsIWebBrowserSetup> webBrowserSetup =
     557           2 :     do_QueryInterface(baseWindow);
     558           1 :   if (webBrowserSetup) {
     559           1 :     webBrowserSetup->SetProperty(nsIWebBrowserSetup::SETUP_ALLOW_DNS_PREFETCH,
     560           1 :                                  true);
     561             :   } else {
     562             :     NS_WARNING("baseWindow doesn't QI to nsIWebBrowserSetup, skipping "
     563           0 :                "DNS prefetching enable step.");
     564             :   }
     565             : 
     566           2 :   nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
     567           1 :   MOZ_ASSERT(docShell);
     568             : 
     569           2 :   docShell->SetAffectPrivateSessionLifetime(
     570           2 :       mChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME);
     571           2 :   nsCOMPtr<nsILoadContext> loadContext = do_GetInterface(WebNavigation());
     572           1 :   MOZ_ASSERT(loadContext);
     573           1 :   loadContext->SetPrivateBrowsing(OriginAttributesRef().mPrivateBrowsingId > 0);
     574           2 :   loadContext->SetRemoteTabs(
     575           2 :       mChromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW);
     576             : 
     577             :   // Few lines before, baseWindow->Create() will end up creating a new
     578             :   // window root in nsGlobalWindow::SetDocShell.
     579             :   // Then this chrome event handler, will be inherited to inner windows.
     580             :   // We want to also set it to the docshell so that inner windows
     581             :   // and any code that has access to the docshell
     582             :   // can all listen to the same chrome event handler.
     583             :   // XXX: ideally, we would set a chrome event handler earlier,
     584             :   // and all windows, even the root one, will use the docshell one.
     585           2 :   nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
     586           1 :   NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
     587             :   nsCOMPtr<EventTarget> chromeHandler =
     588           2 :     do_QueryInterface(window->GetChromeEventHandler());
     589           1 :   docShell->SetChromeEventHandler(chromeHandler);
     590             : 
     591           1 :   if (window->GetCurrentInnerWindow()) {
     592           0 :     window->SetKeyboardIndicators(ShowAccelerators(), ShowFocusRings());
     593             :   } else {
     594             :     // Skip ShouldShowFocusRing check if no inner window is available
     595           1 :     window->SetInitialKeyboardIndicators(ShowAccelerators(), ShowFocusRings());
     596             :   }
     597             : 
     598             :   // Set prerender flag if necessary.
     599           1 :   if (mIsPrerendered) {
     600           0 :     docShell->SetIsPrerendered();
     601             :   }
     602             : 
     603           1 :   nsContentUtils::SetScrollbarsVisibility(window->GetDocShell(),
     604           2 :     !!(mChromeFlags & nsIWebBrowserChrome::CHROME_SCROLLBARS));
     605             : 
     606           2 :   nsWeakPtr weakPtrThis = do_GetWeakReference(static_cast<nsITabChild*>(this));  // for capture by the lambda
     607             :   ContentReceivedInputBlockCallback callback(
     608           2 :       [weakPtrThis](const ScrollableLayerGuid& aGuid,
     609             :                     uint64_t aInputBlockId,
     610           0 :                     bool aPreventDefault)
     611             :       {
     612           0 :         if (nsCOMPtr<nsITabChild> tabChild = do_QueryReferent(weakPtrThis)) {
     613           0 :           static_cast<TabChild*>(tabChild.get())->ContentReceivedInputBlock(aGuid, aInputBlockId, aPreventDefault);
     614             :         }
     615           2 :       });
     616           2 :   mAPZEventState = new APZEventState(mPuppetWidget, Move(callback));
     617             : 
     618           1 :   mIPCOpen = true;
     619             : 
     620           1 :   if (GroupedSHistory::GroupedHistoryEnabled()) {
     621             :     // Set session history listener.
     622           0 :     nsCOMPtr<nsISHistory> shistory = GetRelatedSHistory();
     623           0 :     if (!shistory) {
     624           0 :       return NS_ERROR_FAILURE;
     625             :     }
     626           0 :     mHistoryListener = new TabChildSHistoryListener(this);
     627           0 :     nsCOMPtr<nsISHistoryListener> listener(do_QueryObject(mHistoryListener));
     628           0 :     shistory->AddSHistoryListener(listener);
     629           0 :     nsCOMPtr<nsIPartialSHistoryListener> partialListener(do_QueryObject(mHistoryListener));
     630           0 :     shistory->SetPartialSHistoryListener(partialListener);
     631             :   }
     632             : 
     633           1 :   return NS_OK;
     634             : }
     635             : 
     636             : void
     637           1 : TabChild::NotifyTabContextUpdated(bool aIsPreallocated)
     638             : {
     639           2 :   nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
     640           1 :   MOZ_ASSERT(docShell);
     641             : 
     642           1 :   if (!docShell) {
     643           0 :     return;
     644             :   }
     645             : 
     646           1 :   UpdateFrameType();
     647             : 
     648           1 :   if (aIsPreallocated)  {
     649           0 :     nsDocShell::Cast(docShell)->SetOriginAttributes(OriginAttributesRef());
     650             :   }
     651             : 
     652             :   // Set SANDBOXED_AUXILIARY_NAVIGATION flag if this is a receiver page.
     653           1 :   if (!PresentationURL().IsEmpty()) {
     654           0 :     docShell->SetSandboxFlags(SANDBOXED_AUXILIARY_NAVIGATION);
     655             :   }
     656             : }
     657             : 
     658             : void
     659           1 : TabChild::UpdateFrameType()
     660             : {
     661           2 :   nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
     662           1 :   MOZ_ASSERT(docShell);
     663             : 
     664             :   // TODO: Bug 1252794 - remove frameType from nsIDocShell.idl
     665           2 :   docShell->SetFrameType(IsMozBrowserElement() ? nsIDocShell::FRAME_TYPE_BROWSER :
     666           2 :                            nsIDocShell::FRAME_TYPE_REGULAR);
     667           1 : }
     668             : 
     669         188 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChild)
     670         187 :   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome)
     671         157 :   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome2)
     672         157 :   NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow)
     673         142 :   NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChromeFocus)
     674         142 :   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
     675          76 :   NS_INTERFACE_MAP_ENTRY(nsIWindowProvider)
     676          76 :   NS_INTERFACE_MAP_ENTRY(nsITabChild)
     677          26 :   NS_INTERFACE_MAP_ENTRY(nsIObserver)
     678          26 :   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
     679          22 :   NS_INTERFACE_MAP_ENTRY(nsITooltipListener)
     680          20 : NS_INTERFACE_MAP_END_INHERITING(TabChildBase)
     681             : 
     682         208 : NS_IMPL_ADDREF_INHERITED(TabChild, TabChildBase);
     683         198 : NS_IMPL_RELEASE_INHERITED(TabChild, TabChildBase);
     684             : 
     685             : NS_IMETHODIMP
     686           2 : TabChild::SetStatus(uint32_t aStatusType, const char16_t* aStatus)
     687             : {
     688           2 :   return SetStatusWithContext(aStatusType,
     689           6 :       aStatus ? static_cast<const nsString &>(nsDependentString(aStatus))
     690             :               : EmptyString(),
     691           4 :       nullptr);
     692             : }
     693             : 
     694             : NS_IMETHODIMP
     695           0 : TabChild::GetWebBrowser(nsIWebBrowser** aWebBrowser)
     696             : {
     697           0 :   NS_WARNING("TabChild::GetWebBrowser not supported in TabChild");
     698             : 
     699           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     700             : }
     701             : 
     702             : NS_IMETHODIMP
     703           0 : TabChild::SetWebBrowser(nsIWebBrowser* aWebBrowser)
     704             : {
     705           0 :   NS_WARNING("TabChild::SetWebBrowser not supported in TabChild");
     706             : 
     707           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     708             : }
     709             : 
     710             : NS_IMETHODIMP
     711           1 : TabChild::GetChromeFlags(uint32_t* aChromeFlags)
     712             : {
     713           1 :   *aChromeFlags = mChromeFlags;
     714           1 :   return NS_OK;
     715             : }
     716             : 
     717             : NS_IMETHODIMP
     718           0 : TabChild::SetChromeFlags(uint32_t aChromeFlags)
     719             : {
     720           0 :   NS_WARNING("trying to SetChromeFlags from content process?");
     721             : 
     722           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     723             : }
     724             : 
     725             : NS_IMETHODIMP
     726           0 : TabChild::DestroyBrowserWindow()
     727             : {
     728           0 :   NS_WARNING("TabChild::DestroyBrowserWindow not supported in TabChild");
     729             : 
     730           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     731             : }
     732             : 
     733             : NS_IMETHODIMP
     734           0 : TabChild::RemoteSizeShellTo(int32_t aWidth, int32_t aHeight,
     735             :                             int32_t aShellItemWidth, int32_t aShellItemHeight)
     736             : {
     737           0 :   nsCOMPtr<nsIDocShell> ourDocShell = do_GetInterface(WebNavigation());
     738           0 :   nsCOMPtr<nsIBaseWindow> docShellAsWin(do_QueryInterface(ourDocShell));
     739             :   int32_t width, height;
     740           0 :   docShellAsWin->GetSize(&width, &height);
     741             : 
     742           0 :   uint32_t flags = 0;
     743           0 :   if (width == aWidth) {
     744           0 :     flags |= nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_CX;
     745             :   }
     746             : 
     747           0 :   if (height == aHeight) {
     748           0 :     flags |= nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_CY;
     749             :   }
     750             : 
     751           0 :   bool sent = SendSizeShellTo(flags, aWidth, aHeight, aShellItemWidth, aShellItemHeight);
     752             : 
     753           0 :   return sent ? NS_OK : NS_ERROR_FAILURE;
     754             : }
     755             : 
     756             : NS_IMETHODIMP
     757           0 : TabChild::RemoteDropLinks(uint32_t aLinksCount,
     758             :                           nsIDroppedLinkItem** aLinks)
     759             : {
     760           0 :   nsTArray<nsString> linksArray;
     761           0 :   nsresult rv = NS_OK;
     762           0 :   for (uint32_t i = 0; i < aLinksCount; i++) {
     763           0 :     nsString tmp;
     764           0 :     rv = aLinks[i]->GetUrl(tmp);
     765           0 :     if (NS_FAILED(rv)) {
     766           0 :       return rv;
     767             :     }
     768           0 :     linksArray.AppendElement(tmp);
     769             : 
     770           0 :     rv = aLinks[i]->GetName(tmp);
     771           0 :     if (NS_FAILED(rv)) {
     772           0 :       return rv;
     773             :     }
     774           0 :     linksArray.AppendElement(tmp);
     775             : 
     776           0 :     rv = aLinks[i]->GetType(tmp);
     777           0 :     if (NS_FAILED(rv)) {
     778           0 :       return rv;
     779             :     }
     780           0 :     linksArray.AppendElement(tmp);
     781             :   }
     782           0 :   bool sent = SendDropLinks(linksArray);
     783             : 
     784           0 :   return sent ? NS_OK : NS_ERROR_FAILURE;
     785             : }
     786             : 
     787             : NS_IMETHODIMP
     788           0 : TabChild::SizeBrowserTo(int32_t aWidth, int32_t aHeight)
     789             : {
     790           0 :   NS_WARNING("TabChild::SizeBrowserTo not supported in TabChild");
     791             : 
     792           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     793             : }
     794             : 
     795             : NS_IMETHODIMP
     796           0 : TabChild::ShowAsModal()
     797             : {
     798           0 :   NS_WARNING("TabChild::ShowAsModal not supported in TabChild");
     799             : 
     800           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     801             : }
     802             : 
     803             : NS_IMETHODIMP
     804           0 : TabChild::IsWindowModal(bool* aRetVal)
     805             : {
     806           0 :   *aRetVal = false;
     807           0 :   return NS_OK;
     808             : }
     809             : 
     810             : NS_IMETHODIMP
     811           0 : TabChild::ExitModalEventLoop(nsresult aStatus)
     812             : {
     813           0 :   NS_WARNING("TabChild::ExitModalEventLoop not supported in TabChild");
     814             : 
     815           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     816             : }
     817             : 
     818             : NS_IMETHODIMP
     819           2 : TabChild::SetStatusWithContext(uint32_t aStatusType,
     820             :                                const nsAString& aStatusText,
     821             :                                nsISupports* aStatusContext)
     822             : {
     823             :   // We can only send the status after the ipc machinery is set up,
     824             :   // mRemoteFrame is a good indicator.
     825           2 :   if (mRemoteFrame)
     826           2 :     SendSetStatus(aStatusType, nsString(aStatusText));
     827           2 :   return NS_OK;
     828             : }
     829             : 
     830             : NS_IMETHODIMP
     831           0 : TabChild::SetDimensions(uint32_t aFlags, int32_t aX, int32_t aY,
     832             :                         int32_t aCx, int32_t aCy)
     833             : {
     834             :   // The parent is in charge of the dimension changes. If JS code wants to
     835             :   // change the dimensions (moveTo, screenX, etc.) we send a message to the
     836             :   // parent about the new requested dimension, the parent does the resize/move
     837             :   // then send a message to the child to update itself. For APIs like screenX
     838             :   // this function is called with the current value for the non-changed values.
     839             :   // In a series of calls like window.screenX = 10; window.screenY = 10; for
     840             :   // the second call, since screenX is not yet updated we might accidentally
     841             :   // reset back screenX to it's old value. To avoid this if a parameter did not
     842             :   // change we want the parent to ignore its value.
     843             :   int32_t x, y, cx, cy;
     844           0 :   GetDimensions(aFlags, &x, &y, &cx, &cy);
     845             : 
     846           0 :   if (x == aX) {
     847           0 :     aFlags |= nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_X;
     848             :   }
     849             : 
     850           0 :   if (y == aY) {
     851           0 :     aFlags |= nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_Y;
     852             :   }
     853             : 
     854           0 :   if (cx == aCx) {
     855           0 :     aFlags |= nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_CX;
     856             :   }
     857             : 
     858           0 :   if (cy == aCy) {
     859           0 :     aFlags |= nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_CY;
     860             :   }
     861             : 
     862           0 :   Unused << SendSetDimensions(aFlags, aX, aY, aCx, aCy);
     863             : 
     864           0 :   return NS_OK;
     865             : }
     866             : 
     867             : NS_IMETHODIMP
     868           0 : TabChild::GetDimensions(uint32_t aFlags, int32_t* aX,
     869             :                              int32_t* aY, int32_t* aCx, int32_t* aCy)
     870             : {
     871           0 :   ScreenIntRect rect = GetOuterRect();
     872           0 :   if (aX) {
     873           0 :     *aX = rect.x;
     874             :   }
     875           0 :   if (aY) {
     876           0 :     *aY = rect.y;
     877             :   }
     878           0 :   if (aCx) {
     879           0 :     *aCx = rect.width;
     880             :   }
     881           0 :   if (aCy) {
     882           0 :     *aCy = rect.height;
     883             :   }
     884             : 
     885           0 :   return NS_OK;
     886             : }
     887             : 
     888             : NS_IMETHODIMP
     889           0 : TabChild::SetFocus()
     890             : {
     891           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     892             : }
     893             : 
     894             : NS_IMETHODIMP
     895           4 : TabChild::GetVisibility(bool* aVisibility)
     896             : {
     897           4 :   *aVisibility = true;
     898           4 :   return NS_OK;
     899             : }
     900             : 
     901             : NS_IMETHODIMP
     902           0 : TabChild::SetVisibility(bool aVisibility)
     903             : {
     904             :   // should the platform support this? Bug 666365
     905           0 :   return NS_OK;
     906             : }
     907             : 
     908             : NS_IMETHODIMP
     909           0 : TabChild::GetTitle(char16_t** aTitle)
     910             : {
     911           0 :   NS_WARNING("TabChild::GetTitle not supported in TabChild");
     912             : 
     913           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     914             : }
     915             : 
     916             : NS_IMETHODIMP
     917           1 : TabChild::SetTitle(const char16_t* aTitle)
     918             : {
     919             :   // JavaScript sends the "DOMTitleChanged" event to the parent
     920             :   // via the message manager.
     921           1 :   return NS_OK;
     922             : }
     923             : 
     924             : NS_IMETHODIMP
     925           0 : TabChild::GetSiteWindow(void** aSiteWindow)
     926             : {
     927           0 :   NS_WARNING("TabChild::GetSiteWindow not supported in TabChild");
     928             : 
     929           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     930             : }
     931             : 
     932             : NS_IMETHODIMP
     933           0 : TabChild::Blur()
     934             : {
     935           0 :   return NS_ERROR_NOT_IMPLEMENTED;
     936             : }
     937             : 
     938             : NS_IMETHODIMP
     939           0 : TabChild::FocusNextElement(bool aForDocumentNavigation)
     940             : {
     941           0 :   SendMoveFocus(true, aForDocumentNavigation);
     942           0 :   return NS_OK;
     943             : }
     944             : 
     945             : NS_IMETHODIMP
     946           0 : TabChild::FocusPrevElement(bool aForDocumentNavigation)
     947             : {
     948           0 :   SendMoveFocus(false, aForDocumentNavigation);
     949           0 :   return NS_OK;
     950             : }
     951             : 
     952             : NS_IMETHODIMP
     953          22 : TabChild::GetInterface(const nsIID & aIID, void **aSink)
     954             : {
     955          22 :     if (aIID.Equals(NS_GET_IID(nsIWebBrowserChrome3))) {
     956           2 :       NS_IF_ADDREF(((nsISupports *) (*aSink = mWebBrowserChrome)));
     957           2 :       return NS_OK;
     958             :     }
     959             : 
     960             :     // XXXbz should we restrict the set of interfaces we hand out here?
     961             :     // See bug 537429
     962          20 :     return QueryInterface(aIID, aSink);
     963             : }
     964             : 
     965             : NS_IMETHODIMP
     966           0 : TabChild::ProvideWindow(mozIDOMWindowProxy* aParent,
     967             :                         uint32_t aChromeFlags,
     968             :                         bool aCalledFromJS,
     969             :                         bool aPositionSpecified, bool aSizeSpecified,
     970             :                         nsIURI* aURI, const nsAString& aName,
     971             :                         const nsACString& aFeatures, bool aForceNoOpener,
     972             :                         bool* aWindowIsNew, mozIDOMWindowProxy** aReturn)
     973             : {
     974           0 :     *aReturn = nullptr;
     975             : 
     976             :     // If aParent is inside an <iframe mozbrowser> and this isn't a request to
     977             :     // open a modal-type window, we're going to create a new <iframe mozbrowser>
     978             :     // and return its window here.
     979           0 :     nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent);
     980           0 :     bool iframeMoz = (docshell && docshell->GetIsInMozBrowser() &&
     981           0 :                       !(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL |
     982             :                                         nsIWebBrowserChrome::CHROME_OPENAS_DIALOG |
     983           0 :                                         nsIWebBrowserChrome::CHROME_OPENAS_CHROME)));
     984             : 
     985           0 :     if (!iframeMoz) {
     986             :       int32_t openLocation =
     987           0 :         nsWindowWatcher::GetWindowOpenLocation(nsPIDOMWindowOuter::From(aParent),
     988             :                                                aChromeFlags, aCalledFromJS,
     989           0 :                                                aPositionSpecified, aSizeSpecified);
     990             : 
     991             :       // If it turns out we're opening in the current browser, just hand over the
     992             :       // current browser's docshell.
     993           0 :       if (openLocation == nsIBrowserDOMWindow::OPEN_CURRENTWINDOW) {
     994           0 :         nsCOMPtr<nsIWebBrowser> browser = do_GetInterface(WebNavigation());
     995           0 :         *aWindowIsNew = false;
     996           0 :         return browser->GetContentDOMWindow(aReturn);
     997             :       }
     998             :     }
     999             : 
    1000             :     // Note that ProvideWindowCommon may return NS_ERROR_ABORT if the
    1001             :     // open window call was canceled.  It's important that we pass this error
    1002             :     // code back to our caller.
    1003           0 :     ContentChild* cc = ContentChild::GetSingleton();
    1004           0 :     return cc->ProvideWindowCommon(this,
    1005             :                                    aParent,
    1006             :                                    iframeMoz,
    1007             :                                    aChromeFlags,
    1008             :                                    aCalledFromJS,
    1009             :                                    aPositionSpecified,
    1010             :                                    aSizeSpecified,
    1011             :                                    aURI,
    1012             :                                    aName,
    1013             :                                    aFeatures,
    1014             :                                    aForceNoOpener,
    1015             :                                    aWindowIsNew,
    1016           0 :                                    aReturn);
    1017             : }
    1018             : 
    1019             : void
    1020           0 : TabChild::DestroyWindow()
    1021             : {
    1022           0 :     nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(WebNavigation());
    1023           0 :     if (baseWindow)
    1024           0 :         baseWindow->Destroy();
    1025             : 
    1026             :     // NB: the order of mPuppetWidget->Destroy() and mRemoteFrame->Destroy()
    1027             :     // is important: we want to kill off remote layers before their
    1028             :     // frames
    1029           0 :     if (mPuppetWidget) {
    1030           0 :         mPuppetWidget->Destroy();
    1031             :     }
    1032             : 
    1033           0 :     if (mRemoteFrame) {
    1034           0 :         mRemoteFrame->Destroy();
    1035           0 :         mRemoteFrame = nullptr;
    1036             :     }
    1037             : 
    1038             : 
    1039           0 :     if (mLayersId != 0) {
    1040           0 :       StaticMutexAutoLock lock(sTabChildrenMutex);
    1041             : 
    1042           0 :       MOZ_ASSERT(sTabChildren);
    1043           0 :       sTabChildren->Remove(mLayersId);
    1044           0 :       if (!sTabChildren->Count()) {
    1045           0 :         delete sTabChildren;
    1046           0 :         sTabChildren = nullptr;
    1047             :       }
    1048           0 :       mLayersId = 0;
    1049             :     }
    1050           0 : }
    1051             : 
    1052             : void
    1053           0 : TabChild::ActorDestroy(ActorDestroyReason why)
    1054             : {
    1055           0 :   mIPCOpen = false;
    1056             : 
    1057           0 :   DestroyWindow();
    1058             : 
    1059           0 :   if (mTabChildGlobal) {
    1060             :     // We should have a message manager if the global is alive, but it
    1061             :     // seems sometimes we don't.  Assert in aurora/nightly, but don't
    1062             :     // crash in release builds.
    1063           0 :     MOZ_DIAGNOSTIC_ASSERT(mTabChildGlobal->mMessageManager);
    1064           0 :     if (mTabChildGlobal->mMessageManager) {
    1065             :       // The messageManager relays messages via the TabChild which
    1066             :       // no longer exists.
    1067             :       static_cast<nsFrameMessageManager*>
    1068           0 :         (mTabChildGlobal->mMessageManager.get())->Disconnect();
    1069           0 :       mTabChildGlobal->mMessageManager = nullptr;
    1070             :     }
    1071             :   }
    1072             : 
    1073           0 :   CompositorBridgeChild* compositorChild = static_cast<CompositorBridgeChild*>(CompositorBridgeChild::Get());
    1074           0 :   compositorChild->CancelNotifyAfterRemotePaint(this);
    1075             : 
    1076           0 :   if (GetTabId() != 0) {
    1077           0 :     NestedTabChildMap().erase(GetTabId());
    1078             :   }
    1079           0 : }
    1080             : 
    1081           0 : TabChild::~TabChild()
    1082             : {
    1083           0 :   DestroyWindow();
    1084             : 
    1085           0 :   nsCOMPtr<nsIWebBrowser> webBrowser = do_QueryInterface(WebNavigation());
    1086           0 :   if (webBrowser) {
    1087           0 :     webBrowser->SetContainerWindow(nullptr);
    1088             :   }
    1089             : 
    1090           0 :   if (mHistoryListener) {
    1091           0 :     mHistoryListener->ClearTabChild();
    1092             :   }
    1093           0 : }
    1094             : 
    1095             : mozilla::ipc::IPCResult
    1096           1 : TabChild::RecvLoadURL(const nsCString& aURI,
    1097             :                       const ShowInfo& aInfo)
    1098             : {
    1099           1 :   if (!mDidLoadURLInit) {
    1100           1 :     mDidLoadURLInit = true;
    1101           1 :     if (!InitTabChildGlobal()) {
    1102           0 :       return IPC_FAIL_NO_REASON(this);
    1103             :     }
    1104             : 
    1105           1 :     ApplyShowInfo(aInfo);
    1106             :   }
    1107             : 
    1108             :   nsresult rv =
    1109           3 :     WebNavigation()->LoadURI(NS_ConvertUTF8toUTF16(aURI).get(),
    1110             :                              nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
    1111             :                              nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_PRINCIPAL,
    1112           2 :                              nullptr, nullptr, nullptr, nsContentUtils::GetSystemPrincipal());
    1113           1 :   if (NS_FAILED(rv)) {
    1114           0 :       NS_WARNING("WebNavigation()->LoadURI failed. Eating exception, what else can I do?");
    1115             :   }
    1116             : 
    1117             : #ifdef MOZ_CRASHREPORTER
    1118           1 :   CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("URL"), aURI);
    1119             : #endif
    1120             : 
    1121           1 :   return IPC_OK();
    1122             : }
    1123             : 
    1124             : void
    1125           0 : TabChild::DoFakeShow(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
    1126             :                      const uint64_t& aLayersId,
    1127             :                      const CompositorOptions& aCompositorOptions,
    1128             :                      PRenderFrameChild* aRenderFrame, const ShowInfo& aShowInfo)
    1129             : {
    1130           0 :   InitRenderingState(aTextureFactoryIdentifier, aLayersId, aCompositorOptions, aRenderFrame);
    1131           0 :   RecvShow(ScreenIntSize(0, 0), aShowInfo, mParentIsActive, nsSizeMode_Normal);
    1132           0 :   mDidFakeShow = true;
    1133           0 : }
    1134             : 
    1135             : void
    1136           2 : TabChild::ApplyShowInfo(const ShowInfo& aInfo)
    1137             : {
    1138           2 :   if (mDidSetRealShowInfo) {
    1139           1 :     return;
    1140             :   }
    1141             : 
    1142           1 :   if (!aInfo.fakeShowInfo()) {
    1143             :     // Once we've got one ShowInfo from parent, no need to update the values
    1144             :     // anymore.
    1145           1 :     mDidSetRealShowInfo = true;
    1146             :   }
    1147             : 
    1148           2 :   nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
    1149           1 :   if (docShell) {
    1150           2 :     nsCOMPtr<nsIDocShellTreeItem> item = do_GetInterface(docShell);
    1151           1 :     if (IsMozBrowser()) {
    1152             :       // B2G allows window.name to be set by changing the name attribute on the
    1153             :       // <iframe mozbrowser> element. window.open calls cause this attribute to
    1154             :       // be set to the correct value. A normal <xul:browser> element has no such
    1155             :       // attribute. The data we get here comes from reading the attribute, so we
    1156             :       // shouldn't trust it for <xul:browser> elements.
    1157           0 :       item->SetName(aInfo.name());
    1158             :     }
    1159           1 :     docShell->SetFullscreenAllowed(aInfo.fullscreenAllowed());
    1160           1 :     if (aInfo.isPrivate()) {
    1161           0 :       nsCOMPtr<nsILoadContext> context = do_GetInterface(docShell);
    1162             :       // No need to re-set private browsing mode.
    1163           0 :       if (!context->UsePrivateBrowsing()) {
    1164           0 :         if (docShell->GetHasLoadedNonBlankURI()) {
    1165           0 :           nsContentUtils::ReportToConsoleNonLocalized(
    1166           0 :             NS_LITERAL_STRING("We should not switch to Private Browsing after loading a document."),
    1167             :             nsIScriptError::warningFlag,
    1168           0 :             NS_LITERAL_CSTRING("mozprivatebrowsing"),
    1169           0 :             nullptr);
    1170             :         } else {
    1171           0 :           OriginAttributes attrs(nsDocShell::Cast(docShell)->GetOriginAttributes());
    1172           0 :           attrs.SyncAttributesWithPrivateBrowsing(true);
    1173           0 :           nsDocShell::Cast(docShell)->SetOriginAttributes(attrs);
    1174             :         }
    1175             :       }
    1176             :     }
    1177             :   }
    1178           1 :   mDPI = aInfo.dpi();
    1179           1 :   mRounding = aInfo.widgetRounding();
    1180           1 :   mDefaultScale = aInfo.defaultScale();
    1181           1 :   mIsTransparent = aInfo.isTransparent();
    1182             : }
    1183             : 
    1184             : mozilla::ipc::IPCResult
    1185           1 : TabChild::RecvShow(const ScreenIntSize& aSize,
    1186             :                    const ShowInfo& aInfo,
    1187             :                    const bool& aParentIsActive,
    1188             :                    const nsSizeMode& aSizeMode)
    1189             : {
    1190           1 :   bool res = true;
    1191             : 
    1192           1 :   mPuppetWidget->SetSizeMode(aSizeMode);
    1193           1 :   if (!mDidFakeShow) {
    1194           2 :     nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(WebNavigation());
    1195           1 :     if (!baseWindow) {
    1196           0 :         NS_ERROR("WebNavigation() doesn't QI to nsIBaseWindow");
    1197           0 :         return IPC_FAIL_NO_REASON(this);
    1198             :     }
    1199             : 
    1200           1 :     baseWindow->SetVisibility(true);
    1201           1 :     res = InitTabChildGlobal();
    1202             :   }
    1203             : 
    1204           1 :   ApplyShowInfo(aInfo);
    1205           1 :   RecvParentActivated(aParentIsActive);
    1206             : 
    1207           1 :   if (!res) {
    1208           0 :     return IPC_FAIL_NO_REASON(this);
    1209             :   }
    1210           1 :   return IPC_OK();
    1211             : }
    1212             : 
    1213             : mozilla::ipc::IPCResult
    1214           1 : TabChild::RecvInitRendering(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
    1215             :                             const uint64_t& aLayersId,
    1216             :                             const CompositorOptions& aCompositorOptions,
    1217             :                             const bool& aLayersConnected,
    1218             :                             PRenderFrameChild* aRenderFrame)
    1219             : {
    1220           1 :   MOZ_ASSERT((!mDidFakeShow && aRenderFrame) || (mDidFakeShow && !aRenderFrame));
    1221             : 
    1222           1 :   mLayersConnected = aLayersConnected;
    1223           1 :   InitRenderingState(aTextureFactoryIdentifier, aLayersId, aCompositorOptions, aRenderFrame);
    1224           1 :   return IPC_OK();
    1225             : }
    1226             : 
    1227             : mozilla::ipc::IPCResult
    1228           3 : TabChild::RecvUpdateDimensions(const DimensionInfo& aDimensionInfo)
    1229             : {
    1230           3 :     if (!mRemoteFrame) {
    1231           0 :         return IPC_OK();
    1232             :     }
    1233             : 
    1234           3 :     mUnscaledOuterRect = aDimensionInfo.rect();
    1235           3 :     mClientOffset = aDimensionInfo.clientOffset();
    1236           3 :     mChromeDisp = aDimensionInfo.chromeDisp();
    1237             : 
    1238           3 :     mOrientation = aDimensionInfo.orientation();
    1239           3 :     SetUnscaledInnerSize(aDimensionInfo.size());
    1240           7 :     if (!mHasValidInnerSize &&
    1241           4 :         aDimensionInfo.size().width != 0 &&
    1242           1 :         aDimensionInfo.size().height != 0) {
    1243           1 :       mHasValidInnerSize = true;
    1244             :     }
    1245             : 
    1246           3 :     ScreenIntSize screenSize = GetInnerSize();
    1247           3 :     ScreenIntRect screenRect = GetOuterRect();
    1248             : 
    1249             :     // Set the size on the document viewer before we update the widget and
    1250             :     // trigger a reflow. Otherwise the MobileViewportManager reads the stale
    1251             :     // size from the content viewer when it computes a new CSS viewport.
    1252           6 :     nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(WebNavigation());
    1253           6 :     baseWin->SetPositionAndSize(0, 0, screenSize.width, screenSize.height,
    1254           6 :                                 nsIBaseWindow::eRepaint);
    1255             : 
    1256          12 :     mPuppetWidget->Resize(screenRect.x + mClientOffset.x + mChromeDisp.x,
    1257           3 :                           screenRect.y + mClientOffset.y + mChromeDisp.y,
    1258           9 :                           screenSize.width, screenSize.height, true);
    1259             : 
    1260           3 :     return IPC_OK();
    1261             : }
    1262             : 
    1263             : mozilla::ipc::IPCResult
    1264           1 : TabChild::RecvSizeModeChanged(const nsSizeMode& aSizeMode)
    1265             : {
    1266           1 :   mPuppetWidget->SetSizeMode(aSizeMode);
    1267           1 :   if (!mPuppetWidget->IsVisible()) {
    1268           0 :     return IPC_OK();
    1269             :   }
    1270           2 :   nsCOMPtr<nsIDocument> document(GetDocument());
    1271           2 :   nsCOMPtr<nsIPresShell> presShell = document->GetShell();
    1272           1 :   if (presShell) {
    1273           1 :     nsPresContext* presContext = presShell->GetPresContext();
    1274           1 :     if (presContext) {
    1275           1 :       presContext->SizeModeChanged(aSizeMode);
    1276             :     }
    1277             :   }
    1278           1 :   return IPC_OK();
    1279             : }
    1280             : 
    1281             : bool
    1282           0 : TabChild::UpdateFrame(const FrameMetrics& aFrameMetrics)
    1283             : {
    1284           0 :   return TabChildBase::UpdateFrameHandler(aFrameMetrics);
    1285             : }
    1286             : 
    1287             : mozilla::ipc::IPCResult
    1288           0 : TabChild::RecvSuppressDisplayport(const bool& aEnabled)
    1289             : {
    1290           0 :   if (aEnabled) {
    1291           0 :     mActiveSuppressDisplayport++;
    1292             :   } else {
    1293           0 :     mActiveSuppressDisplayport--;
    1294             :   }
    1295             : 
    1296           0 :   MOZ_ASSERT(mActiveSuppressDisplayport >= 0);
    1297           0 :   APZCCallbackHelper::SuppressDisplayport(aEnabled, GetPresShell());
    1298           0 :   return IPC_OK();
    1299             : }
    1300             : 
    1301             : void
    1302           0 : TabChild::HandleDoubleTap(const CSSPoint& aPoint, const Modifiers& aModifiers,
    1303             :                           const ScrollableLayerGuid& aGuid)
    1304             : {
    1305             :   TABC_LOG("Handling double tap at %s with %p %p\n",
    1306             :     Stringify(aPoint).c_str(), mGlobal.get(), mTabChildGlobal.get());
    1307             : 
    1308           0 :   if (!mGlobal || !mTabChildGlobal) {
    1309           0 :     return;
    1310             :   }
    1311             : 
    1312             :   // Note: there is nothing to do with the modifiers here, as we are not
    1313             :   // synthesizing any sort of mouse event.
    1314           0 :   nsCOMPtr<nsIDocument> document = GetDocument();
    1315           0 :   CSSRect zoomToRect = CalculateRectToZoomTo(document, aPoint);
    1316             :   // The double-tap can be dispatched by any scroll frame (so |aGuid| could be
    1317             :   // the guid of any scroll frame), but the zoom-to-rect operation must be
    1318             :   // performed by the root content scroll frame, so query its identifiers
    1319             :   // for the SendZoomToRect() call rather than using the ones from |aGuid|.
    1320             :   uint32_t presShellId;
    1321             :   ViewID viewId;
    1322           0 :   if (APZCCallbackHelper::GetOrCreateScrollIdentifiers(
    1323           0 :       document->GetDocumentElement(), &presShellId, &viewId) && mApzcTreeManager) {
    1324           0 :     ScrollableLayerGuid guid(mLayersId, presShellId, viewId);
    1325             : 
    1326           0 :     mApzcTreeManager->ZoomToRect(guid, zoomToRect, DEFAULT_BEHAVIOR);
    1327             :   }
    1328             : }
    1329             : 
    1330             : mozilla::ipc::IPCResult
    1331           0 : TabChild::RecvHandleTap(const GeckoContentController::TapType& aType,
    1332             :                         const LayoutDevicePoint& aPoint,
    1333             :                         const Modifiers& aModifiers,
    1334             :                         const ScrollableLayerGuid& aGuid,
    1335             :                         const uint64_t& aInputBlockId)
    1336             : {
    1337           0 :   nsCOMPtr<nsIPresShell> presShell = GetPresShell();
    1338           0 :   if (!presShell) {
    1339           0 :     return IPC_OK();
    1340             :   }
    1341           0 :   if (!presShell->GetPresContext()) {
    1342           0 :     return IPC_OK();
    1343             :   }
    1344           0 :   CSSToLayoutDeviceScale scale(presShell->GetPresContext()->CSSToDevPixelScale());
    1345           0 :   CSSPoint point = APZCCallbackHelper::ApplyCallbackTransform(aPoint / scale, aGuid);
    1346             : 
    1347           0 :   switch (aType) {
    1348             :   case GeckoContentController::TapType::eSingleTap:
    1349           0 :     if (mGlobal && mTabChildGlobal) {
    1350           0 :       mAPZEventState->ProcessSingleTap(point, scale, aModifiers, aGuid, 1);
    1351             :     }
    1352           0 :     break;
    1353             :   case GeckoContentController::TapType::eDoubleTap:
    1354           0 :     HandleDoubleTap(point, aModifiers, aGuid);
    1355           0 :     break;
    1356             :   case GeckoContentController::TapType::eSecondTap:
    1357           0 :     if (mGlobal && mTabChildGlobal) {
    1358           0 :       mAPZEventState->ProcessSingleTap(point, scale, aModifiers, aGuid, 2);
    1359             :     }
    1360           0 :     break;
    1361             :   case GeckoContentController::TapType::eLongTap:
    1362           0 :     if (mGlobal && mTabChildGlobal) {
    1363           0 :       mAPZEventState->ProcessLongTap(presShell, point, scale, aModifiers, aGuid,
    1364           0 :           aInputBlockId);
    1365             :     }
    1366           0 :     break;
    1367             :   case GeckoContentController::TapType::eLongTapUp:
    1368           0 :     if (mGlobal && mTabChildGlobal) {
    1369           0 :       mAPZEventState->ProcessLongTapUp(presShell, point, scale, aModifiers);
    1370             :     }
    1371           0 :     break;
    1372             :   }
    1373           0 :   return IPC_OK();
    1374             : }
    1375             : 
    1376             : bool
    1377           0 : TabChild::NotifyAPZStateChange(const ViewID& aViewId,
    1378             :                                const layers::GeckoContentController::APZStateChange& aChange,
    1379             :                                const int& aArg)
    1380             : {
    1381           0 :   mAPZEventState->ProcessAPZStateChange(aViewId, aChange, aArg);
    1382           0 :   if (aChange == layers::GeckoContentController::APZStateChange::eTransformEnd) {
    1383             :     // This is used by tests to determine when the APZ is done doing whatever
    1384             :     // it's doing. XXX generify this as needed when writing additional tests.
    1385           0 :     nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
    1386           0 :     observerService->NotifyObservers(nullptr, "APZ:TransformEnd", nullptr);
    1387             :   }
    1388           0 :   return true;
    1389             : }
    1390             : 
    1391             : void
    1392           0 : TabChild::StartScrollbarDrag(const layers::AsyncDragMetrics& aDragMetrics)
    1393             : {
    1394           0 :   ScrollableLayerGuid guid(mLayersId, aDragMetrics.mPresShellId,
    1395           0 :                            aDragMetrics.mViewId);
    1396             : 
    1397           0 :   if (mApzcTreeManager) {
    1398           0 :     mApzcTreeManager->StartScrollbarDrag(guid, aDragMetrics);
    1399             :   }
    1400           0 : }
    1401             : 
    1402             : void
    1403           0 : TabChild::ZoomToRect(const uint32_t& aPresShellId,
    1404             :                      const FrameMetrics::ViewID& aViewId,
    1405             :                      const CSSRect& aRect,
    1406             :                      const uint32_t& aFlags)
    1407             : {
    1408           0 :   ScrollableLayerGuid guid(mLayersId, aPresShellId, aViewId);
    1409             : 
    1410           0 :   if (mApzcTreeManager) {
    1411           0 :     mApzcTreeManager->ZoomToRect(guid, aRect, aFlags);
    1412             :   }
    1413           0 : }
    1414             : 
    1415             : mozilla::ipc::IPCResult
    1416           1 : TabChild::RecvActivate()
    1417             : {
    1418           2 :   nsCOMPtr<nsIWebBrowserFocus> browser = do_QueryInterface(WebNavigation());
    1419           1 :   browser->Activate();
    1420           2 :   return IPC_OK();
    1421             : }
    1422             : 
    1423             : mozilla::ipc::IPCResult
    1424           0 : TabChild::RecvDeactivate()
    1425             : {
    1426           0 :   nsCOMPtr<nsIWebBrowserFocus> browser = do_QueryInterface(WebNavigation());
    1427           0 :   browser->Deactivate();
    1428           0 :   return IPC_OK();
    1429             : }
    1430             : 
    1431             : mozilla::ipc::IPCResult
    1432           2 : TabChild::RecvParentActivated(const bool& aActivated)
    1433             : {
    1434           2 :   mParentIsActive = aActivated;
    1435             : 
    1436           2 :   nsFocusManager* fm = nsFocusManager::GetFocusManager();
    1437           2 :   NS_ENSURE_TRUE(fm, IPC_OK());
    1438             : 
    1439           4 :   nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
    1440           2 :   fm->ParentActivated(window, aActivated);
    1441           2 :   return IPC_OK();
    1442             : }
    1443             : 
    1444             : mozilla::ipc::IPCResult
    1445           0 : TabChild::RecvSetKeyboardIndicators(const UIStateChangeType& aShowAccelerators,
    1446             :                                     const UIStateChangeType& aShowFocusRings)
    1447             : {
    1448           0 :   nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
    1449           0 :   NS_ENSURE_TRUE(window, IPC_OK());
    1450             : 
    1451           0 :   window->SetKeyboardIndicators(aShowAccelerators, aShowFocusRings);
    1452           0 :   return IPC_OK();
    1453             : }
    1454             : 
    1455             : mozilla::ipc::IPCResult
    1456           0 : TabChild::RecvStopIMEStateManagement()
    1457             : {
    1458           0 :   IMEStateManager::StopIMEStateManagement();
    1459           0 :   return IPC_OK();
    1460             : }
    1461             : 
    1462             : mozilla::ipc::IPCResult
    1463           0 : TabChild::RecvMenuKeyboardListenerInstalled(const bool& aInstalled)
    1464             : {
    1465           0 :   IMEStateManager::OnInstalledMenuKeyboardListener(aInstalled);
    1466           0 :   return IPC_OK();
    1467             : }
    1468             : 
    1469             : mozilla::ipc::IPCResult
    1470           0 : TabChild::RecvNotifyAttachGroupedSHistory(const uint32_t& aOffset)
    1471             : {
    1472             :   // nsISHistory uses int32_t
    1473           0 :   if (NS_WARN_IF(aOffset > INT32_MAX)) {
    1474           0 :     return IPC_FAIL_NO_REASON(this);
    1475             :   }
    1476             : 
    1477           0 :   nsCOMPtr<nsISHistory> shistory = GetRelatedSHistory();
    1478           0 :   NS_ENSURE_TRUE(shistory, IPC_FAIL_NO_REASON(this));
    1479             : 
    1480           0 :   if (NS_FAILED(shistory->OnAttachGroupedSHistory(aOffset))) {
    1481           0 :     return IPC_FAIL_NO_REASON(this);
    1482             :   }
    1483           0 :   return IPC_OK();
    1484             : }
    1485             : 
    1486             : mozilla::ipc::IPCResult
    1487           0 : TabChild::RecvNotifyPartialSHistoryActive(const uint32_t& aGlobalLength,
    1488             :                                           const uint32_t& aTargetLocalIndex)
    1489             : {
    1490             :   // nsISHistory uses int32_t
    1491           0 :   if (NS_WARN_IF(aGlobalLength > INT32_MAX || aTargetLocalIndex > INT32_MAX)) {
    1492           0 :     return IPC_FAIL_NO_REASON(this);
    1493             :   }
    1494             : 
    1495           0 :   nsCOMPtr<nsISHistory> shistory = GetRelatedSHistory();
    1496           0 :   NS_ENSURE_TRUE(shistory, IPC_FAIL_NO_REASON(this));
    1497             : 
    1498           0 :   if (NS_FAILED(shistory->OnPartialSHistoryActive(aGlobalLength,
    1499             :                                                   aTargetLocalIndex))) {
    1500           0 :     return IPC_FAIL_NO_REASON(this);
    1501             :   }
    1502           0 :   return IPC_OK();
    1503             : }
    1504             : 
    1505             : mozilla::ipc::IPCResult
    1506           0 : TabChild::RecvNotifyPartialSHistoryDeactive()
    1507             : {
    1508           0 :   nsCOMPtr<nsISHistory> shistory = GetRelatedSHistory();
    1509           0 :   NS_ENSURE_TRUE(shistory, IPC_FAIL_NO_REASON(this));
    1510             : 
    1511           0 :   if (NS_FAILED(shistory->OnPartialSHistoryDeactive())) {
    1512           0 :     return IPC_FAIL_NO_REASON(this);
    1513             :   }
    1514           0 :   return IPC_OK();
    1515             : }
    1516             : 
    1517             : mozilla::ipc::IPCResult
    1518           0 : TabChild::RecvMouseEvent(const nsString& aType,
    1519             :                          const float&    aX,
    1520             :                          const float&    aY,
    1521             :                          const int32_t&  aButton,
    1522             :                          const int32_t&  aClickCount,
    1523             :                          const int32_t&  aModifiers,
    1524             :                          const bool&     aIgnoreRootScrollFrame)
    1525             : {
    1526           0 :   APZCCallbackHelper::DispatchMouseEvent(GetPresShell(), aType,
    1527           0 :                                          CSSPoint(aX, aY), aButton, aClickCount,
    1528           0 :                                          aModifiers, aIgnoreRootScrollFrame,
    1529             :                                          nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN,
    1530           0 :                                          0 /* Use the default value here. */);
    1531           0 :   return IPC_OK();
    1532             : }
    1533             : 
    1534             : mozilla::ipc::IPCResult
    1535           4 : TabChild::RecvRealMouseMoveEvent(const WidgetMouseEvent& aEvent,
    1536             :                                  const ScrollableLayerGuid& aGuid,
    1537             :                                  const uint64_t& aInputBlockId)
    1538             : {
    1539           4 :   if (!RecvRealMouseButtonEvent(aEvent, aGuid, aInputBlockId)) {
    1540           0 :     return IPC_FAIL_NO_REASON(this);
    1541             :   }
    1542           4 :   return IPC_OK();
    1543             : }
    1544             : 
    1545             : mozilla::ipc::IPCResult
    1546           0 : TabChild::RecvSynthMouseMoveEvent(const WidgetMouseEvent& aEvent,
    1547             :                                   const ScrollableLayerGuid& aGuid,
    1548             :                                   const uint64_t& aInputBlockId)
    1549             : {
    1550           0 :   if (!RecvRealMouseButtonEvent(aEvent, aGuid, aInputBlockId)) {
    1551           0 :     return IPC_FAIL_NO_REASON(this);
    1552             :   }
    1553           0 :   return IPC_OK();
    1554             : }
    1555             : 
    1556             : mozilla::ipc::IPCResult
    1557           6 : TabChild::RecvRealMouseButtonEvent(const WidgetMouseEvent& aEvent,
    1558             :                                    const ScrollableLayerGuid& aGuid,
    1559             :                                    const uint64_t& aInputBlockId)
    1560             : {
    1561             :   // Mouse events like eMouseEnterIntoWidget, that are created in the parent
    1562             :   // process EventStateManager code, have an input block id which they get from
    1563             :   // the InputAPZContext in the parent process stack. However, they did not
    1564             :   // actually go through the APZ code and so their mHandledByAPZ flag is false.
    1565             :   // Since thos events didn't go through APZ, we don't need to send
    1566             :   // notifications for them.
    1567           6 :   bool pendingLayerization = false;
    1568           6 :   if (aInputBlockId && aEvent.mFlags.mHandledByAPZ) {
    1569           0 :     nsCOMPtr<nsIDocument> document(GetDocument());
    1570             :     pendingLayerization =
    1571           0 :       APZCCallbackHelper::SendSetTargetAPZCNotification(mPuppetWidget, document,
    1572             :                                                         aEvent, aGuid,
    1573           0 :                                                         aInputBlockId);
    1574             :   }
    1575             : 
    1576             :   nsEventStatus unused;
    1577          12 :   InputAPZContext context(aGuid, aInputBlockId, unused);
    1578           6 :   if (pendingLayerization) {
    1579           0 :     context.SetPendingLayerization();
    1580             :   }
    1581             : 
    1582          12 :   WidgetMouseEvent localEvent(aEvent);
    1583           6 :   localEvent.mWidget = mPuppetWidget;
    1584             :   APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
    1585           6 :       mPuppetWidget->GetDefaultScale());
    1586           6 :   APZCCallbackHelper::DispatchWidgetEvent(localEvent);
    1587             : 
    1588           6 :   if (aInputBlockId && aEvent.mFlags.mHandledByAPZ) {
    1589           0 :     mAPZEventState->ProcessMouseEvent(aEvent, aGuid, aInputBlockId);
    1590             :   }
    1591          12 :   return IPC_OK();
    1592             : }
    1593             : 
    1594             : 
    1595             : // In case handling repeated mouse wheel takes much time, we skip firing current
    1596             : // wheel event if it may be coalesced to the next one.
    1597             : bool
    1598           0 : TabChild::MaybeCoalesceWheelEvent(const WidgetWheelEvent& aEvent,
    1599             :                                   const ScrollableLayerGuid& aGuid,
    1600             :                                   const uint64_t& aInputBlockId,
    1601             :                                   bool* aIsNextWheelEvent)
    1602             : {
    1603           0 :   MOZ_ASSERT(aIsNextWheelEvent);
    1604           0 :   if (aEvent.mMessage == eWheel) {
    1605           0 :     GetIPCChannel()->PeekMessages(
    1606           0 :         [aIsNextWheelEvent](const IPC::Message& aMsg) -> bool {
    1607           0 :           if (aMsg.type() == mozilla::dom::PBrowser::Msg_MouseWheelEvent__ID) {
    1608           0 :             *aIsNextWheelEvent = true;
    1609             :           }
    1610           0 :           return false; // Stop peeking.
    1611           0 :         });
    1612             :     // We only coalesce the current event when
    1613             :     // 1. It's eWheel (we don't coalesce eOperationStart and eWheelOperationEnd)
    1614             :     // 2. It's not the first wheel event.
    1615             :     // 3. It's not the last wheel event.
    1616             :     // 4. It's dispatched before the last wheel event was processed +
    1617             :     //    the processing time of the last event.
    1618             :     //    This way pages spending lots of time in wheel listeners get wheel
    1619             :     //    events coalesced more aggressively.
    1620             :     // 5. It has same attributes as the coalesced wheel event which is not yet
    1621             :     //    fired.
    1622           0 :     if (!mLastWheelProcessedTimeFromParent.IsNull() &&
    1623           0 :         *aIsNextWheelEvent &&
    1624           0 :         aEvent.mTimeStamp < (mLastWheelProcessedTimeFromParent +
    1625           0 :                              mLastWheelProcessingDuration) &&
    1626           0 :         (mCoalescedWheelData.IsEmpty() ||
    1627           0 :          mCoalescedWheelData.CanCoalesce(aEvent, aGuid, aInputBlockId))) {
    1628           0 :       mCoalescedWheelData.Coalesce(aEvent, aGuid, aInputBlockId);
    1629           0 :       return true;
    1630             :     }
    1631             :   }
    1632           0 :   return false;
    1633             : }
    1634             : 
    1635             : void
    1636           0 : TabChild::MaybeDispatchCoalescedWheelEvent()
    1637             : {
    1638           0 :   if (mCoalescedWheelData.IsEmpty()) {
    1639           0 :     return;
    1640             :   }
    1641             :   const WidgetWheelEvent* wheelEvent =
    1642           0 :     mCoalescedWheelData.GetCoalescedWheelEvent();
    1643           0 :   MOZ_ASSERT(wheelEvent);
    1644             :   DispatchWheelEvent(*wheelEvent,
    1645           0 :                      mCoalescedWheelData.GetScrollableLayerGuid(),
    1646           0 :                      mCoalescedWheelData.GetInputBlockId());
    1647           0 :   mCoalescedWheelData.Reset();
    1648             : }
    1649             : 
    1650             : void
    1651           0 : TabChild::DispatchWheelEvent(const WidgetWheelEvent& aEvent,
    1652             :                                   const ScrollableLayerGuid& aGuid,
    1653             :                                   const uint64_t& aInputBlockId)
    1654             : {
    1655           0 :   WidgetWheelEvent localEvent(aEvent);
    1656           0 :   if (aInputBlockId && aEvent.mFlags.mHandledByAPZ) {
    1657           0 :     nsCOMPtr<nsIDocument> document(GetDocument());
    1658           0 :     APZCCallbackHelper::SendSetTargetAPZCNotification(
    1659           0 :       mPuppetWidget, document, aEvent, aGuid, aInputBlockId);
    1660             :   }
    1661             : 
    1662           0 :   localEvent.mWidget = mPuppetWidget;
    1663             :   APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
    1664           0 :                                              mPuppetWidget->GetDefaultScale());
    1665           0 :   APZCCallbackHelper::DispatchWidgetEvent(localEvent);
    1666             : 
    1667           0 :   if (localEvent.mCanTriggerSwipe) {
    1668           0 :     SendRespondStartSwipeEvent(aInputBlockId, localEvent.TriggersSwipe());
    1669             :   }
    1670             : 
    1671           0 :   if (aInputBlockId && aEvent.mFlags.mHandledByAPZ) {
    1672           0 :     mAPZEventState->ProcessWheelEvent(localEvent, aGuid, aInputBlockId);
    1673             :   }
    1674           0 : }
    1675             : 
    1676             : mozilla::ipc::IPCResult
    1677           0 : TabChild::RecvMouseWheelEvent(const WidgetWheelEvent& aEvent,
    1678             :                               const ScrollableLayerGuid& aGuid,
    1679             :                               const uint64_t& aInputBlockId)
    1680             : {
    1681           0 :   bool isNextWheelEvent = false;
    1682           0 :   if (MaybeCoalesceWheelEvent(aEvent, aGuid, aInputBlockId,
    1683             :                               &isNextWheelEvent)) {
    1684           0 :     return IPC_OK();
    1685             :   }
    1686           0 :   if (isNextWheelEvent) {
    1687             :     // Update mLastWheelProcessedTimeFromParent so that we can compare the end
    1688             :     // time of the current event with the dispatched time of the next event.
    1689           0 :     mLastWheelProcessedTimeFromParent = aEvent.mTimeStamp;
    1690           0 :     mozilla::TimeStamp beforeDispatchingTime = TimeStamp::Now();
    1691           0 :     MaybeDispatchCoalescedWheelEvent();
    1692           0 :     DispatchWheelEvent(aEvent, aGuid, aInputBlockId);
    1693           0 :     mLastWheelProcessingDuration = (TimeStamp::Now() - beforeDispatchingTime);
    1694           0 :     mLastWheelProcessedTimeFromParent += mLastWheelProcessingDuration;
    1695             :   } else {
    1696             :     // This is the last wheel event. Set mLastWheelProcessedTimeFromParent to
    1697             :     // null moment to avoid coalesce the next incoming wheel event.
    1698           0 :     mLastWheelProcessedTimeFromParent = TimeStamp();
    1699           0 :     MaybeDispatchCoalescedWheelEvent();
    1700           0 :     DispatchWheelEvent(aEvent, aGuid, aInputBlockId);
    1701             :   }
    1702           0 :   return IPC_OK();
    1703             : }
    1704             : 
    1705             : mozilla::ipc::IPCResult
    1706           0 : TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent,
    1707             :                              const ScrollableLayerGuid& aGuid,
    1708             :                              const uint64_t& aInputBlockId,
    1709             :                              const nsEventStatus& aApzResponse)
    1710             : {
    1711             :   TABC_LOG("Receiving touch event of type %d\n", aEvent.mMessage);
    1712             : 
    1713           0 :   WidgetTouchEvent localEvent(aEvent);
    1714           0 :   localEvent.mWidget = mPuppetWidget;
    1715             : 
    1716             :   APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
    1717           0 :                                              mPuppetWidget->GetDefaultScale());
    1718             : 
    1719           0 :   if (localEvent.mMessage == eTouchStart && AsyncPanZoomEnabled()) {
    1720           0 :     nsCOMPtr<nsIDocument> document = GetDocument();
    1721           0 :     if (gfxPrefs::TouchActionEnabled()) {
    1722           0 :       APZCCallbackHelper::SendSetAllowedTouchBehaviorNotification(
    1723             :         mPuppetWidget, document, localEvent, aInputBlockId,
    1724           0 :         mSetAllowedTouchBehaviorCallback);
    1725             :     }
    1726           0 :     APZCCallbackHelper::SendSetTargetAPZCNotification(mPuppetWidget, document,
    1727             :                                                       localEvent, aGuid,
    1728           0 :                                                       aInputBlockId);
    1729             :   }
    1730             : 
    1731             :   // Dispatch event to content (potentially a long-running operation)
    1732           0 :   nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent);
    1733             : 
    1734           0 :   if (!AsyncPanZoomEnabled()) {
    1735             :     // We shouldn't have any e10s platforms that have touch events enabled
    1736             :     // without APZ.
    1737           0 :     MOZ_ASSERT(false);
    1738             :     return IPC_OK();
    1739             :   }
    1740             : 
    1741           0 :   mAPZEventState->ProcessTouchEvent(localEvent, aGuid, aInputBlockId,
    1742           0 :                                     aApzResponse, status);
    1743           0 :   return IPC_OK();
    1744             : }
    1745             : 
    1746             : mozilla::ipc::IPCResult
    1747           0 : TabChild::RecvRealTouchMoveEvent(const WidgetTouchEvent& aEvent,
    1748             :                                  const ScrollableLayerGuid& aGuid,
    1749             :                                  const uint64_t& aInputBlockId,
    1750             :                                  const nsEventStatus& aApzResponse)
    1751             : {
    1752           0 :   if (!RecvRealTouchEvent(aEvent, aGuid, aInputBlockId, aApzResponse)) {
    1753           0 :     return IPC_FAIL_NO_REASON(this);
    1754             :   }
    1755           0 :   return IPC_OK();
    1756             : }
    1757             : 
    1758             : mozilla::ipc::IPCResult
    1759           0 : TabChild::RecvRealDragEvent(const WidgetDragEvent& aEvent,
    1760             :                             const uint32_t& aDragAction,
    1761             :                             const uint32_t& aDropEffect)
    1762             : {
    1763           0 :   WidgetDragEvent localEvent(aEvent);
    1764           0 :   localEvent.mWidget = mPuppetWidget;
    1765             : 
    1766           0 :   nsCOMPtr<nsIDragSession> dragSession = nsContentUtils::GetDragSession();
    1767           0 :   if (dragSession) {
    1768           0 :     dragSession->SetDragAction(aDragAction);
    1769           0 :     nsCOMPtr<nsIDOMDataTransfer> initialDataTransfer;
    1770           0 :     dragSession->GetDataTransfer(getter_AddRefs(initialDataTransfer));
    1771           0 :     if (initialDataTransfer) {
    1772           0 :       initialDataTransfer->SetDropEffectInt(aDropEffect);
    1773             :     }
    1774             :   }
    1775             : 
    1776           0 :   if (aEvent.mMessage == eDrop) {
    1777           0 :     bool canDrop = true;
    1778           0 :     if (!dragSession || NS_FAILED(dragSession->GetCanDrop(&canDrop)) ||
    1779           0 :         !canDrop) {
    1780           0 :       localEvent.mMessage = eDragExit;
    1781             :     }
    1782           0 :   } else if (aEvent.mMessage == eDragOver) {
    1783             :     nsCOMPtr<nsIDragService> dragService =
    1784           0 :       do_GetService("@mozilla.org/widget/dragservice;1");
    1785           0 :     if (dragService) {
    1786             :       // This will dispatch 'drag' event at the source if the
    1787             :       // drag transaction started in this process.
    1788           0 :       dragService->FireDragEventAtSource(eDrag, aEvent.mModifiers);
    1789             :     }
    1790             :   }
    1791             : 
    1792           0 :   APZCCallbackHelper::DispatchWidgetEvent(localEvent);
    1793           0 :   return IPC_OK();
    1794             : }
    1795             : 
    1796             : mozilla::ipc::IPCResult
    1797           0 : TabChild::RecvPluginEvent(const WidgetPluginEvent& aEvent)
    1798             : {
    1799           0 :   WidgetPluginEvent localEvent(aEvent);
    1800           0 :   localEvent.mWidget = mPuppetWidget;
    1801           0 :   nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent);
    1802           0 :   if (status != nsEventStatus_eConsumeNoDefault) {
    1803             :     // If not consumed, we should call default action
    1804           0 :     SendDefaultProcOfPluginEvent(aEvent);
    1805             :   }
    1806           0 :   return IPC_OK();
    1807             : }
    1808             : 
    1809             : void
    1810           0 : TabChild::RequestEditCommands(nsIWidget::NativeKeyBindingsType aType,
    1811             :                               const WidgetKeyboardEvent& aEvent,
    1812             :                               nsTArray<CommandInt>& aCommands)
    1813             : {
    1814           0 :   MOZ_ASSERT(aCommands.IsEmpty());
    1815             : 
    1816           0 :   if (NS_WARN_IF(aEvent.IsEditCommandsInitialized(aType))) {
    1817           0 :     aCommands = aEvent.EditCommandsConstRef(aType);
    1818           0 :     return;
    1819             :   }
    1820             : 
    1821           0 :   switch (aType) {
    1822             :     case nsIWidget::NativeKeyBindingsForSingleLineEditor:
    1823             :     case nsIWidget::NativeKeyBindingsForMultiLineEditor:
    1824             :     case nsIWidget::NativeKeyBindingsForRichTextEditor:
    1825           0 :       break;
    1826             :     default:
    1827           0 :       MOZ_ASSERT_UNREACHABLE("Invalid native key bindings type");
    1828             :   }
    1829             : 
    1830             :   // Don't send aEvent to the parent process directly because it'll be marked
    1831             :   // as posted to remote process.
    1832           0 :   WidgetKeyboardEvent localEvent(aEvent);
    1833           0 :   SendRequestNativeKeyBindings(aType, localEvent, &aCommands);
    1834             : }
    1835             : 
    1836             : mozilla::ipc::IPCResult
    1837           0 : TabChild::RecvNativeSynthesisResponse(const uint64_t& aObserverId,
    1838             :                                       const nsCString& aResponse)
    1839             : {
    1840           0 :   mozilla::widget::AutoObserverNotifier::NotifySavedObserver(aObserverId,
    1841           0 :                                                              aResponse.get());
    1842           0 :   return IPC_OK();
    1843             : }
    1844             : 
    1845             : // In case handling repeated keys takes much time, we skip firing new ones.
    1846             : bool
    1847           0 : TabChild::SkipRepeatedKeyEvent(const WidgetKeyboardEvent& aEvent)
    1848             : {
    1849           0 :   if (mRepeatedKeyEventTime.IsNull() ||
    1850           0 :       !aEvent.mIsRepeat ||
    1851           0 :       (aEvent.mMessage != eKeyDown && aEvent.mMessage != eKeyPress)) {
    1852           0 :     mRepeatedKeyEventTime = TimeStamp();
    1853           0 :     mSkipKeyPress = false;
    1854           0 :     return false;
    1855             :   }
    1856             : 
    1857           0 :   if ((aEvent.mMessage == eKeyDown &&
    1858           0 :        (mRepeatedKeyEventTime > aEvent.mTimeStamp)) ||
    1859           0 :       (mSkipKeyPress && (aEvent.mMessage == eKeyPress))) {
    1860             :     // If we skip a keydown event, also the following keypress events should be
    1861             :     // skipped.
    1862           0 :     mSkipKeyPress |= aEvent.mMessage == eKeyDown;
    1863           0 :     return true;
    1864             :   }
    1865             : 
    1866           0 :   if (aEvent.mMessage == eKeyDown) {
    1867             :     // If keydown wasn't skipped, nor should the possible following keypress.
    1868           0 :     mRepeatedKeyEventTime = TimeStamp();
    1869           0 :     mSkipKeyPress = false;
    1870             :   }
    1871           0 :   return false;
    1872             : }
    1873             : 
    1874             : void
    1875           0 : TabChild::UpdateRepeatedKeyEventEndTime(const WidgetKeyboardEvent& aEvent)
    1876             : {
    1877           0 :   if (aEvent.mIsRepeat &&
    1878           0 :       (aEvent.mMessage == eKeyDown || aEvent.mMessage == eKeyPress)) {
    1879           0 :     mRepeatedKeyEventTime = TimeStamp::Now();
    1880             :   }
    1881           0 : }
    1882             : 
    1883             : mozilla::ipc::IPCResult
    1884           0 : TabChild::RecvRealKeyEvent(const WidgetKeyboardEvent& aEvent)
    1885             : {
    1886           0 :   if (SkipRepeatedKeyEvent(aEvent)) {
    1887           0 :     return IPC_OK();
    1888             :   }
    1889             : 
    1890           0 :   MOZ_ASSERT(aEvent.mMessage != eKeyPress ||
    1891             :              aEvent.AreAllEditCommandsInitialized(),
    1892             :     "eKeyPress event should have native key binding information");
    1893             : 
    1894             :   // If content code called preventDefault() on a keydown event, then we don't
    1895             :   // want to process any following keypress events.
    1896           0 :   if (aEvent.mMessage == eKeyPress && mIgnoreKeyPressEvent) {
    1897           0 :     return IPC_OK();
    1898             :   }
    1899             : 
    1900           0 :   WidgetKeyboardEvent localEvent(aEvent);
    1901           0 :   localEvent.mWidget = mPuppetWidget;
    1902           0 :   localEvent.mUniqueId = aEvent.mUniqueId;
    1903           0 :   nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent);
    1904             : 
    1905             :   // Update the end time of the possible repeated event so that we can skip
    1906             :   // some incoming events in case event handling took long time.
    1907           0 :   UpdateRepeatedKeyEventEndTime(localEvent);
    1908             : 
    1909           0 :   if (aEvent.mMessage == eKeyDown) {
    1910           0 :     mIgnoreKeyPressEvent = status == nsEventStatus_eConsumeNoDefault;
    1911             :   }
    1912             : 
    1913           0 :   if (localEvent.mFlags.mIsSuppressedOrDelayed) {
    1914           0 :     localEvent.PreventDefault();
    1915             :   }
    1916             : 
    1917             :   // If a response is desired from the content process, resend the key event.
    1918             :   // If mAccessKeyForwardedToChild is set, then don't resend the key event yet
    1919             :   // as RecvHandleAccessKey will do this.
    1920           0 :   if (localEvent.WantReplyFromContentProcess()) {
    1921           0 :     SendReplyKeyEvent(localEvent);
    1922             :   }
    1923             : 
    1924           0 :   if (localEvent.mAccessKeyForwardedToChild) {
    1925           0 :     SendAccessKeyNotHandled(localEvent);
    1926             :   }
    1927             : 
    1928           0 :   return IPC_OK();
    1929             : }
    1930             : 
    1931             : mozilla::ipc::IPCResult
    1932           0 : TabChild::RecvKeyEvent(const nsString& aType,
    1933             :                        const int32_t& aKeyCode,
    1934             :                        const int32_t& aCharCode,
    1935             :                        const int32_t& aModifiers,
    1936             :                        const bool& aPreventDefault)
    1937             : {
    1938           0 :   bool ignored = false;
    1939           0 :   nsContentUtils::SendKeyEvent(mPuppetWidget, aType, aKeyCode, aCharCode,
    1940           0 :                                aModifiers, aPreventDefault, &ignored);
    1941           0 :   return IPC_OK();
    1942             : }
    1943             : 
    1944             : mozilla::ipc::IPCResult
    1945           0 : TabChild::RecvCompositionEvent(const WidgetCompositionEvent& aEvent)
    1946             : {
    1947           0 :   WidgetCompositionEvent localEvent(aEvent);
    1948           0 :   localEvent.mWidget = mPuppetWidget;
    1949           0 :   APZCCallbackHelper::DispatchWidgetEvent(localEvent);
    1950           0 :   Unused << SendOnEventNeedingAckHandled(aEvent.mMessage);
    1951           0 :   return IPC_OK();
    1952             : }
    1953             : 
    1954             : mozilla::ipc::IPCResult
    1955           0 : TabChild::RecvSelectionEvent(const WidgetSelectionEvent& aEvent)
    1956             : {
    1957           0 :   WidgetSelectionEvent localEvent(aEvent);
    1958           0 :   localEvent.mWidget = mPuppetWidget;
    1959           0 :   APZCCallbackHelper::DispatchWidgetEvent(localEvent);
    1960           0 :   Unused << SendOnEventNeedingAckHandled(aEvent.mMessage);
    1961           0 :   return IPC_OK();
    1962             : }
    1963             : 
    1964             : mozilla::ipc::IPCResult
    1965           0 : TabChild::RecvPasteTransferable(const IPCDataTransfer& aDataTransfer,
    1966             :                                 const bool& aIsPrivateData,
    1967             :                                 const IPC::Principal& aRequestingPrincipal)
    1968             : {
    1969             :   nsresult rv;
    1970             :   nsCOMPtr<nsITransferable> trans =
    1971           0 :     do_CreateInstance("@mozilla.org/widget/transferable;1", &rv);
    1972           0 :   NS_ENSURE_SUCCESS(rv, IPC_OK());
    1973           0 :   trans->Init(nullptr);
    1974             : 
    1975           0 :   rv = nsContentUtils::IPCTransferableToTransferable(aDataTransfer,
    1976             :                                                      aIsPrivateData,
    1977             :                                                      aRequestingPrincipal,
    1978             :                                                      trans, nullptr, this);
    1979           0 :   NS_ENSURE_SUCCESS(rv, IPC_OK());
    1980             : 
    1981           0 :   nsCOMPtr<nsIDocShell> ourDocShell = do_GetInterface(WebNavigation());
    1982           0 :   if (NS_WARN_IF(!ourDocShell)) {
    1983           0 :     return IPC_OK();
    1984             :   }
    1985             : 
    1986             :   nsCOMPtr<nsICommandParams> params =
    1987           0 :     do_CreateInstance("@mozilla.org/embedcomp/command-params;1", &rv);
    1988           0 :   NS_ENSURE_SUCCESS(rv, IPC_OK());
    1989             : 
    1990           0 :   rv = params->SetISupportsValue("transferable", trans);
    1991           0 :   NS_ENSURE_SUCCESS(rv, IPC_OK());
    1992             : 
    1993           0 :   ourDocShell->DoCommandWithParams("cmd_pasteTransferable", params);
    1994           0 :   return IPC_OK();
    1995             : }
    1996             : 
    1997             : 
    1998             : a11y::PDocAccessibleChild*
    1999           0 : TabChild::AllocPDocAccessibleChild(PDocAccessibleChild*, const uint64_t&,
    2000             :                                    const uint32_t&, const IAccessibleHolder&)
    2001             : {
    2002           0 :   MOZ_ASSERT(false, "should never call this!");
    2003             :   return nullptr;
    2004             : }
    2005             : 
    2006             : bool
    2007           0 : TabChild::DeallocPDocAccessibleChild(a11y::PDocAccessibleChild* aChild)
    2008             : {
    2009             : #ifdef ACCESSIBILITY
    2010           0 :   delete static_cast<mozilla::a11y::DocAccessibleChild*>(aChild);
    2011             : #endif
    2012           0 :   return true;
    2013             : }
    2014             : 
    2015             : PDocumentRendererChild*
    2016           0 : TabChild::AllocPDocumentRendererChild(const nsRect& documentRect,
    2017             :                                       const mozilla::gfx::Matrix& transform,
    2018             :                                       const nsString& bgcolor,
    2019             :                                       const uint32_t& renderFlags,
    2020             :                                       const bool& flushLayout,
    2021             :                                       const nsIntSize& renderSize)
    2022             : {
    2023           0 :     return new DocumentRendererChild();
    2024             : }
    2025             : 
    2026             : bool
    2027           0 : TabChild::DeallocPDocumentRendererChild(PDocumentRendererChild* actor)
    2028             : {
    2029           0 :     delete actor;
    2030           0 :     return true;
    2031             : }
    2032             : 
    2033             : mozilla::ipc::IPCResult
    2034           0 : TabChild::RecvPDocumentRendererConstructor(PDocumentRendererChild* actor,
    2035             :                                            const nsRect& documentRect,
    2036             :                                            const mozilla::gfx::Matrix& transform,
    2037             :                                            const nsString& bgcolor,
    2038             :                                            const uint32_t& renderFlags,
    2039             :                                            const bool& flushLayout,
    2040             :                                            const nsIntSize& renderSize)
    2041             : {
    2042           0 :     DocumentRendererChild *render = static_cast<DocumentRendererChild *>(actor);
    2043             : 
    2044           0 :     nsCOMPtr<nsIWebBrowser> browser = do_QueryInterface(WebNavigation());
    2045           0 :     if (!browser)
    2046           0 :         return IPC_OK(); // silently ignore
    2047           0 :     nsCOMPtr<mozIDOMWindowProxy> window;
    2048           0 :     if (NS_FAILED(browser->GetContentDOMWindow(getter_AddRefs(window))) ||
    2049           0 :         !window)
    2050             :     {
    2051           0 :         return IPC_OK(); // silently ignore
    2052             :     }
    2053             : 
    2054           0 :     nsCString data;
    2055           0 :     bool ret = render->RenderDocument(nsPIDOMWindowOuter::From(window),
    2056             :                                       documentRect, transform,
    2057             :                                       bgcolor,
    2058           0 :                                       renderFlags, flushLayout,
    2059           0 :                                       renderSize, data);
    2060           0 :     if (!ret)
    2061           0 :         return IPC_OK(); // silently ignore
    2062             : 
    2063           0 :     if (!PDocumentRendererChild::Send__delete__(actor, renderSize, data)) {
    2064           0 :       return IPC_FAIL_NO_REASON(this);
    2065             :     }
    2066           0 :     return IPC_OK();
    2067             : }
    2068             : 
    2069             : PColorPickerChild*
    2070           0 : TabChild::AllocPColorPickerChild(const nsString&, const nsString&)
    2071             : {
    2072           0 :   MOZ_CRASH("unused");
    2073             :   return nullptr;
    2074             : }
    2075             : 
    2076             : bool
    2077           0 : TabChild::DeallocPColorPickerChild(PColorPickerChild* aColorPicker)
    2078             : {
    2079           0 :   nsColorPickerProxy* picker = static_cast<nsColorPickerProxy*>(aColorPicker);
    2080           0 :   NS_RELEASE(picker);
    2081           0 :   return true;
    2082             : }
    2083             : 
    2084             : PFilePickerChild*
    2085           0 : TabChild::AllocPFilePickerChild(const nsString&, const int16_t&)
    2086             : {
    2087           0 :   MOZ_CRASH("unused");
    2088             :   return nullptr;
    2089             : }
    2090             : 
    2091             : bool
    2092           0 : TabChild::DeallocPFilePickerChild(PFilePickerChild* actor)
    2093             : {
    2094           0 :   nsFilePickerProxy* filePicker = static_cast<nsFilePickerProxy*>(actor);
    2095           0 :   NS_RELEASE(filePicker);
    2096           0 :   return true;
    2097             : }
    2098             : 
    2099             : auto
    2100           0 : TabChild::AllocPIndexedDBPermissionRequestChild(const Principal& aPrincipal)
    2101             :   -> PIndexedDBPermissionRequestChild*
    2102             : {
    2103           0 :   MOZ_CRASH("PIndexedDBPermissionRequestChild actors should always be created "
    2104             :             "manually!");
    2105             : }
    2106             : 
    2107             : bool
    2108           0 : TabChild::DeallocPIndexedDBPermissionRequestChild(
    2109             :                                        PIndexedDBPermissionRequestChild* aActor)
    2110             : {
    2111           0 :   MOZ_ASSERT(aActor);
    2112           0 :   delete aActor;
    2113           0 :   return true;
    2114             : }
    2115             : 
    2116             : mozilla::ipc::IPCResult
    2117           0 : TabChild::RecvActivateFrameEvent(const nsString& aType, const bool& capture)
    2118             : {
    2119           0 :   nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
    2120           0 :   NS_ENSURE_TRUE(window, IPC_OK());
    2121             :   nsCOMPtr<EventTarget> chromeHandler =
    2122           0 :     do_QueryInterface(window->GetChromeEventHandler());
    2123           0 :   NS_ENSURE_TRUE(chromeHandler, IPC_OK());
    2124           0 :   RefPtr<ContentListener> listener = new ContentListener(this);
    2125           0 :   chromeHandler->AddEventListener(aType, listener, capture);
    2126           0 :   return IPC_OK();
    2127             : }
    2128             : 
    2129             : mozilla::ipc::IPCResult
    2130          12 : TabChild::RecvLoadRemoteScript(const nsString& aURL, const bool& aRunInGlobalScope)
    2131             : {
    2132          12 :   if (!mGlobal && !InitTabChildGlobal())
    2133             :     // This can happen if we're half-destroyed.  It's not a fatal
    2134             :     // error.
    2135           0 :     return IPC_OK();
    2136             : 
    2137          12 :   LoadScriptInternal(aURL, aRunInGlobalScope);
    2138          12 :   return IPC_OK();
    2139             : }
    2140             : 
    2141             : mozilla::ipc::IPCResult
    2142           8 : TabChild::RecvAsyncMessage(const nsString& aMessage,
    2143             :                            InfallibleTArray<CpowEntry>&& aCpows,
    2144             :                            const IPC::Principal& aPrincipal,
    2145             :                            const ClonedMessageData& aData)
    2146             : {
    2147          16 :   NS_LossyConvertUTF16toASCII messageNameCStr(aMessage);
    2148          16 :   AUTO_PROFILER_LABEL_DYNAMIC("TabChild::RecvAsyncMessage", EVENTS,
    2149             :                               messageNameCStr.get());
    2150             : 
    2151          16 :   CrossProcessCpowHolder cpows(Manager(), aCpows);
    2152           8 :   if (!mTabChildGlobal) {
    2153           0 :     return IPC_OK();
    2154             :   }
    2155             : 
    2156             :   // We should have a message manager if the global is alive, but it
    2157             :   // seems sometimes we don't.  Assert in aurora/nightly, but don't
    2158             :   // crash in release builds.
    2159           8 :   MOZ_DIAGNOSTIC_ASSERT(mTabChildGlobal->mMessageManager);
    2160           8 :   if (!mTabChildGlobal->mMessageManager) {
    2161           0 :     return IPC_OK();
    2162             :   }
    2163             : 
    2164          16 :   JS::Rooted<JSObject*> kungFuDeathGrip(dom::RootingCx(), GetGlobal());
    2165          16 :   StructuredCloneData data;
    2166           8 :   UnpackClonedMessageDataForChild(aData, data);
    2167             :   RefPtr<nsFrameMessageManager> mm =
    2168          16 :     static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get());
    2169           8 :   mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal), nullptr,
    2170           8 :                      aMessage, false, &data, &cpows, aPrincipal, nullptr);
    2171           8 :   return IPC_OK();
    2172             : }
    2173             : 
    2174             : mozilla::ipc::IPCResult
    2175           0 : TabChild::RecvSwappedWithOtherRemoteLoader(const IPCTabContext& aContext)
    2176             : {
    2177           0 :   nsCOMPtr<nsIDocShell> ourDocShell = do_GetInterface(WebNavigation());
    2178           0 :   if (NS_WARN_IF(!ourDocShell)) {
    2179           0 :     return IPC_OK();
    2180             :   }
    2181             : 
    2182           0 :   nsCOMPtr<nsPIDOMWindowOuter> ourWindow = ourDocShell->GetWindow();
    2183           0 :   if (NS_WARN_IF(!ourWindow)) {
    2184           0 :     return IPC_OK();
    2185             :   }
    2186             : 
    2187           0 :   RefPtr<nsDocShell> docShell = static_cast<nsDocShell*>(ourDocShell.get());
    2188             : 
    2189           0 :   nsCOMPtr<EventTarget> ourEventTarget = ourWindow->GetParentTarget();
    2190             : 
    2191           0 :   docShell->SetInFrameSwap(true);
    2192             : 
    2193           0 :   nsContentUtils::FirePageShowEvent(ourDocShell, ourEventTarget, false);
    2194           0 :   nsContentUtils::FirePageHideEvent(ourDocShell, ourEventTarget);
    2195             : 
    2196             :   // Owner content type may have changed, so store the possibly updated context
    2197             :   // and notify others.
    2198           0 :   MaybeInvalidTabContext maybeContext(aContext);
    2199           0 :   if (!maybeContext.IsValid()) {
    2200           0 :     NS_ERROR(nsPrintfCString("Received an invalid TabContext from "
    2201             :                              "the parent process. (%s)",
    2202             :                              maybeContext.GetInvalidReason()).get());
    2203           0 :     MOZ_CRASH("Invalid TabContext received from the parent process.");
    2204             :   }
    2205             : 
    2206           0 :   if (!UpdateTabContextAfterSwap(maybeContext.GetTabContext())) {
    2207           0 :     MOZ_CRASH("Update to TabContext after swap was denied.");
    2208             :   }
    2209             : 
    2210             :   // Since mIsMozBrowserElement may change in UpdateTabContextAfterSwap, so we
    2211             :   // call UpdateFrameType here to make sure the frameType on the docshell is
    2212             :   // correct.
    2213           0 :   UpdateFrameType();
    2214             : 
    2215             :   // Ignore previous value of mTriedBrowserInit since owner content has changed.
    2216           0 :   mTriedBrowserInit = true;
    2217             :   // Initialize the child side of the browser element machinery, if appropriate.
    2218           0 :   if (IsMozBrowser()) {
    2219           0 :     RecvLoadRemoteScript(BROWSER_ELEMENT_CHILD_SCRIPT, true);
    2220             :   }
    2221             : 
    2222           0 :   nsContentUtils::FirePageShowEvent(ourDocShell, ourEventTarget, true);
    2223             : 
    2224           0 :   docShell->SetInFrameSwap(false);
    2225             : 
    2226           0 :   return IPC_OK();
    2227             : }
    2228             : 
    2229             : mozilla::ipc::IPCResult
    2230           0 : TabChild::RecvHandleAccessKey(const WidgetKeyboardEvent& aEvent,
    2231             :                               nsTArray<uint32_t>&& aCharCodes,
    2232             :                               const int32_t& aModifierMask)
    2233             : {
    2234           0 :   nsCOMPtr<nsIDocument> document(GetDocument());
    2235           0 :   nsCOMPtr<nsIPresShell> presShell = document->GetShell();
    2236           0 :   if (presShell) {
    2237           0 :     nsPresContext* pc = presShell->GetPresContext();
    2238           0 :     if (pc) {
    2239           0 :       if (!pc->EventStateManager()->
    2240           0 :                  HandleAccessKey(&(const_cast<WidgetKeyboardEvent&>(aEvent)),
    2241             :                                  pc, aCharCodes,
    2242             :                                  aModifierMask, true)) {
    2243             :         // If no accesskey was found, inform the parent so that accesskeys on
    2244             :         // menus can be handled.
    2245           0 :         WidgetKeyboardEvent localEvent(aEvent);
    2246           0 :         localEvent.mWidget = mPuppetWidget;
    2247           0 :         SendAccessKeyNotHandled(localEvent);
    2248             :       }
    2249             :     }
    2250             :   }
    2251             : 
    2252           0 :   return IPC_OK();
    2253             : }
    2254             : 
    2255             : mozilla::ipc::IPCResult
    2256           1 : TabChild::RecvSetUseGlobalHistory(const bool& aUse)
    2257             : {
    2258           2 :   nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
    2259           1 :   MOZ_ASSERT(docShell);
    2260             : 
    2261           1 :   nsresult rv = docShell->SetUseGlobalHistory(aUse);
    2262           1 :   if (NS_FAILED(rv)) {
    2263           0 :     NS_WARNING("Failed to set UseGlobalHistory on TabChild docShell");
    2264             :   }
    2265             : 
    2266           2 :   return IPC_OK();
    2267             : }
    2268             : 
    2269             : mozilla::ipc::IPCResult
    2270           0 : TabChild::RecvPrint(const uint64_t& aOuterWindowID, const PrintData& aPrintData)
    2271             : {
    2272             : #ifdef NS_PRINTING
    2273             :   nsGlobalWindow* outerWindow =
    2274           0 :     nsGlobalWindow::GetOuterWindowWithId(aOuterWindowID);
    2275           0 :   if (NS_WARN_IF(!outerWindow)) {
    2276           0 :     return IPC_OK();
    2277             :   }
    2278             : 
    2279             :   nsCOMPtr<nsIWebBrowserPrint> webBrowserPrint =
    2280           0 :     do_GetInterface(outerWindow->AsOuter());
    2281           0 :   if (NS_WARN_IF(!webBrowserPrint)) {
    2282           0 :     return IPC_OK();
    2283             :   }
    2284             : 
    2285             :   nsCOMPtr<nsIPrintSettingsService> printSettingsSvc =
    2286           0 :     do_GetService("@mozilla.org/gfx/printsettings-service;1");
    2287           0 :   if (NS_WARN_IF(!printSettingsSvc)) {
    2288           0 :     return IPC_OK();
    2289             :   }
    2290             : 
    2291           0 :   nsCOMPtr<nsIPrintSettings> printSettings;
    2292             :   nsresult rv =
    2293           0 :     printSettingsSvc->GetNewPrintSettings(getter_AddRefs(printSettings));
    2294           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    2295           0 :     return IPC_OK();
    2296             :   }
    2297             : 
    2298             :   nsCOMPtr<nsIPrintSession>  printSession =
    2299           0 :     do_CreateInstance("@mozilla.org/gfx/printsession;1", &rv);
    2300           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    2301           0 :     return IPC_OK();
    2302             :   }
    2303             : 
    2304           0 :   printSettings->SetPrintSession(printSession);
    2305           0 :   printSettingsSvc->DeserializeToPrintSettings(aPrintData, printSettings);
    2306           0 :   rv = webBrowserPrint->Print(printSettings, nullptr);
    2307           0 :   if (NS_WARN_IF(NS_FAILED(rv))) {
    2308           0 :     return IPC_OK();
    2309             :   }
    2310             : 
    2311             : #endif
    2312           0 :   return IPC_OK();
    2313             : }
    2314             : 
    2315             : mozilla::ipc::IPCResult
    2316           0 : TabChild::RecvUpdateNativeWindowHandle(const uintptr_t& aNewHandle)
    2317             : {
    2318             : #if defined(XP_WIN) && defined(ACCESSIBILITY)
    2319             :   mNativeWindowHandle = aNewHandle;
    2320             :   return IPC_OK();
    2321             : #else
    2322           0 :   return IPC_FAIL_NO_REASON(this);
    2323             : #endif
    2324             : }
    2325             : 
    2326             : mozilla::ipc::IPCResult
    2327           0 : TabChild::RecvDestroy()
    2328             : {
    2329           0 :   MOZ_ASSERT(mDestroyed == false);
    2330           0 :   mDestroyed = true;
    2331             : 
    2332             :   nsTArray<PContentPermissionRequestChild*> childArray =
    2333           0 :       nsContentPermissionUtils::GetContentPermissionRequestChildById(GetTabId());
    2334             : 
    2335             :   // Need to close undeleted ContentPermissionRequestChilds before tab is closed.
    2336           0 :   for (auto& permissionRequestChild : childArray) {
    2337           0 :       auto child = static_cast<RemotePermissionRequest*>(permissionRequestChild);
    2338           0 :       child->Destroy();
    2339             :   }
    2340             : 
    2341           0 :   while (mActiveSuppressDisplayport > 0) {
    2342           0 :     APZCCallbackHelper::SuppressDisplayport(false, nullptr);
    2343           0 :     mActiveSuppressDisplayport--;
    2344             :   }
    2345             : 
    2346           0 :   if (mTabChildGlobal) {
    2347             :     // Message handlers are called from the event loop, so it better be safe to
    2348             :     // run script.
    2349           0 :     MOZ_ASSERT(nsContentUtils::IsSafeToRunScript());
    2350           0 :     mTabChildGlobal->DispatchTrustedEvent(NS_LITERAL_STRING("unload"));
    2351             :   }
    2352             : 
    2353             :   nsCOMPtr<nsIObserverService> observerService =
    2354           0 :     mozilla::services::GetObserverService();
    2355             : 
    2356           0 :   observerService->RemoveObserver(this, BEFORE_FIRST_PAINT);
    2357             : 
    2358             :   // XXX what other code in ~TabChild() should we be running here?
    2359           0 :   DestroyWindow();
    2360             : 
    2361             :   // Bounce through the event loop once to allow any delayed teardown runnables
    2362             :   // that were just generated to have a chance to run.
    2363           0 :   nsCOMPtr<nsIRunnable> deleteRunnable = new DelayedDeleteRunnable(this);
    2364           0 :   MOZ_ALWAYS_SUCCEEDS(NS_DispatchToCurrentThread(deleteRunnable));
    2365             : 
    2366           0 :   return IPC_OK();
    2367             : }
    2368             : 
    2369             : void
    2370           0 : TabChild::AddPendingDocShellBlocker()
    2371             : {
    2372           0 :   mPendingDocShellBlockers++;
    2373           0 : }
    2374             : 
    2375             : void
    2376           0 : TabChild::RemovePendingDocShellBlocker()
    2377             : {
    2378           0 :   mPendingDocShellBlockers--;
    2379           0 :   if (!mPendingDocShellBlockers && mPendingDocShellReceivedMessage) {
    2380           0 :     mPendingDocShellReceivedMessage = false;
    2381           0 :     InternalSetDocShellIsActive(mPendingDocShellIsActive,
    2382           0 :                                 mPendingDocShellPreserveLayers);
    2383             :   }
    2384           0 : }
    2385             : 
    2386             : void
    2387           2 : TabChild::InternalSetDocShellIsActive(bool aIsActive, bool aPreserveLayers)
    2388             : {
    2389           2 :   auto clearForcePaint = MakeScopeExit([&] {
    2390             :     // We might force a paint, or we might already have painted and this is a
    2391             :     // no-op. In either case, once we exit this scope, we need to alert the
    2392             :     // ProcessHangMonitor that we've finished responding to what might have
    2393             :     // been a request to force paint. This is so that the BackgroundHangMonitor
    2394             :     // for force painting can be made to wait again.
    2395           2 :     if (aIsActive) {
    2396           2 :       ProcessHangMonitor::ClearForcePaint();
    2397             :     }
    2398           4 :   });
    2399             : 
    2400           2 :   if (mCompositorOptions) {
    2401             :     // Note that |GetLayerManager()| has side-effects in that it creates a layer
    2402             :     // manager if one doesn't exist already. Calling it inside a debug-only
    2403             :     // assertion is generally bad but in this case we call it unconditionally
    2404             :     // just below so it's ok.
    2405           2 :     MOZ_ASSERT(mPuppetWidget);
    2406           2 :     MOZ_ASSERT(mPuppetWidget->GetLayerManager());
    2407           2 :     MOZ_ASSERT(mPuppetWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT
    2408             :             || mPuppetWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_WR
    2409             :             || (gfxPlatform::IsHeadless() && mPuppetWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_BASIC));
    2410             : 
    2411             :     // We send the current layer observer epoch to the compositor so that
    2412             :     // TabParent knows whether a layer update notification corresponds to the
    2413             :     // latest SetDocShellIsActive request that was made.
    2414           2 :     mPuppetWidget->GetLayerManager()->SetLayerObserverEpoch(mLayerObserverEpoch);
    2415             :   }
    2416             : 
    2417             :   // docshell is consider prerendered only if not active yet
    2418           2 :   mIsPrerendered &= !aIsActive;
    2419           2 :   nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
    2420           2 :   if (docShell) {
    2421             :     bool wasActive;
    2422           2 :     docShell->GetIsActive(&wasActive);
    2423           2 :     if (aIsActive && wasActive) {
    2424             :       // This request is a no-op. In this case, we still want a MozLayerTreeReady
    2425             :       // notification to fire in the parent (so that it knows that the child has
    2426             :       // updated its epoch). ForcePaintNoOp does that.
    2427           2 :       if (IPCOpen()) {
    2428           2 :         Unused << SendForcePaintNoOp(mLayerObserverEpoch);
    2429           2 :         return;
    2430             :       }
    2431             :     }
    2432             : 
    2433           0 :     docShell->SetIsActive(aIsActive);
    2434             :   }
    2435             : 
    2436           0 :   if (aIsActive) {
    2437           0 :     MakeVisible();
    2438             : 
    2439             :     // We don't use TabChildBase::GetPresShell() here because that would create
    2440             :     // a content viewer if one doesn't exist yet. Creating a content viewer can
    2441             :     // cause JS to run, which we want to avoid. nsIDocShell::GetPresShell
    2442             :     // returns null if no content viewer exists yet.
    2443           0 :     if (nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell()) {
    2444           0 :       if (nsIFrame* root = presShell->FrameConstructor()->GetRootFrame()) {
    2445           0 :         FrameLayerBuilder::InvalidateAllLayersForFrame(
    2446           0 :           nsLayoutUtils::GetDisplayRootFrame(root));
    2447           0 :         root->SchedulePaint();
    2448             :       }
    2449             : 
    2450           0 :       Telemetry::AutoTimer<Telemetry::TABCHILD_PAINT_TIME> timer;
    2451             :       // If we need to repaint, let's do that right away. No sense waiting until
    2452             :       // we get back to the event loop again. We suppress the display port so that
    2453             :       // we only paint what's visible. This ensures that the tab we're switching
    2454             :       // to paints as quickly as possible.
    2455           0 :       APZCCallbackHelper::SuppressDisplayport(true, presShell);
    2456           0 :       if (nsContentUtils::IsSafeToRunScript()) {
    2457           0 :         WebWidget()->PaintNowIfNeeded();
    2458             :       } else {
    2459           0 :         RefPtr<nsViewManager> vm = presShell->GetViewManager();
    2460           0 :         if (nsView* view = vm->GetRootView()) {
    2461           0 :           presShell->Paint(view, view->GetBounds(),
    2462           0 :                            nsIPresShell::PAINT_LAYERS);
    2463             :         }
    2464             :       }
    2465           0 :       APZCCallbackHelper::SuppressDisplayport(false, presShell);
    2466             :     }
    2467           0 :   } else if (!aPreserveLayers) {
    2468           0 :     MakeHidden();
    2469             :   }
    2470             : }
    2471             : 
    2472             : mozilla::ipc::IPCResult
    2473           2 : TabChild::RecvSetDocShellIsActive(const bool& aIsActive,
    2474             :                                   const bool& aPreserveLayers,
    2475             :                                   const uint64_t& aLayerObserverEpoch)
    2476             : {
    2477             :   // Since requests to change the active docshell come in from both the hang
    2478             :   // monitor channel and the PContent channel, we have an ordering problem. This
    2479             :   // code ensures that we respect the order in which the requests were made and
    2480             :   // ignore stale requests.
    2481           2 :   if (mLayerObserverEpoch >= aLayerObserverEpoch) {
    2482           0 :     return IPC_OK();
    2483             :   }
    2484           2 :   mLayerObserverEpoch = aLayerObserverEpoch;
    2485             : 
    2486             :   // If we're currently waiting for window opening to complete, we need to hold
    2487             :   // off on setting the docshell active. We queue up the values we're receiving
    2488             :   // in the mWindowOpenDocShellActiveStatus.
    2489           2 :   if (mPendingDocShellBlockers > 0) {
    2490           0 :     mPendingDocShellReceivedMessage = true;
    2491           0 :     mPendingDocShellIsActive = aIsActive;
    2492           0 :     mPendingDocShellPreserveLayers = aPreserveLayers;
    2493           0 :     return IPC_OK();
    2494             :   }
    2495             : 
    2496           2 :   InternalSetDocShellIsActive(aIsActive, aPreserveLayers);
    2497           2 :   return IPC_OK();
    2498             : }
    2499             : 
    2500             : mozilla::ipc::IPCResult
    2501           0 : TabChild::RecvNavigateByKey(const bool& aForward, const bool& aForDocumentNavigation)
    2502             : {
    2503           0 :   nsIFocusManager* fm = nsFocusManager::GetFocusManager();
    2504           0 :   if (fm) {
    2505           0 :     nsCOMPtr<nsIDOMElement> result;
    2506           0 :     nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
    2507             : 
    2508             :     // Move to the first or last document.
    2509           0 :     uint32_t type = aForward ?
    2510           0 :       (aForDocumentNavigation ? static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_FIRSTDOC) :
    2511             :                                 static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_ROOT)) :
    2512           0 :       (aForDocumentNavigation ? static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_LASTDOC) :
    2513           0 :                                 static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_LAST));
    2514           0 :     fm->MoveFocus(window, nullptr, type,
    2515           0 :                   nsIFocusManager::FLAG_BYKEY, getter_AddRefs(result));
    2516             : 
    2517             :     // No valid root element was found, so move to the first focusable element.
    2518           0 :     if (!result && aForward && !aForDocumentNavigation) {
    2519           0 :       fm->MoveFocus(window, nullptr, nsIFocusManager::MOVEFOCUS_FIRST,
    2520           0 :                   nsIFocusManager::FLAG_BYKEY, getter_AddRefs(result));
    2521             :     }
    2522             : 
    2523           0 :     SendRequestFocus(false);
    2524             :   }
    2525             : 
    2526           0 :   return IPC_OK();
    2527             : }
    2528             : 
    2529             : mozilla::ipc::IPCResult
    2530           0 : TabChild::RecvHandledWindowedPluginKeyEvent(
    2531             :             const NativeEventData& aKeyEventData,
    2532             :             const bool& aIsConsumed)
    2533             : {
    2534           0 :   if (NS_WARN_IF(!mPuppetWidget)) {
    2535           0 :     return IPC_OK();
    2536             :   }
    2537           0 :   mPuppetWidget->HandledWindowedPluginKeyEvent(aKeyEventData, aIsConsumed);
    2538           0 :   return IPC_OK();
    2539             : }
    2540             : 
    2541             : PRenderFrameChild*
    2542           1 : TabChild::AllocPRenderFrameChild()
    2543             : {
    2544           1 :     return new RenderFrameChild();
    2545             : }
    2546             : 
    2547             : bool
    2548           0 : TabChild::DeallocPRenderFrameChild(PRenderFrameChild* aFrame)
    2549             : {
    2550           0 :     delete aFrame;
    2551           0 :     return true;
    2552             : }
    2553             : 
    2554             : bool
    2555           3 : TabChild::InitTabChildGlobal()
    2556             : {
    2557           3 :   if (!mGlobal && !mTabChildGlobal) {
    2558           2 :     nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(WebNavigation());
    2559           1 :     NS_ENSURE_TRUE(window, false);
    2560             :     nsCOMPtr<EventTarget> chromeHandler =
    2561           2 :       do_QueryInterface(window->GetChromeEventHandler());
    2562           1 :     NS_ENSURE_TRUE(chromeHandler, false);
    2563             : 
    2564           2 :     RefPtr<TabChildGlobal> scope = new TabChildGlobal(this);
    2565             : 
    2566           1 :     nsISupports* scopeSupports = NS_ISUPPORTS_CAST(EventTarget*, scope);
    2567             : 
    2568           1 :     NS_NAMED_LITERAL_CSTRING(globalId, "outOfProcessTabChildGlobal");
    2569           1 :     NS_ENSURE_TRUE(InitChildGlobalInternal(scopeSupports, globalId), false);
    2570             : 
    2571           1 :     scope->Init();
    2572             : 
    2573           2 :     nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(chromeHandler);
    2574           1 :     NS_ENSURE_TRUE(root, false);
    2575           1 :     root->SetParentTarget(scope);
    2576             : 
    2577           1 :     mTabChildGlobal = scope.forget();;
    2578             :   }
    2579             : 
    2580           3 :   if (!mTriedBrowserInit) {
    2581           1 :     mTriedBrowserInit = true;
    2582             :     // Initialize the child side of the browser element machinery,
    2583             :     // if appropriate.
    2584           1 :     if (IsMozBrowser()) {
    2585           0 :       RecvLoadRemoteScript(BROWSER_ELEMENT_CHILD_SCRIPT, true);
    2586             :     }
    2587             :   }
    2588             : 
    2589           3 :   return true;
    2590             : }
    2591             : 
    2592             : void
    2593           1 : TabChild::InitRenderingState(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
    2594             :                              const uint64_t& aLayersId,
    2595             :                              const CompositorOptions& aCompositorOptions,
    2596             :                              PRenderFrameChild* aRenderFrame)
    2597             : {
    2598           1 :     mPuppetWidget->InitIMEState();
    2599             : 
    2600           1 :     if (!aRenderFrame) {
    2601           0 :       NS_WARNING("failed to construct RenderFrame");
    2602           0 :       return;
    2603             :     }
    2604             : 
    2605           1 :     MOZ_ASSERT(aLayersId != 0);
    2606           1 :     mTextureFactoryIdentifier = aTextureFactoryIdentifier;
    2607             : 
    2608             :     // Pushing layers transactions directly to a separate
    2609             :     // compositor context.
    2610           1 :     PCompositorBridgeChild* compositorChild = CompositorBridgeChild::Get();
    2611           1 :     if (!compositorChild) {
    2612           0 :       NS_WARNING("failed to get CompositorBridgeChild instance");
    2613           0 :       return;
    2614             :     }
    2615             : 
    2616           1 :     mCompositorOptions = Some(aCompositorOptions);
    2617             : 
    2618           1 :     mRemoteFrame = static_cast<RenderFrameChild*>(aRenderFrame);
    2619           1 :     if (aLayersId != 0) {
    2620           2 :       StaticMutexAutoLock lock(sTabChildrenMutex);
    2621             : 
    2622           1 :       if (!sTabChildren) {
    2623           1 :         sTabChildren = new TabChildMap;
    2624             :       }
    2625           1 :       MOZ_ASSERT(!sTabChildren->Get(aLayersId));
    2626           1 :       sTabChildren->Put(aLayersId, this);
    2627           1 :       mLayersId = aLayersId;
    2628             :     }
    2629             : 
    2630             :     ShadowLayerForwarder* lf =
    2631           2 :         mPuppetWidget->GetLayerManager(
    2632           1 :             nullptr, mTextureFactoryIdentifier.mParentBackend)
    2633           1 :                 ->AsShadowForwarder();
    2634             : 
    2635           1 :     LayerManager* lm = mPuppetWidget->GetLayerManager();
    2636           1 :     if (lm->AsWebRenderLayerManager()) {
    2637           0 :       lm->AsWebRenderLayerManager()->Initialize(compositorChild,
    2638             :                                                 wr::AsPipelineId(aLayersId),
    2639           0 :                                                 &mTextureFactoryIdentifier);
    2640           0 :       ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
    2641           0 :       gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);
    2642           0 :       InitAPZState();
    2643             :     }
    2644             : 
    2645           1 :     if (lf) {
    2646           2 :       nsTArray<LayersBackend> backends;
    2647           1 :       backends.AppendElement(mTextureFactoryIdentifier.mParentBackend);
    2648             :       PLayerTransactionChild* shadowManager =
    2649           1 :           compositorChild->SendPLayerTransactionConstructor(backends, aLayersId);
    2650           1 :       if (shadowManager) {
    2651           1 :         lf->SetShadowManager(shadowManager);
    2652           1 :         lf->IdentifyTextureHost(mTextureFactoryIdentifier);
    2653           1 :         ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
    2654           1 :         gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);
    2655           1 :         InitAPZState();
    2656             :       }
    2657             :     }
    2658             : 
    2659             :     nsCOMPtr<nsIObserverService> observerService =
    2660           2 :         mozilla::services::GetObserverService();
    2661             : 
    2662           1 :     if (observerService) {
    2663           2 :         observerService->AddObserver(this,
    2664             :                                      BEFORE_FIRST_PAINT,
    2665           2 :                                      false);
    2666             :     }
    2667             : }
    2668             : 
    2669             : void
    2670           1 : TabChild::InitAPZState()
    2671             : {
    2672           1 :   if (!mCompositorOptions->UseAPZ()) {
    2673           0 :     return;
    2674             :   }
    2675           1 :   auto cbc = CompositorBridgeChild::Get();
    2676             : 
    2677             :   // Initialize the ApzcTreeManager. This takes multiple casts because of ugly multiple inheritance.
    2678           1 :   PAPZCTreeManagerChild* baseProtocol = cbc->SendPAPZCTreeManagerConstructor(mLayersId);
    2679           1 :   APZCTreeManagerChild* derivedProtocol = static_cast<APZCTreeManagerChild*>(baseProtocol);
    2680             : 
    2681           1 :   mApzcTreeManager = RefPtr<IAPZCTreeManager>(derivedProtocol);
    2682             : 
    2683             :   // Initialize the GeckoContentController for this tab. We don't hold a reference because we don't need it.
    2684             :   // The ContentProcessController will hold a reference to the tab, and will be destroyed by the compositor or ipdl
    2685             :   // during destruction.
    2686           3 :   RefPtr<GeckoContentController> contentController = new ContentProcessController(this);
    2687           2 :   APZChild* apzChild = new APZChild(contentController);
    2688           1 :   cbc->SetEventTargetForActor(
    2689           2 :     apzChild, TabGroup()->EventTargetFor(TaskCategory::Other));
    2690           1 :   MOZ_ASSERT(apzChild->GetActorEventTarget());
    2691           1 :   cbc->SendPAPZConstructor(apzChild, mLayersId);
    2692             : }
    2693             : 
    2694             : void
    2695           2 : TabChild::GetDPI(float* aDPI)
    2696             : {
    2697           2 :     *aDPI = -1.0;
    2698           2 :     if (!(mDidFakeShow || mDidSetRealShowInfo)) {
    2699           1 :         return;
    2700             :     }
    2701             : 
    2702           1 :     if (mDPI > 0) {
    2703           1 :       *aDPI = mDPI;
    2704           1 :       return;
    2705             :     }
    2706             : 
    2707             :     // Fallback to a sync call if needed.
    2708           0 :     SendGetDPI(aDPI);
    2709             : }
    2710             : 
    2711             : void
    2712           2 : TabChild::GetDefaultScale(double* aScale)
    2713             : {
    2714           2 :     *aScale = -1.0;
    2715           2 :     if (!(mDidFakeShow || mDidSetRealShowInfo)) {
    2716           1 :         return;
    2717             :     }
    2718             : 
    2719           1 :     if (mDefaultScale > 0) {
    2720           1 :       *aScale = mDefaultScale;
    2721           1 :       return;
    2722             :     }
    2723             : 
    2724             :     // Fallback to a sync call if needed.
    2725           0 :     SendGetDefaultScale(aScale);
    2726             : }
    2727             : 
    2728             : void
    2729           0 : TabChild::GetWidgetRounding(int32_t* aRounding)
    2730             : {
    2731           0 :   *aRounding = 1;
    2732           0 :   if (!(mDidFakeShow || mDidSetRealShowInfo)) {
    2733           0 :     return;
    2734             :   }
    2735           0 :   if (mRounding > 0) {
    2736           0 :     *aRounding = mRounding;
    2737           0 :     return;
    2738             :   }
    2739             : 
    2740             :   // Fallback to a sync call if needed.
    2741           0 :   SendGetWidgetRounding(aRounding);
    2742             : }
    2743             : 
    2744             : void
    2745           2 : TabChild::NotifyPainted()
    2746             : {
    2747           2 :     if (!mNotified) {
    2748           1 :         mRemoteFrame->SendNotifyCompositorTransaction();
    2749           1 :         mNotified = true;
    2750             :     }
    2751           2 : }
    2752             : 
    2753             : void
    2754           0 : TabChild::MakeVisible()
    2755             : {
    2756           0 :   if (mPuppetWidget && mPuppetWidget->IsVisible()) {
    2757           0 :     return;
    2758             :   }
    2759             : 
    2760           0 :   if (mPuppetWidget) {
    2761           0 :     mPuppetWidget->Show(true);
    2762             :   }
    2763             : }
    2764             : 
    2765             : void
    2766           0 : TabChild::MakeHidden()
    2767             : {
    2768           0 :   if (mPuppetWidget && !mPuppetWidget->IsVisible()) {
    2769           0 :     return;
    2770             :   }
    2771             : 
    2772           0 :   ClearCachedResources();
    2773             : 
    2774             :   // Hide all plugins in this tab.
    2775           0 :   if (nsCOMPtr<nsIPresShell> shell = GetPresShell()) {
    2776           0 :     if (nsPresContext* presContext = shell->GetPresContext()) {
    2777           0 :       nsRootPresContext* rootPresContext = presContext->GetRootPresContext();
    2778           0 :       nsIFrame* rootFrame = shell->FrameConstructor()->GetRootFrame();
    2779           0 :       rootPresContext->ComputePluginGeometryUpdates(rootFrame, nullptr, nullptr);
    2780           0 :       rootPresContext->ApplyPluginGeometryUpdates();
    2781             :     }
    2782             :   }
    2783             : 
    2784           0 :   if (mPuppetWidget) {
    2785           0 :     mPuppetWidget->Show(false);
    2786             :   }
    2787             : }
    2788             : 
    2789             : NS_IMETHODIMP
    2790           3 : TabChild::GetMessageManager(nsIContentFrameMessageManager** aResult)
    2791             : {
    2792           3 :   if (mTabChildGlobal) {
    2793           3 :     NS_ADDREF(*aResult = mTabChildGlobal);
    2794           3 :     return NS_OK;
    2795             :   }
    2796           0 :   *aResult = nullptr;
    2797           0 :   return NS_ERROR_FAILURE;
    2798             : }
    2799             : 
    2800             : NS_IMETHODIMP
    2801           0 : TabChild::GetWebBrowserChrome(nsIWebBrowserChrome3** aWebBrowserChrome)
    2802             : {
    2803           0 :   NS_IF_ADDREF(*aWebBrowserChrome = mWebBrowserChrome);
    2804           0 :   return NS_OK;
    2805             : }
    2806             : 
    2807             : NS_IMETHODIMP
    2808           1 : TabChild::SetWebBrowserChrome(nsIWebBrowserChrome3* aWebBrowserChrome)
    2809             : {
    2810           1 :   mWebBrowserChrome = aWebBrowserChrome;
    2811           1 :   return NS_OK;
    2812             : }
    2813             : 
    2814             : void
    2815           0 : TabChild::SendRequestFocus(bool aCanFocus)
    2816             : {
    2817           0 :   PBrowserChild::SendRequestFocus(aCanFocus);
    2818           0 : }
    2819             : 
    2820             : void
    2821           0 : TabChild::SendGetTabCount(uint32_t* tabCount)
    2822             : {
    2823           0 :   PBrowserChild::SendGetTabCount(tabCount);
    2824           0 : }
    2825             : 
    2826             : void
    2827           2 : TabChild::EnableDisableCommands(const nsAString& aAction,
    2828             :                                 nsTArray<nsCString>& aEnabledCommands,
    2829             :                                 nsTArray<nsCString>& aDisabledCommands)
    2830             : {
    2831           4 :   PBrowserChild::SendEnableDisableCommands(PromiseFlatString(aAction),
    2832           2 :                                            aEnabledCommands, aDisabledCommands);
    2833           2 : }
    2834             : 
    2835             : NS_IMETHODIMP
    2836           0 : TabChild::GetTabId(uint64_t* aId)
    2837             : {
    2838           0 :   *aId = GetTabId();
    2839           0 :   return NS_OK;
    2840             : }
    2841             : 
    2842             : void
    2843           0 : TabChild::SetTabId(const TabId& aTabId)
    2844             : {
    2845           0 :   MOZ_ASSERT(mUniqueId == 0);
    2846             : 
    2847           0 :   mUniqueId = aTabId;
    2848           0 :   NestedTabChildMap()[mUniqueId] = this;
    2849           0 : }
    2850             : 
    2851             : bool
    2852           0 : TabChild::DoSendBlockingMessage(JSContext* aCx,
    2853             :                                 const nsAString& aMessage,
    2854             :                                 StructuredCloneData& aData,
    2855             :                                 JS::Handle<JSObject *> aCpows,
    2856             :                                 nsIPrincipal* aPrincipal,
    2857             :                                 nsTArray<StructuredCloneData>* aRetVal,
    2858             :                                 bool aIsSync)
    2859             : {
    2860           0 :   ClonedMessageData data;
    2861           0 :   if (!BuildClonedMessageDataForChild(Manager(), aData, data)) {
    2862           0 :     return false;
    2863             :   }
    2864           0 :   InfallibleTArray<CpowEntry> cpows;
    2865           0 :   if (aCpows && !Manager()->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
    2866           0 :     return false;
    2867             :   }
    2868           0 :   if (aIsSync) {
    2869           0 :     return SendSyncMessage(PromiseFlatString(aMessage), data, cpows,
    2870           0 :                            Principal(aPrincipal), aRetVal);
    2871             :   }
    2872             : 
    2873           0 :   return SendRpcMessage(PromiseFlatString(aMessage), data, cpows,
    2874           0 :                         Principal(aPrincipal), aRetVal);
    2875             : }
    2876             : 
    2877             : nsresult
    2878          30 : TabChild::DoSendAsyncMessage(JSContext* aCx,
    2879             :                              const nsAString& aMessage,
    2880             :                              StructuredCloneData& aData,
    2881             :                              JS::Handle<JSObject *> aCpows,
    2882             :                              nsIPrincipal* aPrincipal)
    2883             : {
    2884          60 :   ClonedMessageData data;
    2885          30 :   if (!BuildClonedMessageDataForChild(Manager(), aData, data)) {
    2886           0 :     return NS_ERROR_DOM_DATA_CLONE_ERR;
    2887             :   }
    2888          60 :   InfallibleTArray<CpowEntry> cpows;
    2889          30 :   if (aCpows && !Manager()->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) {
    2890           0 :     return NS_ERROR_UNEXPECTED;
    2891             :   }
    2892          60 :   if (!SendAsyncMessage(PromiseFlatString(aMessage), cpows,
    2893          60 :                         Principal(aPrincipal), data)) {
    2894           0 :     return NS_ERROR_UNEXPECTED;
    2895             :   }
    2896          30 :   return NS_OK;
    2897             : }
    2898             : 
    2899             : /* static */ nsTArray<RefPtr<TabChild>>
    2900           0 : TabChild::GetAll()
    2901             : {
    2902           0 :   StaticMutexAutoLock lock(sTabChildrenMutex);
    2903             : 
    2904           0 :   nsTArray<RefPtr<TabChild>> list;
    2905           0 :   if (!sTabChildren) {
    2906           0 :     return list;
    2907             :   }
    2908             : 
    2909           0 :   for (auto iter = sTabChildren->Iter(); !iter.Done(); iter.Next()) {
    2910           0 :     list.AppendElement(iter.Data());
    2911             :   }
    2912             : 
    2913           0 :   return list;
    2914             : }
    2915             : 
    2916             : TabChild*
    2917           0 : TabChild::GetFrom(nsIPresShell* aPresShell)
    2918             : {
    2919           0 :   nsIDocument* doc = aPresShell->GetDocument();
    2920           0 :   if (!doc) {
    2921           0 :       return nullptr;
    2922             :   }
    2923           0 :   nsCOMPtr<nsIDocShell> docShell(doc->GetDocShell());
    2924           0 :   return GetFrom(docShell);
    2925             : }
    2926             : 
    2927             : TabChild*
    2928          86 : TabChild::GetFrom(uint64_t aLayersId)
    2929             : {
    2930         172 :   StaticMutexAutoLock lock(sTabChildrenMutex);
    2931          86 :   if (!sTabChildren) {
    2932          30 :     return nullptr;
    2933             :   }
    2934          56 :   return sTabChildren->Get(aLayersId);
    2935             : }
    2936             : 
    2937             : void
    2938          27 : TabChild::DidComposite(uint64_t aTransactionId,
    2939             :                        const TimeStamp& aCompositeStart,
    2940             :                        const TimeStamp& aCompositeEnd)
    2941             : {
    2942          27 :   MOZ_ASSERT(mPuppetWidget);
    2943          27 :   MOZ_ASSERT(mPuppetWidget->GetLayerManager());
    2944          27 :   MOZ_ASSERT(mPuppetWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT
    2945             :              || mPuppetWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_WR
    2946             :              || (gfxPlatform::IsHeadless() && mPuppetWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_BASIC));
    2947             : 
    2948          27 :   mPuppetWidget->GetLayerManager()->DidComposite(aTransactionId, aCompositeStart, aCompositeEnd);
    2949          27 : }
    2950             : 
    2951             : void
    2952           4 : TabChild::DidRequestComposite(const TimeStamp& aCompositeReqStart,
    2953             :                               const TimeStamp& aCompositeReqEnd)
    2954             : {
    2955           8 :   nsCOMPtr<nsIDocShell> docShellComPtr = do_GetInterface(WebNavigation());
    2956           4 :   if (!docShellComPtr) {
    2957           0 :     return;
    2958             :   }
    2959             : 
    2960           4 :   nsDocShell* docShell = static_cast<nsDocShell*>(docShellComPtr.get());
    2961           8 :   RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
    2962             : 
    2963           4 :   if (timelines && timelines->HasConsumer(docShell)) {
    2964             :     // Since we're assuming that it's impossible for content JS to directly
    2965             :     // trigger a synchronous paint, we can avoid capturing a stack trace here,
    2966             :     // which means we won't run into JS engine reentrancy issues like bug
    2967             :     // 1310014.
    2968           0 :     timelines->AddMarkerForDocShell(docShell,
    2969             :       "CompositeForwardTransaction", aCompositeReqStart,
    2970           0 :       MarkerTracingType::START, MarkerStackRequest::NO_STACK);
    2971           0 :     timelines->AddMarkerForDocShell(docShell,
    2972             :       "CompositeForwardTransaction", aCompositeReqEnd,
    2973           0 :       MarkerTracingType::END, MarkerStackRequest::NO_STACK);
    2974             :   }
    2975             : }
    2976             : 
    2977             : void
    2978           0 : TabChild::ClearCachedResources()
    2979             : {
    2980           0 :   MOZ_ASSERT(mPuppetWidget);
    2981           0 :   MOZ_ASSERT(mPuppetWidget->GetLayerManager());
    2982           0 :   MOZ_ASSERT(mPuppetWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT
    2983             :              || mPuppetWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_WR
    2984             :              || (gfxPlatform::IsHeadless() && mPuppetWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_BASIC));
    2985             : 
    2986           0 :   mPuppetWidget->GetLayerManager()->ClearCachedResources();
    2987           0 : }
    2988             : 
    2989             : void
    2990           0 : TabChild::InvalidateLayers()
    2991             : {
    2992           0 :   MOZ_ASSERT(mPuppetWidget);
    2993           0 :   MOZ_ASSERT(mPuppetWidget->GetLayerManager());
    2994           0 :   MOZ_ASSERT(mPuppetWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT
    2995             :              || mPuppetWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_WR
    2996             :              || (gfxPlatform::IsHeadless() && mPuppetWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_BASIC));
    2997             : 
    2998           0 :   RefPtr<LayerManager> lm = mPuppetWidget->GetLayerManager();
    2999           0 :   FrameLayerBuilder::InvalidateAllLayers(lm);
    3000           0 : }
    3001             : 
    3002             : void
    3003           0 : TabChild::ReinitRendering()
    3004             : {
    3005           0 :   MOZ_ASSERT(mLayersId);
    3006             : 
    3007             :   // Before we establish a new PLayerTransaction, we must connect our layer tree
    3008             :   // id, CompositorBridge, and the widget compositor all together again.
    3009             :   // Normally this happens in TabParent before TabChild is given rendering
    3010             :   // information.
    3011             :   //
    3012             :   // In this case, we will send a sync message to our TabParent, which in turn
    3013             :   // will send a sync message to the Compositor of the widget owning this tab.
    3014             :   // This guarantees the correct association is in place before our
    3015             :   // PLayerTransaction constructor message arrives on the cross-process
    3016             :   // compositor bridge.
    3017           0 :   CompositorOptions options;
    3018           0 :   SendEnsureLayersConnected(&options);
    3019           0 :   mCompositorOptions = Some(options);
    3020             : 
    3021           0 :   RefPtr<CompositorBridgeChild> cb = CompositorBridgeChild::Get();
    3022           0 :   if (gfxVars::UseWebRender()) {
    3023           0 :     RefPtr<LayerManager> lm = mPuppetWidget->RecreateLayerManager(nullptr);
    3024           0 :     MOZ_ASSERT(lm->AsWebRenderLayerManager());
    3025           0 :     lm->AsWebRenderLayerManager()->Initialize(cb,
    3026             :                                               wr::AsPipelineId(mLayersId),
    3027           0 :                                               &mTextureFactoryIdentifier);
    3028             :   } else {
    3029           0 :     bool success = false;
    3030           0 :     nsTArray<LayersBackend> ignored;
    3031           0 :     PLayerTransactionChild* shadowManager = cb->SendPLayerTransactionConstructor(ignored, LayersId());
    3032           0 :     if (shadowManager &&
    3033           0 :         shadowManager->SendGetTextureFactoryIdentifier(&mTextureFactoryIdentifier) &&
    3034           0 :         mTextureFactoryIdentifier.mParentBackend != LayersBackend::LAYERS_NONE)
    3035             :     {
    3036           0 :       success = true;
    3037             :     }
    3038           0 :     if (!success) {
    3039           0 :       NS_WARNING("failed to re-allocate layer transaction");
    3040           0 :       return;
    3041             :     }
    3042             : 
    3043           0 :     RefPtr<LayerManager> lm = mPuppetWidget->RecreateLayerManager(shadowManager);
    3044           0 :     ShadowLayerForwarder* lf = lm->AsShadowForwarder();
    3045           0 :     lf->IdentifyTextureHost(mTextureFactoryIdentifier);
    3046             :   }
    3047             : 
    3048           0 :   ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier);
    3049           0 :   gfx::VRManagerChild::IdentifyTextureHost(mTextureFactoryIdentifier);
    3050             : 
    3051           0 :   InitAPZState();
    3052             : 
    3053           0 :   nsCOMPtr<nsIDocument> doc(GetDocument());
    3054           0 :   doc->NotifyLayerManagerRecreated();
    3055             : }
    3056             : 
    3057             : void
    3058           0 : TabChild::ReinitRenderingForDeviceReset()
    3059             : {
    3060           0 :   InvalidateLayers();
    3061             : 
    3062           0 :   RefPtr<LayerManager> lm = mPuppetWidget->GetLayerManager();
    3063           0 :   if (WebRenderLayerManager* wlm = lm->AsWebRenderLayerManager()) {
    3064           0 :     wlm->DoDestroy(/* aIsSync */ true);
    3065           0 :   } else if (ClientLayerManager* clm = lm->AsClientLayerManager()) {
    3066           0 :     if (ShadowLayerForwarder* fwd = clm->AsShadowForwarder()) {
    3067             :       // Force the LayerTransactionChild to synchronously shutdown. It is
    3068             :       // okay to do this early, we'll simply stop sending messages. This
    3069             :       // step is necessary since otherwise the compositor will think we
    3070             :       // are trying to attach two layer trees to the same ID.
    3071           0 :       fwd->SynchronouslyShutdown();
    3072             :     }
    3073             :   } else {
    3074           0 :     return;
    3075             :   }
    3076             : 
    3077             :   // Proceed with destroying and recreating the layer manager.
    3078           0 :   ReinitRendering();
    3079             : }
    3080             : 
    3081             : void
    3082           0 : TabChild::CompositorUpdated(const TextureFactoryIdentifier& aNewIdentifier,
    3083             :                             uint64_t aDeviceResetSeqNo)
    3084             : {
    3085           0 :   MOZ_ASSERT(mPuppetWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT
    3086             :              || mPuppetWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_WR
    3087             :              || (gfxPlatform::IsHeadless() && mPuppetWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_BASIC));
    3088             : 
    3089           0 :   RefPtr<LayerManager> lm = mPuppetWidget->GetLayerManager();
    3090             : 
    3091           0 :   mTextureFactoryIdentifier = aNewIdentifier;
    3092           0 :   lm->UpdateTextureFactoryIdentifier(aNewIdentifier, aDeviceResetSeqNo);
    3093           0 :   FrameLayerBuilder::InvalidateAllLayers(lm);
    3094           0 : }
    3095             : 
    3096             : NS_IMETHODIMP
    3097           0 : TabChild::OnShowTooltip(int32_t aXCoords, int32_t aYCoords, const char16_t *aTipText,
    3098             :                         const char16_t *aTipDir)
    3099             : {
    3100           0 :     nsString str(aTipText);
    3101           0 :     nsString dir(aTipDir);
    3102           0 :     SendShowTooltip(aXCoords, aYCoords, str, dir);
    3103           0 :     return NS_OK;
    3104             : }
    3105             : 
    3106             : NS_IMETHODIMP
    3107           0 : TabChild::OnHideTooltip()
    3108             : {
    3109           0 :     SendHideTooltip();
    3110           0 :     return NS_OK;
    3111             : }
    3112             : 
    3113             : mozilla::ipc::IPCResult
    3114           0 : TabChild::RecvRequestNotifyAfterRemotePaint()
    3115             : {
    3116             :   // Get the CompositorBridgeChild instance for this content thread.
    3117           0 :   CompositorBridgeChild* compositor = CompositorBridgeChild::Get();
    3118             : 
    3119             :   // Tell the CompositorBridgeChild that, when it gets a RemotePaintIsReady
    3120             :   // message that it should forward it us so that we can bounce it to our
    3121             :   // RenderFrameParent.
    3122           0 :   compositor->RequestNotifyAfterRemotePaint(this);
    3123           0 :   return IPC_OK();
    3124             : }
    3125             : 
    3126             : mozilla::ipc::IPCResult
    3127           0 : TabChild::RecvUIResolutionChanged(const float& aDpi,
    3128             :                                   const int32_t& aRounding,
    3129             :                                   const double& aScale)
    3130             : {
    3131           0 :   ScreenIntSize oldScreenSize = GetInnerSize();
    3132           0 :   mDPI = 0;
    3133           0 :   mRounding = 0;
    3134           0 :   mDefaultScale = 0;
    3135           0 :   static_cast<PuppetWidget*>(mPuppetWidget.get())->UpdateBackingScaleCache(aDpi, aRounding, aScale);
    3136           0 :   nsCOMPtr<nsIDocument> document(GetDocument());
    3137           0 :   nsCOMPtr<nsIPresShell> presShell = document->GetShell();
    3138           0 :   if (presShell) {
    3139           0 :     RefPtr<nsPresContext> presContext = presShell->GetPresContext();
    3140           0 :     if (presContext) {
    3141           0 :       presContext->UIResolutionChangedSync();
    3142             :     }
    3143             :   }
    3144             : 
    3145           0 :   ScreenIntSize screenSize = GetInnerSize();
    3146           0 :   if (mHasValidInnerSize && oldScreenSize != screenSize) {
    3147           0 :     ScreenIntRect screenRect = GetOuterRect();
    3148           0 :     mPuppetWidget->Resize(screenRect.x + mClientOffset.x + mChromeDisp.x,
    3149           0 :                           screenRect.y + mClientOffset.y + mChromeDisp.y,
    3150           0 :                           screenSize.width, screenSize.height, true);
    3151             : 
    3152           0 :     nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(WebNavigation());
    3153           0 :     baseWin->SetPositionAndSize(0, 0, screenSize.width, screenSize.height,
    3154           0 :                                 nsIBaseWindow::eRepaint);
    3155             :   }
    3156             : 
    3157           0 :   return IPC_OK();
    3158             : }
    3159             : 
    3160             : mozilla::ipc::IPCResult
    3161           0 : TabChild::RecvThemeChanged(nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache)
    3162             : {
    3163           0 :   LookAndFeel::SetIntCache(aLookAndFeelIntCache);
    3164           0 :   nsCOMPtr<nsIDocument> document(GetDocument());
    3165           0 :   nsCOMPtr<nsIPresShell> presShell = document->GetShell();
    3166           0 :   if (presShell) {
    3167           0 :     RefPtr<nsPresContext> presContext = presShell->GetPresContext();
    3168           0 :     if (presContext) {
    3169           0 :       presContext->ThemeChanged();
    3170             :     }
    3171             :   }
    3172           0 :   return IPC_OK();
    3173             : }
    3174             : 
    3175             : mozilla::ipc::IPCResult
    3176           0 : TabChild::RecvAwaitLargeAlloc()
    3177             : {
    3178           0 :   mAwaitingLA = true;
    3179           0 :   return IPC_OK();
    3180             : }
    3181             : 
    3182             : bool
    3183           0 : TabChild::IsAwaitingLargeAlloc()
    3184             : {
    3185           0 :   return mAwaitingLA;
    3186             : }
    3187             : 
    3188             : bool
    3189           0 : TabChild::StopAwaitingLargeAlloc()
    3190             : {
    3191           0 :   bool awaiting = mAwaitingLA;
    3192           0 :   mAwaitingLA = false;
    3193           0 :   return awaiting;
    3194             : }
    3195             : 
    3196             : mozilla::ipc::IPCResult
    3197           0 : TabChild::RecvSetWindowName(const nsString& aName)
    3198             : {
    3199           0 :   nsCOMPtr<nsIDocShellTreeItem> item = do_QueryInterface(WebNavigation());
    3200           0 :   if (item) {
    3201           0 :     item->SetName(aName);
    3202             :   }
    3203           0 :   return IPC_OK();
    3204             : }
    3205             : 
    3206             : mozilla::ipc::IPCResult
    3207           0 : TabChild::RecvSetOriginAttributes(const OriginAttributes& aOriginAttributes)
    3208             : {
    3209           0 :   nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation());
    3210           0 :   nsDocShell::Cast(docShell)->SetOriginAttributes(aOriginAttributes);
    3211             : 
    3212           0 :   return IPC_OK();
    3213             : }
    3214             : 
    3215             : mozilla::ipc::IPCResult
    3216           1 : TabChild::RecvSetWidgetNativeData(const WindowsHandle& aWidgetNativeData)
    3217             : {
    3218           1 :   mWidgetNativeData = aWidgetNativeData;
    3219           1 :   return IPC_OK();
    3220             : }
    3221             : 
    3222             : mozilla::plugins::PPluginWidgetChild*
    3223           0 : TabChild::AllocPPluginWidgetChild()
    3224             : {
    3225             : #ifdef XP_WIN
    3226             :   return new mozilla::plugins::PluginWidgetChild();
    3227             : #else
    3228           0 :   MOZ_ASSERT_UNREACHABLE();
    3229             :   return nullptr;
    3230             : #endif
    3231             : }
    3232             : 
    3233             : bool
    3234           0 : TabChild::DeallocPPluginWidgetChild(mozilla::plugins::PPluginWidgetChild* aActor)
    3235             : {
    3236           0 :   delete aActor;
    3237           0 :   return true;
    3238             : }
    3239             : 
    3240             : #ifdef XP_WIN
    3241             : nsresult
    3242             : TabChild::CreatePluginWidget(nsIWidget* aParent, nsIWidget** aOut)
    3243             : {
    3244             :   *aOut = nullptr;
    3245             :   mozilla::plugins::PluginWidgetChild* child =
    3246             :     static_cast<mozilla::plugins::PluginWidgetChild*>(SendPPluginWidgetConstructor());
    3247             :   if (!child) {
    3248             :     NS_ERROR("couldn't create PluginWidgetChild");
    3249             :     return NS_ERROR_UNEXPECTED;
    3250             :   }
    3251             :   nsCOMPtr<nsIWidget> pluginWidget = nsIWidget::CreatePluginProxyWidget(this, child);
    3252             :   if (!pluginWidget) {
    3253             :     NS_ERROR("couldn't create PluginWidgetProxy");
    3254             :     return NS_ERROR_UNEXPECTED;
    3255             :   }
    3256             : 
    3257             :   nsWidgetInitData initData;
    3258             :   initData.mWindowType = eWindowType_plugin_ipc_content;
    3259             :   initData.mUnicode = false;
    3260             :   initData.clipChildren = true;
    3261             :   initData.clipSiblings = true;
    3262             :   nsresult rv = pluginWidget->Create(aParent, nullptr,
    3263             :                                      LayoutDeviceIntRect(0, 0, 0, 0),
    3264             :                                      &initData);
    3265             :   if (NS_FAILED(rv)) {
    3266             :     NS_WARNING("Creating native plugin widget on the chrome side failed.");
    3267             :   }
    3268             :   pluginWidget.forget(aOut);
    3269             :   return rv;
    3270             : }
    3271             : #endif // XP_WIN
    3272             : 
    3273             : PPaymentRequestChild*
    3274           0 : TabChild::AllocPPaymentRequestChild()
    3275             : {
    3276           0 :   MOZ_CRASH("We should never be manually allocating PPaymentRequestChild actors");
    3277             :   return nullptr;
    3278             : }
    3279             : 
    3280             : bool
    3281           0 : TabChild::DeallocPPaymentRequestChild(PPaymentRequestChild* actor)
    3282             : {
    3283           0 :   return true;
    3284             : }
    3285             : 
    3286             : ScreenIntSize
    3287           3 : TabChild::GetInnerSize()
    3288             : {
    3289             :   LayoutDeviceIntSize innerSize =
    3290           3 :     RoundedToInt(mUnscaledInnerSize * mPuppetWidget->GetDefaultScale());
    3291           3 :   return ViewAs<ScreenPixel>(innerSize, PixelCastJustification::LayoutDeviceIsScreenForTabDims);
    3292             : };
    3293             : 
    3294             : ScreenIntRect
    3295           3 : TabChild::GetOuterRect()
    3296             : {
    3297             :   LayoutDeviceIntRect outerRect =
    3298           3 :     RoundedToInt(mUnscaledOuterRect * mPuppetWidget->GetDefaultScale());
    3299           3 :   return ViewAs<ScreenPixel>(outerRect, PixelCastJustification::LayoutDeviceIsScreenForTabDims);
    3300             : }
    3301             : 
    3302             : void
    3303           1 : TabChild::ForcePaint(uint64_t aLayerObserverEpoch)
    3304             : {
    3305           1 :   if (!IPCOpen()) {
    3306             :     // Don't bother doing anything now. Better to wait until we receive the
    3307             :     // message on the PContent channel.
    3308           1 :     return;
    3309             :   }
    3310             : 
    3311           0 :   nsAutoScriptBlocker scriptBlocker;
    3312           0 :   RecvSetDocShellIsActive(true, false, aLayerObserverEpoch);
    3313             : }
    3314             : 
    3315             : void
    3316           0 : TabChild::BeforeUnloadAdded()
    3317             : {
    3318             :   // Don't bother notifying the parent if we don't have an IPC link open.
    3319           0 :   if (mBeforeUnloadListeners == 0 && IPCOpen()) {
    3320           0 :     SendSetHasBeforeUnload(true);
    3321             :   }
    3322             : 
    3323           0 :   mBeforeUnloadListeners++;
    3324           0 :   MOZ_ASSERT(mBeforeUnloadListeners >= 0);
    3325           0 : }
    3326             : 
    3327             : void
    3328           0 : TabChild::BeforeUnloadRemoved()
    3329             : {
    3330           0 :   mBeforeUnloadListeners--;
    3331           0 :   MOZ_ASSERT(mBeforeUnloadListeners >= 0);
    3332             : 
    3333             :   // Don't bother notifying the parent if we don't have an IPC link open.
    3334           0 :   if (mBeforeUnloadListeners == 0 && IPCOpen()) {
    3335           0 :     SendSetHasBeforeUnload(false);
    3336             :   }
    3337           0 : }
    3338             : 
    3339             : already_AddRefed<nsISHistory>
    3340           0 : TabChild::GetRelatedSHistory()
    3341             : {
    3342           0 :   nsCOMPtr<nsISHistory> shistory;
    3343           0 :   mWebNav->GetSessionHistory(getter_AddRefs(shistory));
    3344           0 :   return shistory.forget();
    3345             : }
    3346             : 
    3347             : nsresult
    3348           0 : TabChildSHistoryListener::SHistoryDidUpdate(bool aTruncate /* = false */)
    3349             : {
    3350           0 :   RefPtr<TabChild> tabChild(mTabChild);
    3351           0 :   if (NS_WARN_IF(!tabChild)) {
    3352           0 :     return NS_ERROR_FAILURE;
    3353             :   }
    3354             : 
    3355           0 :   nsCOMPtr<nsISHistory> shistory = tabChild->GetRelatedSHistory();
    3356           0 :   NS_ENSURE_TRUE(shistory, NS_ERROR_FAILURE);
    3357             : 
    3358             :   int32_t index, count;
    3359           0 :   nsresult rv = shistory->GetIndex(&index);
    3360           0 :   NS_ENSURE_SUCCESS(rv, rv);
    3361           0 :   rv = shistory->GetCount(&count);
    3362           0 :   NS_ENSURE_SUCCESS(rv, rv);
    3363             : 
    3364             :   // XXX: It would be nice if we could batch these updates like SessionStore
    3365             :   // does, and provide a form of `Flush` command which would allow us to trigger
    3366             :   // an update, and wait for the state to become consistent.
    3367           0 :   NS_ENSURE_TRUE(tabChild->SendSHistoryUpdate(count, index, aTruncate), NS_ERROR_FAILURE);
    3368           0 :   return NS_OK;
    3369             : }
    3370             : 
    3371             : mozilla::dom::TabGroup*
    3372          35 : TabChild::TabGroup()
    3373             : {
    3374          35 :   return mTabGroup;
    3375             : }
    3376             : 
    3377             : /*******************************************************************************
    3378             :  * nsISHistoryListener
    3379             :  ******************************************************************************/
    3380             : 
    3381             : NS_IMETHODIMP
    3382           0 : TabChildSHistoryListener::OnHistoryNewEntry(nsIURI *aNewURI, int32_t aOldIndex)
    3383             : {
    3384           0 :   return NS_ERROR_NOT_IMPLEMENTED;
    3385             : }
    3386             : 
    3387             : NS_IMETHODIMP
    3388           0 : TabChildSHistoryListener::OnHistoryGoBack(nsIURI *aBackURI, bool *_retval)
    3389             : {
    3390           0 :   return NS_ERROR_NOT_IMPLEMENTED;
    3391             : }
    3392             : 
    3393             : NS_IMETHODIMP
    3394           0 : TabChildSHistoryListener::OnHistoryGoForward(nsIURI *aForwardURI, bool *_retval)
    3395             : {
    3396           0 :   return NS_ERROR_NOT_IMPLEMENTED;
    3397             : }
    3398             : 
    3399             : NS_IMETHODIMP
    3400           0 : TabChildSHistoryListener::OnHistoryReload(nsIURI *aReloadURI, uint32_t aReloadFlags, bool *_retval)
    3401             : {
    3402           0 :   return NS_ERROR_NOT_IMPLEMENTED;
    3403             : }
    3404             : 
    3405             : NS_IMETHODIMP
    3406           0 : TabChildSHistoryListener::OnHistoryGotoIndex(int32_t aIndex, nsIURI *aGotoURI, bool *_retval)
    3407             : {
    3408           0 :   return NS_ERROR_NOT_IMPLEMENTED;
    3409             : }
    3410             : 
    3411             : NS_IMETHODIMP
    3412           0 : TabChildSHistoryListener::OnHistoryPurge(int32_t aNumEntries, bool *_retval)
    3413             : {
    3414           0 :   return NS_ERROR_NOT_IMPLEMENTED;
    3415             : }
    3416             : 
    3417             : NS_IMETHODIMP
    3418           0 : TabChildSHistoryListener::OnHistoryReplaceEntry(int32_t aIndex)
    3419             : {
    3420           0 :   return NS_ERROR_NOT_IMPLEMENTED;
    3421             : }
    3422             : 
    3423             : NS_IMETHODIMP
    3424           0 : TabChildSHistoryListener::OnLengthChanged(int32_t aCount)
    3425             : {
    3426           0 :   return SHistoryDidUpdate(/* aTruncate = */ true);
    3427             : }
    3428             : 
    3429             : NS_IMETHODIMP
    3430           0 : TabChildSHistoryListener::OnIndexChanged(int32_t aIndex)
    3431             : {
    3432           0 :   return SHistoryDidUpdate(/* aTruncate = */ false);
    3433             : }
    3434             : 
    3435             : NS_IMETHODIMP
    3436           0 : TabChildSHistoryListener::OnRequestCrossBrowserNavigation(uint32_t aIndex)
    3437             : {
    3438           0 :   RefPtr<TabChild> tabChild(mTabChild);
    3439           0 :   if (!tabChild) {
    3440           0 :     return NS_ERROR_FAILURE;
    3441             :   }
    3442             : 
    3443           0 :   return tabChild->SendRequestCrossBrowserNavigation(aIndex) ?
    3444           0 :            NS_OK : NS_ERROR_FAILURE;
    3445             : }
    3446             : 
    3447           1 : TabChildGlobal::TabChildGlobal(TabChild* aTabChild)
    3448           1 : : mTabChild(aTabChild)
    3449             : {
    3450           1 :   SetIsNotDOMBinding();
    3451           1 : }
    3452             : 
    3453           0 : TabChildGlobal::~TabChildGlobal()
    3454             : {
    3455           0 : }
    3456             : 
    3457             : void
    3458           1 : TabChildGlobal::Init()
    3459             : {
    3460           1 :   NS_ASSERTION(!mMessageManager, "Re-initializing?!?");
    3461             :   mMessageManager = new nsFrameMessageManager(mTabChild,
    3462             :                                               nullptr,
    3463           2 :                                               MM_CHILD);
    3464             : 
    3465           1 :   TelemetryScrollProbe::Create(this);
    3466           1 : }
    3467             : 
    3468             : NS_IMPL_CYCLE_COLLECTION_CLASS(TabChildGlobal)
    3469             : 
    3470           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(TabChildGlobal,
    3471             :                                                 DOMEventTargetHelper)
    3472           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager);
    3473           0 :   NS_IMPL_CYCLE_COLLECTION_UNLINK(mTabChild);
    3474           0 :   tmp->UnlinkHostObjectURIs();
    3475           0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
    3476             : 
    3477           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(TabChildGlobal,
    3478             :                                                   DOMEventTargetHelper)
    3479           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mMessageManager)
    3480           0 :   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTabChild)
    3481           0 :   tmp->TraverseHostObjectURIs(cb);
    3482           0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
    3483             : 
    3484        1180 : NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChildGlobal)
    3485        1179 :   NS_INTERFACE_MAP_ENTRY(nsIMessageListenerManager)
    3486        1178 :   NS_INTERFACE_MAP_ENTRY(nsIMessageSender)
    3487        1177 :   NS_INTERFACE_MAP_ENTRY(nsISyncMessageSender)
    3488        1177 :   NS_INTERFACE_MAP_ENTRY(nsIContentFrameMessageManager)
    3489        1173 :   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
    3490        1173 :   NS_INTERFACE_MAP_ENTRY(nsIGlobalObject)
    3491         248 :   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
    3492         248 :   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ContentFrameMessageManager)
    3493         247 : NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
    3494             : 
    3495        1771 : NS_IMPL_ADDREF_INHERITED(TabChildGlobal, DOMEventTargetHelper)
    3496        1763 : NS_IMPL_RELEASE_INHERITED(TabChildGlobal, DOMEventTargetHelper)
    3497             : 
    3498             : // This method isn't automatically forwarded safely because it's notxpcom, so
    3499             : // the IDL binding doesn't know what value to return.
    3500             : NS_IMETHODIMP_(bool)
    3501           0 : TabChildGlobal::MarkForCC()
    3502             : {
    3503           0 :   if (mTabChild) {
    3504           0 :     mTabChild->MarkScopesForCC();
    3505             :   }
    3506           0 :   EventListenerManager* elm = GetExistingListenerManager();
    3507           0 :   if (elm) {
    3508           0 :     elm->MarkForCC();
    3509             :   }
    3510           0 :   return mMessageManager ? mMessageManager->MarkForCC() : false;
    3511             : }
    3512             : 
    3513             : NS_IMETHODIMP
    3514          78 : TabChildGlobal::GetContent(mozIDOMWindowProxy** aContent)
    3515             : {
    3516          78 :   *aContent = nullptr;
    3517          78 :   if (!mTabChild)
    3518           0 :     return NS_ERROR_NULL_POINTER;
    3519         156 :   nsCOMPtr<nsPIDOMWindowOuter> window = do_GetInterface(mTabChild->WebNavigation());
    3520          78 :   window.forget(aContent);
    3521          78 :   return NS_OK;
    3522             : }
    3523             : 
    3524             : NS_IMETHODIMP
    3525          42 : TabChildGlobal::GetDocShell(nsIDocShell** aDocShell)
    3526             : {
    3527          42 :   *aDocShell = nullptr;
    3528          42 :   if (!mTabChild)
    3529           0 :     return NS_ERROR_NULL_POINTER;
    3530          84 :   nsCOMPtr<nsIDocShell> docShell = do_GetInterface(mTabChild->WebNavigation());
    3531          42 :   docShell.swap(*aDocShell);
    3532          42 :   return NS_OK;
    3533             : }
    3534             : 
    3535             : nsIPrincipal*
    3536           0 : TabChildGlobal::GetPrincipal()
    3537             : {
    3538           0 :   if (!mTabChild)
    3539           0 :     return nullptr;
    3540           0 :   return mTabChild->GetPrincipal();
    3541             : }
    3542             : 
    3543             : JSObject*
    3544        2070 : TabChildGlobal::GetGlobalJSObject()
    3545             : {
    3546        2070 :   NS_ENSURE_TRUE(mTabChild, nullptr);
    3547        2070 :   return mTabChild->GetGlobal();
    3548             : }
    3549             : 
    3550             : nsresult
    3551           0 : TabChildGlobal::Dispatch(const char* aName,
    3552             :                          TaskCategory aCategory,
    3553             :                          already_AddRefed<nsIRunnable>&& aRunnable)
    3554             : {
    3555           0 :   if (mTabChild && mTabChild->TabGroup()) {
    3556           0 :     return mTabChild->TabGroup()->Dispatch(aName, aCategory, Move(aRunnable));
    3557             :   }
    3558           0 :   return DispatcherTrait::Dispatch(aName, aCategory, Move(aRunnable));
    3559             : }
    3560             : 
    3561             : nsISerialEventTarget*
    3562           0 : TabChildGlobal::EventTargetFor(TaskCategory aCategory) const
    3563             : {
    3564           0 :   if (mTabChild && mTabChild->TabGroup()) {
    3565           0 :     return mTabChild->TabGroup()->EventTargetFor(aCategory);
    3566             :   }
    3567           0 :   return DispatcherTrait::EventTargetFor(aCategory);
    3568             : }
    3569             : 
    3570             : AbstractThread*
    3571           0 : TabChildGlobal::AbstractMainThreadFor(TaskCategory aCategory)
    3572             : {
    3573           0 :   if (mTabChild && mTabChild->TabGroup()) {
    3574           0 :     return mTabChild->TabGroup()->AbstractMainThreadFor(aCategory);
    3575             :   }
    3576           0 :   return DispatcherTrait::AbstractMainThreadFor(aCategory);
    3577             : }

Generated by: LCOV version 1.13