dom/ipc/TabParent.cpp

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     1 /* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8; -*- */
     2 /* vim: set sw=2 ts=8 et 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/. */
     7 #include "base/basictypes.h"
     9 #include "TabParent.h"
    11 #include "AppProcessChecker.h"
    12 #include "IDBFactory.h"
    13 #include "IndexedDBParent.h"
    14 #include "mozIApplication.h"
    15 #include "mozilla/BrowserElementParent.h"
    16 #include "mozilla/docshell/OfflineCacheUpdateParent.h"
    17 #include "mozilla/dom/ContentParent.h"
    18 #include "mozilla/dom/PContentPermissionRequestParent.h"
    19 #include "mozilla/EventStateManager.h"
    20 #include "mozilla/Hal.h"
    21 #include "mozilla/ipc/DocumentRendererParent.h"
    22 #include "mozilla/layers/CompositorParent.h"
    23 #include "mozilla/layout/RenderFrameParent.h"
    24 #include "mozilla/MouseEvents.h"
    25 #include "mozilla/Preferences.h"
    26 #include "mozilla/TextEvents.h"
    27 #include "mozilla/TouchEvents.h"
    28 #include "mozilla/unused.h"
    29 #include "nsCOMPtr.h"
    30 #include "nsContentPermissionHelper.h"
    31 #include "nsContentUtils.h"
    32 #include "nsDebug.h"
    33 #include "nsFocusManager.h"
    34 #include "nsFrameLoader.h"
    35 #include "nsIContent.h"
    36 #include "nsIDocShell.h"
    37 #include "nsIDocShellTreeOwner.h"
    38 #include "nsIDOMElement.h"
    39 #include "nsIDOMEvent.h"
    40 #include "nsIDOMWindow.h"
    41 #include "nsIDOMWindowUtils.h"
    42 #include "nsIInterfaceRequestorUtils.h"
    43 #include "nsIPromptFactory.h"
    44 #include "nsIURI.h"
    45 #include "nsIWebBrowserChrome.h"
    46 #include "nsIXULBrowserWindow.h"
    47 #include "nsIXULWindow.h"
    48 #include "nsViewManager.h"
    49 #include "nsIWidget.h"
    50 #include "nsIWindowWatcher.h"
    51 #include "nsPIDOMWindow.h"
    52 #include "nsPrintfCString.h"
    53 #include "nsServiceManagerUtils.h"
    54 #include "nsThreadUtils.h"
    55 #include "private/pprio.h"
    56 #include "PermissionMessageUtils.h"
    57 #include "StructuredCloneUtils.h"
    58 #include "ColorPickerParent.h"
    59 #include "JavaScriptParent.h"
    60 #include "FilePickerParent.h"
    61 #include "TabChild.h"
    62 #include "LoadContext.h"
    63 #include "nsNetCID.h"
    64 #include <algorithm>
    66 using namespace mozilla::dom;
    67 using namespace mozilla::ipc;
    68 using namespace mozilla::layers;
    69 using namespace mozilla::layout;
    70 using namespace mozilla::services;
    71 using namespace mozilla::widget;
    72 using namespace mozilla::dom::indexedDB;
    73 using namespace mozilla::jsipc;
    75 // The flags passed by the webProgress notifications are 16 bits shifted
    76 // from the ones registered by webProgressListeners.
    77 #define NOTIFY_FLAG_SHIFT 16
    79 class OpenFileAndSendFDRunnable : public nsRunnable
    80 {
    81     const nsString mPath;
    82     nsRefPtr<TabParent> mTabParent;
    83     nsCOMPtr<nsIEventTarget> mEventTarget;
    84     PRFileDesc* mFD;
    86 public:
    87     OpenFileAndSendFDRunnable(const nsAString& aPath, TabParent* aTabParent)
    88       : mPath(aPath), mTabParent(aTabParent), mFD(nullptr)
    89     {
    90         MOZ_ASSERT(NS_IsMainThread());
    91         MOZ_ASSERT(!aPath.IsEmpty());
    92         MOZ_ASSERT(aTabParent);
    93     }
    95     void Dispatch()
    96     {
    97         MOZ_ASSERT(NS_IsMainThread());
    99         mEventTarget = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
   100         NS_ENSURE_TRUE_VOID(mEventTarget);
   102         nsresult rv = mEventTarget->Dispatch(this, NS_DISPATCH_NORMAL);
   103         NS_ENSURE_SUCCESS_VOID(rv);
   104     }
   106 private:
   107     ~OpenFileAndSendFDRunnable()
   108     {
   109         MOZ_ASSERT(!mFD);
   110     }
   112     // This shouldn't be called directly except by the event loop. Use Dispatch
   113     // to start the sequence.
   114     NS_IMETHOD Run()
   115     {
   116         if (NS_IsMainThread()) {
   117             SendResponse();
   118         } else if (mFD) {
   119             CloseFile();
   120         } else {
   121             OpenFile();
   122         }
   124         return NS_OK;
   125     }
   127     void SendResponse()
   128     {
   129         MOZ_ASSERT(NS_IsMainThread());
   130         MOZ_ASSERT(mTabParent);
   131         MOZ_ASSERT(mEventTarget);
   132         MOZ_ASSERT(mFD);
   134         nsRefPtr<TabParent> tabParent;
   135         mTabParent.swap(tabParent);
   137         using mozilla::ipc::FileDescriptor;
   139         FileDescriptor::PlatformHandleType handle =
   140             FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(mFD));
   142         mozilla::unused << tabParent->SendCacheFileDescriptor(mPath, handle);
   144         nsCOMPtr<nsIEventTarget> eventTarget;
   145         mEventTarget.swap(eventTarget);
   147         if (NS_FAILED(eventTarget->Dispatch(this, NS_DISPATCH_NORMAL))) {
   148             NS_WARNING("Failed to dispatch to stream transport service!");
   150             // It's probably safer to take the main thread IO hit here rather
   151             // than leak a file descriptor.
   152             CloseFile();
   153         }
   154     }
   156     void OpenFile()
   157     {
   158         MOZ_ASSERT(!NS_IsMainThread());
   159         MOZ_ASSERT(!mFD);
   161         nsCOMPtr<nsIFile> file;
   162         nsresult rv = NS_NewLocalFile(mPath, false, getter_AddRefs(file));
   163         NS_ENSURE_SUCCESS_VOID(rv);
   165         PRFileDesc* fd;
   166         rv = file->OpenNSPRFileDesc(PR_RDONLY, 0, &fd);
   167         NS_ENSURE_SUCCESS_VOID(rv);
   169         mFD = fd;
   171         if (NS_FAILED(NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL))) {
   172             NS_WARNING("Failed to dispatch to main thread!");
   174             CloseFile();
   175         }
   176     }
   178     void CloseFile()
   179     {
   180         // It's possible for this to happen on the main thread if the dispatch
   181         // to the stream service fails after we've already opened the file so
   182         // we can't assert the thread we're running on.
   184         MOZ_ASSERT(mFD);
   186         PRStatus prrc;
   187         prrc = PR_Close(mFD);
   188         if (prrc != PR_SUCCESS) {
   189           NS_ERROR("PR_Close() failed.");
   190         }
   191         mFD = nullptr;
   192     }
   193 };
   195 namespace mozilla {
   196 namespace dom {
   198 TabParent* sEventCapturer;
   200 TabParent *TabParent::mIMETabParent = nullptr;
   202 NS_IMPL_ISUPPORTS(TabParent, nsITabParent, nsIAuthPromptProvider, nsISecureBrowserUI)
   204 TabParent::TabParent(ContentParent* aManager, const TabContext& aContext, uint32_t aChromeFlags)
   205   : TabContext(aContext)
   206   , mFrameElement(nullptr)
   207   , mIMESelectionAnchor(0)
   208   , mIMESelectionFocus(0)
   209   , mIMEComposing(false)
   210   , mIMECompositionEnding(false)
   211   , mIMECompositionStart(0)
   212   , mIMESeqno(0)
   213   , mIMECompositionRectOffset(0)
   214   , mEventCaptureDepth(0)
   215   , mRect(0, 0, 0, 0)
   216   , mDimensions(0, 0)
   217   , mOrientation(0)
   218   , mDPI(0)
   219   , mDefaultScale(0)
   220   , mShown(false)
   221   , mUpdatedDimensions(false)
   222   , mManager(aManager)
   223   , mMarkedDestroying(false)
   224   , mIsDestroyed(false)
   225   , mAppPackageFileDescriptorSent(false)
   226   , mChromeFlags(aChromeFlags)
   227 {
   228 }
   230 TabParent::~TabParent()
   231 {
   232 }
   234 void
   235 TabParent::SetOwnerElement(Element* aElement)
   236 {
   237   mFrameElement = aElement;
   238   TryCacheDPIAndScale();
   239 }
   241 void
   242 TabParent::GetAppType(nsAString& aOut)
   243 {
   244   aOut.Truncate();
   245   nsCOMPtr<Element> elem = do_QueryInterface(mFrameElement);
   246   if (!elem) {
   247     return;
   248   }
   250   elem->GetAttr(kNameSpaceID_None, nsGkAtoms::mozapptype, aOut);
   251 }
   253 bool
   254 TabParent::IsVisible()
   255 {
   256   nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
   257   if (!frameLoader) {
   258     return false;
   259   }
   261   bool visible = false;
   262   frameLoader->GetVisible(&visible);
   263   return visible;
   264 }
   266 void
   267 TabParent::Destroy()
   268 {
   269   if (mIsDestroyed) {
   270     return;
   271   }
   273   // If this fails, it's most likely due to a content-process crash,
   274   // and auto-cleanup will kick in.  Otherwise, the child side will
   275   // destroy itself and send back __delete__().
   276   unused << SendDestroy();
   278   const InfallibleTArray<PIndexedDBParent*>& idbParents =
   279     ManagedPIndexedDBParent();
   280   for (uint32_t i = 0; i < idbParents.Length(); ++i) {
   281     static_cast<IndexedDBParent*>(idbParents[i])->Disconnect();
   282   }
   284   const InfallibleTArray<POfflineCacheUpdateParent*>& ocuParents =
   285     ManagedPOfflineCacheUpdateParent();
   286   for (uint32_t i = 0; i < ocuParents.Length(); ++i) {
   287     nsRefPtr<mozilla::docshell::OfflineCacheUpdateParent> ocuParent =
   288       static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(ocuParents[i]);
   289     ocuParent->StopSendingMessagesToChild();
   290   }
   292   if (RenderFrameParent* frame = GetRenderFrame()) {
   293     frame->Destroy();
   294   }
   295   mIsDestroyed = true;
   297   Manager()->NotifyTabDestroying(this);
   298   mMarkedDestroying = true;
   299 }
   301 bool
   302 TabParent::Recv__delete__()
   303 {
   304   Manager()->NotifyTabDestroyed(this, mMarkedDestroying);
   305   return true;
   306 }
   308 void
   309 TabParent::ActorDestroy(ActorDestroyReason why)
   310 {
   311   if (sEventCapturer == this) {
   312     sEventCapturer = nullptr;
   313   }
   314   if (mIMETabParent == this) {
   315     mIMETabParent = nullptr;
   316   }
   317   nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
   318   nsCOMPtr<nsIObserverService> os = services::GetObserverService();
   319   nsRefPtr<nsFrameMessageManager> fmm;
   320   if (frameLoader) {
   321     fmm = frameLoader->GetFrameMessageManager();
   322     nsCOMPtr<Element> frameElement(mFrameElement);
   323     ReceiveMessage(CHILD_PROCESS_SHUTDOWN_MESSAGE, false, nullptr, nullptr,
   324                    nullptr);
   325     frameLoader->DestroyChild();
   327     if (why == AbnormalShutdown && os) {
   328       os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, frameLoader),
   329                           "oop-frameloader-crashed", nullptr);
   330       nsContentUtils::DispatchTrustedEvent(frameElement->OwnerDoc(), frameElement,
   331                                            NS_LITERAL_STRING("oop-browser-crashed"),
   332                                            true, true);
   333     }
   334   }
   336   if (os) {
   337     os->NotifyObservers(NS_ISUPPORTS_CAST(nsITabParent*, this), "ipc:browser-destroyed", nullptr);
   338   }
   339   if (fmm) {
   340     fmm->Disconnect();
   341   }
   342 }
   344 bool
   345 TabParent::RecvMoveFocus(const bool& aForward)
   346 {
   347   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
   348   if (fm) {
   349     nsCOMPtr<nsIDOMElement> dummy;
   350     uint32_t type = aForward ? uint32_t(nsIFocusManager::MOVEFOCUS_FORWARD)
   351                              : uint32_t(nsIFocusManager::MOVEFOCUS_BACKWARD);
   352     nsCOMPtr<nsIDOMElement> frame = do_QueryInterface(mFrameElement);
   353     fm->MoveFocus(nullptr, frame, type, nsIFocusManager::FLAG_BYKEY,
   354                   getter_AddRefs(dummy));
   355   }
   356   return true;
   357 }
   359 bool
   360 TabParent::RecvEvent(const RemoteDOMEvent& aEvent)
   361 {
   362   nsCOMPtr<nsIDOMEvent> event = do_QueryInterface(aEvent.mEvent);
   363   NS_ENSURE_TRUE(event, true);
   365   nsCOMPtr<mozilla::dom::EventTarget> target = do_QueryInterface(mFrameElement);
   366   NS_ENSURE_TRUE(target, true);
   368   event->SetOwner(target);
   370   bool dummy;
   371   target->DispatchEvent(event, &dummy);
   372   return true;
   373 }
   375 bool
   376 TabParent::AnswerCreateWindow(PBrowserParent** retval)
   377 {
   378     if (!mBrowserDOMWindow) {
   379         return false;
   380     }
   382     // Only non-app, non-browser processes may call CreateWindow.
   383     if (IsBrowserOrApp()) {
   384         return false;
   385     }
   387     // Get a new rendering area from the browserDOMWin.  We don't want
   388     // to be starting any loads here, so get it with a null URI.
   389     nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
   390     mBrowserDOMWindow->OpenURIInFrame(nullptr, nullptr,
   391                                       nsIBrowserDOMWindow::OPEN_NEWTAB,
   392                                       nsIBrowserDOMWindow::OPEN_NEW,
   393                                       getter_AddRefs(frameLoaderOwner));
   394     if (!frameLoaderOwner) {
   395         return false;
   396     }
   398     nsRefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
   399     if (!frameLoader) {
   400         return false;
   401     }
   403     *retval = frameLoader->GetRemoteBrowser();
   404     return true;
   405 }
   407 void
   408 TabParent::LoadURL(nsIURI* aURI)
   409 {
   410     MOZ_ASSERT(aURI);
   412     if (mIsDestroyed) {
   413         return;
   414     }
   416     nsCString spec;
   417     aURI->GetSpec(spec);
   419     if (!mShown) {
   420         NS_WARNING(nsPrintfCString("TabParent::LoadURL(%s) called before "
   421                                    "Show(). Ignoring LoadURL.\n",
   422                                    spec.get()).get());
   423         return;
   424     }
   426     unused << SendLoadURL(spec);
   428     // If this app is a packaged app then we can speed startup by sending over
   429     // the file descriptor for the "application.zip" file that it will
   430     // invariably request. Only do this once.
   431     if (!mAppPackageFileDescriptorSent) {
   432         mAppPackageFileDescriptorSent = true;
   434         nsCOMPtr<mozIApplication> app = GetOwnOrContainingApp();
   435         if (app) {
   436             nsString manifestURL;
   437             nsresult rv = app->GetManifestURL(manifestURL);
   438             NS_ENSURE_SUCCESS_VOID(rv);
   440             if (StringBeginsWith(manifestURL, NS_LITERAL_STRING("app:"))) {
   441                 nsString basePath;
   442                 rv = app->GetBasePath(basePath);
   443                 NS_ENSURE_SUCCESS_VOID(rv);
   445                 nsString appId;
   446                 rv = app->GetId(appId);
   447                 NS_ENSURE_SUCCESS_VOID(rv);
   449                 nsCOMPtr<nsIFile> packageFile;
   450                 rv = NS_NewLocalFile(basePath, false,
   451                                      getter_AddRefs(packageFile));
   452                 NS_ENSURE_SUCCESS_VOID(rv);
   454                 rv = packageFile->Append(appId);
   455                 NS_ENSURE_SUCCESS_VOID(rv);
   457                 rv = packageFile->Append(NS_LITERAL_STRING("application.zip"));
   458                 NS_ENSURE_SUCCESS_VOID(rv);
   460                 nsString path;
   461                 rv = packageFile->GetPath(path);
   462                 NS_ENSURE_SUCCESS_VOID(rv);
   464                 nsRefPtr<OpenFileAndSendFDRunnable> openFileRunnable =
   465                     new OpenFileAndSendFDRunnable(path, this);
   466                 openFileRunnable->Dispatch();
   467             }
   468         }
   469     }
   470 }
   472 void
   473 TabParent::Show(const nsIntSize& size)
   474 {
   475     // sigh
   476     mShown = true;
   477     mDimensions = size;
   478     if (!mIsDestroyed) {
   479       unused << SendShow(size);
   480     }
   481 }
   483 void
   484 TabParent::UpdateDimensions(const nsRect& rect, const nsIntSize& size)
   485 {
   486   if (mIsDestroyed) {
   487     return;
   488   }
   489   hal::ScreenConfiguration config;
   490   hal::GetCurrentScreenConfiguration(&config);
   491   ScreenOrientation orientation = config.orientation();
   493   if (!mUpdatedDimensions || mOrientation != orientation ||
   494       mDimensions != size || !mRect.IsEqualEdges(rect)) {
   495     mUpdatedDimensions = true;
   496     mRect = rect;
   497     mDimensions = size;
   498     mOrientation = orientation;
   500     unused << SendUpdateDimensions(mRect, mDimensions, mOrientation);
   501   }
   502 }
   504 void
   505 TabParent::UpdateFrame(const FrameMetrics& aFrameMetrics)
   506 {
   507   if (!mIsDestroyed) {
   508     unused << SendUpdateFrame(aFrameMetrics);
   509   }
   510 }
   512 void
   513 TabParent::AcknowledgeScrollUpdate(const ViewID& aScrollId, const uint32_t& aScrollGeneration)
   514 {
   515   if (!mIsDestroyed) {
   516     unused << SendAcknowledgeScrollUpdate(aScrollId, aScrollGeneration);
   517   }
   518 }
   520 void TabParent::HandleDoubleTap(const CSSPoint& aPoint,
   521                                 int32_t aModifiers,
   522                                 const ScrollableLayerGuid &aGuid)
   523 {
   524   if (!mIsDestroyed) {
   525     unused << SendHandleDoubleTap(aPoint, aGuid);
   526   }
   527 }
   529 void TabParent::HandleSingleTap(const CSSPoint& aPoint,
   530                                 int32_t aModifiers,
   531                                 const ScrollableLayerGuid &aGuid)
   532 {
   533   // TODO Send the modifier data to TabChild for use in mouse events.
   534   if (!mIsDestroyed) {
   535     unused << SendHandleSingleTap(aPoint, aGuid);
   536   }
   537 }
   539 void TabParent::HandleLongTap(const CSSPoint& aPoint,
   540                               int32_t aModifiers,
   541                               const ScrollableLayerGuid &aGuid)
   542 {
   543   if (!mIsDestroyed) {
   544     unused << SendHandleLongTap(aPoint, aGuid);
   545   }
   546 }
   548 void TabParent::HandleLongTapUp(const CSSPoint& aPoint,
   549                                 int32_t aModifiers,
   550                                 const ScrollableLayerGuid &aGuid)
   551 {
   552   if (!mIsDestroyed) {
   553     unused << SendHandleLongTapUp(aPoint, aGuid);
   554   }
   555 }
   557 void TabParent::NotifyAPZStateChange(ViewID aViewId,
   558                                      APZStateChange aChange,
   559                                      int aArg)
   560 {
   561   if (!mIsDestroyed) {
   562     unused << SendNotifyAPZStateChange(aViewId, aChange, aArg);
   563   }
   564 }
   566 void
   567 TabParent::Activate()
   568 {
   569   if (!mIsDestroyed) {
   570     unused << SendActivate();
   571   }
   572 }
   574 void
   575 TabParent::Deactivate()
   576 {
   577   if (!mIsDestroyed) {
   578     unused << SendDeactivate();
   579   }
   580 }
   582 NS_IMETHODIMP
   583 TabParent::Init(nsIDOMWindow *window)
   584 {
   585   return NS_OK;
   586 }
   588 NS_IMETHODIMP
   589 TabParent::GetState(uint32_t *aState)
   590 {
   591   NS_ENSURE_ARG(aState);
   592   NS_WARNING("SecurityState not valid here");
   593   *aState = 0;
   594   return NS_OK;
   595 }
   597 NS_IMETHODIMP
   598 TabParent::SetDocShell(nsIDocShell *aDocShell)
   599 {
   600   NS_ENSURE_ARG(aDocShell);
   601   NS_WARNING("No mDocShell member in TabParent so there is no docShell to set");
   602   return NS_OK;
   603 }
   605 PDocumentRendererParent*
   606 TabParent::AllocPDocumentRendererParent(const nsRect& documentRect,
   607                                         const gfx::Matrix& transform,
   608                                         const nsString& bgcolor,
   609                                         const uint32_t& renderFlags,
   610                                         const bool& flushLayout,
   611                                         const nsIntSize& renderSize)
   612 {
   613     return new DocumentRendererParent();
   614 }
   616 bool
   617 TabParent::DeallocPDocumentRendererParent(PDocumentRendererParent* actor)
   618 {
   619     delete actor;
   620     return true;
   621 }
   623 PContentPermissionRequestParent*
   624 TabParent::AllocPContentPermissionRequestParent(const InfallibleTArray<PermissionRequest>& aRequests,
   625                                                 const IPC::Principal& aPrincipal)
   626 {
   627   return CreateContentPermissionRequestParent(aRequests, mFrameElement, aPrincipal);
   628 }
   630 bool
   631 TabParent::DeallocPContentPermissionRequestParent(PContentPermissionRequestParent* actor)
   632 {
   633   delete actor;
   634   return true;
   635 }
   637 PFilePickerParent*
   638 TabParent::AllocPFilePickerParent(const nsString& aTitle, const int16_t& aMode)
   639 {
   640   return new FilePickerParent(aTitle, aMode);
   641 }
   643 bool
   644 TabParent::DeallocPFilePickerParent(PFilePickerParent* actor)
   645 {
   646   delete actor;
   647   return true;
   648 }
   650 void
   651 TabParent::SendMouseEvent(const nsAString& aType, float aX, float aY,
   652                           int32_t aButton, int32_t aClickCount,
   653                           int32_t aModifiers, bool aIgnoreRootScrollFrame)
   654 {
   655   if (!mIsDestroyed) {
   656     unused << PBrowserParent::SendMouseEvent(nsString(aType), aX, aY,
   657                                              aButton, aClickCount,
   658                                              aModifiers, aIgnoreRootScrollFrame);
   659   }
   660 }
   662 void
   663 TabParent::SendKeyEvent(const nsAString& aType,
   664                         int32_t aKeyCode,
   665                         int32_t aCharCode,
   666                         int32_t aModifiers,
   667                         bool aPreventDefault)
   668 {
   669   if (!mIsDestroyed) {
   670     unused << PBrowserParent::SendKeyEvent(nsString(aType), aKeyCode, aCharCode,
   671                                            aModifiers, aPreventDefault);
   672   }
   673 }
   675 bool
   676 TabParent::MapEventCoordinatesForChildProcess(WidgetEvent* aEvent)
   677 {
   678   nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
   679   if (!frameLoader) {
   680     return false;
   681   }
   682   LayoutDeviceIntPoint offset =
   683     EventStateManager::GetChildProcessOffset(frameLoader, *aEvent);
   684   MapEventCoordinatesForChildProcess(offset, aEvent);
   685   return true;
   686 }
   688 void
   689 TabParent::MapEventCoordinatesForChildProcess(
   690   const LayoutDeviceIntPoint& aOffset, WidgetEvent* aEvent)
   691 {
   692   if (aEvent->eventStructType != NS_TOUCH_EVENT) {
   693     aEvent->refPoint = aOffset;
   694   } else {
   695     aEvent->refPoint = LayoutDeviceIntPoint();
   696     // Then offset all the touch points by that distance, to put them
   697     // in the space where top-left is 0,0.
   698     const nsTArray< nsRefPtr<Touch> >& touches =
   699       aEvent->AsTouchEvent()->touches;
   700     for (uint32_t i = 0; i < touches.Length(); ++i) {
   701       Touch* touch = touches[i];
   702       if (touch) {
   703         touch->mRefPoint += LayoutDeviceIntPoint::ToUntyped(aOffset);
   704       }
   705     }
   706   }
   707 }
   709 bool TabParent::SendRealMouseEvent(WidgetMouseEvent& event)
   710 {
   711   if (mIsDestroyed) {
   712     return false;
   713   }
   714   MaybeForwardEventToRenderFrame(event, nullptr);
   715   if (!MapEventCoordinatesForChildProcess(&event)) {
   716     return false;
   717   }
   718   return PBrowserParent::SendRealMouseEvent(event);
   719 }
   721 CSSPoint TabParent::AdjustTapToChildWidget(const CSSPoint& aPoint)
   722 {
   723   nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
   725   if (!content || !content->OwnerDoc()) {
   726     return aPoint;
   727   }
   729   nsIDocument* doc = content->OwnerDoc();
   730   if (!doc || !doc->GetShell()) {
   731     return aPoint;
   732   }
   733   nsPresContext* presContext = doc->GetShell()->GetPresContext();
   735   return aPoint + CSSPoint(
   736     presContext->DevPixelsToFloatCSSPixels(mChildProcessOffsetAtTouchStart.x),
   737     presContext->DevPixelsToFloatCSSPixels(mChildProcessOffsetAtTouchStart.y));
   738 }
   740 bool TabParent::SendHandleSingleTap(const CSSPoint& aPoint, const ScrollableLayerGuid& aGuid)
   741 {
   742   if (mIsDestroyed) {
   743     return false;
   744   }
   746   return PBrowserParent::SendHandleSingleTap(AdjustTapToChildWidget(aPoint), aGuid);
   747 }
   749 bool TabParent::SendHandleLongTap(const CSSPoint& aPoint, const ScrollableLayerGuid& aGuid)
   750 {
   751   if (mIsDestroyed) {
   752     return false;
   753   }
   755   return PBrowserParent::SendHandleLongTap(AdjustTapToChildWidget(aPoint), aGuid);
   756 }
   758 bool TabParent::SendHandleLongTapUp(const CSSPoint& aPoint, const ScrollableLayerGuid& aGuid)
   759 {
   760   if (mIsDestroyed) {
   761     return false;
   762   }
   764   return PBrowserParent::SendHandleLongTapUp(AdjustTapToChildWidget(aPoint), aGuid);
   765 }
   767 bool TabParent::SendHandleDoubleTap(const CSSPoint& aPoint, const ScrollableLayerGuid& aGuid)
   768 {
   769   if (mIsDestroyed) {
   770     return false;
   771   }
   773   return PBrowserParent::SendHandleDoubleTap(AdjustTapToChildWidget(aPoint), aGuid);
   774 }
   776 bool TabParent::SendMouseWheelEvent(WidgetWheelEvent& event)
   777 {
   778   if (mIsDestroyed) {
   779     return false;
   780   }
   781   MaybeForwardEventToRenderFrame(event, nullptr);
   782   if (!MapEventCoordinatesForChildProcess(&event)) {
   783     return false;
   784   }
   785   return PBrowserParent::SendMouseWheelEvent(event);
   786 }
   788 static void
   789 DoCommandCallback(mozilla::Command aCommand, void* aData)
   790 {
   791   static_cast<InfallibleTArray<mozilla::CommandInt>*>(aData)->AppendElement(aCommand);
   792 }
   794 bool
   795 TabParent::RecvRequestNativeKeyBindings(const WidgetKeyboardEvent& aEvent,
   796                                         MaybeNativeKeyBinding* aBindings)
   797 {
   798   AutoInfallibleTArray<mozilla::CommandInt, 4> singleLine;
   799   AutoInfallibleTArray<mozilla::CommandInt, 4> multiLine;
   800   AutoInfallibleTArray<mozilla::CommandInt, 4> richText;
   802   *aBindings = mozilla::void_t();
   804   nsCOMPtr<nsIWidget> widget = GetWidget();
   805   if (!widget) {
   806     return true;
   807   }
   809   WidgetKeyboardEvent localEvent(aEvent);
   811   if (NS_FAILED(widget->AttachNativeKeyEvent(localEvent))) {
   812     return true;
   813   }
   815   widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForSingleLineEditor,
   816                                   localEvent, DoCommandCallback, &singleLine);
   817   widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForMultiLineEditor,
   818                                   localEvent, DoCommandCallback, &multiLine);
   819   widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForRichTextEditor,
   820                                   localEvent, DoCommandCallback, &richText);
   822   if (!singleLine.IsEmpty() || !multiLine.IsEmpty() || !richText.IsEmpty()) {
   823     *aBindings = NativeKeyBinding(singleLine, multiLine, richText);
   824   }
   826   return true;
   827 }
   829 bool TabParent::SendRealKeyEvent(WidgetKeyboardEvent& event)
   830 {
   831   if (mIsDestroyed) {
   832     return false;
   833   }
   834   MaybeForwardEventToRenderFrame(event, nullptr);
   835   if (!MapEventCoordinatesForChildProcess(&event)) {
   836     return false;
   837   }
   840   MaybeNativeKeyBinding bindings;
   841   bindings = void_t();
   842   if (event.message == NS_KEY_PRESS) {
   843     nsCOMPtr<nsIWidget> widget = GetWidget();
   845     AutoInfallibleTArray<mozilla::CommandInt, 4> singleLine;
   846     AutoInfallibleTArray<mozilla::CommandInt, 4> multiLine;
   847     AutoInfallibleTArray<mozilla::CommandInt, 4> richText;
   849     widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForSingleLineEditor,
   850                                     event, DoCommandCallback, &singleLine);
   851     widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForMultiLineEditor,
   852                                     event, DoCommandCallback, &multiLine);
   853     widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForRichTextEditor,
   854                                     event, DoCommandCallback, &richText);
   856     if (!singleLine.IsEmpty() || !multiLine.IsEmpty() || !richText.IsEmpty()) {
   857       bindings = NativeKeyBinding(singleLine, multiLine, richText);
   858     }
   859   }
   861   return PBrowserParent::SendRealKeyEvent(event, bindings);
   862 }
   864 bool TabParent::SendRealTouchEvent(WidgetTouchEvent& event)
   865 {
   866   if (mIsDestroyed) {
   867     return false;
   868   }
   869   if (event.message == NS_TOUCH_START) {
   870     // Adjust the widget coordinates to be relative to our frame.
   871     nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
   872     if (!frameLoader) {
   873       // No frame anymore?
   874       sEventCapturer = nullptr;
   875       return false;
   876     }
   878     mChildProcessOffsetAtTouchStart =
   879       EventStateManager::GetChildProcessOffset(frameLoader, event);
   881     MOZ_ASSERT((!sEventCapturer && mEventCaptureDepth == 0) ||
   882                (sEventCapturer == this && mEventCaptureDepth > 0));
   883     // We want to capture all remaining touch events in this series
   884     // for fast-path dispatch.
   885     sEventCapturer = this;
   886     ++mEventCaptureDepth;
   887   }
   889   // PresShell::HandleEventInternal adds touches on touch end/cancel.  This
   890   // confuses remote content and the panning and zooming logic into thinking
   891   // that the added touches are part of the touchend/cancel, when actually
   892   // they're not.
   893   if (event.message == NS_TOUCH_END || event.message == NS_TOUCH_CANCEL) {
   894     for (int i = event.touches.Length() - 1; i >= 0; i--) {
   895       if (!event.touches[i]->mChanged) {
   896         event.touches.RemoveElementAt(i);
   897       }
   898     }
   899   }
   901   ScrollableLayerGuid guid;
   902   MaybeForwardEventToRenderFrame(event, &guid);
   904   if (mIsDestroyed) {
   905     return false;
   906   }
   908   MapEventCoordinatesForChildProcess(mChildProcessOffsetAtTouchStart, &event);
   910   return (event.message == NS_TOUCH_MOVE) ?
   911     PBrowserParent::SendRealTouchMoveEvent(event, guid) :
   912     PBrowserParent::SendRealTouchEvent(event, guid);
   913 }
   915 /*static*/ TabParent*
   916 TabParent::GetEventCapturer()
   917 {
   918   return sEventCapturer;
   919 }
   921 bool
   922 TabParent::TryCapture(const WidgetGUIEvent& aEvent)
   923 {
   924   MOZ_ASSERT(sEventCapturer == this && mEventCaptureDepth > 0);
   926   if (aEvent.eventStructType != NS_TOUCH_EVENT) {
   927     // Only capture of touch events is implemented, for now.
   928     return false;
   929   }
   931   WidgetTouchEvent event(*aEvent.AsTouchEvent());
   933   bool isTouchPointUp = (event.message == NS_TOUCH_END ||
   934                          event.message == NS_TOUCH_CANCEL);
   935   if (event.message == NS_TOUCH_START || isTouchPointUp) {
   936     // Let the DOM see touch start/end events so that its touch-point
   937     // state stays consistent.
   938     if (isTouchPointUp && 0 == --mEventCaptureDepth) {
   939       // All event series are un-captured, don't try to catch any
   940       // more.
   941       sEventCapturer = nullptr;
   942     }
   943     return false;
   944   }
   946   SendRealTouchEvent(event);
   947   return true;
   948 }
   950 bool
   951 TabParent::RecvSyncMessage(const nsString& aMessage,
   952                            const ClonedMessageData& aData,
   953                            const InfallibleTArray<CpowEntry>& aCpows,
   954                            const IPC::Principal& aPrincipal,
   955                            InfallibleTArray<nsString>* aJSONRetVal)
   956 {
   957   nsIPrincipal* principal = aPrincipal;
   958   ContentParent* parent = static_cast<ContentParent*>(Manager());
   959   if (!Preferences::GetBool("dom.testing.ignore_ipc_principal", false) &&
   960       principal && !AssertAppPrincipal(parent, principal)) {
   961     return false;
   962   }
   964   StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
   965   CpowIdHolder cpows(parent->GetCPOWManager(), aCpows);
   966   return ReceiveMessage(aMessage, true, &cloneData, &cpows, aPrincipal, aJSONRetVal);
   967 }
   969 bool
   970 TabParent::AnswerRpcMessage(const nsString& aMessage,
   971                             const ClonedMessageData& aData,
   972                             const InfallibleTArray<CpowEntry>& aCpows,
   973                             const IPC::Principal& aPrincipal,
   974                             InfallibleTArray<nsString>* aJSONRetVal)
   975 {
   976   nsIPrincipal* principal = aPrincipal;
   977   ContentParent* parent = static_cast<ContentParent*>(Manager());
   978   if (!Preferences::GetBool("dom.testing.ignore_ipc_principal", false) &&
   979       principal && !AssertAppPrincipal(parent, principal)) {
   980     return false;
   981   }
   983   StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
   984   CpowIdHolder cpows(parent->GetCPOWManager(), aCpows);
   985   return ReceiveMessage(aMessage, true, &cloneData, &cpows, aPrincipal, aJSONRetVal);
   986 }
   988 bool
   989 TabParent::RecvAsyncMessage(const nsString& aMessage,
   990                             const ClonedMessageData& aData,
   991                             const InfallibleTArray<CpowEntry>& aCpows,
   992                             const IPC::Principal& aPrincipal)
   993 {
   994   nsIPrincipal* principal = aPrincipal;
   995   ContentParent* parent = static_cast<ContentParent*>(Manager());
   996   if (!Preferences::GetBool("dom.testing.ignore_ipc_principal", false) &&
   997       principal && !AssertAppPrincipal(parent, principal)) {
   998     return false;
   999   }
  1001   StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
  1002   CpowIdHolder cpows(parent->GetCPOWManager(), aCpows);
  1003   return ReceiveMessage(aMessage, false, &cloneData, &cpows, aPrincipal, nullptr);
  1006 bool
  1007 TabParent::RecvSetCursor(const uint32_t& aCursor)
  1009   nsCOMPtr<nsIWidget> widget = GetWidget();
  1010   if (widget) {
  1011     widget->SetCursor((nsCursor) aCursor);
  1013   return true;
  1016 bool
  1017 TabParent::RecvSetBackgroundColor(const nscolor& aColor)
  1019   if (RenderFrameParent* frame = GetRenderFrame()) {
  1020     frame->SetBackgroundColor(aColor);
  1022   return true;
  1025 nsIXULBrowserWindow*
  1026 TabParent::GetXULBrowserWindow()
  1028   nsCOMPtr<nsIContent> frame = do_QueryInterface(mFrameElement);
  1029   if (!frame) {
  1030     return nullptr;
  1033   nsCOMPtr<nsIDocShell> docShell = frame->OwnerDoc()->GetDocShell();
  1034   if (!docShell) {
  1035     return nullptr;
  1038   nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
  1039   docShell->GetTreeOwner(getter_AddRefs(treeOwner));
  1040   if (!treeOwner) {
  1041     return nullptr;
  1044   nsCOMPtr<nsIXULWindow> window = do_GetInterface(treeOwner);
  1045   if (!window) {
  1046     return nullptr;
  1049   nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow;
  1050   window->GetXULBrowserWindow(getter_AddRefs(xulBrowserWindow));
  1051   return xulBrowserWindow;
  1054 bool
  1055 TabParent::RecvSetStatus(const uint32_t& aType, const nsString& aStatus)
  1057   nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow = GetXULBrowserWindow();
  1058   if (!xulBrowserWindow) {
  1059     return true;
  1062   switch (aType) {
  1063    case nsIWebBrowserChrome::STATUS_SCRIPT:
  1064     xulBrowserWindow->SetJSStatus(aStatus);
  1065     break;
  1066    case nsIWebBrowserChrome::STATUS_LINK:
  1067     xulBrowserWindow->SetOverLink(aStatus, nullptr);
  1068     break;
  1070   return true;
  1073 bool
  1074 TabParent::RecvShowTooltip(const uint32_t& aX, const uint32_t& aY, const nsString& aTooltip)
  1076   nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow = GetXULBrowserWindow();
  1077   if (!xulBrowserWindow) {
  1078     return true;
  1081   xulBrowserWindow->ShowTooltip(aX, aY, aTooltip);
  1082   return true;
  1085 bool
  1086 TabParent::RecvHideTooltip()
  1088   nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow = GetXULBrowserWindow();
  1089   if (!xulBrowserWindow) {
  1090     return true;
  1093   xulBrowserWindow->HideTooltip();
  1094   return true;
  1097 bool
  1098 TabParent::RecvNotifyIMEFocus(const bool& aFocus,
  1099                               nsIMEUpdatePreference* aPreference,
  1100                               uint32_t* aSeqno)
  1102   nsCOMPtr<nsIWidget> widget = GetWidget();
  1103   if (!widget) {
  1104     *aPreference = nsIMEUpdatePreference();
  1105     return true;
  1108   *aSeqno = mIMESeqno;
  1109   mIMETabParent = aFocus ? this : nullptr;
  1110   mIMESelectionAnchor = 0;
  1111   mIMESelectionFocus = 0;
  1112   widget->NotifyIME(IMENotification(aFocus ? NOTIFY_IME_OF_FOCUS :
  1113                                              NOTIFY_IME_OF_BLUR));
  1115   if (aFocus) {
  1116     *aPreference = widget->GetIMEUpdatePreference();
  1117   } else {
  1118     mIMECacheText.Truncate(0);
  1120   return true;
  1123 bool
  1124 TabParent::RecvNotifyIMETextChange(const uint32_t& aStart,
  1125                                    const uint32_t& aEnd,
  1126                                    const uint32_t& aNewEnd,
  1127                                    const bool& aCausedByComposition)
  1129   nsCOMPtr<nsIWidget> widget = GetWidget();
  1130   if (!widget)
  1131     return true;
  1133 #ifdef DEBUG
  1134   nsIMEUpdatePreference updatePreference = widget->GetIMEUpdatePreference();
  1135   NS_ASSERTION(updatePreference.WantTextChange(),
  1136                "Don't call Send/RecvNotifyIMETextChange without NOTIFY_TEXT_CHANGE");
  1137   MOZ_ASSERT(!aCausedByComposition ||
  1138                updatePreference.WantChangesCausedByComposition(),
  1139     "The widget doesn't want text change notification caused by composition");
  1140 #endif
  1142   IMENotification notification(NOTIFY_IME_OF_TEXT_CHANGE);
  1143   notification.mTextChangeData.mStartOffset = aStart;
  1144   notification.mTextChangeData.mOldEndOffset = aEnd;
  1145   notification.mTextChangeData.mNewEndOffset = aNewEnd;
  1146   notification.mTextChangeData.mCausedByComposition = aCausedByComposition;
  1147   widget->NotifyIME(notification);
  1148   return true;
  1151 bool
  1152 TabParent::RecvNotifyIMESelectedCompositionRect(const uint32_t& aOffset,
  1153                                                 const nsIntRect& aRect,
  1154                                                 const nsIntRect& aCaretRect)
  1156   // add rect to cache for another query
  1157   mIMECompositionRectOffset = aOffset;
  1158   mIMECompositionRect = aRect;
  1159   mIMECaretRect = aCaretRect;
  1161   nsCOMPtr<nsIWidget> widget = GetWidget();
  1162   if (!widget) {
  1163     return true;
  1165   widget->NotifyIME(IMENotification(NOTIFY_IME_OF_COMPOSITION_UPDATE));
  1166   return true;
  1169 bool
  1170 TabParent::RecvNotifyIMESelection(const uint32_t& aSeqno,
  1171                                   const uint32_t& aAnchor,
  1172                                   const uint32_t& aFocus,
  1173                                   const bool& aCausedByComposition)
  1175   nsCOMPtr<nsIWidget> widget = GetWidget();
  1176   if (!widget)
  1177     return true;
  1179   if (aSeqno == mIMESeqno) {
  1180     mIMESelectionAnchor = aAnchor;
  1181     mIMESelectionFocus = aFocus;
  1182     const nsIMEUpdatePreference updatePreference =
  1183       widget->GetIMEUpdatePreference();
  1184     if (updatePreference.WantSelectionChange() &&
  1185         (updatePreference.WantChangesCausedByComposition() ||
  1186          !aCausedByComposition)) {
  1187       IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE);
  1188       notification.mSelectionChangeData.mCausedByComposition =
  1189         aCausedByComposition;
  1190       widget->NotifyIME(notification);
  1193   return true;
  1196 bool
  1197 TabParent::RecvNotifyIMETextHint(const nsString& aText)
  1199   // Replace our cache with new text
  1200   mIMECacheText = aText;
  1201   return true;
  1204 bool
  1205 TabParent::RecvRequestFocus(const bool& aCanRaise)
  1207   nsCOMPtr<nsIFocusManager> fm = nsFocusManager::GetFocusManager();
  1208   if (!fm) {
  1209     return true;
  1212   nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
  1213   if (!content || !content->OwnerDoc()) {
  1214     return true;
  1217   uint32_t flags = nsIFocusManager::FLAG_NOSCROLL;
  1218   if (aCanRaise)
  1219     flags |= nsIFocusManager::FLAG_RAISE;
  1221   nsCOMPtr<nsIDOMElement> node = do_QueryInterface(mFrameElement);
  1222   fm->SetFocus(node, flags);
  1223   return true;
  1226 nsIntPoint
  1227 TabParent::GetChildProcessOffset()
  1229   // The "toplevel widget" in child processes is always at position
  1230   // 0,0.  Map the event coordinates to match that.
  1232   nsIntPoint offset(0, 0);
  1233   nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
  1234   if (!frameLoader) {
  1235     return offset;
  1237   nsIFrame* targetFrame = frameLoader->GetPrimaryFrameOfOwningContent();
  1238   if (!targetFrame) {
  1239     return offset;
  1242   // Find out how far we're offset from the nearest widget.
  1243   nsCOMPtr<nsIWidget> widget = GetWidget();
  1244   if (!widget) {
  1245     return offset;
  1247   nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(widget,
  1248                                                             nsIntPoint(0, 0),
  1249                                                             targetFrame);
  1251   return LayoutDeviceIntPoint::ToUntyped(LayoutDeviceIntPoint::FromAppUnitsToNearest(
  1252            pt, targetFrame->PresContext()->AppUnitsPerDevPixel()));
  1255 bool
  1256 TabParent::RecvReplyKeyEvent(const WidgetKeyboardEvent& event)
  1258   NS_ENSURE_TRUE(mFrameElement, true);
  1260   WidgetKeyboardEvent localEvent(event);
  1261   // Set mNoCrossProcessBoundaryForwarding to avoid this event from
  1262   // being infinitely redispatched and forwarded to the child again.
  1263   localEvent.mFlags.mNoCrossProcessBoundaryForwarding = true;
  1265   // Here we convert the WidgetEvent that we received to an nsIDOMEvent
  1266   // to be able to dispatch it to the <browser> element as the target element.
  1267   nsIDocument* doc = mFrameElement->OwnerDoc();
  1268   nsIPresShell* presShell = doc->GetShell();
  1269   NS_ENSURE_TRUE(presShell, true);
  1270   nsPresContext* presContext = presShell->GetPresContext();
  1271   NS_ENSURE_TRUE(presContext, true);
  1273   EventDispatcher::Dispatch(mFrameElement, presContext, &localEvent);
  1274   return true;
  1277 /**
  1278  * Try to answer query event using cached text.
  1280  * For NS_QUERY_SELECTED_TEXT, fail if the cache doesn't contain the whole
  1281  *  selected range. (This shouldn't happen because PuppetWidget should have
  1282  *  already sent the whole selection.)
  1284  * For NS_QUERY_TEXT_CONTENT, fail only if the cache doesn't overlap with
  1285  *  the queried range. Note the difference from above. We use
  1286  *  this behavior because a normal NS_QUERY_TEXT_CONTENT event is allowed to
  1287  *  have out-of-bounds offsets, so that widget can request content without
  1288  *  knowing the exact length of text. It's up to widget to handle cases when
  1289  *  the returned offset/length are different from the queried offset/length.
  1291  * For NS_QUERY_TEXT_RECT, fail if cached offset/length aren't equals to input.
  1292  *   Cocoa widget always queries selected offset, so it works on it.
  1294  * For NS_QUERY_CARET_RECT, fail if cached offset isn't equals to input
  1295  */
  1296 bool
  1297 TabParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent)
  1299   aEvent.mSucceeded = false;
  1300   aEvent.mWasAsync = false;
  1301   aEvent.mReply.mFocusedWidget = nsCOMPtr<nsIWidget>(GetWidget()).get();
  1303   switch (aEvent.message)
  1305   case NS_QUERY_SELECTED_TEXT:
  1307       aEvent.mReply.mOffset = std::min(mIMESelectionAnchor, mIMESelectionFocus);
  1308       if (mIMESelectionAnchor == mIMESelectionFocus) {
  1309         aEvent.mReply.mString.Truncate(0);
  1310       } else {
  1311         if (mIMESelectionAnchor > mIMECacheText.Length() ||
  1312             mIMESelectionFocus > mIMECacheText.Length()) {
  1313           break;
  1315         uint32_t selLen = mIMESelectionAnchor > mIMESelectionFocus ?
  1316                           mIMESelectionAnchor - mIMESelectionFocus :
  1317                           mIMESelectionFocus - mIMESelectionAnchor;
  1318         aEvent.mReply.mString = Substring(mIMECacheText,
  1319                                           aEvent.mReply.mOffset,
  1320                                           selLen);
  1322       aEvent.mReply.mReversed = mIMESelectionFocus < mIMESelectionAnchor;
  1323       aEvent.mReply.mHasSelection = true;
  1324       aEvent.mSucceeded = true;
  1326     break;
  1327   case NS_QUERY_TEXT_CONTENT:
  1329       uint32_t inputOffset = aEvent.mInput.mOffset,
  1330                inputEnd = inputOffset + aEvent.mInput.mLength;
  1332       if (inputEnd > mIMECacheText.Length()) {
  1333         inputEnd = mIMECacheText.Length();
  1335       if (inputEnd < inputOffset) {
  1336         break;
  1338       aEvent.mReply.mOffset = inputOffset;
  1339       aEvent.mReply.mString = Substring(mIMECacheText,
  1340                                         inputOffset,
  1341                                         inputEnd - inputOffset);
  1342       aEvent.mSucceeded = true;
  1344     break;
  1345   case NS_QUERY_TEXT_RECT:
  1347       if (aEvent.mInput.mOffset != mIMECompositionRectOffset ||
  1348           aEvent.mInput.mLength != 1) {
  1349         break;
  1352       aEvent.mReply.mOffset = mIMECompositionRectOffset;
  1353       aEvent.mReply.mRect = mIMECompositionRect - GetChildProcessOffset();
  1354       aEvent.mSucceeded = true;
  1356     break;
  1357   case NS_QUERY_CARET_RECT:
  1359       if (aEvent.mInput.mOffset != mIMECompositionRectOffset) {
  1360         break;
  1363       aEvent.mReply.mOffset = mIMECompositionRectOffset;
  1364       aEvent.mReply.mRect = mIMECaretRect - GetChildProcessOffset();
  1365       aEvent.mSucceeded = true;
  1367     break;
  1369   return true;
  1372 bool
  1373 TabParent::SendCompositionEvent(WidgetCompositionEvent& event)
  1375   if (mIsDestroyed) {
  1376     return false;
  1378   mIMEComposing = event.message != NS_COMPOSITION_END;
  1379   mIMECompositionStart = std::min(mIMESelectionAnchor, mIMESelectionFocus);
  1380   if (mIMECompositionEnding)
  1381     return true;
  1382   event.mSeqno = ++mIMESeqno;
  1383   return PBrowserParent::SendCompositionEvent(event);
  1386 /**
  1387  * During REQUEST_TO_COMMIT_COMPOSITION or REQUEST_TO_CANCEL_COMPOSITION,
  1388  * widget usually sends a NS_TEXT_TEXT event to finalize or clear the
  1389  * composition, respectively
  1391  * Because the event will not reach content in time, we intercept it
  1392  * here and pass the text as the EndIMEComposition return value
  1393  */
  1394 bool
  1395 TabParent::SendTextEvent(WidgetTextEvent& event)
  1397   if (mIsDestroyed) {
  1398     return false;
  1400   if (mIMECompositionEnding) {
  1401     mIMECompositionText = event.theText;
  1402     return true;
  1405   // We must be able to simulate the selection because
  1406   // we might not receive selection updates in time
  1407   if (!mIMEComposing) {
  1408     mIMECompositionStart = std::min(mIMESelectionAnchor, mIMESelectionFocus);
  1410   mIMESelectionAnchor = mIMESelectionFocus =
  1411       mIMECompositionStart + event.theText.Length();
  1413   event.mSeqno = ++mIMESeqno;
  1414   return PBrowserParent::SendTextEvent(event);
  1417 bool
  1418 TabParent::SendSelectionEvent(WidgetSelectionEvent& event)
  1420   if (mIsDestroyed) {
  1421     return false;
  1423   mIMESelectionAnchor = event.mOffset + (event.mReversed ? event.mLength : 0);
  1424   mIMESelectionFocus = event.mOffset + (!event.mReversed ? event.mLength : 0);
  1425   event.mSeqno = ++mIMESeqno;
  1426   return PBrowserParent::SendSelectionEvent(event);
  1429 /*static*/ TabParent*
  1430 TabParent::GetFrom(nsFrameLoader* aFrameLoader)
  1432   if (!aFrameLoader) {
  1433     return nullptr;
  1435   PBrowserParent* remoteBrowser = aFrameLoader->GetRemoteBrowser();
  1436   return static_cast<TabParent*>(remoteBrowser);
  1439 /*static*/ TabParent*
  1440 TabParent::GetFrom(nsIContent* aContent)
  1442   nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(aContent);
  1443   if (!loaderOwner) {
  1444     return nullptr;
  1446   nsRefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
  1447   return GetFrom(frameLoader);
  1450 RenderFrameParent*
  1451 TabParent::GetRenderFrame()
  1453   if (ManagedPRenderFrameParent().IsEmpty()) {
  1454     return nullptr;
  1456   return static_cast<RenderFrameParent*>(ManagedPRenderFrameParent()[0]);
  1459 bool
  1460 TabParent::RecvEndIMEComposition(const bool& aCancel,
  1461                                  nsString* aComposition)
  1463   nsCOMPtr<nsIWidget> widget = GetWidget();
  1464   if (!widget)
  1465     return true;
  1467   mIMECompositionEnding = true;
  1469   widget->NotifyIME(IMENotification(aCancel ? REQUEST_TO_CANCEL_COMPOSITION :
  1470                                               REQUEST_TO_COMMIT_COMPOSITION));
  1472   mIMECompositionEnding = false;
  1473   *aComposition = mIMECompositionText;
  1474   mIMECompositionText.Truncate(0);  
  1475   return true;
  1478 bool
  1479 TabParent::RecvGetInputContext(int32_t* aIMEEnabled,
  1480                                int32_t* aIMEOpen,
  1481                                intptr_t* aNativeIMEContext)
  1483   nsCOMPtr<nsIWidget> widget = GetWidget();
  1484   if (!widget) {
  1485     *aIMEEnabled = IMEState::DISABLED;
  1486     *aIMEOpen = IMEState::OPEN_STATE_NOT_SUPPORTED;
  1487     *aNativeIMEContext = 0;
  1488     return true;
  1491   InputContext context = widget->GetInputContext();
  1492   *aIMEEnabled = static_cast<int32_t>(context.mIMEState.mEnabled);
  1493   *aIMEOpen = static_cast<int32_t>(context.mIMEState.mOpen);
  1494   *aNativeIMEContext = reinterpret_cast<intptr_t>(context.mNativeIMEContext);
  1495   return true;
  1498 bool
  1499 TabParent::RecvSetInputContext(const int32_t& aIMEEnabled,
  1500                                const int32_t& aIMEOpen,
  1501                                const nsString& aType,
  1502                                const nsString& aInputmode,
  1503                                const nsString& aActionHint,
  1504                                const int32_t& aCause,
  1505                                const int32_t& aFocusChange)
  1507   // mIMETabParent (which is actually static) tracks which if any TabParent has IMEFocus
  1508   // When the input mode is set to anything but IMEState::DISABLED,
  1509   // mIMETabParent should be set to this
  1510   mIMETabParent =
  1511     aIMEEnabled != static_cast<int32_t>(IMEState::DISABLED) ? this : nullptr;
  1512   nsCOMPtr<nsIWidget> widget = GetWidget();
  1513   if (!widget || !AllowContentIME())
  1514     return true;
  1516   InputContext context;
  1517   context.mIMEState.mEnabled = static_cast<IMEState::Enabled>(aIMEEnabled);
  1518   context.mIMEState.mOpen = static_cast<IMEState::Open>(aIMEOpen);
  1519   context.mHTMLInputType.Assign(aType);
  1520   context.mHTMLInputInputmode.Assign(aInputmode);
  1521   context.mActionHint.Assign(aActionHint);
  1522   InputContextAction action(
  1523     static_cast<InputContextAction::Cause>(aCause),
  1524     static_cast<InputContextAction::FocusChange>(aFocusChange));
  1525   widget->SetInputContext(context, action);
  1527   nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
  1528   if (!observerService)
  1529     return true;
  1531   nsAutoString state;
  1532   state.AppendInt(aIMEEnabled);
  1533   observerService->NotifyObservers(nullptr, "ime-enabled-state-changed", state.get());
  1535   return true;
  1538 bool
  1539 TabParent::RecvIsParentWindowMainWidgetVisible(bool* aIsVisible)
  1541   nsCOMPtr<nsIContent> frame = do_QueryInterface(mFrameElement);
  1542   if (!frame)
  1543     return true;
  1544   nsCOMPtr<nsIDOMWindowUtils> windowUtils =
  1545     do_QueryInterface(frame->OwnerDoc()->GetWindow());
  1546   nsresult rv = windowUtils->GetIsParentWindowMainWidgetVisible(aIsVisible);
  1547   return NS_SUCCEEDED(rv);
  1550 bool
  1551 TabParent::RecvGetDPI(float* aValue)
  1553   TryCacheDPIAndScale();
  1555   NS_ABORT_IF_FALSE(mDPI > 0,
  1556                     "Must not ask for DPI before OwnerElement is received!");
  1557   *aValue = mDPI;
  1558   return true;
  1561 bool
  1562 TabParent::RecvGetDefaultScale(double* aValue)
  1564   TryCacheDPIAndScale();
  1566   NS_ABORT_IF_FALSE(mDefaultScale.scale > 0,
  1567                     "Must not ask for scale before OwnerElement is received!");
  1568   *aValue = mDefaultScale.scale;
  1569   return true;
  1572 bool
  1573 TabParent::RecvGetWidgetNativeData(WindowsHandle* aValue)
  1575   nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
  1576   if (content) {
  1577     nsIPresShell* shell = content->OwnerDoc()->GetShell();
  1578     if (shell) {
  1579       nsViewManager* vm = shell->GetViewManager();
  1580       nsCOMPtr<nsIWidget> widget;
  1581       vm->GetRootWidget(getter_AddRefs(widget));
  1582       if (widget) {
  1583         *aValue = reinterpret_cast<WindowsHandle>(
  1584           widget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW));
  1585         return true;
  1589   return false;
  1592 bool
  1593 TabParent::ReceiveMessage(const nsString& aMessage,
  1594                           bool aSync,
  1595                           const StructuredCloneData* aCloneData,
  1596                           CpowHolder* aCpows,
  1597                           nsIPrincipal* aPrincipal,
  1598                           InfallibleTArray<nsString>* aJSONRetVal)
  1600   nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
  1601   if (frameLoader && frameLoader->GetFrameMessageManager()) {
  1602     nsRefPtr<nsFrameMessageManager> manager =
  1603       frameLoader->GetFrameMessageManager();
  1605     manager->ReceiveMessage(mFrameElement,
  1606                             aMessage,
  1607                             aSync,
  1608                             aCloneData,
  1609                             aCpows,
  1610                             aPrincipal,
  1611                             aJSONRetVal);
  1613   return true;
  1616 PIndexedDBParent*
  1617 TabParent::AllocPIndexedDBParent(
  1618                             const nsCString& aGroup,
  1619                             const nsCString& aASCIIOrigin, bool* /* aAllowed */)
  1621   return new IndexedDBParent(this);
  1624 bool
  1625 TabParent::DeallocPIndexedDBParent(PIndexedDBParent* aActor)
  1627   delete aActor;
  1628   return true;
  1631 bool
  1632 TabParent::RecvPIndexedDBConstructor(PIndexedDBParent* aActor,
  1633                                      const nsCString& aGroup,
  1634                                      const nsCString& aASCIIOrigin,
  1635                                      bool* aAllowed)
  1637   nsRefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::GetOrCreate();
  1638   NS_ENSURE_TRUE(mgr, false);
  1640   if (!IndexedDatabaseManager::IsMainProcess()) {
  1641     NS_RUNTIMEABORT("Not supported yet!");
  1644   nsresult rv;
  1646   // XXXbent Need to make sure we have a whitelist for chrome databases!
  1648   // Verify that the child is requesting to access a database it's allowed to
  1649   // see.  (aASCIIOrigin here specifies a TabContext + a website origin, and
  1650   // we're checking that the TabContext may access it.)
  1651   //
  1652   // We have to check IsBrowserOrApp() because TabContextMayAccessOrigin will
  1653   // fail if we're not a browser-or-app, since aASCIIOrigin will be a plain URI,
  1654   // but TabContextMayAccessOrigin will construct an extended origin using
  1655   // app-id 0.  Note that as written below, we allow a non browser-or-app child
  1656   // to read any database.  That's a security hole, but we don't ship a
  1657   // configuration which creates non browser-or-app children, so it's not a big
  1658   // deal.
  1659   if (!aASCIIOrigin.EqualsLiteral("chrome") && IsBrowserOrApp() &&
  1660       !IndexedDatabaseManager::TabContextMayAccessOrigin(*this, aASCIIOrigin)) {
  1662     NS_WARNING("App attempted to open databases that it does not have "
  1663                "permission to access!");
  1664     return false;
  1667   nsCOMPtr<nsINode> node = do_QueryInterface(GetOwnerElement());
  1668   NS_ENSURE_TRUE(node, false);
  1670   nsIDocument* doc = node->GetOwnerDocument();
  1671   NS_ENSURE_TRUE(doc, false);
  1673   nsCOMPtr<nsPIDOMWindow> window = doc->GetInnerWindow();
  1674   NS_ENSURE_TRUE(window, false);
  1676   // Let's do a current inner check to see if the inner is active or is in
  1677   // bf cache, and bail out if it's not active.
  1678   nsCOMPtr<nsPIDOMWindow> outer = doc->GetWindow();
  1679   if (!outer || outer->GetCurrentInnerWindow() != window) {
  1680     *aAllowed = false;
  1681     return true;
  1684   ContentParent* contentParent = Manager();
  1685   NS_ASSERTION(contentParent, "Null manager?!");
  1687   nsRefPtr<IDBFactory> factory;
  1688   rv = IDBFactory::Create(window, aGroup, aASCIIOrigin, contentParent,
  1689                           getter_AddRefs(factory));
  1690   NS_ENSURE_SUCCESS(rv, false);
  1692   if (!factory) {
  1693     *aAllowed = false;
  1694     return true;
  1697   IndexedDBParent* actor = static_cast<IndexedDBParent*>(aActor);
  1698   actor->mFactory = factory;
  1699   actor->mASCIIOrigin = aASCIIOrigin;
  1701   *aAllowed = true;
  1702   return true;
  1705 // nsIAuthPromptProvider
  1707 // This method is largely copied from nsDocShell::GetAuthPrompt
  1708 NS_IMETHODIMP
  1709 TabParent::GetAuthPrompt(uint32_t aPromptReason, const nsIID& iid,
  1710                           void** aResult)
  1712   // we're either allowing auth, or it's a proxy request
  1713   nsresult rv;
  1714   nsCOMPtr<nsIPromptFactory> wwatch =
  1715     do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
  1716   NS_ENSURE_SUCCESS(rv, rv);
  1718   nsCOMPtr<nsIDOMWindow> window;
  1719   nsCOMPtr<nsIContent> frame = do_QueryInterface(mFrameElement);
  1720   if (frame)
  1721     window = do_QueryInterface(frame->OwnerDoc()->GetWindow());
  1723   // Get an auth prompter for our window so that the parenting
  1724   // of the dialogs works as it should when using tabs.
  1725   return wwatch->GetPrompt(window, iid,
  1726                            reinterpret_cast<void**>(aResult));
  1729 PColorPickerParent*
  1730 TabParent::AllocPColorPickerParent(const nsString& aTitle,
  1731                                    const nsString& aInitialColor)
  1733   return new ColorPickerParent(aTitle, aInitialColor);
  1736 bool
  1737 TabParent::DeallocPColorPickerParent(PColorPickerParent* actor)
  1739   delete actor;
  1740   return true;
  1743 bool
  1744 TabParent::RecvInitRenderFrame(PRenderFrameParent* aFrame,
  1745                                ScrollingBehavior* aScrolling,
  1746                                TextureFactoryIdentifier* aTextureFactoryIdentifier,
  1747                                uint64_t* aLayersId,
  1748                                bool *aSuccess)
  1750   *aScrolling = UseAsyncPanZoom() ? ASYNC_PAN_ZOOM : DEFAULT_SCROLLING;
  1751   *aTextureFactoryIdentifier = TextureFactoryIdentifier();
  1752   *aLayersId = 0;
  1754   nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
  1755   if (!frameLoader) {
  1756     NS_WARNING("Can't allocate graphics resources. May already be shutting down.");
  1757     *aSuccess = false;
  1758     return true;
  1761   static_cast<RenderFrameParent*>(aFrame)->Init(frameLoader, *aScrolling,
  1762                                                 aTextureFactoryIdentifier, aLayersId);
  1764   *aSuccess = true;
  1765   return true;
  1768 PRenderFrameParent*
  1769 TabParent::AllocPRenderFrameParent()
  1771   MOZ_ASSERT(ManagedPRenderFrameParent().IsEmpty());
  1772   return new RenderFrameParent();
  1775 bool
  1776 TabParent::DeallocPRenderFrameParent(PRenderFrameParent* aFrame)
  1778   delete aFrame;
  1779   return true;
  1782 mozilla::docshell::POfflineCacheUpdateParent*
  1783 TabParent::AllocPOfflineCacheUpdateParent(const URIParams& aManifestURI,
  1784                                           const URIParams& aDocumentURI,
  1785                                           const bool& aStickDocument)
  1787   nsRefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
  1788     new mozilla::docshell::OfflineCacheUpdateParent(OwnOrContainingAppId(),
  1789                                                     IsBrowserElement());
  1790   // Use this reference as the IPDL reference.
  1791   return update.forget().take();
  1794 bool
  1795 TabParent::RecvPOfflineCacheUpdateConstructor(POfflineCacheUpdateParent* aActor,
  1796                                               const URIParams& aManifestURI,
  1797                                               const URIParams& aDocumentURI,
  1798                                               const bool& aStickDocument)
  1800   MOZ_ASSERT(aActor);
  1802   nsRefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
  1803     static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(aActor);
  1805   nsresult rv = update->Schedule(aManifestURI, aDocumentURI, aStickDocument);
  1806   if (NS_FAILED(rv) && !IsDestroyed()) {
  1807     // Inform the child of failure.
  1808     unused << update->SendFinish(false, false);
  1811   return true;
  1814 bool
  1815 TabParent::DeallocPOfflineCacheUpdateParent(POfflineCacheUpdateParent* aActor)
  1817   // Reclaim the IPDL reference.
  1818   nsRefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
  1819     dont_AddRef(
  1820       static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(aActor));
  1821   return true;
  1824 bool
  1825 TabParent::RecvSetOfflinePermission(const IPC::Principal& aPrincipal)
  1827   nsIPrincipal* principal = aPrincipal;
  1828   nsContentUtils::MaybeAllowOfflineAppByDefault(principal, nullptr);
  1829   return true;
  1832 bool
  1833 TabParent::AllowContentIME()
  1835   nsFocusManager* fm = nsFocusManager::GetFocusManager();
  1836   NS_ENSURE_TRUE(fm, false);
  1838   nsCOMPtr<nsIContent> focusedContent = fm->GetFocusedContent();
  1839   if (focusedContent && focusedContent->IsEditable())
  1840     return false;
  1842   return true;
  1845 already_AddRefed<nsFrameLoader>
  1846 TabParent::GetFrameLoader() const
  1848   nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner = do_QueryInterface(mFrameElement);
  1849   return frameLoaderOwner ? frameLoaderOwner->GetFrameLoader() : nullptr;
  1852 void
  1853 TabParent::TryCacheDPIAndScale()
  1855   if (mDPI > 0) {
  1856     return;
  1859   nsCOMPtr<nsIWidget> widget = GetWidget();
  1861   if (!widget && mFrameElement) {
  1862     // Even if we don't have a widget (e.g. because we're display:none), there's
  1863     // probably a widget somewhere in the hierarchy our frame element lives in.
  1864     widget = nsContentUtils::WidgetForDocument(mFrameElement->OwnerDoc());
  1867   if (widget) {
  1868     mDPI = widget->GetDPI();
  1869     mDefaultScale = widget->GetDefaultScale();
  1873 already_AddRefed<nsIWidget>
  1874 TabParent::GetWidget() const
  1876   nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
  1877   if (!content)
  1878     return nullptr;
  1880   nsIFrame *frame = content->GetPrimaryFrame();
  1881   if (!frame)
  1882     return nullptr;
  1884   nsCOMPtr<nsIWidget> widget = frame->GetNearestWidget();
  1885   return widget.forget();
  1888 bool
  1889 TabParent::UseAsyncPanZoom()
  1891   bool usingOffMainThreadCompositing = !!CompositorParent::CompositorLoop();
  1892   bool asyncPanZoomEnabled =
  1893     Preferences::GetBool("layers.async-pan-zoom.enabled", false);
  1894   return (usingOffMainThreadCompositing && asyncPanZoomEnabled &&
  1895           GetScrollingBehavior() == ASYNC_PAN_ZOOM);
  1898 void
  1899 TabParent::MaybeForwardEventToRenderFrame(WidgetInputEvent& aEvent,
  1900                                           ScrollableLayerGuid* aOutTargetGuid)
  1902   if (RenderFrameParent* rfp = GetRenderFrame()) {
  1903     rfp->NotifyInputEvent(aEvent, aOutTargetGuid);
  1907 bool
  1908 TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
  1909                                       const nsString& aURL,
  1910                                       const nsString& aName,
  1911                                       const nsString& aFeatures,
  1912                                       bool* aOutWindowOpened)
  1914   BrowserElementParent::OpenWindowResult opened =
  1915     BrowserElementParent::OpenWindowOOP(static_cast<TabParent*>(aOpener),
  1916                                         this, aURL, aName, aFeatures);
  1917   *aOutWindowOpened = (opened != BrowserElementParent::OPEN_WINDOW_CANCELLED);
  1918   return true;
  1921 bool
  1922 TabParent::RecvPRenderFrameConstructor(PRenderFrameParent* actor)
  1924   return true;
  1927 bool
  1928 TabParent::RecvZoomToRect(const uint32_t& aPresShellId,
  1929                           const ViewID& aViewId,
  1930                           const CSSRect& aRect)
  1932   if (RenderFrameParent* rfp = GetRenderFrame()) {
  1933     rfp->ZoomToRect(aPresShellId, aViewId, aRect);
  1935   return true;
  1938 bool
  1939 TabParent::RecvUpdateZoomConstraints(const uint32_t& aPresShellId,
  1940                                      const ViewID& aViewId,
  1941                                      const bool& aIsRoot,
  1942                                      const ZoomConstraints& aConstraints)
  1944   if (RenderFrameParent* rfp = GetRenderFrame()) {
  1945     rfp->UpdateZoomConstraints(aPresShellId, aViewId, aIsRoot, aConstraints);
  1947   return true;
  1950 bool
  1951 TabParent::RecvContentReceivedTouch(const ScrollableLayerGuid& aGuid,
  1952                                     const bool& aPreventDefault)
  1954   if (RenderFrameParent* rfp = GetRenderFrame()) {
  1955     rfp->ContentReceivedTouch(aGuid, aPreventDefault);
  1957   return true;
  1960 already_AddRefed<nsILoadContext>
  1961 TabParent::GetLoadContext()
  1963   nsCOMPtr<nsILoadContext> loadContext;
  1964   if (mLoadContext) {
  1965     loadContext = mLoadContext;
  1966   } else {
  1967     loadContext = new LoadContext(GetOwnerElement(),
  1968                                   OwnOrContainingAppId(),
  1969                                   true /* aIsContent */,
  1970                                   mChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW,
  1971                                   mChromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW,
  1972                                   IsBrowserElement());
  1973     mLoadContext = loadContext;
  1975   return loadContext.forget();
  1978 /* Be careful if you call this method while proceding a real touch event. For
  1979  * example sending a touchstart during a real touchend may results into
  1980  * a busted mEventCaptureDepth and following touch events may not do what you
  1981  * expect.
  1982  */
  1983 NS_IMETHODIMP
  1984 TabParent::InjectTouchEvent(const nsAString& aType,
  1985                             uint32_t* aIdentifiers,
  1986                             int32_t* aXs,
  1987                             int32_t* aYs,
  1988                             uint32_t* aRxs,
  1989                             uint32_t* aRys,
  1990                             float* aRotationAngles,
  1991                             float* aForces,
  1992                             uint32_t aCount,
  1993                             int32_t aModifiers)
  1995   uint32_t msg;
  1996   nsContentUtils::GetEventIdAndAtom(aType, NS_TOUCH_EVENT, &msg);
  1997   if (msg != NS_TOUCH_START && msg != NS_TOUCH_MOVE &&
  1998       msg != NS_TOUCH_END && msg != NS_TOUCH_CANCEL) {
  1999     return NS_ERROR_FAILURE;
  2002   nsCOMPtr<nsIWidget> widget = GetWidget();
  2003   if (!widget) {
  2004     return NS_ERROR_FAILURE;
  2007   WidgetTouchEvent event(true, msg, widget);
  2008   event.modifiers = aModifiers;
  2009   event.time = PR_IntervalNow();
  2011   event.touches.SetCapacity(aCount);
  2012   for (uint32_t i = 0; i < aCount; ++i) {
  2013     nsRefPtr<Touch> t = new Touch(aIdentifiers[i],
  2014                                   nsIntPoint(aXs[i], aYs[i]),
  2015                                   nsIntPoint(aRxs[i], aRys[i]),
  2016                                   aRotationAngles[i],
  2017                                   aForces[i]);
  2019     // Consider all injected touch events as changedTouches. For more details
  2020     // about the meaning of changedTouches for each event, see
  2021     // https://developer.mozilla.org/docs/Web/API/TouchEvent.changedTouches
  2022     t->mChanged = true;
  2023     event.touches.AppendElement(t);
  2026   if ((msg == NS_TOUCH_END || msg == NS_TOUCH_CANCEL) && sEventCapturer) {
  2027     WidgetGUIEvent* guiEvent = event.AsGUIEvent();
  2028     TryCapture(*guiEvent);
  2031   SendRealTouchEvent(event);
  2032   return NS_OK;
  2035 NS_IMETHODIMP
  2036 TabParent::GetUseAsyncPanZoom(bool* useAsyncPanZoom)
  2038   *useAsyncPanZoom = UseAsyncPanZoom();
  2039   return NS_OK;
  2042 NS_IMETHODIMP
  2043 TabParent::SetIsDocShellActive(bool isActive)
  2045   unused << SendSetIsDocShellActive(isActive);
  2046   return NS_OK;
  2049 } // namespace tabs
  2050 } // namespace mozilla

mercurial