tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

BrowserBridgeChild.cpp (8026B)


      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 #ifdef ACCESSIBILITY
      8 #  include "mozilla/a11y/DocAccessible.h"
      9 #  include "mozilla/a11y/DocManager.h"
     10 #  include "mozilla/a11y/OuterDocAccessible.h"
     11 #endif
     12 #include "mozilla/PresShell.h"
     13 #include "mozilla/dom/BrowserBridgeChild.h"
     14 #include "mozilla/dom/BrowserBridgeHost.h"
     15 #include "mozilla/dom/BrowsingContext.h"
     16 #include "mozilla/dom/MozFrameLoaderOwnerBinding.h"
     17 #include "nsFocusManager.h"
     18 #include "nsFrameLoader.h"
     19 #include "nsFrameLoaderOwner.h"
     20 #include "nsObjectLoadingContent.h"
     21 #include "nsQueryObject.h"
     22 #include "nsSubDocumentFrame.h"
     23 
     24 using namespace mozilla::ipc;
     25 
     26 mozilla::LazyLogModule gBrowserChildFocusLog("BrowserChildFocus");
     27 
     28 #define LOGBROWSERCHILDFOCUS(args) \
     29  MOZ_LOG(gBrowserChildFocusLog, mozilla::LogLevel::Debug, args)
     30 
     31 namespace mozilla::dom {
     32 
     33 BrowserBridgeChild::BrowserBridgeChild(BrowsingContext* aBrowsingContext,
     34                                       TabId aId, const LayersId& aLayersId)
     35    : mId{aId}, mLayersId{aLayersId}, mBrowsingContext(aBrowsingContext) {}
     36 
     37 BrowserBridgeChild::~BrowserBridgeChild() {}
     38 
     39 already_AddRefed<BrowserBridgeHost> BrowserBridgeChild::FinishInit(
     40    nsFrameLoader* aFrameLoader) {
     41  MOZ_DIAGNOSTIC_ASSERT(!mFrameLoader);
     42  mFrameLoader = aFrameLoader;
     43 
     44  RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
     45  Document* doc = owner->OwnerDoc();
     46  doc->OOPChildLoadStarted(this);
     47 
     48 #if defined(ACCESSIBILITY)
     49  if (a11y::DocAccessible* docAcc = a11y::GetExistingDocAccessible(doc)) {
     50    if (a11y::LocalAccessible* ownerAcc = docAcc->GetAccessible(owner)) {
     51      if (a11y::OuterDocAccessible* outerAcc = ownerAcc->AsOuterDoc()) {
     52        outerAcc->SendEmbedderAccessible(this);
     53      }
     54    }
     55  }
     56 #endif  // defined(ACCESSIBILITY)
     57 
     58  return MakeAndAddRef<BrowserBridgeHost>(this);
     59 }
     60 
     61 nsILoadContext* BrowserBridgeChild::GetLoadContext() {
     62  return mBrowsingContext;
     63 }
     64 
     65 void BrowserBridgeChild::NavigateByKey(bool aForward,
     66                                       bool aForDocumentNavigation) {
     67  (void)SendNavigateByKey(aForward, aForDocumentNavigation);
     68 }
     69 
     70 void BrowserBridgeChild::Activate(uint64_t aActionId) {
     71  LOGBROWSERCHILDFOCUS(
     72      ("BrowserBridgeChild::Activate actionid: %" PRIu64, aActionId));
     73  (void)SendActivate(aActionId);
     74 }
     75 
     76 void BrowserBridgeChild::Deactivate(bool aWindowLowering, uint64_t aActionId) {
     77  (void)SendDeactivate(aWindowLowering, aActionId);
     78 }
     79 
     80 /*static*/
     81 BrowserBridgeChild* BrowserBridgeChild::GetFrom(nsFrameLoader* aFrameLoader) {
     82  if (!aFrameLoader) {
     83    return nullptr;
     84  }
     85  return aFrameLoader->GetBrowserBridgeChild();
     86 }
     87 
     88 /*static*/
     89 BrowserBridgeChild* BrowserBridgeChild::GetFrom(nsIContent* aContent) {
     90  RefPtr<nsFrameLoaderOwner> loaderOwner = do_QueryObject(aContent);
     91  if (!loaderOwner) {
     92    return nullptr;
     93  }
     94  RefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
     95  return GetFrom(frameLoader);
     96 }
     97 
     98 mozilla::ipc::IPCResult BrowserBridgeChild::RecvRequestFocus(
     99    const bool& aCanRaise, const CallerType aCallerType) {
    100  // Adapted from BrowserParent
    101  RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
    102  if (!owner) {
    103    return IPC_OK();
    104  }
    105  nsContentUtils::RequestFrameFocus(*owner, aCanRaise, aCallerType);
    106  return IPC_OK();
    107 }
    108 
    109 mozilla::ipc::IPCResult BrowserBridgeChild::RecvMoveFocus(
    110    const bool& aForward, const bool& aForDocumentNavigation) {
    111  // Adapted from BrowserParent
    112  RefPtr<nsFocusManager> fm = nsFocusManager::GetFocusManager();
    113  if (!fm) {
    114    return IPC_OK();
    115  }
    116 
    117  RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
    118  if (!owner) {
    119    return IPC_OK();
    120  }
    121 
    122  RefPtr<Element> dummy;
    123 
    124  uint32_t type =
    125      aForward
    126          ? (aForDocumentNavigation
    127                 ? static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_FORWARDDOC)
    128                 : static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_FORWARD))
    129          : (aForDocumentNavigation
    130                 ? static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_BACKWARDDOC)
    131                 : static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_BACKWARD));
    132  fm->MoveFocus(nullptr, owner, type, nsIFocusManager::FLAG_BYKEY,
    133                getter_AddRefs(dummy));
    134  return IPC_OK();
    135 }
    136 
    137 mozilla::ipc::IPCResult BrowserBridgeChild::RecvMaybeFireEmbedderLoadEvents(
    138    EmbedderElementEventType aFireEventAtEmbeddingElement) {
    139  RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
    140  if (!owner) {
    141    return IPC_OK();
    142  }
    143 
    144  if (aFireEventAtEmbeddingElement == EmbedderElementEventType::LoadEvent) {
    145    nsEventStatus status = nsEventStatus_eIgnore;
    146    WidgetEvent event(/* aIsTrusted = */ true, eLoad);
    147    event.mFlags.mBubbles = false;
    148    event.mFlags.mCancelable = false;
    149    EventDispatcher::Dispatch(owner, nullptr, &event, nullptr, &status);
    150  } else if (aFireEventAtEmbeddingElement ==
    151             EmbedderElementEventType::ErrorEvent) {
    152    mFrameLoader->FireErrorEvent();
    153  }
    154 
    155  UnblockOwnerDocsLoadEvent();
    156 
    157  return IPC_OK();
    158 }
    159 
    160 mozilla::ipc::IPCResult BrowserBridgeChild::RecvScrollRectIntoView(
    161    const nsRect& aRect, const ScrollAxis& aVertical,
    162    const ScrollAxis& aHorizontal, const ScrollFlags& aScrollFlags,
    163    const int32_t& aAppUnitsPerDevPixel) {
    164  RefPtr<Element> owner = mFrameLoader->GetOwnerContent();
    165  if (!owner) {
    166    return IPC_OK();
    167  }
    168 
    169  nsIFrame* frame = owner->GetPrimaryFrame();
    170  if (!frame) {
    171    return IPC_OK();
    172  }
    173 
    174  nsSubDocumentFrame* subdocumentFrame = do_QueryFrame(frame);
    175  if (!subdocumentFrame) {
    176    return IPC_OK();
    177  }
    178 
    179  nsPoint extraOffset = subdocumentFrame->GetExtraOffset();
    180 
    181  int32_t parentAPD = frame->PresContext()->AppUnitsPerDevPixel();
    182  nsRect rect =
    183      aRect.ScaleToOtherAppUnitsRoundOut(aAppUnitsPerDevPixel, parentAPD);
    184  rect += extraOffset;
    185  RefPtr<PresShell> presShell = frame->PresShell();
    186  presShell->ScrollFrameIntoView(frame, Some(rect), aVertical, aHorizontal,
    187                                 aScrollFlags);
    188  return IPC_OK();
    189 }
    190 
    191 mozilla::ipc::IPCResult BrowserBridgeChild::RecvSubFrameCrashed() {
    192  if (RefPtr<nsFrameLoaderOwner> frameLoaderOwner =
    193          do_QueryObject(mFrameLoader->GetOwnerContent())) {
    194    frameLoaderOwner->SubframeCrashed();
    195  }
    196  return IPC_OK();
    197 }
    198 
    199 void BrowserBridgeChild::ActorDestroy(ActorDestroyReason aWhy) {
    200  if (mFrameLoader) {
    201    mFrameLoader->DestroyComplete();
    202  }
    203 
    204  if (!mBrowsingContext) {
    205    // This BBC was never valid, skip teardown.
    206    return;
    207  }
    208 
    209  // Ensure we unblock our document's 'load' event (in case the OOP-iframe has
    210  // been removed before it finished loading, or its subprocess crashed):
    211  UnblockOwnerDocsLoadEvent();
    212 }
    213 
    214 void BrowserBridgeChild::UnblockOwnerDocsLoadEvent() {
    215  if (!mHadInitialLoad) {
    216    mHadInitialLoad = true;
    217 
    218    if (Document* doc = mBrowsingContext->GetParent()->GetExtantDocument()) {
    219      doc->OOPChildLoadDone(this);
    220    }
    221  }
    222 }
    223 
    224 mozilla::ipc::IPCResult BrowserBridgeChild::RecvIntrinsicSizeOrRatioChanged(
    225    const Maybe<IntrinsicSize>& aIntrinsicSize,
    226    const Maybe<AspectRatio>& aIntrinsicRatio) {
    227  if (RefPtr<Element> owner = mFrameLoader->GetOwnerContent()) {
    228    if (nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(owner)) {
    229      static_cast<nsObjectLoadingContent*>(olc.get())
    230          ->SubdocumentIntrinsicSizeOrRatioChanged(aIntrinsicSize,
    231                                                   aIntrinsicRatio);
    232    }
    233  }
    234  return IPC_OK();
    235 }
    236 
    237 mozilla::ipc::IPCResult BrowserBridgeChild::RecvImageLoadComplete(
    238    const nsresult& aResult) {
    239  if (RefPtr<Element> owner = mFrameLoader->GetOwnerContent()) {
    240    if (nsCOMPtr<nsIObjectLoadingContent> olc = do_QueryInterface(owner)) {
    241      static_cast<nsObjectLoadingContent*>(olc.get())
    242          ->SubdocumentImageLoadComplete(aResult);
    243    }
    244  }
    245  return IPC_OK();
    246 }
    247 
    248 }  // namespace mozilla::dom