dom/ipc/TabParent.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/ipc/TabParent.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,2050 @@
     1.4 +/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8; -*- */
     1.5 +/* vim: set sw=2 ts=8 et tw=80 : */
     1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.9 +
    1.10 +#include "base/basictypes.h"
    1.11 +
    1.12 +#include "TabParent.h"
    1.13 +
    1.14 +#include "AppProcessChecker.h"
    1.15 +#include "IDBFactory.h"
    1.16 +#include "IndexedDBParent.h"
    1.17 +#include "mozIApplication.h"
    1.18 +#include "mozilla/BrowserElementParent.h"
    1.19 +#include "mozilla/docshell/OfflineCacheUpdateParent.h"
    1.20 +#include "mozilla/dom/ContentParent.h"
    1.21 +#include "mozilla/dom/PContentPermissionRequestParent.h"
    1.22 +#include "mozilla/EventStateManager.h"
    1.23 +#include "mozilla/Hal.h"
    1.24 +#include "mozilla/ipc/DocumentRendererParent.h"
    1.25 +#include "mozilla/layers/CompositorParent.h"
    1.26 +#include "mozilla/layout/RenderFrameParent.h"
    1.27 +#include "mozilla/MouseEvents.h"
    1.28 +#include "mozilla/Preferences.h"
    1.29 +#include "mozilla/TextEvents.h"
    1.30 +#include "mozilla/TouchEvents.h"
    1.31 +#include "mozilla/unused.h"
    1.32 +#include "nsCOMPtr.h"
    1.33 +#include "nsContentPermissionHelper.h"
    1.34 +#include "nsContentUtils.h"
    1.35 +#include "nsDebug.h"
    1.36 +#include "nsFocusManager.h"
    1.37 +#include "nsFrameLoader.h"
    1.38 +#include "nsIContent.h"
    1.39 +#include "nsIDocShell.h"
    1.40 +#include "nsIDocShellTreeOwner.h"
    1.41 +#include "nsIDOMElement.h"
    1.42 +#include "nsIDOMEvent.h"
    1.43 +#include "nsIDOMWindow.h"
    1.44 +#include "nsIDOMWindowUtils.h"
    1.45 +#include "nsIInterfaceRequestorUtils.h"
    1.46 +#include "nsIPromptFactory.h"
    1.47 +#include "nsIURI.h"
    1.48 +#include "nsIWebBrowserChrome.h"
    1.49 +#include "nsIXULBrowserWindow.h"
    1.50 +#include "nsIXULWindow.h"
    1.51 +#include "nsViewManager.h"
    1.52 +#include "nsIWidget.h"
    1.53 +#include "nsIWindowWatcher.h"
    1.54 +#include "nsPIDOMWindow.h"
    1.55 +#include "nsPrintfCString.h"
    1.56 +#include "nsServiceManagerUtils.h"
    1.57 +#include "nsThreadUtils.h"
    1.58 +#include "private/pprio.h"
    1.59 +#include "PermissionMessageUtils.h"
    1.60 +#include "StructuredCloneUtils.h"
    1.61 +#include "ColorPickerParent.h"
    1.62 +#include "JavaScriptParent.h"
    1.63 +#include "FilePickerParent.h"
    1.64 +#include "TabChild.h"
    1.65 +#include "LoadContext.h"
    1.66 +#include "nsNetCID.h"
    1.67 +#include <algorithm>
    1.68 +
    1.69 +using namespace mozilla::dom;
    1.70 +using namespace mozilla::ipc;
    1.71 +using namespace mozilla::layers;
    1.72 +using namespace mozilla::layout;
    1.73 +using namespace mozilla::services;
    1.74 +using namespace mozilla::widget;
    1.75 +using namespace mozilla::dom::indexedDB;
    1.76 +using namespace mozilla::jsipc;
    1.77 +
    1.78 +// The flags passed by the webProgress notifications are 16 bits shifted
    1.79 +// from the ones registered by webProgressListeners.
    1.80 +#define NOTIFY_FLAG_SHIFT 16
    1.81 +
    1.82 +class OpenFileAndSendFDRunnable : public nsRunnable
    1.83 +{
    1.84 +    const nsString mPath;
    1.85 +    nsRefPtr<TabParent> mTabParent;
    1.86 +    nsCOMPtr<nsIEventTarget> mEventTarget;
    1.87 +    PRFileDesc* mFD;
    1.88 +
    1.89 +public:
    1.90 +    OpenFileAndSendFDRunnable(const nsAString& aPath, TabParent* aTabParent)
    1.91 +      : mPath(aPath), mTabParent(aTabParent), mFD(nullptr)
    1.92 +    {
    1.93 +        MOZ_ASSERT(NS_IsMainThread());
    1.94 +        MOZ_ASSERT(!aPath.IsEmpty());
    1.95 +        MOZ_ASSERT(aTabParent);
    1.96 +    }
    1.97 +
    1.98 +    void Dispatch()
    1.99 +    {
   1.100 +        MOZ_ASSERT(NS_IsMainThread());
   1.101 +
   1.102 +        mEventTarget = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
   1.103 +        NS_ENSURE_TRUE_VOID(mEventTarget);
   1.104 +
   1.105 +        nsresult rv = mEventTarget->Dispatch(this, NS_DISPATCH_NORMAL);
   1.106 +        NS_ENSURE_SUCCESS_VOID(rv);
   1.107 +    }
   1.108 +
   1.109 +private:
   1.110 +    ~OpenFileAndSendFDRunnable()
   1.111 +    {
   1.112 +        MOZ_ASSERT(!mFD);
   1.113 +    }
   1.114 +
   1.115 +    // This shouldn't be called directly except by the event loop. Use Dispatch
   1.116 +    // to start the sequence.
   1.117 +    NS_IMETHOD Run()
   1.118 +    {
   1.119 +        if (NS_IsMainThread()) {
   1.120 +            SendResponse();
   1.121 +        } else if (mFD) {
   1.122 +            CloseFile();
   1.123 +        } else {
   1.124 +            OpenFile();
   1.125 +        }
   1.126 +
   1.127 +        return NS_OK;
   1.128 +    }
   1.129 +
   1.130 +    void SendResponse()
   1.131 +    {
   1.132 +        MOZ_ASSERT(NS_IsMainThread());
   1.133 +        MOZ_ASSERT(mTabParent);
   1.134 +        MOZ_ASSERT(mEventTarget);
   1.135 +        MOZ_ASSERT(mFD);
   1.136 +
   1.137 +        nsRefPtr<TabParent> tabParent;
   1.138 +        mTabParent.swap(tabParent);
   1.139 +
   1.140 +        using mozilla::ipc::FileDescriptor;
   1.141 +
   1.142 +        FileDescriptor::PlatformHandleType handle =
   1.143 +            FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(mFD));
   1.144 +
   1.145 +        mozilla::unused << tabParent->SendCacheFileDescriptor(mPath, handle);
   1.146 +
   1.147 +        nsCOMPtr<nsIEventTarget> eventTarget;
   1.148 +        mEventTarget.swap(eventTarget);
   1.149 +
   1.150 +        if (NS_FAILED(eventTarget->Dispatch(this, NS_DISPATCH_NORMAL))) {
   1.151 +            NS_WARNING("Failed to dispatch to stream transport service!");
   1.152 +
   1.153 +            // It's probably safer to take the main thread IO hit here rather
   1.154 +            // than leak a file descriptor.
   1.155 +            CloseFile();
   1.156 +        }
   1.157 +    }
   1.158 +
   1.159 +    void OpenFile()
   1.160 +    {
   1.161 +        MOZ_ASSERT(!NS_IsMainThread());
   1.162 +        MOZ_ASSERT(!mFD);
   1.163 +
   1.164 +        nsCOMPtr<nsIFile> file;
   1.165 +        nsresult rv = NS_NewLocalFile(mPath, false, getter_AddRefs(file));
   1.166 +        NS_ENSURE_SUCCESS_VOID(rv);
   1.167 +
   1.168 +        PRFileDesc* fd;
   1.169 +        rv = file->OpenNSPRFileDesc(PR_RDONLY, 0, &fd);
   1.170 +        NS_ENSURE_SUCCESS_VOID(rv);
   1.171 +
   1.172 +        mFD = fd;
   1.173 +
   1.174 +        if (NS_FAILED(NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL))) {
   1.175 +            NS_WARNING("Failed to dispatch to main thread!");
   1.176 +
   1.177 +            CloseFile();
   1.178 +        }
   1.179 +    }
   1.180 +
   1.181 +    void CloseFile()
   1.182 +    {
   1.183 +        // It's possible for this to happen on the main thread if the dispatch
   1.184 +        // to the stream service fails after we've already opened the file so
   1.185 +        // we can't assert the thread we're running on.
   1.186 +
   1.187 +        MOZ_ASSERT(mFD);
   1.188 +
   1.189 +        PRStatus prrc;
   1.190 +        prrc = PR_Close(mFD);
   1.191 +        if (prrc != PR_SUCCESS) {
   1.192 +          NS_ERROR("PR_Close() failed.");
   1.193 +        }
   1.194 +        mFD = nullptr;
   1.195 +    }
   1.196 +};
   1.197 +
   1.198 +namespace mozilla {
   1.199 +namespace dom {
   1.200 +
   1.201 +TabParent* sEventCapturer;
   1.202 +
   1.203 +TabParent *TabParent::mIMETabParent = nullptr;
   1.204 +
   1.205 +NS_IMPL_ISUPPORTS(TabParent, nsITabParent, nsIAuthPromptProvider, nsISecureBrowserUI)
   1.206 +
   1.207 +TabParent::TabParent(ContentParent* aManager, const TabContext& aContext, uint32_t aChromeFlags)
   1.208 +  : TabContext(aContext)
   1.209 +  , mFrameElement(nullptr)
   1.210 +  , mIMESelectionAnchor(0)
   1.211 +  , mIMESelectionFocus(0)
   1.212 +  , mIMEComposing(false)
   1.213 +  , mIMECompositionEnding(false)
   1.214 +  , mIMECompositionStart(0)
   1.215 +  , mIMESeqno(0)
   1.216 +  , mIMECompositionRectOffset(0)
   1.217 +  , mEventCaptureDepth(0)
   1.218 +  , mRect(0, 0, 0, 0)
   1.219 +  , mDimensions(0, 0)
   1.220 +  , mOrientation(0)
   1.221 +  , mDPI(0)
   1.222 +  , mDefaultScale(0)
   1.223 +  , mShown(false)
   1.224 +  , mUpdatedDimensions(false)
   1.225 +  , mManager(aManager)
   1.226 +  , mMarkedDestroying(false)
   1.227 +  , mIsDestroyed(false)
   1.228 +  , mAppPackageFileDescriptorSent(false)
   1.229 +  , mChromeFlags(aChromeFlags)
   1.230 +{
   1.231 +}
   1.232 +
   1.233 +TabParent::~TabParent()
   1.234 +{
   1.235 +}
   1.236 +
   1.237 +void
   1.238 +TabParent::SetOwnerElement(Element* aElement)
   1.239 +{
   1.240 +  mFrameElement = aElement;
   1.241 +  TryCacheDPIAndScale();
   1.242 +}
   1.243 +
   1.244 +void
   1.245 +TabParent::GetAppType(nsAString& aOut)
   1.246 +{
   1.247 +  aOut.Truncate();
   1.248 +  nsCOMPtr<Element> elem = do_QueryInterface(mFrameElement);
   1.249 +  if (!elem) {
   1.250 +    return;
   1.251 +  }
   1.252 +
   1.253 +  elem->GetAttr(kNameSpaceID_None, nsGkAtoms::mozapptype, aOut);
   1.254 +}
   1.255 +
   1.256 +bool
   1.257 +TabParent::IsVisible()
   1.258 +{
   1.259 +  nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
   1.260 +  if (!frameLoader) {
   1.261 +    return false;
   1.262 +  }
   1.263 +
   1.264 +  bool visible = false;
   1.265 +  frameLoader->GetVisible(&visible);
   1.266 +  return visible;
   1.267 +}
   1.268 +
   1.269 +void
   1.270 +TabParent::Destroy()
   1.271 +{
   1.272 +  if (mIsDestroyed) {
   1.273 +    return;
   1.274 +  }
   1.275 +
   1.276 +  // If this fails, it's most likely due to a content-process crash,
   1.277 +  // and auto-cleanup will kick in.  Otherwise, the child side will
   1.278 +  // destroy itself and send back __delete__().
   1.279 +  unused << SendDestroy();
   1.280 +
   1.281 +  const InfallibleTArray<PIndexedDBParent*>& idbParents =
   1.282 +    ManagedPIndexedDBParent();
   1.283 +  for (uint32_t i = 0; i < idbParents.Length(); ++i) {
   1.284 +    static_cast<IndexedDBParent*>(idbParents[i])->Disconnect();
   1.285 +  }
   1.286 +
   1.287 +  const InfallibleTArray<POfflineCacheUpdateParent*>& ocuParents =
   1.288 +    ManagedPOfflineCacheUpdateParent();
   1.289 +  for (uint32_t i = 0; i < ocuParents.Length(); ++i) {
   1.290 +    nsRefPtr<mozilla::docshell::OfflineCacheUpdateParent> ocuParent =
   1.291 +      static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(ocuParents[i]);
   1.292 +    ocuParent->StopSendingMessagesToChild();
   1.293 +  }
   1.294 +
   1.295 +  if (RenderFrameParent* frame = GetRenderFrame()) {
   1.296 +    frame->Destroy();
   1.297 +  }
   1.298 +  mIsDestroyed = true;
   1.299 +
   1.300 +  Manager()->NotifyTabDestroying(this);
   1.301 +  mMarkedDestroying = true;
   1.302 +}
   1.303 +
   1.304 +bool
   1.305 +TabParent::Recv__delete__()
   1.306 +{
   1.307 +  Manager()->NotifyTabDestroyed(this, mMarkedDestroying);
   1.308 +  return true;
   1.309 +}
   1.310 +
   1.311 +void
   1.312 +TabParent::ActorDestroy(ActorDestroyReason why)
   1.313 +{
   1.314 +  if (sEventCapturer == this) {
   1.315 +    sEventCapturer = nullptr;
   1.316 +  }
   1.317 +  if (mIMETabParent == this) {
   1.318 +    mIMETabParent = nullptr;
   1.319 +  }
   1.320 +  nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
   1.321 +  nsCOMPtr<nsIObserverService> os = services::GetObserverService();
   1.322 +  nsRefPtr<nsFrameMessageManager> fmm;
   1.323 +  if (frameLoader) {
   1.324 +    fmm = frameLoader->GetFrameMessageManager();
   1.325 +    nsCOMPtr<Element> frameElement(mFrameElement);
   1.326 +    ReceiveMessage(CHILD_PROCESS_SHUTDOWN_MESSAGE, false, nullptr, nullptr,
   1.327 +                   nullptr);
   1.328 +    frameLoader->DestroyChild();
   1.329 +
   1.330 +    if (why == AbnormalShutdown && os) {
   1.331 +      os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, frameLoader),
   1.332 +                          "oop-frameloader-crashed", nullptr);
   1.333 +      nsContentUtils::DispatchTrustedEvent(frameElement->OwnerDoc(), frameElement,
   1.334 +                                           NS_LITERAL_STRING("oop-browser-crashed"),
   1.335 +                                           true, true);
   1.336 +    }
   1.337 +  }
   1.338 +
   1.339 +  if (os) {
   1.340 +    os->NotifyObservers(NS_ISUPPORTS_CAST(nsITabParent*, this), "ipc:browser-destroyed", nullptr);
   1.341 +  }
   1.342 +  if (fmm) {
   1.343 +    fmm->Disconnect();
   1.344 +  }
   1.345 +}
   1.346 +
   1.347 +bool
   1.348 +TabParent::RecvMoveFocus(const bool& aForward)
   1.349 +{
   1.350 +  nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
   1.351 +  if (fm) {
   1.352 +    nsCOMPtr<nsIDOMElement> dummy;
   1.353 +    uint32_t type = aForward ? uint32_t(nsIFocusManager::MOVEFOCUS_FORWARD)
   1.354 +                             : uint32_t(nsIFocusManager::MOVEFOCUS_BACKWARD);
   1.355 +    nsCOMPtr<nsIDOMElement> frame = do_QueryInterface(mFrameElement);
   1.356 +    fm->MoveFocus(nullptr, frame, type, nsIFocusManager::FLAG_BYKEY,
   1.357 +                  getter_AddRefs(dummy));
   1.358 +  }
   1.359 +  return true;
   1.360 +}
   1.361 +
   1.362 +bool
   1.363 +TabParent::RecvEvent(const RemoteDOMEvent& aEvent)
   1.364 +{
   1.365 +  nsCOMPtr<nsIDOMEvent> event = do_QueryInterface(aEvent.mEvent);
   1.366 +  NS_ENSURE_TRUE(event, true);
   1.367 +
   1.368 +  nsCOMPtr<mozilla::dom::EventTarget> target = do_QueryInterface(mFrameElement);
   1.369 +  NS_ENSURE_TRUE(target, true);
   1.370 +
   1.371 +  event->SetOwner(target);
   1.372 +
   1.373 +  bool dummy;
   1.374 +  target->DispatchEvent(event, &dummy);
   1.375 +  return true;
   1.376 +}
   1.377 +
   1.378 +bool
   1.379 +TabParent::AnswerCreateWindow(PBrowserParent** retval)
   1.380 +{
   1.381 +    if (!mBrowserDOMWindow) {
   1.382 +        return false;
   1.383 +    }
   1.384 +
   1.385 +    // Only non-app, non-browser processes may call CreateWindow.
   1.386 +    if (IsBrowserOrApp()) {
   1.387 +        return false;
   1.388 +    }
   1.389 +
   1.390 +    // Get a new rendering area from the browserDOMWin.  We don't want
   1.391 +    // to be starting any loads here, so get it with a null URI.
   1.392 +    nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner;
   1.393 +    mBrowserDOMWindow->OpenURIInFrame(nullptr, nullptr,
   1.394 +                                      nsIBrowserDOMWindow::OPEN_NEWTAB,
   1.395 +                                      nsIBrowserDOMWindow::OPEN_NEW,
   1.396 +                                      getter_AddRefs(frameLoaderOwner));
   1.397 +    if (!frameLoaderOwner) {
   1.398 +        return false;
   1.399 +    }
   1.400 +
   1.401 +    nsRefPtr<nsFrameLoader> frameLoader = frameLoaderOwner->GetFrameLoader();
   1.402 +    if (!frameLoader) {
   1.403 +        return false;
   1.404 +    }
   1.405 +
   1.406 +    *retval = frameLoader->GetRemoteBrowser();
   1.407 +    return true;
   1.408 +}
   1.409 +
   1.410 +void
   1.411 +TabParent::LoadURL(nsIURI* aURI)
   1.412 +{
   1.413 +    MOZ_ASSERT(aURI);
   1.414 +
   1.415 +    if (mIsDestroyed) {
   1.416 +        return;
   1.417 +    }
   1.418 +
   1.419 +    nsCString spec;
   1.420 +    aURI->GetSpec(spec);
   1.421 +
   1.422 +    if (!mShown) {
   1.423 +        NS_WARNING(nsPrintfCString("TabParent::LoadURL(%s) called before "
   1.424 +                                   "Show(). Ignoring LoadURL.\n",
   1.425 +                                   spec.get()).get());
   1.426 +        return;
   1.427 +    }
   1.428 +
   1.429 +    unused << SendLoadURL(spec);
   1.430 +
   1.431 +    // If this app is a packaged app then we can speed startup by sending over
   1.432 +    // the file descriptor for the "application.zip" file that it will
   1.433 +    // invariably request. Only do this once.
   1.434 +    if (!mAppPackageFileDescriptorSent) {
   1.435 +        mAppPackageFileDescriptorSent = true;
   1.436 +
   1.437 +        nsCOMPtr<mozIApplication> app = GetOwnOrContainingApp();
   1.438 +        if (app) {
   1.439 +            nsString manifestURL;
   1.440 +            nsresult rv = app->GetManifestURL(manifestURL);
   1.441 +            NS_ENSURE_SUCCESS_VOID(rv);
   1.442 +
   1.443 +            if (StringBeginsWith(manifestURL, NS_LITERAL_STRING("app:"))) {
   1.444 +                nsString basePath;
   1.445 +                rv = app->GetBasePath(basePath);
   1.446 +                NS_ENSURE_SUCCESS_VOID(rv);
   1.447 +
   1.448 +                nsString appId;
   1.449 +                rv = app->GetId(appId);
   1.450 +                NS_ENSURE_SUCCESS_VOID(rv);
   1.451 +
   1.452 +                nsCOMPtr<nsIFile> packageFile;
   1.453 +                rv = NS_NewLocalFile(basePath, false,
   1.454 +                                     getter_AddRefs(packageFile));
   1.455 +                NS_ENSURE_SUCCESS_VOID(rv);
   1.456 +
   1.457 +                rv = packageFile->Append(appId);
   1.458 +                NS_ENSURE_SUCCESS_VOID(rv);
   1.459 +
   1.460 +                rv = packageFile->Append(NS_LITERAL_STRING("application.zip"));
   1.461 +                NS_ENSURE_SUCCESS_VOID(rv);
   1.462 +
   1.463 +                nsString path;
   1.464 +                rv = packageFile->GetPath(path);
   1.465 +                NS_ENSURE_SUCCESS_VOID(rv);
   1.466 +
   1.467 +                nsRefPtr<OpenFileAndSendFDRunnable> openFileRunnable =
   1.468 +                    new OpenFileAndSendFDRunnable(path, this);
   1.469 +                openFileRunnable->Dispatch();
   1.470 +            }
   1.471 +        }
   1.472 +    }
   1.473 +}
   1.474 +
   1.475 +void
   1.476 +TabParent::Show(const nsIntSize& size)
   1.477 +{
   1.478 +    // sigh
   1.479 +    mShown = true;
   1.480 +    mDimensions = size;
   1.481 +    if (!mIsDestroyed) {
   1.482 +      unused << SendShow(size);
   1.483 +    }
   1.484 +}
   1.485 +
   1.486 +void
   1.487 +TabParent::UpdateDimensions(const nsRect& rect, const nsIntSize& size)
   1.488 +{
   1.489 +  if (mIsDestroyed) {
   1.490 +    return;
   1.491 +  }
   1.492 +  hal::ScreenConfiguration config;
   1.493 +  hal::GetCurrentScreenConfiguration(&config);
   1.494 +  ScreenOrientation orientation = config.orientation();
   1.495 +
   1.496 +  if (!mUpdatedDimensions || mOrientation != orientation ||
   1.497 +      mDimensions != size || !mRect.IsEqualEdges(rect)) {
   1.498 +    mUpdatedDimensions = true;
   1.499 +    mRect = rect;
   1.500 +    mDimensions = size;
   1.501 +    mOrientation = orientation;
   1.502 +
   1.503 +    unused << SendUpdateDimensions(mRect, mDimensions, mOrientation);
   1.504 +  }
   1.505 +}
   1.506 +
   1.507 +void
   1.508 +TabParent::UpdateFrame(const FrameMetrics& aFrameMetrics)
   1.509 +{
   1.510 +  if (!mIsDestroyed) {
   1.511 +    unused << SendUpdateFrame(aFrameMetrics);
   1.512 +  }
   1.513 +}
   1.514 +
   1.515 +void
   1.516 +TabParent::AcknowledgeScrollUpdate(const ViewID& aScrollId, const uint32_t& aScrollGeneration)
   1.517 +{
   1.518 +  if (!mIsDestroyed) {
   1.519 +    unused << SendAcknowledgeScrollUpdate(aScrollId, aScrollGeneration);
   1.520 +  }
   1.521 +}
   1.522 +
   1.523 +void TabParent::HandleDoubleTap(const CSSPoint& aPoint,
   1.524 +                                int32_t aModifiers,
   1.525 +                                const ScrollableLayerGuid &aGuid)
   1.526 +{
   1.527 +  if (!mIsDestroyed) {
   1.528 +    unused << SendHandleDoubleTap(aPoint, aGuid);
   1.529 +  }
   1.530 +}
   1.531 +
   1.532 +void TabParent::HandleSingleTap(const CSSPoint& aPoint,
   1.533 +                                int32_t aModifiers,
   1.534 +                                const ScrollableLayerGuid &aGuid)
   1.535 +{
   1.536 +  // TODO Send the modifier data to TabChild for use in mouse events.
   1.537 +  if (!mIsDestroyed) {
   1.538 +    unused << SendHandleSingleTap(aPoint, aGuid);
   1.539 +  }
   1.540 +}
   1.541 +
   1.542 +void TabParent::HandleLongTap(const CSSPoint& aPoint,
   1.543 +                              int32_t aModifiers,
   1.544 +                              const ScrollableLayerGuid &aGuid)
   1.545 +{
   1.546 +  if (!mIsDestroyed) {
   1.547 +    unused << SendHandleLongTap(aPoint, aGuid);
   1.548 +  }
   1.549 +}
   1.550 +
   1.551 +void TabParent::HandleLongTapUp(const CSSPoint& aPoint,
   1.552 +                                int32_t aModifiers,
   1.553 +                                const ScrollableLayerGuid &aGuid)
   1.554 +{
   1.555 +  if (!mIsDestroyed) {
   1.556 +    unused << SendHandleLongTapUp(aPoint, aGuid);
   1.557 +  }
   1.558 +}
   1.559 +
   1.560 +void TabParent::NotifyAPZStateChange(ViewID aViewId,
   1.561 +                                     APZStateChange aChange,
   1.562 +                                     int aArg)
   1.563 +{
   1.564 +  if (!mIsDestroyed) {
   1.565 +    unused << SendNotifyAPZStateChange(aViewId, aChange, aArg);
   1.566 +  }
   1.567 +}
   1.568 +
   1.569 +void
   1.570 +TabParent::Activate()
   1.571 +{
   1.572 +  if (!mIsDestroyed) {
   1.573 +    unused << SendActivate();
   1.574 +  }
   1.575 +}
   1.576 +
   1.577 +void
   1.578 +TabParent::Deactivate()
   1.579 +{
   1.580 +  if (!mIsDestroyed) {
   1.581 +    unused << SendDeactivate();
   1.582 +  }
   1.583 +}
   1.584 +
   1.585 +NS_IMETHODIMP
   1.586 +TabParent::Init(nsIDOMWindow *window)
   1.587 +{
   1.588 +  return NS_OK;
   1.589 +}
   1.590 +
   1.591 +NS_IMETHODIMP
   1.592 +TabParent::GetState(uint32_t *aState)
   1.593 +{
   1.594 +  NS_ENSURE_ARG(aState);
   1.595 +  NS_WARNING("SecurityState not valid here");
   1.596 +  *aState = 0;
   1.597 +  return NS_OK;
   1.598 +}
   1.599 +
   1.600 +NS_IMETHODIMP
   1.601 +TabParent::SetDocShell(nsIDocShell *aDocShell)
   1.602 +{
   1.603 +  NS_ENSURE_ARG(aDocShell);
   1.604 +  NS_WARNING("No mDocShell member in TabParent so there is no docShell to set");
   1.605 +  return NS_OK;
   1.606 +}
   1.607 +
   1.608 +PDocumentRendererParent*
   1.609 +TabParent::AllocPDocumentRendererParent(const nsRect& documentRect,
   1.610 +                                        const gfx::Matrix& transform,
   1.611 +                                        const nsString& bgcolor,
   1.612 +                                        const uint32_t& renderFlags,
   1.613 +                                        const bool& flushLayout,
   1.614 +                                        const nsIntSize& renderSize)
   1.615 +{
   1.616 +    return new DocumentRendererParent();
   1.617 +}
   1.618 +
   1.619 +bool
   1.620 +TabParent::DeallocPDocumentRendererParent(PDocumentRendererParent* actor)
   1.621 +{
   1.622 +    delete actor;
   1.623 +    return true;
   1.624 +}
   1.625 +
   1.626 +PContentPermissionRequestParent*
   1.627 +TabParent::AllocPContentPermissionRequestParent(const InfallibleTArray<PermissionRequest>& aRequests,
   1.628 +                                                const IPC::Principal& aPrincipal)
   1.629 +{
   1.630 +  return CreateContentPermissionRequestParent(aRequests, mFrameElement, aPrincipal);
   1.631 +}
   1.632 +
   1.633 +bool
   1.634 +TabParent::DeallocPContentPermissionRequestParent(PContentPermissionRequestParent* actor)
   1.635 +{
   1.636 +  delete actor;
   1.637 +  return true;
   1.638 +}
   1.639 +
   1.640 +PFilePickerParent*
   1.641 +TabParent::AllocPFilePickerParent(const nsString& aTitle, const int16_t& aMode)
   1.642 +{
   1.643 +  return new FilePickerParent(aTitle, aMode);
   1.644 +}
   1.645 +
   1.646 +bool
   1.647 +TabParent::DeallocPFilePickerParent(PFilePickerParent* actor)
   1.648 +{
   1.649 +  delete actor;
   1.650 +  return true;
   1.651 +}
   1.652 +
   1.653 +void
   1.654 +TabParent::SendMouseEvent(const nsAString& aType, float aX, float aY,
   1.655 +                          int32_t aButton, int32_t aClickCount,
   1.656 +                          int32_t aModifiers, bool aIgnoreRootScrollFrame)
   1.657 +{
   1.658 +  if (!mIsDestroyed) {
   1.659 +    unused << PBrowserParent::SendMouseEvent(nsString(aType), aX, aY,
   1.660 +                                             aButton, aClickCount,
   1.661 +                                             aModifiers, aIgnoreRootScrollFrame);
   1.662 +  }
   1.663 +}
   1.664 +
   1.665 +void
   1.666 +TabParent::SendKeyEvent(const nsAString& aType,
   1.667 +                        int32_t aKeyCode,
   1.668 +                        int32_t aCharCode,
   1.669 +                        int32_t aModifiers,
   1.670 +                        bool aPreventDefault)
   1.671 +{
   1.672 +  if (!mIsDestroyed) {
   1.673 +    unused << PBrowserParent::SendKeyEvent(nsString(aType), aKeyCode, aCharCode,
   1.674 +                                           aModifiers, aPreventDefault);
   1.675 +  }
   1.676 +}
   1.677 +
   1.678 +bool
   1.679 +TabParent::MapEventCoordinatesForChildProcess(WidgetEvent* aEvent)
   1.680 +{
   1.681 +  nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
   1.682 +  if (!frameLoader) {
   1.683 +    return false;
   1.684 +  }
   1.685 +  LayoutDeviceIntPoint offset =
   1.686 +    EventStateManager::GetChildProcessOffset(frameLoader, *aEvent);
   1.687 +  MapEventCoordinatesForChildProcess(offset, aEvent);
   1.688 +  return true;
   1.689 +}
   1.690 +
   1.691 +void
   1.692 +TabParent::MapEventCoordinatesForChildProcess(
   1.693 +  const LayoutDeviceIntPoint& aOffset, WidgetEvent* aEvent)
   1.694 +{
   1.695 +  if (aEvent->eventStructType != NS_TOUCH_EVENT) {
   1.696 +    aEvent->refPoint = aOffset;
   1.697 +  } else {
   1.698 +    aEvent->refPoint = LayoutDeviceIntPoint();
   1.699 +    // Then offset all the touch points by that distance, to put them
   1.700 +    // in the space where top-left is 0,0.
   1.701 +    const nsTArray< nsRefPtr<Touch> >& touches =
   1.702 +      aEvent->AsTouchEvent()->touches;
   1.703 +    for (uint32_t i = 0; i < touches.Length(); ++i) {
   1.704 +      Touch* touch = touches[i];
   1.705 +      if (touch) {
   1.706 +        touch->mRefPoint += LayoutDeviceIntPoint::ToUntyped(aOffset);
   1.707 +      }
   1.708 +    }
   1.709 +  }
   1.710 +}
   1.711 +
   1.712 +bool TabParent::SendRealMouseEvent(WidgetMouseEvent& event)
   1.713 +{
   1.714 +  if (mIsDestroyed) {
   1.715 +    return false;
   1.716 +  }
   1.717 +  MaybeForwardEventToRenderFrame(event, nullptr);
   1.718 +  if (!MapEventCoordinatesForChildProcess(&event)) {
   1.719 +    return false;
   1.720 +  }
   1.721 +  return PBrowserParent::SendRealMouseEvent(event);
   1.722 +}
   1.723 +
   1.724 +CSSPoint TabParent::AdjustTapToChildWidget(const CSSPoint& aPoint)
   1.725 +{
   1.726 +  nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
   1.727 +
   1.728 +  if (!content || !content->OwnerDoc()) {
   1.729 +    return aPoint;
   1.730 +  }
   1.731 +
   1.732 +  nsIDocument* doc = content->OwnerDoc();
   1.733 +  if (!doc || !doc->GetShell()) {
   1.734 +    return aPoint;
   1.735 +  }
   1.736 +  nsPresContext* presContext = doc->GetShell()->GetPresContext();
   1.737 +
   1.738 +  return aPoint + CSSPoint(
   1.739 +    presContext->DevPixelsToFloatCSSPixels(mChildProcessOffsetAtTouchStart.x),
   1.740 +    presContext->DevPixelsToFloatCSSPixels(mChildProcessOffsetAtTouchStart.y));
   1.741 +}
   1.742 +
   1.743 +bool TabParent::SendHandleSingleTap(const CSSPoint& aPoint, const ScrollableLayerGuid& aGuid)
   1.744 +{
   1.745 +  if (mIsDestroyed) {
   1.746 +    return false;
   1.747 +  }
   1.748 +
   1.749 +  return PBrowserParent::SendHandleSingleTap(AdjustTapToChildWidget(aPoint), aGuid);
   1.750 +}
   1.751 +
   1.752 +bool TabParent::SendHandleLongTap(const CSSPoint& aPoint, const ScrollableLayerGuid& aGuid)
   1.753 +{
   1.754 +  if (mIsDestroyed) {
   1.755 +    return false;
   1.756 +  }
   1.757 +
   1.758 +  return PBrowserParent::SendHandleLongTap(AdjustTapToChildWidget(aPoint), aGuid);
   1.759 +}
   1.760 +
   1.761 +bool TabParent::SendHandleLongTapUp(const CSSPoint& aPoint, const ScrollableLayerGuid& aGuid)
   1.762 +{
   1.763 +  if (mIsDestroyed) {
   1.764 +    return false;
   1.765 +  }
   1.766 +
   1.767 +  return PBrowserParent::SendHandleLongTapUp(AdjustTapToChildWidget(aPoint), aGuid);
   1.768 +}
   1.769 +
   1.770 +bool TabParent::SendHandleDoubleTap(const CSSPoint& aPoint, const ScrollableLayerGuid& aGuid)
   1.771 +{
   1.772 +  if (mIsDestroyed) {
   1.773 +    return false;
   1.774 +  }
   1.775 +
   1.776 +  return PBrowserParent::SendHandleDoubleTap(AdjustTapToChildWidget(aPoint), aGuid);
   1.777 +}
   1.778 +
   1.779 +bool TabParent::SendMouseWheelEvent(WidgetWheelEvent& event)
   1.780 +{
   1.781 +  if (mIsDestroyed) {
   1.782 +    return false;
   1.783 +  }
   1.784 +  MaybeForwardEventToRenderFrame(event, nullptr);
   1.785 +  if (!MapEventCoordinatesForChildProcess(&event)) {
   1.786 +    return false;
   1.787 +  }
   1.788 +  return PBrowserParent::SendMouseWheelEvent(event);
   1.789 +}
   1.790 +
   1.791 +static void
   1.792 +DoCommandCallback(mozilla::Command aCommand, void* aData)
   1.793 +{
   1.794 +  static_cast<InfallibleTArray<mozilla::CommandInt>*>(aData)->AppendElement(aCommand);
   1.795 +}
   1.796 +
   1.797 +bool
   1.798 +TabParent::RecvRequestNativeKeyBindings(const WidgetKeyboardEvent& aEvent,
   1.799 +                                        MaybeNativeKeyBinding* aBindings)
   1.800 +{
   1.801 +  AutoInfallibleTArray<mozilla::CommandInt, 4> singleLine;
   1.802 +  AutoInfallibleTArray<mozilla::CommandInt, 4> multiLine;
   1.803 +  AutoInfallibleTArray<mozilla::CommandInt, 4> richText;
   1.804 +
   1.805 +  *aBindings = mozilla::void_t();
   1.806 +
   1.807 +  nsCOMPtr<nsIWidget> widget = GetWidget();
   1.808 +  if (!widget) {
   1.809 +    return true;
   1.810 +  }
   1.811 +
   1.812 +  WidgetKeyboardEvent localEvent(aEvent);
   1.813 +
   1.814 +  if (NS_FAILED(widget->AttachNativeKeyEvent(localEvent))) {
   1.815 +    return true;
   1.816 +  }
   1.817 +
   1.818 +  widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForSingleLineEditor,
   1.819 +                                  localEvent, DoCommandCallback, &singleLine);
   1.820 +  widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForMultiLineEditor,
   1.821 +                                  localEvent, DoCommandCallback, &multiLine);
   1.822 +  widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForRichTextEditor,
   1.823 +                                  localEvent, DoCommandCallback, &richText);
   1.824 +
   1.825 +  if (!singleLine.IsEmpty() || !multiLine.IsEmpty() || !richText.IsEmpty()) {
   1.826 +    *aBindings = NativeKeyBinding(singleLine, multiLine, richText);
   1.827 +  }
   1.828 +
   1.829 +  return true;
   1.830 +}
   1.831 +
   1.832 +bool TabParent::SendRealKeyEvent(WidgetKeyboardEvent& event)
   1.833 +{
   1.834 +  if (mIsDestroyed) {
   1.835 +    return false;
   1.836 +  }
   1.837 +  MaybeForwardEventToRenderFrame(event, nullptr);
   1.838 +  if (!MapEventCoordinatesForChildProcess(&event)) {
   1.839 +    return false;
   1.840 +  }
   1.841 +
   1.842 +
   1.843 +  MaybeNativeKeyBinding bindings;
   1.844 +  bindings = void_t();
   1.845 +  if (event.message == NS_KEY_PRESS) {
   1.846 +    nsCOMPtr<nsIWidget> widget = GetWidget();
   1.847 +
   1.848 +    AutoInfallibleTArray<mozilla::CommandInt, 4> singleLine;
   1.849 +    AutoInfallibleTArray<mozilla::CommandInt, 4> multiLine;
   1.850 +    AutoInfallibleTArray<mozilla::CommandInt, 4> richText;
   1.851 +
   1.852 +    widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForSingleLineEditor,
   1.853 +                                    event, DoCommandCallback, &singleLine);
   1.854 +    widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForMultiLineEditor,
   1.855 +                                    event, DoCommandCallback, &multiLine);
   1.856 +    widget->ExecuteNativeKeyBinding(nsIWidget::NativeKeyBindingsForRichTextEditor,
   1.857 +                                    event, DoCommandCallback, &richText);
   1.858 +
   1.859 +    if (!singleLine.IsEmpty() || !multiLine.IsEmpty() || !richText.IsEmpty()) {
   1.860 +      bindings = NativeKeyBinding(singleLine, multiLine, richText);
   1.861 +    }
   1.862 +  }
   1.863 +
   1.864 +  return PBrowserParent::SendRealKeyEvent(event, bindings);
   1.865 +}
   1.866 +
   1.867 +bool TabParent::SendRealTouchEvent(WidgetTouchEvent& event)
   1.868 +{
   1.869 +  if (mIsDestroyed) {
   1.870 +    return false;
   1.871 +  }
   1.872 +  if (event.message == NS_TOUCH_START) {
   1.873 +    // Adjust the widget coordinates to be relative to our frame.
   1.874 +    nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
   1.875 +    if (!frameLoader) {
   1.876 +      // No frame anymore?
   1.877 +      sEventCapturer = nullptr;
   1.878 +      return false;
   1.879 +    }
   1.880 +
   1.881 +    mChildProcessOffsetAtTouchStart =
   1.882 +      EventStateManager::GetChildProcessOffset(frameLoader, event);
   1.883 +
   1.884 +    MOZ_ASSERT((!sEventCapturer && mEventCaptureDepth == 0) ||
   1.885 +               (sEventCapturer == this && mEventCaptureDepth > 0));
   1.886 +    // We want to capture all remaining touch events in this series
   1.887 +    // for fast-path dispatch.
   1.888 +    sEventCapturer = this;
   1.889 +    ++mEventCaptureDepth;
   1.890 +  }
   1.891 +
   1.892 +  // PresShell::HandleEventInternal adds touches on touch end/cancel.  This
   1.893 +  // confuses remote content and the panning and zooming logic into thinking
   1.894 +  // that the added touches are part of the touchend/cancel, when actually
   1.895 +  // they're not.
   1.896 +  if (event.message == NS_TOUCH_END || event.message == NS_TOUCH_CANCEL) {
   1.897 +    for (int i = event.touches.Length() - 1; i >= 0; i--) {
   1.898 +      if (!event.touches[i]->mChanged) {
   1.899 +        event.touches.RemoveElementAt(i);
   1.900 +      }
   1.901 +    }
   1.902 +  }
   1.903 +
   1.904 +  ScrollableLayerGuid guid;
   1.905 +  MaybeForwardEventToRenderFrame(event, &guid);
   1.906 +
   1.907 +  if (mIsDestroyed) {
   1.908 +    return false;
   1.909 +  }
   1.910 +
   1.911 +  MapEventCoordinatesForChildProcess(mChildProcessOffsetAtTouchStart, &event);
   1.912 +
   1.913 +  return (event.message == NS_TOUCH_MOVE) ?
   1.914 +    PBrowserParent::SendRealTouchMoveEvent(event, guid) :
   1.915 +    PBrowserParent::SendRealTouchEvent(event, guid);
   1.916 +}
   1.917 +
   1.918 +/*static*/ TabParent*
   1.919 +TabParent::GetEventCapturer()
   1.920 +{
   1.921 +  return sEventCapturer;
   1.922 +}
   1.923 +
   1.924 +bool
   1.925 +TabParent::TryCapture(const WidgetGUIEvent& aEvent)
   1.926 +{
   1.927 +  MOZ_ASSERT(sEventCapturer == this && mEventCaptureDepth > 0);
   1.928 +
   1.929 +  if (aEvent.eventStructType != NS_TOUCH_EVENT) {
   1.930 +    // Only capture of touch events is implemented, for now.
   1.931 +    return false;
   1.932 +  }
   1.933 +
   1.934 +  WidgetTouchEvent event(*aEvent.AsTouchEvent());
   1.935 +
   1.936 +  bool isTouchPointUp = (event.message == NS_TOUCH_END ||
   1.937 +                         event.message == NS_TOUCH_CANCEL);
   1.938 +  if (event.message == NS_TOUCH_START || isTouchPointUp) {
   1.939 +    // Let the DOM see touch start/end events so that its touch-point
   1.940 +    // state stays consistent.
   1.941 +    if (isTouchPointUp && 0 == --mEventCaptureDepth) {
   1.942 +      // All event series are un-captured, don't try to catch any
   1.943 +      // more.
   1.944 +      sEventCapturer = nullptr;
   1.945 +    }
   1.946 +    return false;
   1.947 +  }
   1.948 +
   1.949 +  SendRealTouchEvent(event);
   1.950 +  return true;
   1.951 +}
   1.952 +
   1.953 +bool
   1.954 +TabParent::RecvSyncMessage(const nsString& aMessage,
   1.955 +                           const ClonedMessageData& aData,
   1.956 +                           const InfallibleTArray<CpowEntry>& aCpows,
   1.957 +                           const IPC::Principal& aPrincipal,
   1.958 +                           InfallibleTArray<nsString>* aJSONRetVal)
   1.959 +{
   1.960 +  nsIPrincipal* principal = aPrincipal;
   1.961 +  ContentParent* parent = static_cast<ContentParent*>(Manager());
   1.962 +  if (!Preferences::GetBool("dom.testing.ignore_ipc_principal", false) &&
   1.963 +      principal && !AssertAppPrincipal(parent, principal)) {
   1.964 +    return false;
   1.965 +  }
   1.966 +
   1.967 +  StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
   1.968 +  CpowIdHolder cpows(parent->GetCPOWManager(), aCpows);
   1.969 +  return ReceiveMessage(aMessage, true, &cloneData, &cpows, aPrincipal, aJSONRetVal);
   1.970 +}
   1.971 +
   1.972 +bool
   1.973 +TabParent::AnswerRpcMessage(const nsString& aMessage,
   1.974 +                            const ClonedMessageData& aData,
   1.975 +                            const InfallibleTArray<CpowEntry>& aCpows,
   1.976 +                            const IPC::Principal& aPrincipal,
   1.977 +                            InfallibleTArray<nsString>* aJSONRetVal)
   1.978 +{
   1.979 +  nsIPrincipal* principal = aPrincipal;
   1.980 +  ContentParent* parent = static_cast<ContentParent*>(Manager());
   1.981 +  if (!Preferences::GetBool("dom.testing.ignore_ipc_principal", false) &&
   1.982 +      principal && !AssertAppPrincipal(parent, principal)) {
   1.983 +    return false;
   1.984 +  }
   1.985 +
   1.986 +  StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
   1.987 +  CpowIdHolder cpows(parent->GetCPOWManager(), aCpows);
   1.988 +  return ReceiveMessage(aMessage, true, &cloneData, &cpows, aPrincipal, aJSONRetVal);
   1.989 +}
   1.990 +
   1.991 +bool
   1.992 +TabParent::RecvAsyncMessage(const nsString& aMessage,
   1.993 +                            const ClonedMessageData& aData,
   1.994 +                            const InfallibleTArray<CpowEntry>& aCpows,
   1.995 +                            const IPC::Principal& aPrincipal)
   1.996 +{
   1.997 +  nsIPrincipal* principal = aPrincipal;
   1.998 +  ContentParent* parent = static_cast<ContentParent*>(Manager());
   1.999 +  if (!Preferences::GetBool("dom.testing.ignore_ipc_principal", false) &&
  1.1000 +      principal && !AssertAppPrincipal(parent, principal)) {
  1.1001 +    return false;
  1.1002 +  }
  1.1003 +
  1.1004 +  StructuredCloneData cloneData = ipc::UnpackClonedMessageDataForParent(aData);
  1.1005 +  CpowIdHolder cpows(parent->GetCPOWManager(), aCpows);
  1.1006 +  return ReceiveMessage(aMessage, false, &cloneData, &cpows, aPrincipal, nullptr);
  1.1007 +}
  1.1008 +
  1.1009 +bool
  1.1010 +TabParent::RecvSetCursor(const uint32_t& aCursor)
  1.1011 +{
  1.1012 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.1013 +  if (widget) {
  1.1014 +    widget->SetCursor((nsCursor) aCursor);
  1.1015 +  }
  1.1016 +  return true;
  1.1017 +}
  1.1018 +
  1.1019 +bool
  1.1020 +TabParent::RecvSetBackgroundColor(const nscolor& aColor)
  1.1021 +{
  1.1022 +  if (RenderFrameParent* frame = GetRenderFrame()) {
  1.1023 +    frame->SetBackgroundColor(aColor);
  1.1024 +  }
  1.1025 +  return true;
  1.1026 +}
  1.1027 +
  1.1028 +nsIXULBrowserWindow*
  1.1029 +TabParent::GetXULBrowserWindow()
  1.1030 +{
  1.1031 +  nsCOMPtr<nsIContent> frame = do_QueryInterface(mFrameElement);
  1.1032 +  if (!frame) {
  1.1033 +    return nullptr;
  1.1034 +  }
  1.1035 +
  1.1036 +  nsCOMPtr<nsIDocShell> docShell = frame->OwnerDoc()->GetDocShell();
  1.1037 +  if (!docShell) {
  1.1038 +    return nullptr;
  1.1039 +  }
  1.1040 +
  1.1041 +  nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
  1.1042 +  docShell->GetTreeOwner(getter_AddRefs(treeOwner));
  1.1043 +  if (!treeOwner) {
  1.1044 +    return nullptr;
  1.1045 +  }
  1.1046 +
  1.1047 +  nsCOMPtr<nsIXULWindow> window = do_GetInterface(treeOwner);
  1.1048 +  if (!window) {
  1.1049 +    return nullptr;
  1.1050 +  }
  1.1051 +
  1.1052 +  nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow;
  1.1053 +  window->GetXULBrowserWindow(getter_AddRefs(xulBrowserWindow));
  1.1054 +  return xulBrowserWindow;
  1.1055 +}
  1.1056 +
  1.1057 +bool
  1.1058 +TabParent::RecvSetStatus(const uint32_t& aType, const nsString& aStatus)
  1.1059 +{
  1.1060 +  nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow = GetXULBrowserWindow();
  1.1061 +  if (!xulBrowserWindow) {
  1.1062 +    return true;
  1.1063 +  }
  1.1064 +
  1.1065 +  switch (aType) {
  1.1066 +   case nsIWebBrowserChrome::STATUS_SCRIPT:
  1.1067 +    xulBrowserWindow->SetJSStatus(aStatus);
  1.1068 +    break;
  1.1069 +   case nsIWebBrowserChrome::STATUS_LINK:
  1.1070 +    xulBrowserWindow->SetOverLink(aStatus, nullptr);
  1.1071 +    break;
  1.1072 +  }
  1.1073 +  return true;
  1.1074 +}
  1.1075 +
  1.1076 +bool
  1.1077 +TabParent::RecvShowTooltip(const uint32_t& aX, const uint32_t& aY, const nsString& aTooltip)
  1.1078 +{
  1.1079 +  nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow = GetXULBrowserWindow();
  1.1080 +  if (!xulBrowserWindow) {
  1.1081 +    return true;
  1.1082 +  }
  1.1083 +
  1.1084 +  xulBrowserWindow->ShowTooltip(aX, aY, aTooltip);
  1.1085 +  return true;
  1.1086 +}
  1.1087 +
  1.1088 +bool
  1.1089 +TabParent::RecvHideTooltip()
  1.1090 +{
  1.1091 +  nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow = GetXULBrowserWindow();
  1.1092 +  if (!xulBrowserWindow) {
  1.1093 +    return true;
  1.1094 +  }
  1.1095 +
  1.1096 +  xulBrowserWindow->HideTooltip();
  1.1097 +  return true;
  1.1098 +}
  1.1099 +
  1.1100 +bool
  1.1101 +TabParent::RecvNotifyIMEFocus(const bool& aFocus,
  1.1102 +                              nsIMEUpdatePreference* aPreference,
  1.1103 +                              uint32_t* aSeqno)
  1.1104 +{
  1.1105 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.1106 +  if (!widget) {
  1.1107 +    *aPreference = nsIMEUpdatePreference();
  1.1108 +    return true;
  1.1109 +  }
  1.1110 +
  1.1111 +  *aSeqno = mIMESeqno;
  1.1112 +  mIMETabParent = aFocus ? this : nullptr;
  1.1113 +  mIMESelectionAnchor = 0;
  1.1114 +  mIMESelectionFocus = 0;
  1.1115 +  widget->NotifyIME(IMENotification(aFocus ? NOTIFY_IME_OF_FOCUS :
  1.1116 +                                             NOTIFY_IME_OF_BLUR));
  1.1117 +
  1.1118 +  if (aFocus) {
  1.1119 +    *aPreference = widget->GetIMEUpdatePreference();
  1.1120 +  } else {
  1.1121 +    mIMECacheText.Truncate(0);
  1.1122 +  }
  1.1123 +  return true;
  1.1124 +}
  1.1125 +
  1.1126 +bool
  1.1127 +TabParent::RecvNotifyIMETextChange(const uint32_t& aStart,
  1.1128 +                                   const uint32_t& aEnd,
  1.1129 +                                   const uint32_t& aNewEnd,
  1.1130 +                                   const bool& aCausedByComposition)
  1.1131 +{
  1.1132 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.1133 +  if (!widget)
  1.1134 +    return true;
  1.1135 +
  1.1136 +#ifdef DEBUG
  1.1137 +  nsIMEUpdatePreference updatePreference = widget->GetIMEUpdatePreference();
  1.1138 +  NS_ASSERTION(updatePreference.WantTextChange(),
  1.1139 +               "Don't call Send/RecvNotifyIMETextChange without NOTIFY_TEXT_CHANGE");
  1.1140 +  MOZ_ASSERT(!aCausedByComposition ||
  1.1141 +               updatePreference.WantChangesCausedByComposition(),
  1.1142 +    "The widget doesn't want text change notification caused by composition");
  1.1143 +#endif
  1.1144 +
  1.1145 +  IMENotification notification(NOTIFY_IME_OF_TEXT_CHANGE);
  1.1146 +  notification.mTextChangeData.mStartOffset = aStart;
  1.1147 +  notification.mTextChangeData.mOldEndOffset = aEnd;
  1.1148 +  notification.mTextChangeData.mNewEndOffset = aNewEnd;
  1.1149 +  notification.mTextChangeData.mCausedByComposition = aCausedByComposition;
  1.1150 +  widget->NotifyIME(notification);
  1.1151 +  return true;
  1.1152 +}
  1.1153 +
  1.1154 +bool
  1.1155 +TabParent::RecvNotifyIMESelectedCompositionRect(const uint32_t& aOffset,
  1.1156 +                                                const nsIntRect& aRect,
  1.1157 +                                                const nsIntRect& aCaretRect)
  1.1158 +{
  1.1159 +  // add rect to cache for another query
  1.1160 +  mIMECompositionRectOffset = aOffset;
  1.1161 +  mIMECompositionRect = aRect;
  1.1162 +  mIMECaretRect = aCaretRect;
  1.1163 +
  1.1164 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.1165 +  if (!widget) {
  1.1166 +    return true;
  1.1167 +  }
  1.1168 +  widget->NotifyIME(IMENotification(NOTIFY_IME_OF_COMPOSITION_UPDATE));
  1.1169 +  return true;
  1.1170 +}
  1.1171 +
  1.1172 +bool
  1.1173 +TabParent::RecvNotifyIMESelection(const uint32_t& aSeqno,
  1.1174 +                                  const uint32_t& aAnchor,
  1.1175 +                                  const uint32_t& aFocus,
  1.1176 +                                  const bool& aCausedByComposition)
  1.1177 +{
  1.1178 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.1179 +  if (!widget)
  1.1180 +    return true;
  1.1181 +
  1.1182 +  if (aSeqno == mIMESeqno) {
  1.1183 +    mIMESelectionAnchor = aAnchor;
  1.1184 +    mIMESelectionFocus = aFocus;
  1.1185 +    const nsIMEUpdatePreference updatePreference =
  1.1186 +      widget->GetIMEUpdatePreference();
  1.1187 +    if (updatePreference.WantSelectionChange() &&
  1.1188 +        (updatePreference.WantChangesCausedByComposition() ||
  1.1189 +         !aCausedByComposition)) {
  1.1190 +      IMENotification notification(NOTIFY_IME_OF_SELECTION_CHANGE);
  1.1191 +      notification.mSelectionChangeData.mCausedByComposition =
  1.1192 +        aCausedByComposition;
  1.1193 +      widget->NotifyIME(notification);
  1.1194 +    }
  1.1195 +  }
  1.1196 +  return true;
  1.1197 +}
  1.1198 +
  1.1199 +bool
  1.1200 +TabParent::RecvNotifyIMETextHint(const nsString& aText)
  1.1201 +{
  1.1202 +  // Replace our cache with new text
  1.1203 +  mIMECacheText = aText;
  1.1204 +  return true;
  1.1205 +}
  1.1206 +
  1.1207 +bool
  1.1208 +TabParent::RecvRequestFocus(const bool& aCanRaise)
  1.1209 +{
  1.1210 +  nsCOMPtr<nsIFocusManager> fm = nsFocusManager::GetFocusManager();
  1.1211 +  if (!fm) {
  1.1212 +    return true;
  1.1213 +  }
  1.1214 +
  1.1215 +  nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
  1.1216 +  if (!content || !content->OwnerDoc()) {
  1.1217 +    return true;
  1.1218 +  }
  1.1219 +
  1.1220 +  uint32_t flags = nsIFocusManager::FLAG_NOSCROLL;
  1.1221 +  if (aCanRaise)
  1.1222 +    flags |= nsIFocusManager::FLAG_RAISE;
  1.1223 +
  1.1224 +  nsCOMPtr<nsIDOMElement> node = do_QueryInterface(mFrameElement);
  1.1225 +  fm->SetFocus(node, flags);
  1.1226 +  return true;
  1.1227 +}
  1.1228 +
  1.1229 +nsIntPoint
  1.1230 +TabParent::GetChildProcessOffset()
  1.1231 +{
  1.1232 +  // The "toplevel widget" in child processes is always at position
  1.1233 +  // 0,0.  Map the event coordinates to match that.
  1.1234 +
  1.1235 +  nsIntPoint offset(0, 0);
  1.1236 +  nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
  1.1237 +  if (!frameLoader) {
  1.1238 +    return offset;
  1.1239 +  }
  1.1240 +  nsIFrame* targetFrame = frameLoader->GetPrimaryFrameOfOwningContent();
  1.1241 +  if (!targetFrame) {
  1.1242 +    return offset;
  1.1243 +  }
  1.1244 +
  1.1245 +  // Find out how far we're offset from the nearest widget.
  1.1246 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.1247 +  if (!widget) {
  1.1248 +    return offset;
  1.1249 +  }
  1.1250 +  nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(widget,
  1.1251 +                                                            nsIntPoint(0, 0),
  1.1252 +                                                            targetFrame);
  1.1253 +
  1.1254 +  return LayoutDeviceIntPoint::ToUntyped(LayoutDeviceIntPoint::FromAppUnitsToNearest(
  1.1255 +           pt, targetFrame->PresContext()->AppUnitsPerDevPixel()));
  1.1256 +}
  1.1257 +
  1.1258 +bool
  1.1259 +TabParent::RecvReplyKeyEvent(const WidgetKeyboardEvent& event)
  1.1260 +{
  1.1261 +  NS_ENSURE_TRUE(mFrameElement, true);
  1.1262 +
  1.1263 +  WidgetKeyboardEvent localEvent(event);
  1.1264 +  // Set mNoCrossProcessBoundaryForwarding to avoid this event from
  1.1265 +  // being infinitely redispatched and forwarded to the child again.
  1.1266 +  localEvent.mFlags.mNoCrossProcessBoundaryForwarding = true;
  1.1267 +
  1.1268 +  // Here we convert the WidgetEvent that we received to an nsIDOMEvent
  1.1269 +  // to be able to dispatch it to the <browser> element as the target element.
  1.1270 +  nsIDocument* doc = mFrameElement->OwnerDoc();
  1.1271 +  nsIPresShell* presShell = doc->GetShell();
  1.1272 +  NS_ENSURE_TRUE(presShell, true);
  1.1273 +  nsPresContext* presContext = presShell->GetPresContext();
  1.1274 +  NS_ENSURE_TRUE(presContext, true);
  1.1275 +
  1.1276 +  EventDispatcher::Dispatch(mFrameElement, presContext, &localEvent);
  1.1277 +  return true;
  1.1278 +}
  1.1279 +
  1.1280 +/**
  1.1281 + * Try to answer query event using cached text.
  1.1282 + *
  1.1283 + * For NS_QUERY_SELECTED_TEXT, fail if the cache doesn't contain the whole
  1.1284 + *  selected range. (This shouldn't happen because PuppetWidget should have
  1.1285 + *  already sent the whole selection.)
  1.1286 + *
  1.1287 + * For NS_QUERY_TEXT_CONTENT, fail only if the cache doesn't overlap with
  1.1288 + *  the queried range. Note the difference from above. We use
  1.1289 + *  this behavior because a normal NS_QUERY_TEXT_CONTENT event is allowed to
  1.1290 + *  have out-of-bounds offsets, so that widget can request content without
  1.1291 + *  knowing the exact length of text. It's up to widget to handle cases when
  1.1292 + *  the returned offset/length are different from the queried offset/length.
  1.1293 + *
  1.1294 + * For NS_QUERY_TEXT_RECT, fail if cached offset/length aren't equals to input.
  1.1295 + *   Cocoa widget always queries selected offset, so it works on it.
  1.1296 + *
  1.1297 + * For NS_QUERY_CARET_RECT, fail if cached offset isn't equals to input
  1.1298 + */
  1.1299 +bool
  1.1300 +TabParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent)
  1.1301 +{
  1.1302 +  aEvent.mSucceeded = false;
  1.1303 +  aEvent.mWasAsync = false;
  1.1304 +  aEvent.mReply.mFocusedWidget = nsCOMPtr<nsIWidget>(GetWidget()).get();
  1.1305 +
  1.1306 +  switch (aEvent.message)
  1.1307 +  {
  1.1308 +  case NS_QUERY_SELECTED_TEXT:
  1.1309 +    {
  1.1310 +      aEvent.mReply.mOffset = std::min(mIMESelectionAnchor, mIMESelectionFocus);
  1.1311 +      if (mIMESelectionAnchor == mIMESelectionFocus) {
  1.1312 +        aEvent.mReply.mString.Truncate(0);
  1.1313 +      } else {
  1.1314 +        if (mIMESelectionAnchor > mIMECacheText.Length() ||
  1.1315 +            mIMESelectionFocus > mIMECacheText.Length()) {
  1.1316 +          break;
  1.1317 +        }
  1.1318 +        uint32_t selLen = mIMESelectionAnchor > mIMESelectionFocus ?
  1.1319 +                          mIMESelectionAnchor - mIMESelectionFocus :
  1.1320 +                          mIMESelectionFocus - mIMESelectionAnchor;
  1.1321 +        aEvent.mReply.mString = Substring(mIMECacheText,
  1.1322 +                                          aEvent.mReply.mOffset,
  1.1323 +                                          selLen);
  1.1324 +      }
  1.1325 +      aEvent.mReply.mReversed = mIMESelectionFocus < mIMESelectionAnchor;
  1.1326 +      aEvent.mReply.mHasSelection = true;
  1.1327 +      aEvent.mSucceeded = true;
  1.1328 +    }
  1.1329 +    break;
  1.1330 +  case NS_QUERY_TEXT_CONTENT:
  1.1331 +    {
  1.1332 +      uint32_t inputOffset = aEvent.mInput.mOffset,
  1.1333 +               inputEnd = inputOffset + aEvent.mInput.mLength;
  1.1334 +
  1.1335 +      if (inputEnd > mIMECacheText.Length()) {
  1.1336 +        inputEnd = mIMECacheText.Length();
  1.1337 +      }
  1.1338 +      if (inputEnd < inputOffset) {
  1.1339 +        break;
  1.1340 +      }
  1.1341 +      aEvent.mReply.mOffset = inputOffset;
  1.1342 +      aEvent.mReply.mString = Substring(mIMECacheText,
  1.1343 +                                        inputOffset,
  1.1344 +                                        inputEnd - inputOffset);
  1.1345 +      aEvent.mSucceeded = true;
  1.1346 +    }
  1.1347 +    break;
  1.1348 +  case NS_QUERY_TEXT_RECT:
  1.1349 +    {
  1.1350 +      if (aEvent.mInput.mOffset != mIMECompositionRectOffset ||
  1.1351 +          aEvent.mInput.mLength != 1) {
  1.1352 +        break;
  1.1353 +      }
  1.1354 +
  1.1355 +      aEvent.mReply.mOffset = mIMECompositionRectOffset;
  1.1356 +      aEvent.mReply.mRect = mIMECompositionRect - GetChildProcessOffset();
  1.1357 +      aEvent.mSucceeded = true;
  1.1358 +    }
  1.1359 +    break;
  1.1360 +  case NS_QUERY_CARET_RECT:
  1.1361 +    {
  1.1362 +      if (aEvent.mInput.mOffset != mIMECompositionRectOffset) {
  1.1363 +        break;
  1.1364 +      }
  1.1365 +
  1.1366 +      aEvent.mReply.mOffset = mIMECompositionRectOffset;
  1.1367 +      aEvent.mReply.mRect = mIMECaretRect - GetChildProcessOffset();
  1.1368 +      aEvent.mSucceeded = true;
  1.1369 +    }
  1.1370 +    break;
  1.1371 +  }
  1.1372 +  return true;
  1.1373 +}
  1.1374 +
  1.1375 +bool
  1.1376 +TabParent::SendCompositionEvent(WidgetCompositionEvent& event)
  1.1377 +{
  1.1378 +  if (mIsDestroyed) {
  1.1379 +    return false;
  1.1380 +  }
  1.1381 +  mIMEComposing = event.message != NS_COMPOSITION_END;
  1.1382 +  mIMECompositionStart = std::min(mIMESelectionAnchor, mIMESelectionFocus);
  1.1383 +  if (mIMECompositionEnding)
  1.1384 +    return true;
  1.1385 +  event.mSeqno = ++mIMESeqno;
  1.1386 +  return PBrowserParent::SendCompositionEvent(event);
  1.1387 +}
  1.1388 +
  1.1389 +/**
  1.1390 + * During REQUEST_TO_COMMIT_COMPOSITION or REQUEST_TO_CANCEL_COMPOSITION,
  1.1391 + * widget usually sends a NS_TEXT_TEXT event to finalize or clear the
  1.1392 + * composition, respectively
  1.1393 + *
  1.1394 + * Because the event will not reach content in time, we intercept it
  1.1395 + * here and pass the text as the EndIMEComposition return value
  1.1396 + */
  1.1397 +bool
  1.1398 +TabParent::SendTextEvent(WidgetTextEvent& event)
  1.1399 +{
  1.1400 +  if (mIsDestroyed) {
  1.1401 +    return false;
  1.1402 +  }
  1.1403 +  if (mIMECompositionEnding) {
  1.1404 +    mIMECompositionText = event.theText;
  1.1405 +    return true;
  1.1406 +  }
  1.1407 +
  1.1408 +  // We must be able to simulate the selection because
  1.1409 +  // we might not receive selection updates in time
  1.1410 +  if (!mIMEComposing) {
  1.1411 +    mIMECompositionStart = std::min(mIMESelectionAnchor, mIMESelectionFocus);
  1.1412 +  }
  1.1413 +  mIMESelectionAnchor = mIMESelectionFocus =
  1.1414 +      mIMECompositionStart + event.theText.Length();
  1.1415 +
  1.1416 +  event.mSeqno = ++mIMESeqno;
  1.1417 +  return PBrowserParent::SendTextEvent(event);
  1.1418 +}
  1.1419 +
  1.1420 +bool
  1.1421 +TabParent::SendSelectionEvent(WidgetSelectionEvent& event)
  1.1422 +{
  1.1423 +  if (mIsDestroyed) {
  1.1424 +    return false;
  1.1425 +  }
  1.1426 +  mIMESelectionAnchor = event.mOffset + (event.mReversed ? event.mLength : 0);
  1.1427 +  mIMESelectionFocus = event.mOffset + (!event.mReversed ? event.mLength : 0);
  1.1428 +  event.mSeqno = ++mIMESeqno;
  1.1429 +  return PBrowserParent::SendSelectionEvent(event);
  1.1430 +}
  1.1431 +
  1.1432 +/*static*/ TabParent*
  1.1433 +TabParent::GetFrom(nsFrameLoader* aFrameLoader)
  1.1434 +{
  1.1435 +  if (!aFrameLoader) {
  1.1436 +    return nullptr;
  1.1437 +  }
  1.1438 +  PBrowserParent* remoteBrowser = aFrameLoader->GetRemoteBrowser();
  1.1439 +  return static_cast<TabParent*>(remoteBrowser);
  1.1440 +}
  1.1441 +
  1.1442 +/*static*/ TabParent*
  1.1443 +TabParent::GetFrom(nsIContent* aContent)
  1.1444 +{
  1.1445 +  nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(aContent);
  1.1446 +  if (!loaderOwner) {
  1.1447 +    return nullptr;
  1.1448 +  }
  1.1449 +  nsRefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
  1.1450 +  return GetFrom(frameLoader);
  1.1451 +}
  1.1452 +
  1.1453 +RenderFrameParent*
  1.1454 +TabParent::GetRenderFrame()
  1.1455 +{
  1.1456 +  if (ManagedPRenderFrameParent().IsEmpty()) {
  1.1457 +    return nullptr;
  1.1458 +  }
  1.1459 +  return static_cast<RenderFrameParent*>(ManagedPRenderFrameParent()[0]);
  1.1460 +}
  1.1461 +
  1.1462 +bool
  1.1463 +TabParent::RecvEndIMEComposition(const bool& aCancel,
  1.1464 +                                 nsString* aComposition)
  1.1465 +{
  1.1466 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.1467 +  if (!widget)
  1.1468 +    return true;
  1.1469 +
  1.1470 +  mIMECompositionEnding = true;
  1.1471 +
  1.1472 +  widget->NotifyIME(IMENotification(aCancel ? REQUEST_TO_CANCEL_COMPOSITION :
  1.1473 +                                              REQUEST_TO_COMMIT_COMPOSITION));
  1.1474 +
  1.1475 +  mIMECompositionEnding = false;
  1.1476 +  *aComposition = mIMECompositionText;
  1.1477 +  mIMECompositionText.Truncate(0);  
  1.1478 +  return true;
  1.1479 +}
  1.1480 +
  1.1481 +bool
  1.1482 +TabParent::RecvGetInputContext(int32_t* aIMEEnabled,
  1.1483 +                               int32_t* aIMEOpen,
  1.1484 +                               intptr_t* aNativeIMEContext)
  1.1485 +{
  1.1486 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.1487 +  if (!widget) {
  1.1488 +    *aIMEEnabled = IMEState::DISABLED;
  1.1489 +    *aIMEOpen = IMEState::OPEN_STATE_NOT_SUPPORTED;
  1.1490 +    *aNativeIMEContext = 0;
  1.1491 +    return true;
  1.1492 +  }
  1.1493 +
  1.1494 +  InputContext context = widget->GetInputContext();
  1.1495 +  *aIMEEnabled = static_cast<int32_t>(context.mIMEState.mEnabled);
  1.1496 +  *aIMEOpen = static_cast<int32_t>(context.mIMEState.mOpen);
  1.1497 +  *aNativeIMEContext = reinterpret_cast<intptr_t>(context.mNativeIMEContext);
  1.1498 +  return true;
  1.1499 +}
  1.1500 +
  1.1501 +bool
  1.1502 +TabParent::RecvSetInputContext(const int32_t& aIMEEnabled,
  1.1503 +                               const int32_t& aIMEOpen,
  1.1504 +                               const nsString& aType,
  1.1505 +                               const nsString& aInputmode,
  1.1506 +                               const nsString& aActionHint,
  1.1507 +                               const int32_t& aCause,
  1.1508 +                               const int32_t& aFocusChange)
  1.1509 +{
  1.1510 +  // mIMETabParent (which is actually static) tracks which if any TabParent has IMEFocus
  1.1511 +  // When the input mode is set to anything but IMEState::DISABLED,
  1.1512 +  // mIMETabParent should be set to this
  1.1513 +  mIMETabParent =
  1.1514 +    aIMEEnabled != static_cast<int32_t>(IMEState::DISABLED) ? this : nullptr;
  1.1515 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.1516 +  if (!widget || !AllowContentIME())
  1.1517 +    return true;
  1.1518 +
  1.1519 +  InputContext context;
  1.1520 +  context.mIMEState.mEnabled = static_cast<IMEState::Enabled>(aIMEEnabled);
  1.1521 +  context.mIMEState.mOpen = static_cast<IMEState::Open>(aIMEOpen);
  1.1522 +  context.mHTMLInputType.Assign(aType);
  1.1523 +  context.mHTMLInputInputmode.Assign(aInputmode);
  1.1524 +  context.mActionHint.Assign(aActionHint);
  1.1525 +  InputContextAction action(
  1.1526 +    static_cast<InputContextAction::Cause>(aCause),
  1.1527 +    static_cast<InputContextAction::FocusChange>(aFocusChange));
  1.1528 +  widget->SetInputContext(context, action);
  1.1529 +
  1.1530 +  nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
  1.1531 +  if (!observerService)
  1.1532 +    return true;
  1.1533 +
  1.1534 +  nsAutoString state;
  1.1535 +  state.AppendInt(aIMEEnabled);
  1.1536 +  observerService->NotifyObservers(nullptr, "ime-enabled-state-changed", state.get());
  1.1537 +
  1.1538 +  return true;
  1.1539 +}
  1.1540 +
  1.1541 +bool
  1.1542 +TabParent::RecvIsParentWindowMainWidgetVisible(bool* aIsVisible)
  1.1543 +{
  1.1544 +  nsCOMPtr<nsIContent> frame = do_QueryInterface(mFrameElement);
  1.1545 +  if (!frame)
  1.1546 +    return true;
  1.1547 +  nsCOMPtr<nsIDOMWindowUtils> windowUtils =
  1.1548 +    do_QueryInterface(frame->OwnerDoc()->GetWindow());
  1.1549 +  nsresult rv = windowUtils->GetIsParentWindowMainWidgetVisible(aIsVisible);
  1.1550 +  return NS_SUCCEEDED(rv);
  1.1551 +}
  1.1552 +
  1.1553 +bool
  1.1554 +TabParent::RecvGetDPI(float* aValue)
  1.1555 +{
  1.1556 +  TryCacheDPIAndScale();
  1.1557 +
  1.1558 +  NS_ABORT_IF_FALSE(mDPI > 0,
  1.1559 +                    "Must not ask for DPI before OwnerElement is received!");
  1.1560 +  *aValue = mDPI;
  1.1561 +  return true;
  1.1562 +}
  1.1563 +
  1.1564 +bool
  1.1565 +TabParent::RecvGetDefaultScale(double* aValue)
  1.1566 +{
  1.1567 +  TryCacheDPIAndScale();
  1.1568 +
  1.1569 +  NS_ABORT_IF_FALSE(mDefaultScale.scale > 0,
  1.1570 +                    "Must not ask for scale before OwnerElement is received!");
  1.1571 +  *aValue = mDefaultScale.scale;
  1.1572 +  return true;
  1.1573 +}
  1.1574 +
  1.1575 +bool
  1.1576 +TabParent::RecvGetWidgetNativeData(WindowsHandle* aValue)
  1.1577 +{
  1.1578 +  nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
  1.1579 +  if (content) {
  1.1580 +    nsIPresShell* shell = content->OwnerDoc()->GetShell();
  1.1581 +    if (shell) {
  1.1582 +      nsViewManager* vm = shell->GetViewManager();
  1.1583 +      nsCOMPtr<nsIWidget> widget;
  1.1584 +      vm->GetRootWidget(getter_AddRefs(widget));
  1.1585 +      if (widget) {
  1.1586 +        *aValue = reinterpret_cast<WindowsHandle>(
  1.1587 +          widget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW));
  1.1588 +        return true;
  1.1589 +      }
  1.1590 +    }
  1.1591 +  }
  1.1592 +  return false;
  1.1593 +}
  1.1594 +
  1.1595 +bool
  1.1596 +TabParent::ReceiveMessage(const nsString& aMessage,
  1.1597 +                          bool aSync,
  1.1598 +                          const StructuredCloneData* aCloneData,
  1.1599 +                          CpowHolder* aCpows,
  1.1600 +                          nsIPrincipal* aPrincipal,
  1.1601 +                          InfallibleTArray<nsString>* aJSONRetVal)
  1.1602 +{
  1.1603 +  nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
  1.1604 +  if (frameLoader && frameLoader->GetFrameMessageManager()) {
  1.1605 +    nsRefPtr<nsFrameMessageManager> manager =
  1.1606 +      frameLoader->GetFrameMessageManager();
  1.1607 +
  1.1608 +    manager->ReceiveMessage(mFrameElement,
  1.1609 +                            aMessage,
  1.1610 +                            aSync,
  1.1611 +                            aCloneData,
  1.1612 +                            aCpows,
  1.1613 +                            aPrincipal,
  1.1614 +                            aJSONRetVal);
  1.1615 +  }
  1.1616 +  return true;
  1.1617 +}
  1.1618 +
  1.1619 +PIndexedDBParent*
  1.1620 +TabParent::AllocPIndexedDBParent(
  1.1621 +                            const nsCString& aGroup,
  1.1622 +                            const nsCString& aASCIIOrigin, bool* /* aAllowed */)
  1.1623 +{
  1.1624 +  return new IndexedDBParent(this);
  1.1625 +}
  1.1626 +
  1.1627 +bool
  1.1628 +TabParent::DeallocPIndexedDBParent(PIndexedDBParent* aActor)
  1.1629 +{
  1.1630 +  delete aActor;
  1.1631 +  return true;
  1.1632 +}
  1.1633 +
  1.1634 +bool
  1.1635 +TabParent::RecvPIndexedDBConstructor(PIndexedDBParent* aActor,
  1.1636 +                                     const nsCString& aGroup,
  1.1637 +                                     const nsCString& aASCIIOrigin,
  1.1638 +                                     bool* aAllowed)
  1.1639 +{
  1.1640 +  nsRefPtr<IndexedDatabaseManager> mgr = IndexedDatabaseManager::GetOrCreate();
  1.1641 +  NS_ENSURE_TRUE(mgr, false);
  1.1642 +
  1.1643 +  if (!IndexedDatabaseManager::IsMainProcess()) {
  1.1644 +    NS_RUNTIMEABORT("Not supported yet!");
  1.1645 +  }
  1.1646 +
  1.1647 +  nsresult rv;
  1.1648 +
  1.1649 +  // XXXbent Need to make sure we have a whitelist for chrome databases!
  1.1650 +
  1.1651 +  // Verify that the child is requesting to access a database it's allowed to
  1.1652 +  // see.  (aASCIIOrigin here specifies a TabContext + a website origin, and
  1.1653 +  // we're checking that the TabContext may access it.)
  1.1654 +  //
  1.1655 +  // We have to check IsBrowserOrApp() because TabContextMayAccessOrigin will
  1.1656 +  // fail if we're not a browser-or-app, since aASCIIOrigin will be a plain URI,
  1.1657 +  // but TabContextMayAccessOrigin will construct an extended origin using
  1.1658 +  // app-id 0.  Note that as written below, we allow a non browser-or-app child
  1.1659 +  // to read any database.  That's a security hole, but we don't ship a
  1.1660 +  // configuration which creates non browser-or-app children, so it's not a big
  1.1661 +  // deal.
  1.1662 +  if (!aASCIIOrigin.EqualsLiteral("chrome") && IsBrowserOrApp() &&
  1.1663 +      !IndexedDatabaseManager::TabContextMayAccessOrigin(*this, aASCIIOrigin)) {
  1.1664 +
  1.1665 +    NS_WARNING("App attempted to open databases that it does not have "
  1.1666 +               "permission to access!");
  1.1667 +    return false;
  1.1668 +  }
  1.1669 +
  1.1670 +  nsCOMPtr<nsINode> node = do_QueryInterface(GetOwnerElement());
  1.1671 +  NS_ENSURE_TRUE(node, false);
  1.1672 +
  1.1673 +  nsIDocument* doc = node->GetOwnerDocument();
  1.1674 +  NS_ENSURE_TRUE(doc, false);
  1.1675 +
  1.1676 +  nsCOMPtr<nsPIDOMWindow> window = doc->GetInnerWindow();
  1.1677 +  NS_ENSURE_TRUE(window, false);
  1.1678 +
  1.1679 +  // Let's do a current inner check to see if the inner is active or is in
  1.1680 +  // bf cache, and bail out if it's not active.
  1.1681 +  nsCOMPtr<nsPIDOMWindow> outer = doc->GetWindow();
  1.1682 +  if (!outer || outer->GetCurrentInnerWindow() != window) {
  1.1683 +    *aAllowed = false;
  1.1684 +    return true;
  1.1685 +  }
  1.1686 +
  1.1687 +  ContentParent* contentParent = Manager();
  1.1688 +  NS_ASSERTION(contentParent, "Null manager?!");
  1.1689 +
  1.1690 +  nsRefPtr<IDBFactory> factory;
  1.1691 +  rv = IDBFactory::Create(window, aGroup, aASCIIOrigin, contentParent,
  1.1692 +                          getter_AddRefs(factory));
  1.1693 +  NS_ENSURE_SUCCESS(rv, false);
  1.1694 +
  1.1695 +  if (!factory) {
  1.1696 +    *aAllowed = false;
  1.1697 +    return true;
  1.1698 +  }
  1.1699 +
  1.1700 +  IndexedDBParent* actor = static_cast<IndexedDBParent*>(aActor);
  1.1701 +  actor->mFactory = factory;
  1.1702 +  actor->mASCIIOrigin = aASCIIOrigin;
  1.1703 +
  1.1704 +  *aAllowed = true;
  1.1705 +  return true;
  1.1706 +}
  1.1707 +
  1.1708 +// nsIAuthPromptProvider
  1.1709 +
  1.1710 +// This method is largely copied from nsDocShell::GetAuthPrompt
  1.1711 +NS_IMETHODIMP
  1.1712 +TabParent::GetAuthPrompt(uint32_t aPromptReason, const nsIID& iid,
  1.1713 +                          void** aResult)
  1.1714 +{
  1.1715 +  // we're either allowing auth, or it's a proxy request
  1.1716 +  nsresult rv;
  1.1717 +  nsCOMPtr<nsIPromptFactory> wwatch =
  1.1718 +    do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
  1.1719 +  NS_ENSURE_SUCCESS(rv, rv);
  1.1720 +
  1.1721 +  nsCOMPtr<nsIDOMWindow> window;
  1.1722 +  nsCOMPtr<nsIContent> frame = do_QueryInterface(mFrameElement);
  1.1723 +  if (frame)
  1.1724 +    window = do_QueryInterface(frame->OwnerDoc()->GetWindow());
  1.1725 +
  1.1726 +  // Get an auth prompter for our window so that the parenting
  1.1727 +  // of the dialogs works as it should when using tabs.
  1.1728 +  return wwatch->GetPrompt(window, iid,
  1.1729 +                           reinterpret_cast<void**>(aResult));
  1.1730 +}
  1.1731 +
  1.1732 +PColorPickerParent*
  1.1733 +TabParent::AllocPColorPickerParent(const nsString& aTitle,
  1.1734 +                                   const nsString& aInitialColor)
  1.1735 +{
  1.1736 +  return new ColorPickerParent(aTitle, aInitialColor);
  1.1737 +}
  1.1738 +
  1.1739 +bool
  1.1740 +TabParent::DeallocPColorPickerParent(PColorPickerParent* actor)
  1.1741 +{
  1.1742 +  delete actor;
  1.1743 +  return true;
  1.1744 +}
  1.1745 +
  1.1746 +bool
  1.1747 +TabParent::RecvInitRenderFrame(PRenderFrameParent* aFrame,
  1.1748 +                               ScrollingBehavior* aScrolling,
  1.1749 +                               TextureFactoryIdentifier* aTextureFactoryIdentifier,
  1.1750 +                               uint64_t* aLayersId,
  1.1751 +                               bool *aSuccess)
  1.1752 +{
  1.1753 +  *aScrolling = UseAsyncPanZoom() ? ASYNC_PAN_ZOOM : DEFAULT_SCROLLING;
  1.1754 +  *aTextureFactoryIdentifier = TextureFactoryIdentifier();
  1.1755 +  *aLayersId = 0;
  1.1756 +
  1.1757 +  nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
  1.1758 +  if (!frameLoader) {
  1.1759 +    NS_WARNING("Can't allocate graphics resources. May already be shutting down.");
  1.1760 +    *aSuccess = false;
  1.1761 +    return true;
  1.1762 +  }
  1.1763 +
  1.1764 +  static_cast<RenderFrameParent*>(aFrame)->Init(frameLoader, *aScrolling,
  1.1765 +                                                aTextureFactoryIdentifier, aLayersId);
  1.1766 +
  1.1767 +  *aSuccess = true;
  1.1768 +  return true;
  1.1769 +}
  1.1770 +
  1.1771 +PRenderFrameParent*
  1.1772 +TabParent::AllocPRenderFrameParent()
  1.1773 +{
  1.1774 +  MOZ_ASSERT(ManagedPRenderFrameParent().IsEmpty());
  1.1775 +  return new RenderFrameParent();
  1.1776 +}
  1.1777 +
  1.1778 +bool
  1.1779 +TabParent::DeallocPRenderFrameParent(PRenderFrameParent* aFrame)
  1.1780 +{
  1.1781 +  delete aFrame;
  1.1782 +  return true;
  1.1783 +}
  1.1784 +
  1.1785 +mozilla::docshell::POfflineCacheUpdateParent*
  1.1786 +TabParent::AllocPOfflineCacheUpdateParent(const URIParams& aManifestURI,
  1.1787 +                                          const URIParams& aDocumentURI,
  1.1788 +                                          const bool& aStickDocument)
  1.1789 +{
  1.1790 +  nsRefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
  1.1791 +    new mozilla::docshell::OfflineCacheUpdateParent(OwnOrContainingAppId(),
  1.1792 +                                                    IsBrowserElement());
  1.1793 +  // Use this reference as the IPDL reference.
  1.1794 +  return update.forget().take();
  1.1795 +}
  1.1796 +
  1.1797 +bool
  1.1798 +TabParent::RecvPOfflineCacheUpdateConstructor(POfflineCacheUpdateParent* aActor,
  1.1799 +                                              const URIParams& aManifestURI,
  1.1800 +                                              const URIParams& aDocumentURI,
  1.1801 +                                              const bool& aStickDocument)
  1.1802 +{
  1.1803 +  MOZ_ASSERT(aActor);
  1.1804 +
  1.1805 +  nsRefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
  1.1806 +    static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(aActor);
  1.1807 +
  1.1808 +  nsresult rv = update->Schedule(aManifestURI, aDocumentURI, aStickDocument);
  1.1809 +  if (NS_FAILED(rv) && !IsDestroyed()) {
  1.1810 +    // Inform the child of failure.
  1.1811 +    unused << update->SendFinish(false, false);
  1.1812 +  }
  1.1813 +
  1.1814 +  return true;
  1.1815 +}
  1.1816 +
  1.1817 +bool
  1.1818 +TabParent::DeallocPOfflineCacheUpdateParent(POfflineCacheUpdateParent* aActor)
  1.1819 +{
  1.1820 +  // Reclaim the IPDL reference.
  1.1821 +  nsRefPtr<mozilla::docshell::OfflineCacheUpdateParent> update =
  1.1822 +    dont_AddRef(
  1.1823 +      static_cast<mozilla::docshell::OfflineCacheUpdateParent*>(aActor));
  1.1824 +  return true;
  1.1825 +}
  1.1826 +
  1.1827 +bool
  1.1828 +TabParent::RecvSetOfflinePermission(const IPC::Principal& aPrincipal)
  1.1829 +{
  1.1830 +  nsIPrincipal* principal = aPrincipal;
  1.1831 +  nsContentUtils::MaybeAllowOfflineAppByDefault(principal, nullptr);
  1.1832 +  return true;
  1.1833 +}
  1.1834 +
  1.1835 +bool
  1.1836 +TabParent::AllowContentIME()
  1.1837 +{
  1.1838 +  nsFocusManager* fm = nsFocusManager::GetFocusManager();
  1.1839 +  NS_ENSURE_TRUE(fm, false);
  1.1840 +
  1.1841 +  nsCOMPtr<nsIContent> focusedContent = fm->GetFocusedContent();
  1.1842 +  if (focusedContent && focusedContent->IsEditable())
  1.1843 +    return false;
  1.1844 +
  1.1845 +  return true;
  1.1846 +}
  1.1847 +
  1.1848 +already_AddRefed<nsFrameLoader>
  1.1849 +TabParent::GetFrameLoader() const
  1.1850 +{
  1.1851 +  nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner = do_QueryInterface(mFrameElement);
  1.1852 +  return frameLoaderOwner ? frameLoaderOwner->GetFrameLoader() : nullptr;
  1.1853 +}
  1.1854 +
  1.1855 +void
  1.1856 +TabParent::TryCacheDPIAndScale()
  1.1857 +{
  1.1858 +  if (mDPI > 0) {
  1.1859 +    return;
  1.1860 +  }
  1.1861 +
  1.1862 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.1863 +
  1.1864 +  if (!widget && mFrameElement) {
  1.1865 +    // Even if we don't have a widget (e.g. because we're display:none), there's
  1.1866 +    // probably a widget somewhere in the hierarchy our frame element lives in.
  1.1867 +    widget = nsContentUtils::WidgetForDocument(mFrameElement->OwnerDoc());
  1.1868 +  }
  1.1869 +
  1.1870 +  if (widget) {
  1.1871 +    mDPI = widget->GetDPI();
  1.1872 +    mDefaultScale = widget->GetDefaultScale();
  1.1873 +  }
  1.1874 +}
  1.1875 +
  1.1876 +already_AddRefed<nsIWidget>
  1.1877 +TabParent::GetWidget() const
  1.1878 +{
  1.1879 +  nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
  1.1880 +  if (!content)
  1.1881 +    return nullptr;
  1.1882 +
  1.1883 +  nsIFrame *frame = content->GetPrimaryFrame();
  1.1884 +  if (!frame)
  1.1885 +    return nullptr;
  1.1886 +
  1.1887 +  nsCOMPtr<nsIWidget> widget = frame->GetNearestWidget();
  1.1888 +  return widget.forget();
  1.1889 +}
  1.1890 +
  1.1891 +bool
  1.1892 +TabParent::UseAsyncPanZoom()
  1.1893 +{
  1.1894 +  bool usingOffMainThreadCompositing = !!CompositorParent::CompositorLoop();
  1.1895 +  bool asyncPanZoomEnabled =
  1.1896 +    Preferences::GetBool("layers.async-pan-zoom.enabled", false);
  1.1897 +  return (usingOffMainThreadCompositing && asyncPanZoomEnabled &&
  1.1898 +          GetScrollingBehavior() == ASYNC_PAN_ZOOM);
  1.1899 +}
  1.1900 +
  1.1901 +void
  1.1902 +TabParent::MaybeForwardEventToRenderFrame(WidgetInputEvent& aEvent,
  1.1903 +                                          ScrollableLayerGuid* aOutTargetGuid)
  1.1904 +{
  1.1905 +  if (RenderFrameParent* rfp = GetRenderFrame()) {
  1.1906 +    rfp->NotifyInputEvent(aEvent, aOutTargetGuid);
  1.1907 +  }
  1.1908 +}
  1.1909 +
  1.1910 +bool
  1.1911 +TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
  1.1912 +                                      const nsString& aURL,
  1.1913 +                                      const nsString& aName,
  1.1914 +                                      const nsString& aFeatures,
  1.1915 +                                      bool* aOutWindowOpened)
  1.1916 +{
  1.1917 +  BrowserElementParent::OpenWindowResult opened =
  1.1918 +    BrowserElementParent::OpenWindowOOP(static_cast<TabParent*>(aOpener),
  1.1919 +                                        this, aURL, aName, aFeatures);
  1.1920 +  *aOutWindowOpened = (opened != BrowserElementParent::OPEN_WINDOW_CANCELLED);
  1.1921 +  return true;
  1.1922 +}
  1.1923 +
  1.1924 +bool
  1.1925 +TabParent::RecvPRenderFrameConstructor(PRenderFrameParent* actor)
  1.1926 +{
  1.1927 +  return true;
  1.1928 +}
  1.1929 +
  1.1930 +bool
  1.1931 +TabParent::RecvZoomToRect(const uint32_t& aPresShellId,
  1.1932 +                          const ViewID& aViewId,
  1.1933 +                          const CSSRect& aRect)
  1.1934 +{
  1.1935 +  if (RenderFrameParent* rfp = GetRenderFrame()) {
  1.1936 +    rfp->ZoomToRect(aPresShellId, aViewId, aRect);
  1.1937 +  }
  1.1938 +  return true;
  1.1939 +}
  1.1940 +
  1.1941 +bool
  1.1942 +TabParent::RecvUpdateZoomConstraints(const uint32_t& aPresShellId,
  1.1943 +                                     const ViewID& aViewId,
  1.1944 +                                     const bool& aIsRoot,
  1.1945 +                                     const ZoomConstraints& aConstraints)
  1.1946 +{
  1.1947 +  if (RenderFrameParent* rfp = GetRenderFrame()) {
  1.1948 +    rfp->UpdateZoomConstraints(aPresShellId, aViewId, aIsRoot, aConstraints);
  1.1949 +  }
  1.1950 +  return true;
  1.1951 +}
  1.1952 +
  1.1953 +bool
  1.1954 +TabParent::RecvContentReceivedTouch(const ScrollableLayerGuid& aGuid,
  1.1955 +                                    const bool& aPreventDefault)
  1.1956 +{
  1.1957 +  if (RenderFrameParent* rfp = GetRenderFrame()) {
  1.1958 +    rfp->ContentReceivedTouch(aGuid, aPreventDefault);
  1.1959 +  }
  1.1960 +  return true;
  1.1961 +}
  1.1962 +
  1.1963 +already_AddRefed<nsILoadContext>
  1.1964 +TabParent::GetLoadContext()
  1.1965 +{
  1.1966 +  nsCOMPtr<nsILoadContext> loadContext;
  1.1967 +  if (mLoadContext) {
  1.1968 +    loadContext = mLoadContext;
  1.1969 +  } else {
  1.1970 +    loadContext = new LoadContext(GetOwnerElement(),
  1.1971 +                                  OwnOrContainingAppId(),
  1.1972 +                                  true /* aIsContent */,
  1.1973 +                                  mChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW,
  1.1974 +                                  mChromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW,
  1.1975 +                                  IsBrowserElement());
  1.1976 +    mLoadContext = loadContext;
  1.1977 +  }
  1.1978 +  return loadContext.forget();
  1.1979 +}
  1.1980 +
  1.1981 +/* Be careful if you call this method while proceding a real touch event. For
  1.1982 + * example sending a touchstart during a real touchend may results into
  1.1983 + * a busted mEventCaptureDepth and following touch events may not do what you
  1.1984 + * expect.
  1.1985 + */
  1.1986 +NS_IMETHODIMP
  1.1987 +TabParent::InjectTouchEvent(const nsAString& aType,
  1.1988 +                            uint32_t* aIdentifiers,
  1.1989 +                            int32_t* aXs,
  1.1990 +                            int32_t* aYs,
  1.1991 +                            uint32_t* aRxs,
  1.1992 +                            uint32_t* aRys,
  1.1993 +                            float* aRotationAngles,
  1.1994 +                            float* aForces,
  1.1995 +                            uint32_t aCount,
  1.1996 +                            int32_t aModifiers)
  1.1997 +{
  1.1998 +  uint32_t msg;
  1.1999 +  nsContentUtils::GetEventIdAndAtom(aType, NS_TOUCH_EVENT, &msg);
  1.2000 +  if (msg != NS_TOUCH_START && msg != NS_TOUCH_MOVE &&
  1.2001 +      msg != NS_TOUCH_END && msg != NS_TOUCH_CANCEL) {
  1.2002 +    return NS_ERROR_FAILURE;
  1.2003 +  }
  1.2004 +
  1.2005 +  nsCOMPtr<nsIWidget> widget = GetWidget();
  1.2006 +  if (!widget) {
  1.2007 +    return NS_ERROR_FAILURE;
  1.2008 +  }
  1.2009 +
  1.2010 +  WidgetTouchEvent event(true, msg, widget);
  1.2011 +  event.modifiers = aModifiers;
  1.2012 +  event.time = PR_IntervalNow();
  1.2013 +
  1.2014 +  event.touches.SetCapacity(aCount);
  1.2015 +  for (uint32_t i = 0; i < aCount; ++i) {
  1.2016 +    nsRefPtr<Touch> t = new Touch(aIdentifiers[i],
  1.2017 +                                  nsIntPoint(aXs[i], aYs[i]),
  1.2018 +                                  nsIntPoint(aRxs[i], aRys[i]),
  1.2019 +                                  aRotationAngles[i],
  1.2020 +                                  aForces[i]);
  1.2021 +
  1.2022 +    // Consider all injected touch events as changedTouches. For more details
  1.2023 +    // about the meaning of changedTouches for each event, see
  1.2024 +    // https://developer.mozilla.org/docs/Web/API/TouchEvent.changedTouches
  1.2025 +    t->mChanged = true;
  1.2026 +    event.touches.AppendElement(t);
  1.2027 +  }
  1.2028 +
  1.2029 +  if ((msg == NS_TOUCH_END || msg == NS_TOUCH_CANCEL) && sEventCapturer) {
  1.2030 +    WidgetGUIEvent* guiEvent = event.AsGUIEvent();
  1.2031 +    TryCapture(*guiEvent);
  1.2032 +  }
  1.2033 +
  1.2034 +  SendRealTouchEvent(event);
  1.2035 +  return NS_OK;
  1.2036 +}
  1.2037 +
  1.2038 +NS_IMETHODIMP
  1.2039 +TabParent::GetUseAsyncPanZoom(bool* useAsyncPanZoom)
  1.2040 +{
  1.2041 +  *useAsyncPanZoom = UseAsyncPanZoom();
  1.2042 +  return NS_OK;
  1.2043 +}
  1.2044 +
  1.2045 +NS_IMETHODIMP
  1.2046 +TabParent::SetIsDocShellActive(bool isActive)
  1.2047 +{
  1.2048 +  unused << SendSetIsDocShellActive(isActive);
  1.2049 +  return NS_OK;
  1.2050 +}
  1.2051 +
  1.2052 +} // namespace tabs
  1.2053 +} // namespace mozilla

mercurial