1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/ipc/TabChild.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,2811 @@ 1.4 +/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8; -*- */ 1.5 +/* vim: set sw=2 sts=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 "TabChild.h" 1.13 + 1.14 +#include "Layers.h" 1.15 +#include "ContentChild.h" 1.16 +#include "IndexedDBChild.h" 1.17 +#include "mozilla/Preferences.h" 1.18 +#include "mozilla/ClearOnShutdown.h" 1.19 +#include "mozilla/EventListenerManager.h" 1.20 +#include "mozilla/IntentionalCrash.h" 1.21 +#include "mozilla/docshell/OfflineCacheUpdateChild.h" 1.22 +#include "mozilla/ipc/DocumentRendererChild.h" 1.23 +#include "mozilla/ipc/FileDescriptorUtils.h" 1.24 +#include "mozilla/layers/ActiveElementManager.h" 1.25 +#include "mozilla/layers/APZCCallbackHelper.h" 1.26 +#include "mozilla/layers/AsyncPanZoomController.h" 1.27 +#include "mozilla/layers/CompositorChild.h" 1.28 +#include "mozilla/layers/ImageBridgeChild.h" 1.29 +#include "mozilla/layers/ShadowLayers.h" 1.30 +#include "mozilla/layout/RenderFrameChild.h" 1.31 +#include "mozilla/MouseEvents.h" 1.32 +#include "mozilla/Services.h" 1.33 +#include "mozilla/StaticPtr.h" 1.34 +#include "mozilla/TextEvents.h" 1.35 +#include "mozilla/TouchEvents.h" 1.36 +#include "mozilla/unused.h" 1.37 +#include "mozIApplication.h" 1.38 +#include "nsContentUtils.h" 1.39 +#include "nsCxPusher.h" 1.40 +#include "nsEmbedCID.h" 1.41 +#include <algorithm> 1.42 +#ifdef MOZ_CRASHREPORTER 1.43 +#include "nsExceptionHandler.h" 1.44 +#endif 1.45 +#include "nsFilePickerProxy.h" 1.46 +#include "mozilla/dom/Element.h" 1.47 +#include "nsIBaseWindow.h" 1.48 +#include "nsICachedFileDescriptorListener.h" 1.49 +#include "nsIDocumentInlines.h" 1.50 +#include "nsIDocShellTreeOwner.h" 1.51 +#include "nsIDOMEvent.h" 1.52 +#include "nsIDOMWindow.h" 1.53 +#include "nsIDOMWindowUtils.h" 1.54 +#include "nsIDocShell.h" 1.55 +#include "nsIURI.h" 1.56 +#include "nsIURIFixup.h" 1.57 +#include "nsCDefaultURIFixup.h" 1.58 +#include "nsIWebBrowser.h" 1.59 +#include "nsIWebBrowserFocus.h" 1.60 +#include "nsIWebBrowserSetup.h" 1.61 +#include "nsIWebProgress.h" 1.62 +#include "nsIXULRuntime.h" 1.63 +#include "nsInterfaceHashtable.h" 1.64 +#include "nsPIDOMWindow.h" 1.65 +#include "nsPIWindowRoot.h" 1.66 +#include "nsLayoutUtils.h" 1.67 +#include "nsPrintfCString.h" 1.68 +#include "nsThreadUtils.h" 1.69 +#include "nsWeakReference.h" 1.70 +#include "PermissionMessageUtils.h" 1.71 +#include "PCOMContentPermissionRequestChild.h" 1.72 +#include "PuppetWidget.h" 1.73 +#include "StructuredCloneUtils.h" 1.74 +#include "nsViewportInfo.h" 1.75 +#include "JavaScriptChild.h" 1.76 +#include "nsILoadContext.h" 1.77 +#include "ipc/nsGUIEventIPC.h" 1.78 +#include "mozilla/gfx/Matrix.h" 1.79 +#include "UnitTransforms.h" 1.80 +#include "ClientLayerManager.h" 1.81 + 1.82 +#include "nsColorPickerProxy.h" 1.83 + 1.84 +#ifdef DEBUG 1.85 +#include "PCOMContentPermissionRequestChild.h" 1.86 +#endif /* DEBUG */ 1.87 + 1.88 +#define BROWSER_ELEMENT_CHILD_SCRIPT \ 1.89 + NS_LITERAL_STRING("chrome://global/content/BrowserElementChild.js") 1.90 + 1.91 +using namespace mozilla; 1.92 +using namespace mozilla::dom; 1.93 +using namespace mozilla::dom::ipc; 1.94 +using namespace mozilla::ipc; 1.95 +using namespace mozilla::layers; 1.96 +using namespace mozilla::layout; 1.97 +using namespace mozilla::docshell; 1.98 +using namespace mozilla::dom::indexedDB; 1.99 +using namespace mozilla::widget; 1.100 +using namespace mozilla::jsipc; 1.101 + 1.102 +NS_IMPL_ISUPPORTS(ContentListener, nsIDOMEventListener) 1.103 + 1.104 +static const CSSSize kDefaultViewportSize(980, 480); 1.105 + 1.106 +static const char BROWSER_ZOOM_TO_RECT[] = "browser-zoom-to-rect"; 1.107 +static const char BEFORE_FIRST_PAINT[] = "before-first-paint"; 1.108 + 1.109 +static bool sCpowsEnabled = false; 1.110 +static int32_t sActiveDurationMs = 10; 1.111 +static bool sActiveDurationMsSet = false; 1.112 + 1.113 +typedef nsDataHashtable<nsUint64HashKey, TabChild*> TabChildMap; 1.114 +static TabChildMap* sTabChildren; 1.115 + 1.116 +TabChildBase::TabChildBase() 1.117 + : mOldViewportWidth(0.0f) 1.118 + , mContentDocumentIsDisplayed(false) 1.119 + , mTabChildGlobal(nullptr) 1.120 + , mInnerSize(0, 0) 1.121 +{ 1.122 +} 1.123 + 1.124 +NS_IMPL_CYCLE_COLLECTING_ADDREF(TabChildBase) 1.125 +NS_IMPL_CYCLE_COLLECTING_RELEASE(TabChildBase) 1.126 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(TabChildBase) 1.127 + NS_INTERFACE_MAP_ENTRY(nsISupports) 1.128 +NS_INTERFACE_MAP_END 1.129 + 1.130 +NS_IMPL_CYCLE_COLLECTION(TabChildBase, mTabChildGlobal, mGlobal) 1.131 + 1.132 +void 1.133 +TabChildBase::InitializeRootMetrics() 1.134 +{ 1.135 + // Calculate a really simple resolution that we probably won't 1.136 + // be keeping, as well as putting the scroll offset back to 1.137 + // the top-left of the page. 1.138 + mLastRootMetrics.mViewport = CSSRect(CSSPoint(), kDefaultViewportSize); 1.139 + mLastRootMetrics.mCompositionBounds = ParentLayerIntRect( 1.140 + ParentLayerIntPoint(), 1.141 + ViewAs<ParentLayerPixel>(mInnerSize, PixelCastJustification::ScreenToParentLayerForRoot)); 1.142 + mLastRootMetrics.SetZoom(mLastRootMetrics.CalculateIntrinsicScale()); 1.143 + mLastRootMetrics.mDevPixelsPerCSSPixel = WebWidget()->GetDefaultScale(); 1.144 + // We use ScreenToLayerScale(1) below in order to turn the 1.145 + // async zoom amount into the gecko zoom amount. 1.146 + mLastRootMetrics.mCumulativeResolution = 1.147 + mLastRootMetrics.GetZoom() / mLastRootMetrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1); 1.148 + // This is the root layer, so the cumulative resolution is the same 1.149 + // as the resolution. 1.150 + mLastRootMetrics.mResolution = mLastRootMetrics.mCumulativeResolution / LayoutDeviceToParentLayerScale(1); 1.151 + mLastRootMetrics.SetScrollOffset(CSSPoint(0, 0)); 1.152 +} 1.153 + 1.154 +bool 1.155 +TabChildBase::HasValidInnerSize() 1.156 +{ 1.157 + return (mInnerSize.width != 0) && (mInnerSize.height != 0); 1.158 +} 1.159 + 1.160 +void 1.161 +TabChildBase::SetCSSViewport(const CSSSize& aSize) 1.162 +{ 1.163 + mOldViewportWidth = aSize.width; 1.164 + 1.165 + if (mContentDocumentIsDisplayed) { 1.166 + nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils()); 1.167 + utils->SetCSSViewport(aSize.width, aSize.height); 1.168 + } 1.169 +} 1.170 + 1.171 +CSSSize 1.172 +TabChildBase::GetPageSize(nsCOMPtr<nsIDocument> aDocument, const CSSSize& aViewport) 1.173 +{ 1.174 + nsCOMPtr<Element> htmlDOMElement = aDocument->GetHtmlElement(); 1.175 + HTMLBodyElement* bodyDOMElement = aDocument->GetBodyElement(); 1.176 + 1.177 + if (!htmlDOMElement && !bodyDOMElement) { 1.178 + // For non-HTML content (e.g. SVG), just assume page size == viewport size. 1.179 + return aViewport; 1.180 + } 1.181 + 1.182 + int32_t htmlWidth = 0, htmlHeight = 0; 1.183 + if (htmlDOMElement) { 1.184 + htmlWidth = htmlDOMElement->ScrollWidth(); 1.185 + htmlHeight = htmlDOMElement->ScrollHeight(); 1.186 + } 1.187 + int32_t bodyWidth = 0, bodyHeight = 0; 1.188 + if (bodyDOMElement) { 1.189 + bodyWidth = bodyDOMElement->ScrollWidth(); 1.190 + bodyHeight = bodyDOMElement->ScrollHeight(); 1.191 + } 1.192 + return CSSSize(std::max(htmlWidth, bodyWidth), 1.193 + std::max(htmlHeight, bodyHeight)); 1.194 +} 1.195 + 1.196 +bool 1.197 +TabChildBase::HandlePossibleViewportChange() 1.198 +{ 1.199 + if (!IsAsyncPanZoomEnabled()) { 1.200 + return false; 1.201 + } 1.202 + 1.203 + nsCOMPtr<nsIDocument> document(GetDocument()); 1.204 + nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils()); 1.205 + 1.206 + nsViewportInfo viewportInfo = nsContentUtils::GetViewportInfo(document, mInnerSize); 1.207 + uint32_t presShellId; 1.208 + mozilla::layers::FrameMetrics::ViewID viewId; 1.209 + bool scrollIdentifiersValid = APZCCallbackHelper::GetScrollIdentifiers( 1.210 + document->GetDocumentElement(), &presShellId, &viewId); 1.211 + if (scrollIdentifiersValid) { 1.212 + ZoomConstraints constraints( 1.213 + viewportInfo.IsZoomAllowed(), 1.214 + viewportInfo.IsDoubleTapZoomAllowed(), 1.215 + viewportInfo.GetMinZoom(), 1.216 + viewportInfo.GetMaxZoom()); 1.217 + DoUpdateZoomConstraints(presShellId, 1.218 + viewId, 1.219 + /* isRoot = */ true, 1.220 + constraints); 1.221 + } 1.222 + 1.223 + float screenW = mInnerSize.width; 1.224 + float screenH = mInnerSize.height; 1.225 + CSSSize viewport(viewportInfo.GetSize()); 1.226 + 1.227 + // We're not being displayed in any way; don't bother doing anything because 1.228 + // that will just confuse future adjustments. 1.229 + if (!screenW || !screenH) { 1.230 + return false; 1.231 + } 1.232 + 1.233 + float oldBrowserWidth = mOldViewportWidth; 1.234 + mLastRootMetrics.mViewport.SizeTo(viewport); 1.235 + if (!oldBrowserWidth) { 1.236 + oldBrowserWidth = kDefaultViewportSize.width; 1.237 + } 1.238 + SetCSSViewport(viewport); 1.239 + 1.240 + // If this page has not been painted yet, then this must be getting run 1.241 + // because a meta-viewport element was added (via the DOMMetaAdded handler). 1.242 + // in this case, we should not do anything that forces a reflow (see bug 1.243 + // 759678) such as requesting the page size or sending a viewport update. this 1.244 + // code will get run again in the before-first-paint handler and that point we 1.245 + // will run though all of it. the reason we even bother executing up to this 1.246 + // point on the DOMMetaAdded handler is so that scripts that use 1.247 + // window.innerWidth before they are painted have a correct value (bug 1.248 + // 771575). 1.249 + if (!mContentDocumentIsDisplayed) { 1.250 + return false; 1.251 + } 1.252 + 1.253 + float oldScreenWidth = mLastRootMetrics.mCompositionBounds.width; 1.254 + if (!oldScreenWidth) { 1.255 + oldScreenWidth = mInnerSize.width; 1.256 + } 1.257 + 1.258 + FrameMetrics metrics(mLastRootMetrics); 1.259 + metrics.mViewport = CSSRect(CSSPoint(), viewport); 1.260 + metrics.mCompositionBounds = ParentLayerIntRect( 1.261 + ParentLayerIntPoint(), 1.262 + ViewAs<ParentLayerPixel>(mInnerSize, PixelCastJustification::ScreenToParentLayerForRoot)); 1.263 + metrics.SetRootCompositionSize( 1.264 + ScreenSize(mInnerSize) * ScreenToLayoutDeviceScale(1.0f) / metrics.mDevPixelsPerCSSPixel); 1.265 + 1.266 + // This change to the zoom accounts for all types of changes I can conceive: 1.267 + // 1. screen size changes, CSS viewport does not (pages with no meta viewport 1.268 + // or a fixed size viewport) 1.269 + // 2. screen size changes, CSS viewport also does (pages with a device-width 1.270 + // viewport) 1.271 + // 3. screen size remains constant, but CSS viewport changes (meta viewport 1.272 + // tag is added or removed) 1.273 + // 4. neither screen size nor CSS viewport changes 1.274 + // 1.275 + // In all of these cases, we maintain how much actual content is visible 1.276 + // within the screen width. Note that "actual content" may be different with 1.277 + // respect to CSS pixels because of the CSS viewport size changing. 1.278 + float oldIntrinsicScale = oldScreenWidth / oldBrowserWidth; 1.279 + metrics.ZoomBy(metrics.CalculateIntrinsicScale().scale / oldIntrinsicScale); 1.280 + 1.281 + // Changing the zoom when we're not doing a first paint will get ignored 1.282 + // by AsyncPanZoomController and causes a blurry flash. 1.283 + bool isFirstPaint; 1.284 + nsresult rv = utils->GetIsFirstPaint(&isFirstPaint); 1.285 + if (NS_FAILED(rv) || isFirstPaint) { 1.286 + // FIXME/bug 799585(?): GetViewportInfo() returns a defaultZoom of 1.287 + // 0.0 to mean "did not calculate a zoom". In that case, we default 1.288 + // it to the intrinsic scale. 1.289 + if (viewportInfo.GetDefaultZoom().scale < 0.01f) { 1.290 + viewportInfo.SetDefaultZoom(metrics.CalculateIntrinsicScale()); 1.291 + } 1.292 + 1.293 + CSSToScreenScale defaultZoom = viewportInfo.GetDefaultZoom(); 1.294 + MOZ_ASSERT(viewportInfo.GetMinZoom() <= defaultZoom && 1.295 + defaultZoom <= viewportInfo.GetMaxZoom()); 1.296 + metrics.SetZoom(defaultZoom); 1.297 + 1.298 + metrics.SetScrollId(viewId); 1.299 + } 1.300 + 1.301 + metrics.mCumulativeResolution = metrics.GetZoom() / metrics.mDevPixelsPerCSSPixel * ScreenToLayerScale(1); 1.302 + // This is the root layer, so the cumulative resolution is the same 1.303 + // as the resolution. 1.304 + metrics.mResolution = metrics.mCumulativeResolution / LayoutDeviceToParentLayerScale(1); 1.305 + utils->SetResolution(metrics.mResolution.scale, metrics.mResolution.scale); 1.306 + 1.307 + CSSSize scrollPort = metrics.CalculateCompositedSizeInCssPixels(); 1.308 + utils->SetScrollPositionClampingScrollPortSize(scrollPort.width, scrollPort.height); 1.309 + 1.310 + // The call to GetPageSize forces a resize event to content, so we need to 1.311 + // make sure that we have the right CSS viewport and 1.312 + // scrollPositionClampingScrollPortSize set up before that happens. 1.313 + 1.314 + CSSSize pageSize = GetPageSize(document, viewport); 1.315 + if (!pageSize.width) { 1.316 + // Return early rather than divide by 0. 1.317 + return false; 1.318 + } 1.319 + metrics.mScrollableRect = CSSRect(CSSPoint(), pageSize); 1.320 + 1.321 + // Calculate a display port _after_ having a scrollable rect because the 1.322 + // display port is clamped to the scrollable rect. 1.323 + metrics.SetDisplayPortMargins(AsyncPanZoomController::CalculatePendingDisplayPort( 1.324 + // The page must have been refreshed in some way such as a new document or 1.325 + // new CSS viewport, so we know that there's no velocity, acceleration, and 1.326 + // we have no idea how long painting will take. 1.327 + metrics, ScreenPoint(0.0f, 0.0f), 0.0)); 1.328 + metrics.SetUseDisplayPortMargins(); 1.329 + 1.330 + // Force a repaint with these metrics. This, among other things, sets the 1.331 + // displayport, so we start with async painting. 1.332 + mLastRootMetrics = ProcessUpdateFrame(metrics); 1.333 + 1.334 + if (viewportInfo.IsZoomAllowed() && scrollIdentifiersValid) { 1.335 + // If the CSS viewport is narrower than the screen (i.e. width <= device-width) 1.336 + // then we disable double-tap-to-zoom behaviour. 1.337 + bool allowDoubleTapZoom = (viewport.width > screenW / metrics.mDevPixelsPerCSSPixel.scale); 1.338 + if (allowDoubleTapZoom != viewportInfo.IsDoubleTapZoomAllowed()) { 1.339 + viewportInfo.SetAllowDoubleTapZoom(allowDoubleTapZoom); 1.340 + 1.341 + ZoomConstraints constraints( 1.342 + viewportInfo.IsZoomAllowed(), 1.343 + viewportInfo.IsDoubleTapZoomAllowed(), 1.344 + viewportInfo.GetMinZoom(), 1.345 + viewportInfo.GetMaxZoom()); 1.346 + DoUpdateZoomConstraints(presShellId, 1.347 + viewId, 1.348 + /* isRoot = */ true, 1.349 + constraints); 1.350 + } 1.351 + } 1.352 + 1.353 + return true; 1.354 +} 1.355 + 1.356 +already_AddRefed<nsIDOMWindowUtils> 1.357 +TabChildBase::GetDOMWindowUtils() 1.358 +{ 1.359 + nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(WebNavigation()); 1.360 + nsCOMPtr<nsIDOMWindowUtils> utils = do_GetInterface(window); 1.361 + return utils.forget(); 1.362 +} 1.363 + 1.364 +already_AddRefed<nsIDocument> 1.365 +TabChildBase::GetDocument() 1.366 +{ 1.367 + nsCOMPtr<nsIDOMDocument> domDoc; 1.368 + WebNavigation()->GetDocument(getter_AddRefs(domDoc)); 1.369 + nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc)); 1.370 + return doc.forget(); 1.371 +} 1.372 + 1.373 +void 1.374 +TabChildBase::DispatchMessageManagerMessage(const nsAString& aMessageName, 1.375 + const nsAString& aJSONData) 1.376 +{ 1.377 + AutoSafeJSContext cx; 1.378 + JS::Rooted<JS::Value> json(cx, JSVAL_NULL); 1.379 + StructuredCloneData cloneData; 1.380 + JSAutoStructuredCloneBuffer buffer; 1.381 + if (JS_ParseJSON(cx, 1.382 + static_cast<const jschar*>(aJSONData.BeginReading()), 1.383 + aJSONData.Length(), 1.384 + &json)) { 1.385 + WriteStructuredClone(cx, json, buffer, cloneData.mClosure); 1.386 + cloneData.mData = buffer.data(); 1.387 + cloneData.mDataLength = buffer.nbytes(); 1.388 + } 1.389 + 1.390 + nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(GetGlobal()); 1.391 + // Let the BrowserElementScrolling helper (if it exists) for this 1.392 + // content manipulate the frame state. 1.393 + nsRefPtr<nsFrameMessageManager> mm = 1.394 + static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get()); 1.395 + mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal), 1.396 + aMessageName, false, &cloneData, nullptr, nullptr, nullptr); 1.397 +} 1.398 + 1.399 +bool 1.400 +TabChildBase::UpdateFrameHandler(const FrameMetrics& aFrameMetrics) 1.401 +{ 1.402 + MOZ_ASSERT(aFrameMetrics.GetScrollId() != FrameMetrics::NULL_SCROLL_ID); 1.403 + 1.404 + if (aFrameMetrics.mIsRoot) { 1.405 + nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils()); 1.406 + if (APZCCallbackHelper::HasValidPresShellId(utils, aFrameMetrics)) { 1.407 + mLastRootMetrics = ProcessUpdateFrame(aFrameMetrics); 1.408 + APZCCallbackHelper::UpdateCallbackTransform(aFrameMetrics, mLastRootMetrics); 1.409 + return true; 1.410 + } 1.411 + } else { 1.412 + // aFrameMetrics.mIsRoot is false, so we are trying to update a subframe. 1.413 + // This requires special handling. 1.414 + nsCOMPtr<nsIContent> content = nsLayoutUtils::FindContentFor( 1.415 + aFrameMetrics.GetScrollId()); 1.416 + if (content) { 1.417 + FrameMetrics newSubFrameMetrics(aFrameMetrics); 1.418 + APZCCallbackHelper::UpdateSubFrame(content, newSubFrameMetrics); 1.419 + APZCCallbackHelper::UpdateCallbackTransform(aFrameMetrics, newSubFrameMetrics); 1.420 + return true; 1.421 + } 1.422 + } 1.423 + 1.424 + // We've recieved a message that is out of date and we want to ignore. 1.425 + // However we can't reply without painting so we reply by painting the 1.426 + // exact same thing as we did before. 1.427 + mLastRootMetrics = ProcessUpdateFrame(mLastRootMetrics); 1.428 + return true; 1.429 +} 1.430 + 1.431 +FrameMetrics 1.432 +TabChildBase::ProcessUpdateFrame(const FrameMetrics& aFrameMetrics) 1.433 +{ 1.434 + if (!mGlobal || !mTabChildGlobal) { 1.435 + return aFrameMetrics; 1.436 + } 1.437 + 1.438 + nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils()); 1.439 + 1.440 + FrameMetrics newMetrics = aFrameMetrics; 1.441 + APZCCallbackHelper::UpdateRootFrame(utils, newMetrics); 1.442 + 1.443 + CSSSize cssCompositedSize = newMetrics.CalculateCompositedSizeInCssPixels(); 1.444 + // The BrowserElementScrolling helper must know about these updated metrics 1.445 + // for other functions it performs, such as double tap handling. 1.446 + // Note, %f must not be used because it is locale specific! 1.447 + nsString data; 1.448 + data.AppendPrintf("{ \"x\" : %d", NS_lround(newMetrics.GetScrollOffset().x)); 1.449 + data.AppendPrintf(", \"y\" : %d", NS_lround(newMetrics.GetScrollOffset().y)); 1.450 + data.AppendLiteral(", \"viewport\" : "); 1.451 + data.AppendLiteral("{ \"width\" : "); 1.452 + data.AppendFloat(newMetrics.mViewport.width); 1.453 + data.AppendLiteral(", \"height\" : "); 1.454 + data.AppendFloat(newMetrics.mViewport.height); 1.455 + data.AppendLiteral(" }"); 1.456 + data.AppendLiteral(", \"cssPageRect\" : "); 1.457 + data.AppendLiteral("{ \"x\" : "); 1.458 + data.AppendFloat(newMetrics.mScrollableRect.x); 1.459 + data.AppendLiteral(", \"y\" : "); 1.460 + data.AppendFloat(newMetrics.mScrollableRect.y); 1.461 + data.AppendLiteral(", \"width\" : "); 1.462 + data.AppendFloat(newMetrics.mScrollableRect.width); 1.463 + data.AppendLiteral(", \"height\" : "); 1.464 + data.AppendFloat(newMetrics.mScrollableRect.height); 1.465 + data.AppendLiteral(" }"); 1.466 + data.AppendPrintf(", \"resolution\" : "); // TODO: check if it's actually used? 1.467 + data.AppendPrintf("{ \"width\" : "); 1.468 + data.AppendFloat(newMetrics.CalculateIntrinsicScale().scale); 1.469 + data.AppendPrintf(" }"); 1.470 + data.AppendLiteral(", \"cssCompositedRect\" : "); 1.471 + data.AppendLiteral("{ \"width\" : "); 1.472 + data.AppendFloat(cssCompositedSize.width); 1.473 + data.AppendLiteral(", \"height\" : "); 1.474 + data.AppendFloat(cssCompositedSize.height); 1.475 + data.AppendLiteral(" }"); 1.476 + data.AppendLiteral(" }"); 1.477 + 1.478 + DispatchMessageManagerMessage(NS_LITERAL_STRING("Viewport:Change"), data); 1.479 + return newMetrics; 1.480 +} 1.481 + 1.482 +nsEventStatus 1.483 +TabChildBase::DispatchSynthesizedMouseEvent(uint32_t aMsg, uint64_t aTime, 1.484 + const LayoutDevicePoint& aRefPoint, 1.485 + nsIWidget* aWidget) 1.486 +{ 1.487 + MOZ_ASSERT(aMsg == NS_MOUSE_MOVE || aMsg == NS_MOUSE_BUTTON_DOWN || 1.488 + aMsg == NS_MOUSE_BUTTON_UP); 1.489 + 1.490 + WidgetMouseEvent event(true, aMsg, nullptr, 1.491 + WidgetMouseEvent::eReal, WidgetMouseEvent::eNormal); 1.492 + event.refPoint = LayoutDeviceIntPoint(aRefPoint.x, aRefPoint.y); 1.493 + event.time = aTime; 1.494 + event.button = WidgetMouseEvent::eLeftButton; 1.495 + event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH; 1.496 + if (aMsg != NS_MOUSE_MOVE) { 1.497 + event.clickCount = 1; 1.498 + } 1.499 + event.widget = aWidget; 1.500 + 1.501 + return DispatchWidgetEvent(event); 1.502 +} 1.503 + 1.504 +nsEventStatus 1.505 +TabChildBase::DispatchWidgetEvent(WidgetGUIEvent& event) 1.506 +{ 1.507 + if (!event.widget) 1.508 + return nsEventStatus_eConsumeNoDefault; 1.509 + 1.510 + nsEventStatus status; 1.511 + NS_ENSURE_SUCCESS(event.widget->DispatchEvent(&event, status), 1.512 + nsEventStatus_eConsumeNoDefault); 1.513 + return status; 1.514 +} 1.515 + 1.516 +bool 1.517 +TabChildBase::IsAsyncPanZoomEnabled() 1.518 +{ 1.519 + return mScrolling == ASYNC_PAN_ZOOM; 1.520 +} 1.521 + 1.522 +NS_IMETHODIMP 1.523 +ContentListener::HandleEvent(nsIDOMEvent* aEvent) 1.524 +{ 1.525 + RemoteDOMEvent remoteEvent; 1.526 + remoteEvent.mEvent = do_QueryInterface(aEvent); 1.527 + NS_ENSURE_STATE(remoteEvent.mEvent); 1.528 + mTabChild->SendEvent(remoteEvent); 1.529 + return NS_OK; 1.530 +} 1.531 + 1.532 +class TabChild::CachedFileDescriptorInfo 1.533 +{ 1.534 + struct PathOnlyComparatorHelper 1.535 + { 1.536 + bool Equals(const nsAutoPtr<CachedFileDescriptorInfo>& a, 1.537 + const CachedFileDescriptorInfo& b) const 1.538 + { 1.539 + return a->mPath == b.mPath; 1.540 + } 1.541 + }; 1.542 + 1.543 + struct PathAndCallbackComparatorHelper 1.544 + { 1.545 + bool Equals(const nsAutoPtr<CachedFileDescriptorInfo>& a, 1.546 + const CachedFileDescriptorInfo& b) const 1.547 + { 1.548 + return a->mPath == b.mPath && 1.549 + a->mCallback == b.mCallback; 1.550 + } 1.551 + }; 1.552 + 1.553 +public: 1.554 + nsString mPath; 1.555 + FileDescriptor mFileDescriptor; 1.556 + nsCOMPtr<nsICachedFileDescriptorListener> mCallback; 1.557 + bool mCanceled; 1.558 + 1.559 + CachedFileDescriptorInfo(const nsAString& aPath) 1.560 + : mPath(aPath), mCanceled(false) 1.561 + { } 1.562 + 1.563 + CachedFileDescriptorInfo(const nsAString& aPath, 1.564 + const FileDescriptor& aFileDescriptor) 1.565 + : mPath(aPath), mFileDescriptor(aFileDescriptor), mCanceled(false) 1.566 + { } 1.567 + 1.568 + CachedFileDescriptorInfo(const nsAString& aPath, 1.569 + nsICachedFileDescriptorListener* aCallback) 1.570 + : mPath(aPath), mCallback(aCallback), mCanceled(false) 1.571 + { } 1.572 + 1.573 + PathOnlyComparatorHelper PathOnlyComparator() const 1.574 + { 1.575 + return PathOnlyComparatorHelper(); 1.576 + } 1.577 + 1.578 + PathAndCallbackComparatorHelper PathAndCallbackComparator() const 1.579 + { 1.580 + return PathAndCallbackComparatorHelper(); 1.581 + } 1.582 + 1.583 + void FireCallback() const 1.584 + { 1.585 + mCallback->OnCachedFileDescriptor(mPath, mFileDescriptor); 1.586 + } 1.587 +}; 1.588 + 1.589 +class TabChild::CachedFileDescriptorCallbackRunnable : public nsRunnable 1.590 +{ 1.591 + typedef TabChild::CachedFileDescriptorInfo CachedFileDescriptorInfo; 1.592 + 1.593 + nsAutoPtr<CachedFileDescriptorInfo> mInfo; 1.594 + 1.595 +public: 1.596 + CachedFileDescriptorCallbackRunnable(CachedFileDescriptorInfo* aInfo) 1.597 + : mInfo(aInfo) 1.598 + { 1.599 + MOZ_ASSERT(NS_IsMainThread()); 1.600 + MOZ_ASSERT(aInfo); 1.601 + MOZ_ASSERT(!aInfo->mPath.IsEmpty()); 1.602 + MOZ_ASSERT(aInfo->mCallback); 1.603 + } 1.604 + 1.605 + void Dispatch() 1.606 + { 1.607 + MOZ_ASSERT(NS_IsMainThread()); 1.608 + 1.609 + nsresult rv = NS_DispatchToCurrentThread(this); 1.610 + NS_ENSURE_SUCCESS_VOID(rv); 1.611 + } 1.612 + 1.613 +private: 1.614 + NS_IMETHOD Run() 1.615 + { 1.616 + MOZ_ASSERT(NS_IsMainThread()); 1.617 + MOZ_ASSERT(mInfo); 1.618 + 1.619 + mInfo->FireCallback(); 1.620 + return NS_OK; 1.621 + } 1.622 +}; 1.623 + 1.624 +StaticRefPtr<TabChild> sPreallocatedTab; 1.625 + 1.626 +/*static*/ void 1.627 +TabChild::PreloadSlowThings() 1.628 +{ 1.629 + MOZ_ASSERT(!sPreallocatedTab); 1.630 + 1.631 + nsRefPtr<TabChild> tab(new TabChild(ContentChild::GetSingleton(), 1.632 + TabContext(), /* chromeFlags */ 0)); 1.633 + if (!NS_SUCCEEDED(tab->Init()) || 1.634 + !tab->InitTabChildGlobal(DONT_LOAD_SCRIPTS)) { 1.635 + return; 1.636 + } 1.637 + // Just load and compile these scripts, but don't run them. 1.638 + tab->TryCacheLoadAndCompileScript(BROWSER_ELEMENT_CHILD_SCRIPT, true); 1.639 + // Load, compile, and run these scripts. 1.640 + tab->RecvLoadRemoteScript( 1.641 + NS_LITERAL_STRING("chrome://global/content/preload.js"), 1.642 + true); 1.643 + 1.644 + nsCOMPtr<nsIDocShell> docShell = do_GetInterface(tab->WebNavigation()); 1.645 + if (nsIPresShell* presShell = docShell->GetPresShell()) { 1.646 + // Initialize and do an initial reflow of the about:blank 1.647 + // PresShell to let it preload some things for us. 1.648 + presShell->Initialize(0, 0); 1.649 + nsIDocument* doc = presShell->GetDocument(); 1.650 + doc->FlushPendingNotifications(Flush_Layout); 1.651 + // ... but after it's done, make sure it doesn't do any more 1.652 + // work. 1.653 + presShell->MakeZombie(); 1.654 + } 1.655 + 1.656 + sPreallocatedTab = tab; 1.657 + ClearOnShutdown(&sPreallocatedTab); 1.658 +} 1.659 + 1.660 +/*static*/ already_AddRefed<TabChild> 1.661 +TabChild::Create(ContentChild* aManager, const TabContext &aContext, uint32_t aChromeFlags) 1.662 +{ 1.663 + if (sPreallocatedTab && 1.664 + sPreallocatedTab->mChromeFlags == aChromeFlags && 1.665 + aContext.IsBrowserOrApp()) { 1.666 + 1.667 + nsRefPtr<TabChild> child = sPreallocatedTab.get(); 1.668 + sPreallocatedTab = nullptr; 1.669 + 1.670 + MOZ_ASSERT(!child->mTriedBrowserInit); 1.671 + 1.672 + child->SetTabContext(aContext); 1.673 + child->NotifyTabContextUpdated(); 1.674 + return child.forget(); 1.675 + } 1.676 + 1.677 + nsRefPtr<TabChild> iframe = new TabChild(aManager, 1.678 + aContext, aChromeFlags); 1.679 + return NS_SUCCEEDED(iframe->Init()) ? iframe.forget() : nullptr; 1.680 +} 1.681 + 1.682 + 1.683 +TabChild::TabChild(ContentChild* aManager, const TabContext& aContext, uint32_t aChromeFlags) 1.684 + : TabContext(aContext) 1.685 + , mRemoteFrame(nullptr) 1.686 + , mManager(aManager) 1.687 + , mChromeFlags(aChromeFlags) 1.688 + , mLayersId(0) 1.689 + , mOuterRect(0, 0, 0, 0) 1.690 + , mActivePointerId(-1) 1.691 + , mTapHoldTimer(nullptr) 1.692 + , mAppPackageFileDescriptorRecved(false) 1.693 + , mLastBackgroundColor(NS_RGB(255, 255, 255)) 1.694 + , mDidFakeShow(false) 1.695 + , mNotified(false) 1.696 + , mTriedBrowserInit(false) 1.697 + , mOrientation(eScreenOrientation_PortraitPrimary) 1.698 + , mUpdateHitRegion(false) 1.699 + , mContextMenuHandled(false) 1.700 + , mWaitingTouchListeners(false) 1.701 + , mIgnoreKeyPressEvent(false) 1.702 + , mActiveElementManager(new ActiveElementManager()) 1.703 +{ 1.704 + if (!sActiveDurationMsSet) { 1.705 + Preferences::AddIntVarCache(&sActiveDurationMs, 1.706 + "ui.touch_activation.duration_ms", 1.707 + sActiveDurationMs); 1.708 + sActiveDurationMsSet = true; 1.709 + } 1.710 +} 1.711 + 1.712 +NS_IMETHODIMP 1.713 +TabChild::HandleEvent(nsIDOMEvent* aEvent) 1.714 +{ 1.715 + nsAutoString eventType; 1.716 + aEvent->GetType(eventType); 1.717 + if (eventType.EqualsLiteral("DOMMetaAdded")) { 1.718 + // This meta data may or may not have been a meta viewport tag. If it was, 1.719 + // we should handle it immediately. 1.720 + HandlePossibleViewportChange(); 1.721 + } 1.722 + 1.723 + return NS_OK; 1.724 +} 1.725 + 1.726 +NS_IMETHODIMP 1.727 +TabChild::Observe(nsISupports *aSubject, 1.728 + const char *aTopic, 1.729 + const char16_t *aData) 1.730 +{ 1.731 + if (!strcmp(aTopic, BROWSER_ZOOM_TO_RECT)) { 1.732 + nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(aSubject)); 1.733 + nsCOMPtr<nsITabChild> tabChild(TabChild::GetFrom(docShell)); 1.734 + if (tabChild == this) { 1.735 + nsCOMPtr<nsIDocument> doc(GetDocument()); 1.736 + uint32_t presShellId; 1.737 + ViewID viewId; 1.738 + if (APZCCallbackHelper::GetScrollIdentifiers(doc->GetDocumentElement(), 1.739 + &presShellId, &viewId)) { 1.740 + CSSRect rect; 1.741 + sscanf(NS_ConvertUTF16toUTF8(aData).get(), 1.742 + "{\"x\":%f,\"y\":%f,\"w\":%f,\"h\":%f}", 1.743 + &rect.x, &rect.y, &rect.width, &rect.height); 1.744 + SendZoomToRect(presShellId, viewId, rect); 1.745 + } 1.746 + } 1.747 + } else if (!strcmp(aTopic, BEFORE_FIRST_PAINT)) { 1.748 + if (IsAsyncPanZoomEnabled()) { 1.749 + nsCOMPtr<nsIDocument> subject(do_QueryInterface(aSubject)); 1.750 + nsCOMPtr<nsIDocument> doc(GetDocument()); 1.751 + 1.752 + if (SameCOMIdentity(subject, doc)) { 1.753 + nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils()); 1.754 + utils->SetIsFirstPaint(true); 1.755 + 1.756 + mContentDocumentIsDisplayed = true; 1.757 + 1.758 + // Reset CSS viewport and zoom to default on new page, then 1.759 + // calculate them properly using the actual metadata from the 1.760 + // page. 1.761 + SetCSSViewport(kDefaultViewportSize); 1.762 + 1.763 + // In some cases before-first-paint gets called before 1.764 + // RecvUpdateDimensions is called and therefore before we have an 1.765 + // mInnerSize value set. In such cases defer initializing the viewport 1.766 + // until we we get an inner size. 1.767 + if (HasValidInnerSize()) { 1.768 + InitializeRootMetrics(); 1.769 + utils->SetResolution(mLastRootMetrics.mResolution.scale, 1.770 + mLastRootMetrics.mResolution.scale); 1.771 + HandlePossibleViewportChange(); 1.772 + } 1.773 + } 1.774 + } 1.775 + } 1.776 + 1.777 + return NS_OK; 1.778 +} 1.779 + 1.780 +NS_IMETHODIMP 1.781 +TabChild::OnStateChange(nsIWebProgress* aWebProgress, 1.782 + nsIRequest* aRequest, 1.783 + uint32_t aStateFlags, 1.784 + nsresult aStatus) 1.785 +{ 1.786 + NS_NOTREACHED("not implemented in TabChild"); 1.787 + return NS_OK; 1.788 +} 1.789 + 1.790 +NS_IMETHODIMP 1.791 +TabChild::OnProgressChange(nsIWebProgress* aWebProgress, 1.792 + nsIRequest* aRequest, 1.793 + int32_t aCurSelfProgress, 1.794 + int32_t aMaxSelfProgress, 1.795 + int32_t aCurTotalProgress, 1.796 + int32_t aMaxTotalProgress) 1.797 +{ 1.798 + NS_NOTREACHED("not implemented in TabChild"); 1.799 + return NS_OK; 1.800 +} 1.801 + 1.802 +NS_IMETHODIMP 1.803 +TabChild::OnLocationChange(nsIWebProgress* aWebProgress, 1.804 + nsIRequest* aRequest, 1.805 + nsIURI *aLocation, 1.806 + uint32_t aFlags) 1.807 +{ 1.808 + if (!IsAsyncPanZoomEnabled()) { 1.809 + return NS_OK; 1.810 + } 1.811 + 1.812 + nsCOMPtr<nsIDOMWindow> window; 1.813 + aWebProgress->GetDOMWindow(getter_AddRefs(window)); 1.814 + if (!window) { 1.815 + return NS_OK; 1.816 + } 1.817 + 1.818 + nsCOMPtr<nsIDOMDocument> progressDoc; 1.819 + window->GetDocument(getter_AddRefs(progressDoc)); 1.820 + if (!progressDoc) { 1.821 + return NS_OK; 1.822 + } 1.823 + 1.824 + nsCOMPtr<nsIDOMDocument> domDoc; 1.825 + WebNavigation()->GetDocument(getter_AddRefs(domDoc)); 1.826 + if (!domDoc || !SameCOMIdentity(domDoc, progressDoc)) { 1.827 + return NS_OK; 1.828 + } 1.829 + 1.830 + nsCOMPtr<nsIURIFixup> urifixup(do_GetService(NS_URIFIXUP_CONTRACTID)); 1.831 + if (!urifixup) { 1.832 + return NS_OK; 1.833 + } 1.834 + 1.835 + nsCOMPtr<nsIURI> exposableURI; 1.836 + urifixup->CreateExposableURI(aLocation, getter_AddRefs(exposableURI)); 1.837 + if (!exposableURI) { 1.838 + return NS_OK; 1.839 + } 1.840 + 1.841 + if (!(aFlags & nsIWebProgressListener::LOCATION_CHANGE_SAME_DOCUMENT)) { 1.842 + mContentDocumentIsDisplayed = false; 1.843 + } else if (mLastURI != nullptr) { 1.844 + bool exposableEqualsLast, exposableEqualsNew; 1.845 + exposableURI->Equals(mLastURI.get(), &exposableEqualsLast); 1.846 + exposableURI->Equals(aLocation, &exposableEqualsNew); 1.847 + if (exposableEqualsLast && !exposableEqualsNew) { 1.848 + mContentDocumentIsDisplayed = false; 1.849 + } 1.850 + } 1.851 + 1.852 + return NS_OK; 1.853 +} 1.854 + 1.855 +NS_IMETHODIMP 1.856 +TabChild::OnStatusChange(nsIWebProgress* aWebProgress, 1.857 + nsIRequest* aRequest, 1.858 + nsresult aStatus, 1.859 + const char16_t* aMessage) 1.860 +{ 1.861 + NS_NOTREACHED("not implemented in TabChild"); 1.862 + return NS_OK; 1.863 +} 1.864 + 1.865 +NS_IMETHODIMP 1.866 +TabChild::OnSecurityChange(nsIWebProgress* aWebProgress, 1.867 + nsIRequest* aRequest, 1.868 + uint32_t aState) 1.869 +{ 1.870 + NS_NOTREACHED("not implemented in TabChild"); 1.871 + return NS_OK; 1.872 +} 1.873 + 1.874 +bool 1.875 +TabChild::DoUpdateZoomConstraints(const uint32_t& aPresShellId, 1.876 + const ViewID& aViewId, 1.877 + const bool& aIsRoot, 1.878 + const ZoomConstraints& aConstraints) 1.879 +{ 1.880 + return SendUpdateZoomConstraints(aPresShellId, 1.881 + aViewId, 1.882 + aIsRoot, 1.883 + aConstraints); 1.884 +} 1.885 + 1.886 +nsresult 1.887 +TabChild::Init() 1.888 +{ 1.889 + nsCOMPtr<nsIWebBrowser> webBrowser = do_CreateInstance(NS_WEBBROWSER_CONTRACTID); 1.890 + if (!webBrowser) { 1.891 + NS_ERROR("Couldn't create a nsWebBrowser?"); 1.892 + return NS_ERROR_FAILURE; 1.893 + } 1.894 + 1.895 + webBrowser->SetContainerWindow(this); 1.896 + mWebNav = do_QueryInterface(webBrowser); 1.897 + NS_ASSERTION(mWebNav, "nsWebBrowser doesn't implement nsIWebNavigation?"); 1.898 + 1.899 + nsCOMPtr<nsIDocShellTreeItem> docShellItem(do_QueryInterface(WebNavigation())); 1.900 + docShellItem->SetItemType(nsIDocShellTreeItem::typeContentWrapper); 1.901 + 1.902 + nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(WebNavigation()); 1.903 + if (!baseWindow) { 1.904 + NS_ERROR("mWebNav doesn't QI to nsIBaseWindow"); 1.905 + return NS_ERROR_FAILURE; 1.906 + } 1.907 + 1.908 + mWidget = nsIWidget::CreatePuppetWidget(this); 1.909 + if (!mWidget) { 1.910 + NS_ERROR("couldn't create fake widget"); 1.911 + return NS_ERROR_FAILURE; 1.912 + } 1.913 + mWidget->Create( 1.914 + nullptr, 0, // no parents 1.915 + nsIntRect(nsIntPoint(0, 0), nsIntSize(0, 0)), 1.916 + nullptr, // HandleWidgetEvent 1.917 + nullptr // nsDeviceContext 1.918 + ); 1.919 + 1.920 + baseWindow->InitWindow(0, mWidget, 0, 0, 0, 0); 1.921 + baseWindow->Create(); 1.922 + 1.923 + NotifyTabContextUpdated(); 1.924 + 1.925 + // IPC uses a WebBrowser object for which DNS prefetching is turned off 1.926 + // by default. But here we really want it, so enable it explicitly 1.927 + nsCOMPtr<nsIWebBrowserSetup> webBrowserSetup = 1.928 + do_QueryInterface(baseWindow); 1.929 + if (webBrowserSetup) { 1.930 + webBrowserSetup->SetProperty(nsIWebBrowserSetup::SETUP_ALLOW_DNS_PREFETCH, 1.931 + true); 1.932 + } else { 1.933 + NS_WARNING("baseWindow doesn't QI to nsIWebBrowserSetup, skipping " 1.934 + "DNS prefetching enable step."); 1.935 + } 1.936 + 1.937 + nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation()); 1.938 + MOZ_ASSERT(docShell); 1.939 + 1.940 + docShell->SetAffectPrivateSessionLifetime( 1.941 + mChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_LIFETIME); 1.942 + nsCOMPtr<nsILoadContext> loadContext = do_GetInterface(WebNavigation()); 1.943 + MOZ_ASSERT(loadContext); 1.944 + loadContext->SetPrivateBrowsing( 1.945 + mChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW); 1.946 + loadContext->SetRemoteTabs( 1.947 + mChromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW); 1.948 + 1.949 + nsCOMPtr<nsIWebProgress> webProgress = do_GetInterface(docShell); 1.950 + NS_ENSURE_TRUE(webProgress, NS_ERROR_FAILURE); 1.951 + webProgress->AddProgressListener(this, nsIWebProgress::NOTIFY_LOCATION); 1.952 + 1.953 + // Few lines before, baseWindow->Create() will end up creating a new 1.954 + // window root in nsGlobalWindow::SetDocShell. 1.955 + // Then this chrome event handler, will be inherited to inner windows. 1.956 + // We want to also set it to the docshell so that inner windows 1.957 + // and any code that has access to the docshell 1.958 + // can all listen to the same chrome event handler. 1.959 + // XXX: ideally, we would set a chrome event handler earlier, 1.960 + // and all windows, even the root one, will use the docshell one. 1.961 + nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(WebNavigation()); 1.962 + NS_ENSURE_TRUE(window, NS_ERROR_FAILURE); 1.963 + nsCOMPtr<EventTarget> chromeHandler = 1.964 + do_QueryInterface(window->GetChromeEventHandler()); 1.965 + docShell->SetChromeEventHandler(chromeHandler); 1.966 + 1.967 + return NS_OK; 1.968 +} 1.969 + 1.970 +void 1.971 +TabChild::NotifyTabContextUpdated() 1.972 +{ 1.973 + nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation()); 1.974 + MOZ_ASSERT(docShell); 1.975 + 1.976 + if (docShell) { 1.977 + // nsDocShell will do the right thing if we pass NO_APP_ID or 1.978 + // UNKNOWN_APP_ID for aOwnOrContainingAppId. 1.979 + if (IsBrowserElement()) { 1.980 + docShell->SetIsBrowserInsideApp(BrowserOwnerAppId()); 1.981 + } else { 1.982 + docShell->SetIsApp(OwnAppId()); 1.983 + } 1.984 + } 1.985 +} 1.986 + 1.987 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChild) 1.988 + NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome) 1.989 + NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChrome2) 1.990 + NS_INTERFACE_MAP_ENTRY(nsIEmbeddingSiteWindow) 1.991 + NS_INTERFACE_MAP_ENTRY(nsIWebBrowserChromeFocus) 1.992 + NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor) 1.993 + NS_INTERFACE_MAP_ENTRY(nsIWindowProvider) 1.994 + NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener) 1.995 + NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener) 1.996 + NS_INTERFACE_MAP_ENTRY(nsITabChild) 1.997 + NS_INTERFACE_MAP_ENTRY(nsIObserver) 1.998 + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) 1.999 + NS_INTERFACE_MAP_ENTRY(nsITooltipListener) 1.1000 +NS_INTERFACE_MAP_END_INHERITING(TabChildBase) 1.1001 + 1.1002 +NS_IMPL_ADDREF_INHERITED(TabChild, TabChildBase); 1.1003 +NS_IMPL_RELEASE_INHERITED(TabChild, TabChildBase); 1.1004 + 1.1005 +NS_IMETHODIMP 1.1006 +TabChild::SetStatus(uint32_t aStatusType, const char16_t* aStatus) 1.1007 +{ 1.1008 + return SetStatusWithContext(aStatusType, 1.1009 + aStatus ? static_cast<const nsString &>(nsDependentString(aStatus)) 1.1010 + : EmptyString(), 1.1011 + nullptr); 1.1012 +} 1.1013 + 1.1014 +NS_IMETHODIMP 1.1015 +TabChild::GetWebBrowser(nsIWebBrowser** aWebBrowser) 1.1016 +{ 1.1017 + NS_NOTREACHED("TabChild::GetWebBrowser not supported in TabChild"); 1.1018 + 1.1019 + return NS_ERROR_NOT_IMPLEMENTED; 1.1020 +} 1.1021 + 1.1022 +NS_IMETHODIMP 1.1023 +TabChild::SetWebBrowser(nsIWebBrowser* aWebBrowser) 1.1024 +{ 1.1025 + NS_NOTREACHED("TabChild::SetWebBrowser not supported in TabChild"); 1.1026 + 1.1027 + return NS_ERROR_NOT_IMPLEMENTED; 1.1028 +} 1.1029 + 1.1030 +NS_IMETHODIMP 1.1031 +TabChild::GetChromeFlags(uint32_t* aChromeFlags) 1.1032 +{ 1.1033 + *aChromeFlags = mChromeFlags; 1.1034 + return NS_OK; 1.1035 +} 1.1036 + 1.1037 +NS_IMETHODIMP 1.1038 +TabChild::SetChromeFlags(uint32_t aChromeFlags) 1.1039 +{ 1.1040 + NS_NOTREACHED("trying to SetChromeFlags from content process?"); 1.1041 + 1.1042 + return NS_ERROR_NOT_IMPLEMENTED; 1.1043 +} 1.1044 + 1.1045 +NS_IMETHODIMP 1.1046 +TabChild::DestroyBrowserWindow() 1.1047 +{ 1.1048 + NS_NOTREACHED("TabChild::DestroyBrowserWindow not supported in TabChild"); 1.1049 + 1.1050 + return NS_ERROR_NOT_IMPLEMENTED; 1.1051 +} 1.1052 + 1.1053 +NS_IMETHODIMP 1.1054 +TabChild::SizeBrowserTo(int32_t aCX, int32_t aCY) 1.1055 +{ 1.1056 + NS_NOTREACHED("TabChild::SizeBrowserTo not supported in TabChild"); 1.1057 + 1.1058 + return NS_ERROR_NOT_IMPLEMENTED; 1.1059 +} 1.1060 + 1.1061 +NS_IMETHODIMP 1.1062 +TabChild::ShowAsModal() 1.1063 +{ 1.1064 + NS_NOTREACHED("TabChild::ShowAsModal not supported in TabChild"); 1.1065 + 1.1066 + return NS_ERROR_NOT_IMPLEMENTED; 1.1067 +} 1.1068 + 1.1069 +NS_IMETHODIMP 1.1070 +TabChild::IsWindowModal(bool* aRetVal) 1.1071 +{ 1.1072 + *aRetVal = false; 1.1073 + return NS_OK; 1.1074 +} 1.1075 + 1.1076 +NS_IMETHODIMP 1.1077 +TabChild::ExitModalEventLoop(nsresult aStatus) 1.1078 +{ 1.1079 + NS_NOTREACHED("TabChild::ExitModalEventLoop not supported in TabChild"); 1.1080 + 1.1081 + return NS_ERROR_NOT_IMPLEMENTED; 1.1082 +} 1.1083 + 1.1084 +NS_IMETHODIMP 1.1085 +TabChild::SetStatusWithContext(uint32_t aStatusType, 1.1086 + const nsAString& aStatusText, 1.1087 + nsISupports* aStatusContext) 1.1088 +{ 1.1089 + // We can only send the status after the ipc machinery is set up, 1.1090 + // mRemoteFrame is a good indicator. 1.1091 + if (mRemoteFrame) 1.1092 + SendSetStatus(aStatusType, nsString(aStatusText)); 1.1093 + return NS_OK; 1.1094 +} 1.1095 + 1.1096 +NS_IMETHODIMP 1.1097 +TabChild::SetDimensions(uint32_t aFlags, int32_t aX, int32_t aY, 1.1098 + int32_t aCx, int32_t aCy) 1.1099 +{ 1.1100 + NS_NOTREACHED("TabChild::SetDimensions not supported in TabChild"); 1.1101 + 1.1102 + return NS_ERROR_NOT_IMPLEMENTED; 1.1103 +} 1.1104 + 1.1105 +NS_IMETHODIMP 1.1106 +TabChild::GetDimensions(uint32_t aFlags, int32_t* aX, 1.1107 + int32_t* aY, int32_t* aCx, int32_t* aCy) 1.1108 +{ 1.1109 + if (aX) { 1.1110 + *aX = mOuterRect.x; 1.1111 + } 1.1112 + if (aY) { 1.1113 + *aY = mOuterRect.y; 1.1114 + } 1.1115 + if (aCx) { 1.1116 + *aCx = mOuterRect.width; 1.1117 + } 1.1118 + if (aCy) { 1.1119 + *aCy = mOuterRect.height; 1.1120 + } 1.1121 + 1.1122 + return NS_OK; 1.1123 +} 1.1124 + 1.1125 +NS_IMETHODIMP 1.1126 +TabChild::SetFocus() 1.1127 +{ 1.1128 + NS_WARNING("TabChild::SetFocus not supported in TabChild"); 1.1129 + 1.1130 + return NS_ERROR_NOT_IMPLEMENTED; 1.1131 +} 1.1132 + 1.1133 +NS_IMETHODIMP 1.1134 +TabChild::GetVisibility(bool* aVisibility) 1.1135 +{ 1.1136 + *aVisibility = true; 1.1137 + return NS_OK; 1.1138 +} 1.1139 + 1.1140 +NS_IMETHODIMP 1.1141 +TabChild::SetVisibility(bool aVisibility) 1.1142 +{ 1.1143 + // should the platform support this? Bug 666365 1.1144 + return NS_OK; 1.1145 +} 1.1146 + 1.1147 +NS_IMETHODIMP 1.1148 +TabChild::GetTitle(char16_t** aTitle) 1.1149 +{ 1.1150 + NS_NOTREACHED("TabChild::GetTitle not supported in TabChild"); 1.1151 + 1.1152 + return NS_ERROR_NOT_IMPLEMENTED; 1.1153 +} 1.1154 + 1.1155 +NS_IMETHODIMP 1.1156 +TabChild::SetTitle(const char16_t* aTitle) 1.1157 +{ 1.1158 + // JavaScript sends the "DOMTitleChanged" event to the parent 1.1159 + // via the message manager. 1.1160 + return NS_OK; 1.1161 +} 1.1162 + 1.1163 +NS_IMETHODIMP 1.1164 +TabChild::GetSiteWindow(void** aSiteWindow) 1.1165 +{ 1.1166 + NS_NOTREACHED("TabChild::GetSiteWindow not supported in TabChild"); 1.1167 + 1.1168 + return NS_ERROR_NOT_IMPLEMENTED; 1.1169 +} 1.1170 + 1.1171 +NS_IMETHODIMP 1.1172 +TabChild::Blur() 1.1173 +{ 1.1174 + NS_WARNING("TabChild::Blur not supported in TabChild"); 1.1175 + 1.1176 + return NS_ERROR_NOT_IMPLEMENTED; 1.1177 +} 1.1178 + 1.1179 +NS_IMETHODIMP 1.1180 +TabChild::FocusNextElement() 1.1181 +{ 1.1182 + SendMoveFocus(true); 1.1183 + return NS_OK; 1.1184 +} 1.1185 + 1.1186 +NS_IMETHODIMP 1.1187 +TabChild::FocusPrevElement() 1.1188 +{ 1.1189 + SendMoveFocus(false); 1.1190 + return NS_OK; 1.1191 +} 1.1192 + 1.1193 +NS_IMETHODIMP 1.1194 +TabChild::GetInterface(const nsIID & aIID, void **aSink) 1.1195 +{ 1.1196 + // XXXbz should we restrict the set of interfaces we hand out here? 1.1197 + // See bug 537429 1.1198 + return QueryInterface(aIID, aSink); 1.1199 +} 1.1200 + 1.1201 +NS_IMETHODIMP 1.1202 +TabChild::ProvideWindow(nsIDOMWindow* aParent, uint32_t aChromeFlags, 1.1203 + bool aCalledFromJS, 1.1204 + bool aPositionSpecified, bool aSizeSpecified, 1.1205 + nsIURI* aURI, const nsAString& aName, 1.1206 + const nsACString& aFeatures, bool* aWindowIsNew, 1.1207 + nsIDOMWindow** aReturn) 1.1208 +{ 1.1209 + *aReturn = nullptr; 1.1210 + 1.1211 + // If aParent is inside an <iframe mozbrowser> or <iframe mozapp> and this 1.1212 + // isn't a request to open a modal-type window, we're going to create a new 1.1213 + // <iframe mozbrowser/mozapp> and return its window here. 1.1214 + nsCOMPtr<nsIDocShell> docshell = do_GetInterface(aParent); 1.1215 + if (docshell && docshell->GetIsInBrowserOrApp() && 1.1216 + !(aChromeFlags & (nsIWebBrowserChrome::CHROME_MODAL | 1.1217 + nsIWebBrowserChrome::CHROME_OPENAS_DIALOG | 1.1218 + nsIWebBrowserChrome::CHROME_OPENAS_CHROME))) { 1.1219 + 1.1220 + // Note that BrowserFrameProvideWindow may return NS_ERROR_ABORT if the 1.1221 + // open window call was canceled. It's important that we pass this error 1.1222 + // code back to our caller. 1.1223 + return BrowserFrameProvideWindow(aParent, aURI, aName, aFeatures, 1.1224 + aWindowIsNew, aReturn); 1.1225 + } 1.1226 + 1.1227 + // Otherwise, create a new top-level window. 1.1228 + PBrowserChild* newChild; 1.1229 + if (!CallCreateWindow(&newChild)) { 1.1230 + return NS_ERROR_NOT_AVAILABLE; 1.1231 + } 1.1232 + 1.1233 + *aWindowIsNew = true; 1.1234 + nsCOMPtr<nsIDOMWindow> win = 1.1235 + do_GetInterface(static_cast<TabChild*>(newChild)->WebNavigation()); 1.1236 + win.forget(aReturn); 1.1237 + return NS_OK; 1.1238 +} 1.1239 + 1.1240 +nsresult 1.1241 +TabChild::BrowserFrameProvideWindow(nsIDOMWindow* aOpener, 1.1242 + nsIURI* aURI, 1.1243 + const nsAString& aName, 1.1244 + const nsACString& aFeatures, 1.1245 + bool* aWindowIsNew, 1.1246 + nsIDOMWindow** aReturn) 1.1247 +{ 1.1248 + *aReturn = nullptr; 1.1249 + 1.1250 + nsRefPtr<TabChild> newChild = 1.1251 + new TabChild(ContentChild::GetSingleton(), 1.1252 + /* TabContext */ *this, /* chromeFlags */ 0); 1.1253 + if (!NS_SUCCEEDED(newChild->Init())) { 1.1254 + return NS_ERROR_ABORT; 1.1255 + } 1.1256 + 1.1257 + // We must use PopupIPCTabContext here; ContentParent will not accept the 1.1258 + // result of this->AsIPCTabContext() (which will be a 1.1259 + // BrowserFrameIPCTabContext or an AppFrameIPCTabContext), for security 1.1260 + // reasons. 1.1261 + PopupIPCTabContext context; 1.1262 + context.openerChild() = this; 1.1263 + context.isBrowserElement() = IsBrowserElement(); 1.1264 + 1.1265 + unused << Manager()->SendPBrowserConstructor( 1.1266 + // We release this ref in DeallocPBrowserChild 1.1267 + nsRefPtr<TabChild>(newChild).forget().take(), 1.1268 + IPCTabContext(context, mScrolling), /* chromeFlags */ 0); 1.1269 + 1.1270 + nsAutoCString spec; 1.1271 + if (aURI) { 1.1272 + aURI->GetSpec(spec); 1.1273 + } 1.1274 + 1.1275 + NS_ConvertUTF8toUTF16 url(spec); 1.1276 + nsString name(aName); 1.1277 + NS_ConvertUTF8toUTF16 features(aFeatures); 1.1278 + newChild->SendBrowserFrameOpenWindow(this, url, name, 1.1279 + features, aWindowIsNew); 1.1280 + if (!*aWindowIsNew) { 1.1281 + PBrowserChild::Send__delete__(newChild); 1.1282 + return NS_ERROR_ABORT; 1.1283 + } 1.1284 + 1.1285 + // Unfortunately we don't get a window unless we've shown the frame. That's 1.1286 + // pretty bogus; see bug 763602. 1.1287 + newChild->DoFakeShow(); 1.1288 + 1.1289 + nsCOMPtr<nsIDOMWindow> win = do_GetInterface(newChild->WebNavigation()); 1.1290 + win.forget(aReturn); 1.1291 + return NS_OK; 1.1292 +} 1.1293 + 1.1294 +#ifdef DEBUG 1.1295 +PContentPermissionRequestChild* 1.1296 +TabChild:: SendPContentPermissionRequestConstructor(PContentPermissionRequestChild* aActor, 1.1297 + const InfallibleTArray<PermissionRequest>& aRequests, 1.1298 + const IPC::Principal& aPrincipal) 1.1299 +{ 1.1300 + PCOMContentPermissionRequestChild* child = static_cast<PCOMContentPermissionRequestChild*>(aActor); 1.1301 + PContentPermissionRequestChild* request = PBrowserChild::SendPContentPermissionRequestConstructor(aActor, aRequests, aPrincipal); 1.1302 + child->mIPCOpen = true; 1.1303 + return request; 1.1304 +} 1.1305 +#endif /* DEBUG */ 1.1306 + 1.1307 +void 1.1308 +TabChild::DestroyWindow() 1.1309 +{ 1.1310 + nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(WebNavigation()); 1.1311 + if (baseWindow) 1.1312 + baseWindow->Destroy(); 1.1313 + 1.1314 + // NB: the order of mWidget->Destroy() and mRemoteFrame->Destroy() 1.1315 + // is important: we want to kill off remote layers before their 1.1316 + // frames 1.1317 + if (mWidget) { 1.1318 + mWidget->Destroy(); 1.1319 + } 1.1320 + 1.1321 + if (mRemoteFrame) { 1.1322 + mRemoteFrame->Destroy(); 1.1323 + mRemoteFrame = nullptr; 1.1324 + } 1.1325 + 1.1326 + 1.1327 + if (mLayersId != 0) { 1.1328 + MOZ_ASSERT(sTabChildren); 1.1329 + sTabChildren->Remove(mLayersId); 1.1330 + if (!sTabChildren->Count()) { 1.1331 + delete sTabChildren; 1.1332 + sTabChildren = nullptr; 1.1333 + } 1.1334 + mLayersId = 0; 1.1335 + } 1.1336 +} 1.1337 + 1.1338 +bool 1.1339 +TabChild::UseDirectCompositor() 1.1340 +{ 1.1341 + return !!CompositorChild::Get(); 1.1342 +} 1.1343 + 1.1344 +void 1.1345 +TabChild::ActorDestroy(ActorDestroyReason why) 1.1346 +{ 1.1347 + if (mTabChildGlobal) { 1.1348 + // The messageManager relays messages via the TabChild which 1.1349 + // no longer exists. 1.1350 + static_cast<nsFrameMessageManager*> 1.1351 + (mTabChildGlobal->mMessageManager.get())->Disconnect(); 1.1352 + mTabChildGlobal->mMessageManager = nullptr; 1.1353 + } 1.1354 +} 1.1355 + 1.1356 +TabChild::~TabChild() 1.1357 +{ 1.1358 + DestroyWindow(); 1.1359 + 1.1360 + nsCOMPtr<nsIWebBrowser> webBrowser = do_QueryInterface(WebNavigation()); 1.1361 + if (webBrowser) { 1.1362 + webBrowser->SetContainerWindow(nullptr); 1.1363 + } 1.1364 +} 1.1365 + 1.1366 +void 1.1367 +TabChild::SetProcessNameToAppName() 1.1368 +{ 1.1369 + nsCOMPtr<mozIApplication> app = GetOwnApp(); 1.1370 + if (!app) { 1.1371 + return; 1.1372 + } 1.1373 + 1.1374 + nsAutoString appName; 1.1375 + nsresult rv = app->GetName(appName); 1.1376 + if (NS_FAILED(rv)) { 1.1377 + NS_WARNING("Failed to retrieve app name"); 1.1378 + return; 1.1379 + } 1.1380 + 1.1381 + ContentChild::GetSingleton()->SetProcessName(appName, true); 1.1382 +} 1.1383 + 1.1384 +bool 1.1385 +TabChild::IsRootContentDocument() 1.1386 +{ 1.1387 + // A TabChild is a "root content document" if it's 1.1388 + // 1.1389 + // - <iframe mozapp> not inside another <iframe mozapp>, 1.1390 + // - <iframe mozbrowser> (not mozapp), or 1.1391 + // - a vanilla remote frame (<html:iframe remote=true> or <xul:browser 1.1392 + // remote=true>). 1.1393 + // 1.1394 + // Put another way, an iframe is /not/ a "root content document" iff it's a 1.1395 + // mozapp inside a mozapp. (This corresponds exactly to !HasAppOwnerApp.) 1.1396 + // 1.1397 + // Note that we're lying through our teeth here (thus the scare quotes). 1.1398 + // <html:iframe remote=true> or <xul:browser remote=true> inside another 1.1399 + // content iframe is not actually a root content document, but we say it is. 1.1400 + // 1.1401 + // We do this because we make a remote frame opaque iff 1.1402 + // IsRootContentDocument(), and making vanilla remote frames transparent 1.1403 + // breaks our remote reftests. 1.1404 + 1.1405 + return !HasAppOwnerApp(); 1.1406 +} 1.1407 + 1.1408 +bool 1.1409 +TabChild::RecvLoadURL(const nsCString& uri) 1.1410 +{ 1.1411 + SetProcessNameToAppName(); 1.1412 + 1.1413 + nsresult rv = WebNavigation()->LoadURI(NS_ConvertUTF8toUTF16(uri).get(), 1.1414 + nsIWebNavigation::LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP | 1.1415 + nsIWebNavigation::LOAD_FLAGS_DISALLOW_INHERIT_OWNER, 1.1416 + nullptr, nullptr, nullptr); 1.1417 + if (NS_FAILED(rv)) { 1.1418 + NS_WARNING("WebNavigation()->LoadURI failed. Eating exception, what else can I do?"); 1.1419 + } 1.1420 + 1.1421 +#ifdef MOZ_CRASHREPORTER 1.1422 + CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("URL"), uri); 1.1423 +#endif 1.1424 + 1.1425 + return true; 1.1426 +} 1.1427 + 1.1428 +bool 1.1429 +TabChild::RecvCacheFileDescriptor(const nsString& aPath, 1.1430 + const FileDescriptor& aFileDescriptor) 1.1431 +{ 1.1432 + MOZ_ASSERT(NS_IsMainThread()); 1.1433 + MOZ_ASSERT(!aPath.IsEmpty()); 1.1434 + MOZ_ASSERT(!mAppPackageFileDescriptorRecved); 1.1435 + 1.1436 + mAppPackageFileDescriptorRecved = true; 1.1437 + 1.1438 + // aFileDescriptor may be invalid here, but the callback will choose how to 1.1439 + // handle it. 1.1440 + 1.1441 + // First see if we already have a request for this path. 1.1442 + const CachedFileDescriptorInfo search(aPath); 1.1443 + uint32_t index = 1.1444 + mCachedFileDescriptorInfos.IndexOf(search, 0, 1.1445 + search.PathOnlyComparator()); 1.1446 + if (index == mCachedFileDescriptorInfos.NoIndex) { 1.1447 + // We haven't had any requests for this path yet. Assume that we will 1.1448 + // in a little while and save the file descriptor here. 1.1449 + mCachedFileDescriptorInfos.AppendElement( 1.1450 + new CachedFileDescriptorInfo(aPath, aFileDescriptor)); 1.1451 + return true; 1.1452 + } 1.1453 + 1.1454 + nsAutoPtr<CachedFileDescriptorInfo>& info = 1.1455 + mCachedFileDescriptorInfos[index]; 1.1456 + 1.1457 + MOZ_ASSERT(info); 1.1458 + MOZ_ASSERT(info->mPath == aPath); 1.1459 + MOZ_ASSERT(!info->mFileDescriptor.IsValid()); 1.1460 + MOZ_ASSERT(info->mCallback); 1.1461 + 1.1462 + // If this callback has been canceled then we can simply close the file 1.1463 + // descriptor and forget about the callback. 1.1464 + if (info->mCanceled) { 1.1465 + // Only close if this is a valid file descriptor. 1.1466 + if (aFileDescriptor.IsValid()) { 1.1467 + nsRefPtr<CloseFileRunnable> runnable = 1.1468 + new CloseFileRunnable(aFileDescriptor); 1.1469 + runnable->Dispatch(); 1.1470 + } 1.1471 + } else { 1.1472 + // Not canceled so fire the callback. 1.1473 + info->mFileDescriptor = aFileDescriptor; 1.1474 + 1.1475 + // We don't need a runnable here because we should already be at the top 1.1476 + // of the event loop. Just fire immediately. 1.1477 + info->FireCallback(); 1.1478 + } 1.1479 + 1.1480 + mCachedFileDescriptorInfos.RemoveElementAt(index); 1.1481 + return true; 1.1482 +} 1.1483 + 1.1484 +bool 1.1485 +TabChild::GetCachedFileDescriptor(const nsAString& aPath, 1.1486 + nsICachedFileDescriptorListener* aCallback) 1.1487 +{ 1.1488 + MOZ_ASSERT(NS_IsMainThread()); 1.1489 + MOZ_ASSERT(!aPath.IsEmpty()); 1.1490 + MOZ_ASSERT(aCallback); 1.1491 + 1.1492 + // First see if we've already received a cached file descriptor for this 1.1493 + // path. 1.1494 + const CachedFileDescriptorInfo search(aPath); 1.1495 + uint32_t index = 1.1496 + mCachedFileDescriptorInfos.IndexOf(search, 0, 1.1497 + search.PathOnlyComparator()); 1.1498 + if (index == mCachedFileDescriptorInfos.NoIndex) { 1.1499 + // We haven't received a file descriptor for this path yet. Assume that 1.1500 + // we will in a little while and save the request here. 1.1501 + if (!mAppPackageFileDescriptorRecved) { 1.1502 + mCachedFileDescriptorInfos.AppendElement( 1.1503 + new CachedFileDescriptorInfo(aPath, aCallback)); 1.1504 + } 1.1505 + return false; 1.1506 + } 1.1507 + 1.1508 + nsAutoPtr<CachedFileDescriptorInfo>& info = 1.1509 + mCachedFileDescriptorInfos[index]; 1.1510 + 1.1511 + MOZ_ASSERT(info); 1.1512 + MOZ_ASSERT(info->mPath == aPath); 1.1513 + 1.1514 + // If we got a previous request for this file descriptor that was then 1.1515 + // canceled, insert the new request ahead of the old in the queue so that 1.1516 + // it will be serviced first. 1.1517 + if (info->mCanceled) { 1.1518 + // This insertion will change the array and invalidate |info|, so 1.1519 + // be careful not to touch |info| after this. 1.1520 + mCachedFileDescriptorInfos.InsertElementAt(index, 1.1521 + new CachedFileDescriptorInfo(aPath, aCallback)); 1.1522 + return false; 1.1523 + } 1.1524 + 1.1525 + MOZ_ASSERT(!info->mCallback); 1.1526 + info->mCallback = aCallback; 1.1527 + 1.1528 + nsRefPtr<CachedFileDescriptorCallbackRunnable> runnable = 1.1529 + new CachedFileDescriptorCallbackRunnable(info.forget()); 1.1530 + runnable->Dispatch(); 1.1531 + 1.1532 + mCachedFileDescriptorInfos.RemoveElementAt(index); 1.1533 + return true; 1.1534 +} 1.1535 + 1.1536 +void 1.1537 +TabChild::CancelCachedFileDescriptorCallback( 1.1538 + const nsAString& aPath, 1.1539 + nsICachedFileDescriptorListener* aCallback) 1.1540 +{ 1.1541 + MOZ_ASSERT(NS_IsMainThread()); 1.1542 + MOZ_ASSERT(!aPath.IsEmpty()); 1.1543 + MOZ_ASSERT(aCallback); 1.1544 + 1.1545 + if (mAppPackageFileDescriptorRecved) { 1.1546 + // Already received cached file descriptor for the app package. Nothing to do here. 1.1547 + return; 1.1548 + } 1.1549 + 1.1550 + const CachedFileDescriptorInfo search(aPath, aCallback); 1.1551 + uint32_t index = 1.1552 + mCachedFileDescriptorInfos.IndexOf(search, 0, 1.1553 + search.PathAndCallbackComparator()); 1.1554 + if (index == mCachedFileDescriptorInfos.NoIndex) { 1.1555 + // Nothing to do here. 1.1556 + return; 1.1557 + } 1.1558 + 1.1559 + nsAutoPtr<CachedFileDescriptorInfo>& info = 1.1560 + mCachedFileDescriptorInfos[index]; 1.1561 + 1.1562 + MOZ_ASSERT(info); 1.1563 + MOZ_ASSERT(info->mPath == aPath); 1.1564 + MOZ_ASSERT(!info->mFileDescriptor.IsValid()); 1.1565 + MOZ_ASSERT(info->mCallback == aCallback); 1.1566 + MOZ_ASSERT(!info->mCanceled); 1.1567 + 1.1568 + // Set this flag so that we will close the file descriptor when it arrives. 1.1569 + info->mCanceled = true; 1.1570 +} 1.1571 + 1.1572 +void 1.1573 +TabChild::DoFakeShow() 1.1574 +{ 1.1575 + RecvShow(nsIntSize(0, 0)); 1.1576 + mDidFakeShow = true; 1.1577 +} 1.1578 + 1.1579 +bool 1.1580 +TabChild::RecvShow(const nsIntSize& size) 1.1581 +{ 1.1582 + 1.1583 + if (mDidFakeShow) { 1.1584 + return true; 1.1585 + } 1.1586 + 1.1587 + nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(WebNavigation()); 1.1588 + if (!baseWindow) { 1.1589 + NS_ERROR("WebNavigation() doesn't QI to nsIBaseWindow"); 1.1590 + return false; 1.1591 + } 1.1592 + 1.1593 + if (!InitRenderingState()) { 1.1594 + // We can fail to initialize our widget if the <browser 1.1595 + // remote> has already been destroyed, and we couldn't hook 1.1596 + // into the parent-process's layer system. That's not a fatal 1.1597 + // error. 1.1598 + return true; 1.1599 + } 1.1600 + 1.1601 + baseWindow->SetVisibility(true); 1.1602 + 1.1603 + return InitTabChildGlobal(); 1.1604 +} 1.1605 + 1.1606 +bool 1.1607 +TabChild::RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size, const ScreenOrientation& orientation) 1.1608 +{ 1.1609 + if (!mRemoteFrame) { 1.1610 + return true; 1.1611 + } 1.1612 + 1.1613 + mOuterRect.x = rect.x; 1.1614 + mOuterRect.y = rect.y; 1.1615 + mOuterRect.width = rect.width; 1.1616 + mOuterRect.height = rect.height; 1.1617 + 1.1618 + bool initialSizing = !HasValidInnerSize() 1.1619 + && (size.width != 0 && size.height != 0); 1.1620 + 1.1621 + mOrientation = orientation; 1.1622 + mInnerSize = ScreenIntSize::FromUnknownSize( 1.1623 + gfx::IntSize(size.width, size.height)); 1.1624 + mWidget->Resize(0, 0, size.width, size.height, 1.1625 + true); 1.1626 + 1.1627 + nsCOMPtr<nsIBaseWindow> baseWin = do_QueryInterface(WebNavigation()); 1.1628 + baseWin->SetPositionAndSize(0, 0, size.width, size.height, 1.1629 + true); 1.1630 + 1.1631 + if (initialSizing && mContentDocumentIsDisplayed) { 1.1632 + // If this is the first time we're getting a valid mInnerSize, and the 1.1633 + // before-first-paint event has already been handled, then we need to set 1.1634 + // up our default viewport here. See the corresponding call to 1.1635 + // InitializeRootMetrics in the before-first-paint handler. 1.1636 + InitializeRootMetrics(); 1.1637 + } 1.1638 + 1.1639 + HandlePossibleViewportChange(); 1.1640 + 1.1641 + return true; 1.1642 +} 1.1643 + 1.1644 +bool 1.1645 +TabChild::RecvUpdateFrame(const FrameMetrics& aFrameMetrics) 1.1646 +{ 1.1647 + return TabChildBase::UpdateFrameHandler(aFrameMetrics); 1.1648 +} 1.1649 + 1.1650 +bool 1.1651 +TabChild::RecvAcknowledgeScrollUpdate(const ViewID& aScrollId, 1.1652 + const uint32_t& aScrollGeneration) 1.1653 +{ 1.1654 + APZCCallbackHelper::AcknowledgeScrollUpdate(aScrollId, aScrollGeneration); 1.1655 + return true; 1.1656 +} 1.1657 + 1.1658 +bool 1.1659 +TabChild::RecvHandleDoubleTap(const CSSPoint& aPoint, const ScrollableLayerGuid& aGuid) 1.1660 +{ 1.1661 + if (!mGlobal || !mTabChildGlobal) { 1.1662 + return true; 1.1663 + } 1.1664 + 1.1665 + CSSPoint point = APZCCallbackHelper::ApplyCallbackTransform(aPoint, aGuid); 1.1666 + nsString data; 1.1667 + data.AppendLiteral("{ \"x\" : "); 1.1668 + data.AppendFloat(point.x); 1.1669 + data.AppendLiteral(", \"y\" : "); 1.1670 + data.AppendFloat(point.y); 1.1671 + data.AppendLiteral(" }"); 1.1672 + 1.1673 + DispatchMessageManagerMessage(NS_LITERAL_STRING("Gesture:DoubleTap"), data); 1.1674 + 1.1675 + return true; 1.1676 +} 1.1677 + 1.1678 +bool 1.1679 +TabChild::RecvHandleSingleTap(const CSSPoint& aPoint, const ScrollableLayerGuid& aGuid) 1.1680 +{ 1.1681 + if (!mGlobal || !mTabChildGlobal) { 1.1682 + return true; 1.1683 + } 1.1684 + 1.1685 + LayoutDevicePoint currentPoint = APZCCallbackHelper::ApplyCallbackTransform(aPoint, aGuid) * mWidget->GetDefaultScale();; 1.1686 + 1.1687 + MessageLoop::current()->PostDelayedTask( 1.1688 + FROM_HERE, 1.1689 + NewRunnableMethod(this, &TabChild::FireSingleTapEvent, currentPoint), 1.1690 + sActiveDurationMs); 1.1691 + return true; 1.1692 +} 1.1693 + 1.1694 +void 1.1695 +TabChild::FireSingleTapEvent(LayoutDevicePoint aPoint) 1.1696 +{ 1.1697 + int time = 0; 1.1698 + DispatchSynthesizedMouseEvent(NS_MOUSE_MOVE, time, aPoint, mWidget); 1.1699 + DispatchSynthesizedMouseEvent(NS_MOUSE_BUTTON_DOWN, time, aPoint, mWidget); 1.1700 + DispatchSynthesizedMouseEvent(NS_MOUSE_BUTTON_UP, time, aPoint, mWidget); 1.1701 +} 1.1702 + 1.1703 +bool 1.1704 +TabChild::RecvHandleLongTap(const CSSPoint& aPoint, const ScrollableLayerGuid& aGuid) 1.1705 +{ 1.1706 + if (!mGlobal || !mTabChildGlobal) { 1.1707 + return true; 1.1708 + } 1.1709 + 1.1710 + mContextMenuHandled = 1.1711 + DispatchMouseEvent(NS_LITERAL_STRING("contextmenu"), 1.1712 + APZCCallbackHelper::ApplyCallbackTransform(aPoint, aGuid), 1.1713 + 2, 1, 0, false, 1.1714 + nsIDOMMouseEvent::MOZ_SOURCE_TOUCH); 1.1715 + 1.1716 + SendContentReceivedTouch(aGuid, mContextMenuHandled); 1.1717 + 1.1718 + return true; 1.1719 +} 1.1720 + 1.1721 +bool 1.1722 +TabChild::RecvHandleLongTapUp(const CSSPoint& aPoint, const ScrollableLayerGuid& aGuid) 1.1723 +{ 1.1724 + if (mContextMenuHandled) { 1.1725 + mContextMenuHandled = false; 1.1726 + return true; 1.1727 + } 1.1728 + 1.1729 + RecvHandleSingleTap(aPoint, aGuid); 1.1730 + return true; 1.1731 +} 1.1732 + 1.1733 +bool 1.1734 +TabChild::RecvNotifyAPZStateChange(const ViewID& aViewId, 1.1735 + const APZStateChange& aChange, 1.1736 + const int& aArg) 1.1737 +{ 1.1738 + switch (aChange) 1.1739 + { 1.1740 + case APZStateChange::TransformBegin: 1.1741 + { 1.1742 + nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aViewId); 1.1743 + nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(sf); 1.1744 + if (scrollbarOwner) { 1.1745 + scrollbarOwner->ScrollbarActivityStarted(); 1.1746 + } 1.1747 + break; 1.1748 + } 1.1749 + case APZStateChange::TransformEnd: 1.1750 + { 1.1751 + nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aViewId); 1.1752 + nsIScrollbarOwner* scrollbarOwner = do_QueryFrame(sf); 1.1753 + if (scrollbarOwner) { 1.1754 + scrollbarOwner->ScrollbarActivityStopped(); 1.1755 + } 1.1756 + break; 1.1757 + } 1.1758 + case APZStateChange::StartTouch: 1.1759 + { 1.1760 + mActiveElementManager->HandleTouchStart(aArg); 1.1761 + break; 1.1762 + } 1.1763 + case APZStateChange::StartPanning: 1.1764 + { 1.1765 + mActiveElementManager->HandlePanStart(); 1.1766 + break; 1.1767 + } 1.1768 + case APZStateChange::EndTouch: 1.1769 + { 1.1770 + mActiveElementManager->HandleTouchEnd(aArg); 1.1771 + break; 1.1772 + } 1.1773 + default: 1.1774 + // APZStateChange has a 'sentinel' value, and the compiler complains 1.1775 + // if an enumerator is not handled and there is no 'default' case. 1.1776 + break; 1.1777 + } 1.1778 + return true; 1.1779 +} 1.1780 + 1.1781 +bool 1.1782 +TabChild::RecvActivate() 1.1783 +{ 1.1784 + nsCOMPtr<nsIWebBrowserFocus> browser = do_QueryInterface(WebNavigation()); 1.1785 + browser->Activate(); 1.1786 + return true; 1.1787 +} 1.1788 + 1.1789 +bool TabChild::RecvDeactivate() 1.1790 +{ 1.1791 + nsCOMPtr<nsIWebBrowserFocus> browser = do_QueryInterface(WebNavigation()); 1.1792 + browser->Deactivate(); 1.1793 + return true; 1.1794 +} 1.1795 + 1.1796 +bool 1.1797 +TabChild::RecvMouseEvent(const nsString& aType, 1.1798 + const float& aX, 1.1799 + const float& aY, 1.1800 + const int32_t& aButton, 1.1801 + const int32_t& aClickCount, 1.1802 + const int32_t& aModifiers, 1.1803 + const bool& aIgnoreRootScrollFrame) 1.1804 +{ 1.1805 + DispatchMouseEvent(aType, CSSPoint(aX, aY), aButton, aClickCount, aModifiers, 1.1806 + aIgnoreRootScrollFrame, nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN); 1.1807 + return true; 1.1808 +} 1.1809 + 1.1810 +bool 1.1811 +TabChild::RecvRealMouseEvent(const WidgetMouseEvent& event) 1.1812 +{ 1.1813 + WidgetMouseEvent localEvent(event); 1.1814 + localEvent.widget = mWidget; 1.1815 + DispatchWidgetEvent(localEvent); 1.1816 + return true; 1.1817 +} 1.1818 + 1.1819 +bool 1.1820 +TabChild::RecvMouseWheelEvent(const WidgetWheelEvent& event) 1.1821 +{ 1.1822 + WidgetWheelEvent localEvent(event); 1.1823 + localEvent.widget = mWidget; 1.1824 + DispatchWidgetEvent(localEvent); 1.1825 + return true; 1.1826 +} 1.1827 + 1.1828 +static Touch* 1.1829 +GetTouchForIdentifier(const WidgetTouchEvent& aEvent, int32_t aId) 1.1830 +{ 1.1831 + for (uint32_t i = 0; i < aEvent.touches.Length(); ++i) { 1.1832 + Touch* touch = static_cast<Touch*>(aEvent.touches[i].get()); 1.1833 + if (touch->mIdentifier == aId) { 1.1834 + return touch; 1.1835 + } 1.1836 + } 1.1837 + return nullptr; 1.1838 +} 1.1839 + 1.1840 +void 1.1841 +TabChild::UpdateTapState(const WidgetTouchEvent& aEvent, nsEventStatus aStatus) 1.1842 +{ 1.1843 + static bool sHavePrefs; 1.1844 + static bool sClickHoldContextMenusEnabled; 1.1845 + static nsIntSize sDragThreshold; 1.1846 + static int32_t sContextMenuDelayMs; 1.1847 + if (!sHavePrefs) { 1.1848 + sHavePrefs = true; 1.1849 + Preferences::AddBoolVarCache(&sClickHoldContextMenusEnabled, 1.1850 + "ui.click_hold_context_menus", true); 1.1851 + Preferences::AddIntVarCache(&sDragThreshold.width, 1.1852 + "ui.dragThresholdX", 25); 1.1853 + Preferences::AddIntVarCache(&sDragThreshold.height, 1.1854 + "ui.dragThresholdY", 25); 1.1855 + Preferences::AddIntVarCache(&sContextMenuDelayMs, 1.1856 + "ui.click_hold_context_menus.delay", 500); 1.1857 + } 1.1858 + 1.1859 + if (aEvent.touches.Length() == 0) { 1.1860 + return; 1.1861 + } 1.1862 + 1.1863 + bool currentlyTrackingTouch = (mActivePointerId >= 0); 1.1864 + if (aEvent.message == NS_TOUCH_START) { 1.1865 + if (currentlyTrackingTouch || aEvent.touches.Length() > 1) { 1.1866 + // We're tracking a possible tap for another point, or we saw a 1.1867 + // touchstart for a later pointer after we canceled tracking of 1.1868 + // the first point. Ignore this one. 1.1869 + return; 1.1870 + } 1.1871 + if (aStatus == nsEventStatus_eConsumeNoDefault || 1.1872 + nsIPresShell::gPreventMouseEvents || 1.1873 + aEvent.mFlags.mMultipleActionsPrevented) { 1.1874 + return; 1.1875 + } 1.1876 + 1.1877 + Touch* touch = aEvent.touches[0]; 1.1878 + mGestureDownPoint = LayoutDevicePoint(touch->mRefPoint.x, touch->mRefPoint.y); 1.1879 + mActivePointerId = touch->mIdentifier; 1.1880 + if (sClickHoldContextMenusEnabled) { 1.1881 + MOZ_ASSERT(!mTapHoldTimer); 1.1882 + mTapHoldTimer = NewRunnableMethod(this, 1.1883 + &TabChild::FireContextMenuEvent); 1.1884 + MessageLoop::current()->PostDelayedTask(FROM_HERE, mTapHoldTimer, 1.1885 + sContextMenuDelayMs); 1.1886 + } 1.1887 + return; 1.1888 + } 1.1889 + 1.1890 + // If we're not tracking a touch or this event doesn't include the 1.1891 + // one we care about, bail. 1.1892 + if (!currentlyTrackingTouch) { 1.1893 + return; 1.1894 + } 1.1895 + Touch* trackedTouch = GetTouchForIdentifier(aEvent, mActivePointerId); 1.1896 + if (!trackedTouch) { 1.1897 + return; 1.1898 + } 1.1899 + 1.1900 + LayoutDevicePoint currentPoint = LayoutDevicePoint(trackedTouch->mRefPoint.x, trackedTouch->mRefPoint.y); 1.1901 + int64_t time = aEvent.time; 1.1902 + switch (aEvent.message) { 1.1903 + case NS_TOUCH_MOVE: 1.1904 + if (abs(currentPoint.x - mGestureDownPoint.x) > sDragThreshold.width || 1.1905 + abs(currentPoint.y - mGestureDownPoint.y) > sDragThreshold.height) { 1.1906 + CancelTapTracking(); 1.1907 + } 1.1908 + return; 1.1909 + 1.1910 + case NS_TOUCH_END: 1.1911 + if (!nsIPresShell::gPreventMouseEvents) { 1.1912 + DispatchSynthesizedMouseEvent(NS_MOUSE_MOVE, time, currentPoint, mWidget); 1.1913 + DispatchSynthesizedMouseEvent(NS_MOUSE_BUTTON_DOWN, time, currentPoint, mWidget); 1.1914 + DispatchSynthesizedMouseEvent(NS_MOUSE_BUTTON_UP, time, currentPoint, mWidget); 1.1915 + } 1.1916 + // fall through 1.1917 + case NS_TOUCH_CANCEL: 1.1918 + CancelTapTracking(); 1.1919 + return; 1.1920 + 1.1921 + default: 1.1922 + NS_WARNING("Unknown touch event type"); 1.1923 + } 1.1924 +} 1.1925 + 1.1926 +void 1.1927 +TabChild::FireContextMenuEvent() 1.1928 +{ 1.1929 + double scale; 1.1930 + GetDefaultScale(&scale); 1.1931 + if (scale < 0) { 1.1932 + scale = 1; 1.1933 + } 1.1934 + 1.1935 + MOZ_ASSERT(mTapHoldTimer && mActivePointerId >= 0); 1.1936 + bool defaultPrevented = DispatchMouseEvent(NS_LITERAL_STRING("contextmenu"), 1.1937 + mGestureDownPoint / CSSToLayoutDeviceScale(scale), 1.1938 + 2 /* Right button */, 1.1939 + 1 /* Click count */, 1.1940 + 0 /* Modifiers */, 1.1941 + false /* Ignore root scroll frame */, 1.1942 + nsIDOMMouseEvent::MOZ_SOURCE_TOUCH); 1.1943 + 1.1944 + // Fire a click event if someone didn't call preventDefault() on the context 1.1945 + // menu event. 1.1946 + if (defaultPrevented) { 1.1947 + CancelTapTracking(); 1.1948 + } else if (mTapHoldTimer) { 1.1949 + mTapHoldTimer->Cancel(); 1.1950 + mTapHoldTimer = nullptr; 1.1951 + } 1.1952 +} 1.1953 + 1.1954 +void 1.1955 +TabChild::CancelTapTracking() 1.1956 +{ 1.1957 + mActivePointerId = -1; 1.1958 + if (mTapHoldTimer) { 1.1959 + mTapHoldTimer->Cancel(); 1.1960 + } 1.1961 + mTapHoldTimer = nullptr; 1.1962 +} 1.1963 + 1.1964 +bool 1.1965 +TabChild::RecvRealTouchEvent(const WidgetTouchEvent& aEvent, 1.1966 + const ScrollableLayerGuid& aGuid) 1.1967 +{ 1.1968 + WidgetTouchEvent localEvent(aEvent); 1.1969 + localEvent.widget = mWidget; 1.1970 + for (size_t i = 0; i < localEvent.touches.Length(); i++) { 1.1971 + aEvent.touches[i]->mRefPoint = APZCCallbackHelper::ApplyCallbackTransform(aEvent.touches[i]->mRefPoint, aGuid, mWidget->GetDefaultScale()); 1.1972 + } 1.1973 + 1.1974 + nsEventStatus status = DispatchWidgetEvent(localEvent); 1.1975 + 1.1976 + if (!IsAsyncPanZoomEnabled()) { 1.1977 + UpdateTapState(localEvent, status); 1.1978 + return true; 1.1979 + } 1.1980 + 1.1981 + if (aEvent.message == NS_TOUCH_START && localEvent.touches.Length() > 0) { 1.1982 + mActiveElementManager->SetTargetElement(localEvent.touches[0]->Target()); 1.1983 + } 1.1984 + 1.1985 + nsCOMPtr<nsPIDOMWindow> outerWindow = do_GetInterface(WebNavigation()); 1.1986 + nsCOMPtr<nsPIDOMWindow> innerWindow = outerWindow->GetCurrentInnerWindow(); 1.1987 + 1.1988 + if (!innerWindow || !innerWindow->HasTouchEventListeners()) { 1.1989 + SendContentReceivedTouch(aGuid, false); 1.1990 + return true; 1.1991 + } 1.1992 + 1.1993 + bool isTouchPrevented = nsIPresShell::gPreventMouseEvents || 1.1994 + localEvent.mFlags.mMultipleActionsPrevented; 1.1995 + switch (aEvent.message) { 1.1996 + case NS_TOUCH_START: { 1.1997 + if (isTouchPrevented) { 1.1998 + SendContentReceivedTouch(aGuid, isTouchPrevented); 1.1999 + } else { 1.2000 + mWaitingTouchListeners = true; 1.2001 + } 1.2002 + break; 1.2003 + } 1.2004 + 1.2005 + case NS_TOUCH_MOVE: 1.2006 + case NS_TOUCH_END: 1.2007 + case NS_TOUCH_CANCEL: { 1.2008 + if (mWaitingTouchListeners) { 1.2009 + SendContentReceivedTouch(aGuid, isTouchPrevented); 1.2010 + mWaitingTouchListeners = false; 1.2011 + } 1.2012 + break; 1.2013 + } 1.2014 + 1.2015 + default: 1.2016 + NS_WARNING("Unknown touch event type"); 1.2017 + } 1.2018 + 1.2019 + return true; 1.2020 +} 1.2021 + 1.2022 +bool 1.2023 +TabChild::RecvRealTouchMoveEvent(const WidgetTouchEvent& aEvent, 1.2024 + const ScrollableLayerGuid& aGuid) 1.2025 +{ 1.2026 + return RecvRealTouchEvent(aEvent, aGuid); 1.2027 +} 1.2028 + 1.2029 +void 1.2030 +TabChild::RequestNativeKeyBindings(AutoCacheNativeKeyCommands* aAutoCache, 1.2031 + WidgetKeyboardEvent* aEvent) 1.2032 +{ 1.2033 + MaybeNativeKeyBinding maybeBindings; 1.2034 + if (!SendRequestNativeKeyBindings(*aEvent, &maybeBindings)) { 1.2035 + return; 1.2036 + } 1.2037 + 1.2038 + if (maybeBindings.type() == MaybeNativeKeyBinding::TNativeKeyBinding) { 1.2039 + const NativeKeyBinding& bindings = maybeBindings; 1.2040 + aAutoCache->Cache(bindings.singleLineCommands(), 1.2041 + bindings.multiLineCommands(), 1.2042 + bindings.richTextCommands()); 1.2043 + } else { 1.2044 + aAutoCache->CacheNoCommands(); 1.2045 + } 1.2046 +} 1.2047 + 1.2048 +bool 1.2049 +TabChild::RecvRealKeyEvent(const WidgetKeyboardEvent& event, 1.2050 + const MaybeNativeKeyBinding& aBindings) 1.2051 +{ 1.2052 + PuppetWidget* widget = static_cast<PuppetWidget*>(mWidget.get()); 1.2053 + AutoCacheNativeKeyCommands autoCache(widget); 1.2054 + 1.2055 + if (event.message == NS_KEY_PRESS) { 1.2056 + if (aBindings.type() == MaybeNativeKeyBinding::TNativeKeyBinding) { 1.2057 + const NativeKeyBinding& bindings = aBindings; 1.2058 + autoCache.Cache(bindings.singleLineCommands(), 1.2059 + bindings.multiLineCommands(), 1.2060 + bindings.richTextCommands()); 1.2061 + } else { 1.2062 + autoCache.CacheNoCommands(); 1.2063 + } 1.2064 + } 1.2065 + // If content code called preventDefault() on a keydown event, then we don't 1.2066 + // want to process any following keypress events. 1.2067 + if (event.message == NS_KEY_PRESS && mIgnoreKeyPressEvent) { 1.2068 + return true; 1.2069 + } 1.2070 + 1.2071 + WidgetKeyboardEvent localEvent(event); 1.2072 + localEvent.widget = mWidget; 1.2073 + nsEventStatus status = DispatchWidgetEvent(localEvent); 1.2074 + 1.2075 + if (event.message == NS_KEY_DOWN) { 1.2076 + mIgnoreKeyPressEvent = status == nsEventStatus_eConsumeNoDefault; 1.2077 + } 1.2078 + 1.2079 + if (localEvent.mFlags.mWantReplyFromContentProcess) { 1.2080 + SendReplyKeyEvent(localEvent); 1.2081 + } 1.2082 + 1.2083 + return true; 1.2084 +} 1.2085 + 1.2086 +bool 1.2087 +TabChild::RecvKeyEvent(const nsString& aType, 1.2088 + const int32_t& aKeyCode, 1.2089 + const int32_t& aCharCode, 1.2090 + const int32_t& aModifiers, 1.2091 + const bool& aPreventDefault) 1.2092 +{ 1.2093 + nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils()); 1.2094 + NS_ENSURE_TRUE(utils, true); 1.2095 + bool ignored = false; 1.2096 + utils->SendKeyEvent(aType, aKeyCode, aCharCode, 1.2097 + aModifiers, aPreventDefault, &ignored); 1.2098 + return true; 1.2099 +} 1.2100 + 1.2101 +bool 1.2102 +TabChild::RecvCompositionEvent(const WidgetCompositionEvent& event) 1.2103 +{ 1.2104 + WidgetCompositionEvent localEvent(event); 1.2105 + localEvent.widget = mWidget; 1.2106 + DispatchWidgetEvent(localEvent); 1.2107 + return true; 1.2108 +} 1.2109 + 1.2110 +bool 1.2111 +TabChild::RecvTextEvent(const WidgetTextEvent& event) 1.2112 +{ 1.2113 + WidgetTextEvent localEvent(event); 1.2114 + localEvent.widget = mWidget; 1.2115 + DispatchWidgetEvent(localEvent); 1.2116 + return true; 1.2117 +} 1.2118 + 1.2119 +bool 1.2120 +TabChild::RecvSelectionEvent(const WidgetSelectionEvent& event) 1.2121 +{ 1.2122 + WidgetSelectionEvent localEvent(event); 1.2123 + localEvent.widget = mWidget; 1.2124 + DispatchWidgetEvent(localEvent); 1.2125 + return true; 1.2126 +} 1.2127 + 1.2128 +PDocumentRendererChild* 1.2129 +TabChild::AllocPDocumentRendererChild(const nsRect& documentRect, 1.2130 + const mozilla::gfx::Matrix& transform, 1.2131 + const nsString& bgcolor, 1.2132 + const uint32_t& renderFlags, 1.2133 + const bool& flushLayout, 1.2134 + const nsIntSize& renderSize) 1.2135 +{ 1.2136 + return new DocumentRendererChild(); 1.2137 +} 1.2138 + 1.2139 +bool 1.2140 +TabChild::DeallocPDocumentRendererChild(PDocumentRendererChild* actor) 1.2141 +{ 1.2142 + delete actor; 1.2143 + return true; 1.2144 +} 1.2145 + 1.2146 +bool 1.2147 +TabChild::RecvPDocumentRendererConstructor(PDocumentRendererChild* actor, 1.2148 + const nsRect& documentRect, 1.2149 + const mozilla::gfx::Matrix& transform, 1.2150 + const nsString& bgcolor, 1.2151 + const uint32_t& renderFlags, 1.2152 + const bool& flushLayout, 1.2153 + const nsIntSize& renderSize) 1.2154 +{ 1.2155 + DocumentRendererChild *render = static_cast<DocumentRendererChild *>(actor); 1.2156 + 1.2157 + nsCOMPtr<nsIWebBrowser> browser = do_QueryInterface(WebNavigation()); 1.2158 + if (!browser) 1.2159 + return true; // silently ignore 1.2160 + nsCOMPtr<nsIDOMWindow> window; 1.2161 + if (NS_FAILED(browser->GetContentDOMWindow(getter_AddRefs(window))) || 1.2162 + !window) 1.2163 + { 1.2164 + return true; // silently ignore 1.2165 + } 1.2166 + 1.2167 + nsCString data; 1.2168 + bool ret = render->RenderDocument(window, 1.2169 + documentRect, transform, 1.2170 + bgcolor, 1.2171 + renderFlags, flushLayout, 1.2172 + renderSize, data); 1.2173 + if (!ret) 1.2174 + return true; // silently ignore 1.2175 + 1.2176 + return PDocumentRendererChild::Send__delete__(actor, renderSize, data); 1.2177 +} 1.2178 + 1.2179 +PColorPickerChild* 1.2180 +TabChild::AllocPColorPickerChild(const nsString&, const nsString&) 1.2181 +{ 1.2182 + NS_RUNTIMEABORT("unused"); 1.2183 + return nullptr; 1.2184 +} 1.2185 + 1.2186 +bool 1.2187 +TabChild::DeallocPColorPickerChild(PColorPickerChild* aColorPicker) 1.2188 +{ 1.2189 + nsColorPickerProxy* picker = static_cast<nsColorPickerProxy*>(aColorPicker); 1.2190 + NS_RELEASE(picker); 1.2191 + return true; 1.2192 +} 1.2193 + 1.2194 +PContentPermissionRequestChild* 1.2195 +TabChild::AllocPContentPermissionRequestChild(const InfallibleTArray<PermissionRequest>& aRequests, 1.2196 + const IPC::Principal& aPrincipal) 1.2197 +{ 1.2198 + NS_RUNTIMEABORT("unused"); 1.2199 + return nullptr; 1.2200 +} 1.2201 + 1.2202 +bool 1.2203 +TabChild::DeallocPContentPermissionRequestChild(PContentPermissionRequestChild* actor) 1.2204 +{ 1.2205 + PCOMContentPermissionRequestChild* child = 1.2206 + static_cast<PCOMContentPermissionRequestChild*>(actor); 1.2207 +#ifdef DEBUG 1.2208 + child->mIPCOpen = false; 1.2209 +#endif /* DEBUG */ 1.2210 + child->IPDLRelease(); 1.2211 + return true; 1.2212 +} 1.2213 + 1.2214 +PFilePickerChild* 1.2215 +TabChild::AllocPFilePickerChild(const nsString&, const int16_t&) 1.2216 +{ 1.2217 + NS_RUNTIMEABORT("unused"); 1.2218 + return nullptr; 1.2219 +} 1.2220 + 1.2221 +bool 1.2222 +TabChild::DeallocPFilePickerChild(PFilePickerChild* actor) 1.2223 +{ 1.2224 + nsFilePickerProxy* filePicker = static_cast<nsFilePickerProxy*>(actor); 1.2225 + NS_RELEASE(filePicker); 1.2226 + return true; 1.2227 +} 1.2228 + 1.2229 +bool 1.2230 +TabChild::RecvActivateFrameEvent(const nsString& aType, const bool& capture) 1.2231 +{ 1.2232 + nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(WebNavigation()); 1.2233 + NS_ENSURE_TRUE(window, true); 1.2234 + nsCOMPtr<EventTarget> chromeHandler = 1.2235 + do_QueryInterface(window->GetChromeEventHandler()); 1.2236 + NS_ENSURE_TRUE(chromeHandler, true); 1.2237 + nsRefPtr<ContentListener> listener = new ContentListener(this); 1.2238 + chromeHandler->AddEventListener(aType, listener, capture); 1.2239 + return true; 1.2240 +} 1.2241 + 1.2242 +POfflineCacheUpdateChild* 1.2243 +TabChild::AllocPOfflineCacheUpdateChild(const URIParams& manifestURI, 1.2244 + const URIParams& documentURI, 1.2245 + const bool& stickDocument) 1.2246 +{ 1.2247 + NS_RUNTIMEABORT("unused"); 1.2248 + return nullptr; 1.2249 +} 1.2250 + 1.2251 +bool 1.2252 +TabChild::DeallocPOfflineCacheUpdateChild(POfflineCacheUpdateChild* actor) 1.2253 +{ 1.2254 + OfflineCacheUpdateChild* offlineCacheUpdate = static_cast<OfflineCacheUpdateChild*>(actor); 1.2255 + NS_RELEASE(offlineCacheUpdate); 1.2256 + return true; 1.2257 +} 1.2258 + 1.2259 +bool 1.2260 +TabChild::RecvLoadRemoteScript(const nsString& aURL, const bool& aRunInGlobalScope) 1.2261 +{ 1.2262 + if (!mGlobal && !InitTabChildGlobal()) 1.2263 + // This can happen if we're half-destroyed. It's not a fatal 1.2264 + // error. 1.2265 + return true; 1.2266 + 1.2267 + LoadFrameScriptInternal(aURL, aRunInGlobalScope); 1.2268 + return true; 1.2269 +} 1.2270 + 1.2271 +bool 1.2272 +TabChild::RecvAsyncMessage(const nsString& aMessage, 1.2273 + const ClonedMessageData& aData, 1.2274 + const InfallibleTArray<CpowEntry>& aCpows, 1.2275 + const IPC::Principal& aPrincipal) 1.2276 +{ 1.2277 + if (mTabChildGlobal) { 1.2278 + nsCOMPtr<nsIXPConnectJSObjectHolder> kungFuDeathGrip(GetGlobal()); 1.2279 + StructuredCloneData cloneData = UnpackClonedMessageDataForChild(aData); 1.2280 + nsRefPtr<nsFrameMessageManager> mm = 1.2281 + static_cast<nsFrameMessageManager*>(mTabChildGlobal->mMessageManager.get()); 1.2282 + CpowIdHolder cpows(static_cast<ContentChild*>(Manager())->GetCPOWManager(), aCpows); 1.2283 + mm->ReceiveMessage(static_cast<EventTarget*>(mTabChildGlobal), 1.2284 + aMessage, false, &cloneData, &cpows, aPrincipal, nullptr); 1.2285 + } 1.2286 + return true; 1.2287 +} 1.2288 + 1.2289 +class UnloadScriptEvent : public nsRunnable 1.2290 +{ 1.2291 +public: 1.2292 + UnloadScriptEvent(TabChild* aTabChild, TabChildGlobal* aTabChildGlobal) 1.2293 + : mTabChild(aTabChild), mTabChildGlobal(aTabChildGlobal) 1.2294 + { } 1.2295 + 1.2296 + NS_IMETHOD Run() 1.2297 + { 1.2298 + nsCOMPtr<nsIDOMEvent> event; 1.2299 + NS_NewDOMEvent(getter_AddRefs(event), mTabChildGlobal, nullptr, nullptr); 1.2300 + if (event) { 1.2301 + event->InitEvent(NS_LITERAL_STRING("unload"), false, false); 1.2302 + event->SetTrusted(true); 1.2303 + 1.2304 + bool dummy; 1.2305 + mTabChildGlobal->DispatchEvent(event, &dummy); 1.2306 + } 1.2307 + 1.2308 + return NS_OK; 1.2309 + } 1.2310 + 1.2311 + nsRefPtr<TabChild> mTabChild; 1.2312 + TabChildGlobal* mTabChildGlobal; 1.2313 +}; 1.2314 + 1.2315 +bool 1.2316 +TabChild::RecvDestroy() 1.2317 +{ 1.2318 + if (mTabChildGlobal) { 1.2319 + // Let the frame scripts know the child is being closed 1.2320 + nsContentUtils::AddScriptRunner( 1.2321 + new UnloadScriptEvent(this, mTabChildGlobal) 1.2322 + ); 1.2323 + } 1.2324 + 1.2325 + nsCOMPtr<nsIObserverService> observerService = 1.2326 + mozilla::services::GetObserverService(); 1.2327 + 1.2328 + observerService->RemoveObserver(this, BROWSER_ZOOM_TO_RECT); 1.2329 + observerService->RemoveObserver(this, BEFORE_FIRST_PAINT); 1.2330 + 1.2331 + const InfallibleTArray<PIndexedDBChild*>& idbActors = 1.2332 + ManagedPIndexedDBChild(); 1.2333 + for (uint32_t i = 0; i < idbActors.Length(); ++i) { 1.2334 + static_cast<IndexedDBChild*>(idbActors[i])->Disconnect(); 1.2335 + } 1.2336 + 1.2337 + // XXX what other code in ~TabChild() should we be running here? 1.2338 + DestroyWindow(); 1.2339 + 1.2340 + return Send__delete__(this); 1.2341 +} 1.2342 + 1.2343 +bool 1.2344 +TabChild::RecvSetUpdateHitRegion(const bool& aEnabled) 1.2345 +{ 1.2346 + mUpdateHitRegion = aEnabled; 1.2347 + return true; 1.2348 +} 1.2349 + 1.2350 +bool 1.2351 +TabChild::RecvSetIsDocShellActive(const bool& aIsActive) 1.2352 +{ 1.2353 + nsCOMPtr<nsIDocShell> docShell = do_GetInterface(WebNavigation()); 1.2354 + if (docShell) { 1.2355 + docShell->SetIsActive(aIsActive); 1.2356 + } 1.2357 + return true; 1.2358 +} 1.2359 + 1.2360 +PRenderFrameChild* 1.2361 +TabChild::AllocPRenderFrameChild() 1.2362 +{ 1.2363 + return new RenderFrameChild(); 1.2364 +} 1.2365 + 1.2366 +bool 1.2367 +TabChild::DeallocPRenderFrameChild(PRenderFrameChild* aFrame) 1.2368 +{ 1.2369 + delete aFrame; 1.2370 + return true; 1.2371 +} 1.2372 + 1.2373 +bool 1.2374 +TabChild::InitTabChildGlobal(FrameScriptLoading aScriptLoading) 1.2375 +{ 1.2376 + if (!mGlobal && !mTabChildGlobal) { 1.2377 + nsCOMPtr<nsPIDOMWindow> window = do_GetInterface(WebNavigation()); 1.2378 + NS_ENSURE_TRUE(window, false); 1.2379 + nsCOMPtr<EventTarget> chromeHandler = 1.2380 + do_QueryInterface(window->GetChromeEventHandler()); 1.2381 + NS_ENSURE_TRUE(chromeHandler, false); 1.2382 + 1.2383 + nsRefPtr<TabChildGlobal> scope = new TabChildGlobal(this); 1.2384 + mTabChildGlobal = scope; 1.2385 + 1.2386 + nsISupports* scopeSupports = NS_ISUPPORTS_CAST(EventTarget*, scope); 1.2387 + 1.2388 + NS_NAMED_LITERAL_CSTRING(globalId, "outOfProcessTabChildGlobal"); 1.2389 + NS_ENSURE_TRUE(InitTabChildGlobalInternal(scopeSupports, globalId), false); 1.2390 + 1.2391 + scope->Init(); 1.2392 + 1.2393 + nsCOMPtr<nsPIWindowRoot> root = do_QueryInterface(chromeHandler); 1.2394 + NS_ENSURE_TRUE(root, false); 1.2395 + root->SetParentTarget(scope); 1.2396 + 1.2397 + chromeHandler->AddEventListener(NS_LITERAL_STRING("DOMMetaAdded"), this, false); 1.2398 + } 1.2399 + 1.2400 + if (aScriptLoading != DONT_LOAD_SCRIPTS && !mTriedBrowserInit) { 1.2401 + mTriedBrowserInit = true; 1.2402 + // Initialize the child side of the browser element machinery, 1.2403 + // if appropriate. 1.2404 + if (IsBrowserOrApp()) { 1.2405 + RecvLoadRemoteScript(BROWSER_ELEMENT_CHILD_SCRIPT, true); 1.2406 + } 1.2407 + } 1.2408 + 1.2409 + return true; 1.2410 +} 1.2411 + 1.2412 +bool 1.2413 +TabChild::InitRenderingState() 1.2414 +{ 1.2415 + static_cast<PuppetWidget*>(mWidget.get())->InitIMEState(); 1.2416 + 1.2417 + uint64_t id; 1.2418 + bool success; 1.2419 + RenderFrameChild* remoteFrame = 1.2420 + static_cast<RenderFrameChild*>(SendPRenderFrameConstructor()); 1.2421 + if (!remoteFrame) { 1.2422 + NS_WARNING("failed to construct RenderFrame"); 1.2423 + return false; 1.2424 + } 1.2425 + SendInitRenderFrame(remoteFrame, &mScrolling, &mTextureFactoryIdentifier, &id, &success); 1.2426 + if (!success) { 1.2427 + NS_WARNING("failed to construct RenderFrame"); 1.2428 + PRenderFrameChild::Send__delete__(remoteFrame); 1.2429 + return false; 1.2430 + } 1.2431 + 1.2432 + PLayerTransactionChild* shadowManager = nullptr; 1.2433 + if (id != 0) { 1.2434 + // Pushing layers transactions directly to a separate 1.2435 + // compositor context. 1.2436 + PCompositorChild* compositorChild = CompositorChild::Get(); 1.2437 + if (!compositorChild) { 1.2438 + NS_WARNING("failed to get CompositorChild instance"); 1.2439 + return false; 1.2440 + } 1.2441 + nsTArray<LayersBackend> backends; 1.2442 + backends.AppendElement(mTextureFactoryIdentifier.mParentBackend); 1.2443 + bool success; 1.2444 + shadowManager = 1.2445 + compositorChild->SendPLayerTransactionConstructor(backends, 1.2446 + id, &mTextureFactoryIdentifier, &success); 1.2447 + if (!success) { 1.2448 + NS_WARNING("failed to properly allocate layer transaction"); 1.2449 + return false; 1.2450 + } 1.2451 + } else { 1.2452 + // Pushing transactions to the parent content. 1.2453 + shadowManager = remoteFrame->SendPLayerTransactionConstructor(); 1.2454 + } 1.2455 + 1.2456 + if (!shadowManager) { 1.2457 + NS_WARNING("failed to construct LayersChild"); 1.2458 + // This results in |remoteFrame| being deleted. 1.2459 + PRenderFrameChild::Send__delete__(remoteFrame); 1.2460 + return false; 1.2461 + } 1.2462 + 1.2463 + ShadowLayerForwarder* lf = 1.2464 + mWidget->GetLayerManager(shadowManager, mTextureFactoryIdentifier.mParentBackend) 1.2465 + ->AsShadowForwarder(); 1.2466 + NS_ABORT_IF_FALSE(lf && lf->HasShadowManager(), 1.2467 + "PuppetWidget should have shadow manager"); 1.2468 + lf->IdentifyTextureHost(mTextureFactoryIdentifier); 1.2469 + ImageBridgeChild::IdentifyCompositorTextureHost(mTextureFactoryIdentifier); 1.2470 + 1.2471 + mRemoteFrame = remoteFrame; 1.2472 + if (id != 0) { 1.2473 + if (!sTabChildren) { 1.2474 + sTabChildren = new TabChildMap; 1.2475 + } 1.2476 + sTabChildren->Put(id, this); 1.2477 + mLayersId = id; 1.2478 + } 1.2479 + 1.2480 + nsCOMPtr<nsIObserverService> observerService = 1.2481 + mozilla::services::GetObserverService(); 1.2482 + 1.2483 + if (observerService) { 1.2484 + observerService->AddObserver(this, 1.2485 + BROWSER_ZOOM_TO_RECT, 1.2486 + false); 1.2487 + observerService->AddObserver(this, 1.2488 + BEFORE_FIRST_PAINT, 1.2489 + false); 1.2490 + } 1.2491 + 1.2492 + // This state can't change during the lifetime of the child. 1.2493 + sCpowsEnabled = BrowserTabsRemote(); 1.2494 + if (Preferences::GetBool("dom.ipc.cpows.force-enabled", false)) 1.2495 + sCpowsEnabled = true; 1.2496 + 1.2497 + return true; 1.2498 +} 1.2499 + 1.2500 +void 1.2501 +TabChild::SetBackgroundColor(const nscolor& aColor) 1.2502 +{ 1.2503 + if (mLastBackgroundColor != aColor) { 1.2504 + mLastBackgroundColor = aColor; 1.2505 + SendSetBackgroundColor(mLastBackgroundColor); 1.2506 + } 1.2507 +} 1.2508 + 1.2509 +void 1.2510 +TabChild::GetDPI(float* aDPI) 1.2511 +{ 1.2512 + *aDPI = -1.0; 1.2513 + if (!mRemoteFrame) { 1.2514 + return; 1.2515 + } 1.2516 + 1.2517 + SendGetDPI(aDPI); 1.2518 +} 1.2519 + 1.2520 +void 1.2521 +TabChild::GetDefaultScale(double* aScale) 1.2522 +{ 1.2523 + *aScale = -1.0; 1.2524 + if (!mRemoteFrame) { 1.2525 + return; 1.2526 + } 1.2527 + 1.2528 + SendGetDefaultScale(aScale); 1.2529 +} 1.2530 + 1.2531 +void 1.2532 +TabChild::NotifyPainted() 1.2533 +{ 1.2534 + if (UseDirectCompositor() && !mNotified) { 1.2535 + mRemoteFrame->SendNotifyCompositorTransaction(); 1.2536 + mNotified = true; 1.2537 + } 1.2538 +} 1.2539 + 1.2540 +bool 1.2541 +TabChild::DispatchMouseEvent(const nsString& aType, 1.2542 + const CSSPoint& aPoint, 1.2543 + const int32_t& aButton, 1.2544 + const int32_t& aClickCount, 1.2545 + const int32_t& aModifiers, 1.2546 + const bool& aIgnoreRootScrollFrame, 1.2547 + const unsigned short& aInputSourceArg) 1.2548 +{ 1.2549 + nsCOMPtr<nsIDOMWindowUtils> utils(GetDOMWindowUtils()); 1.2550 + NS_ENSURE_TRUE(utils, true); 1.2551 + 1.2552 + bool defaultPrevented = false; 1.2553 + utils->SendMouseEvent(aType, aPoint.x, aPoint.y, aButton, aClickCount, aModifiers, 1.2554 + aIgnoreRootScrollFrame, 0, aInputSourceArg, false, 4, &defaultPrevented); 1.2555 + return defaultPrevented; 1.2556 +} 1.2557 + 1.2558 +void 1.2559 +TabChild::MakeVisible() 1.2560 +{ 1.2561 + if (mWidget) { 1.2562 + mWidget->Show(true); 1.2563 + } 1.2564 +} 1.2565 + 1.2566 +void 1.2567 +TabChild::MakeHidden() 1.2568 +{ 1.2569 + if (mWidget) { 1.2570 + mWidget->Show(false); 1.2571 + } 1.2572 +} 1.2573 + 1.2574 +void 1.2575 +TabChild::UpdateHitRegion(const nsRegion& aRegion) 1.2576 +{ 1.2577 + mRemoteFrame->SendUpdateHitRegion(aRegion); 1.2578 +} 1.2579 + 1.2580 +NS_IMETHODIMP 1.2581 +TabChild::GetMessageManager(nsIContentFrameMessageManager** aResult) 1.2582 +{ 1.2583 + if (mTabChildGlobal) { 1.2584 + NS_ADDREF(*aResult = mTabChildGlobal); 1.2585 + return NS_OK; 1.2586 + } 1.2587 + *aResult = nullptr; 1.2588 + return NS_ERROR_FAILURE; 1.2589 +} 1.2590 + 1.2591 +void 1.2592 +TabChild::SendRequestFocus(bool aCanFocus) 1.2593 +{ 1.2594 + PBrowserChild::SendRequestFocus(aCanFocus); 1.2595 +} 1.2596 + 1.2597 +PIndexedDBChild* 1.2598 +TabChild::AllocPIndexedDBChild( 1.2599 + const nsCString& aGroup, 1.2600 + const nsCString& aASCIIOrigin, bool* /* aAllowed */) 1.2601 +{ 1.2602 + NS_NOTREACHED("Should never get here!"); 1.2603 + return nullptr; 1.2604 +} 1.2605 + 1.2606 +bool 1.2607 +TabChild::DeallocPIndexedDBChild(PIndexedDBChild* aActor) 1.2608 +{ 1.2609 + delete aActor; 1.2610 + return true; 1.2611 +} 1.2612 + 1.2613 +bool 1.2614 +TabChild::DoSendBlockingMessage(JSContext* aCx, 1.2615 + const nsAString& aMessage, 1.2616 + const StructuredCloneData& aData, 1.2617 + JS::Handle<JSObject *> aCpows, 1.2618 + nsIPrincipal* aPrincipal, 1.2619 + InfallibleTArray<nsString>* aJSONRetVal, 1.2620 + bool aIsSync) 1.2621 +{ 1.2622 + ContentChild* cc = Manager(); 1.2623 + ClonedMessageData data; 1.2624 + if (!BuildClonedMessageDataForChild(cc, aData, data)) { 1.2625 + return false; 1.2626 + } 1.2627 + InfallibleTArray<CpowEntry> cpows; 1.2628 + if (sCpowsEnabled) { 1.2629 + if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) { 1.2630 + return false; 1.2631 + } 1.2632 + } 1.2633 + if (aIsSync) { 1.2634 + return SendSyncMessage(PromiseFlatString(aMessage), data, cpows, 1.2635 + aPrincipal, aJSONRetVal); 1.2636 + } 1.2637 + 1.2638 + return CallRpcMessage(PromiseFlatString(aMessage), data, cpows, 1.2639 + aPrincipal, aJSONRetVal); 1.2640 +} 1.2641 + 1.2642 +bool 1.2643 +TabChild::DoSendAsyncMessage(JSContext* aCx, 1.2644 + const nsAString& aMessage, 1.2645 + const StructuredCloneData& aData, 1.2646 + JS::Handle<JSObject *> aCpows, 1.2647 + nsIPrincipal* aPrincipal) 1.2648 +{ 1.2649 + ContentChild* cc = Manager(); 1.2650 + ClonedMessageData data; 1.2651 + if (!BuildClonedMessageDataForChild(cc, aData, data)) { 1.2652 + return false; 1.2653 + } 1.2654 + InfallibleTArray<CpowEntry> cpows; 1.2655 + if (sCpowsEnabled) { 1.2656 + if (!cc->GetCPOWManager()->Wrap(aCx, aCpows, &cpows)) { 1.2657 + return false; 1.2658 + } 1.2659 + } 1.2660 + return SendAsyncMessage(PromiseFlatString(aMessage), data, cpows, 1.2661 + aPrincipal); 1.2662 +} 1.2663 + 1.2664 +TabChild* 1.2665 +TabChild::GetFrom(nsIPresShell* aPresShell) 1.2666 +{ 1.2667 + nsIDocument* doc = aPresShell->GetDocument(); 1.2668 + if (!doc) { 1.2669 + return nullptr; 1.2670 + } 1.2671 + nsCOMPtr<nsIDocShell> docShell(doc->GetDocShell()); 1.2672 + return GetFrom(docShell); 1.2673 +} 1.2674 + 1.2675 +TabChild* 1.2676 +TabChild::GetFrom(uint64_t aLayersId) 1.2677 +{ 1.2678 + if (!sTabChildren) { 1.2679 + return nullptr; 1.2680 + } 1.2681 + return sTabChildren->Get(aLayersId); 1.2682 +} 1.2683 + 1.2684 +void 1.2685 +TabChild::DidComposite() 1.2686 +{ 1.2687 + MOZ_ASSERT(mWidget); 1.2688 + MOZ_ASSERT(mWidget->GetLayerManager()); 1.2689 + MOZ_ASSERT(mWidget->GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT); 1.2690 + 1.2691 + ClientLayerManager *manager = static_cast<ClientLayerManager*>(mWidget->GetLayerManager()); 1.2692 + manager->DidComposite(); 1.2693 +} 1.2694 + 1.2695 +NS_IMETHODIMP 1.2696 +TabChild::OnShowTooltip(int32_t aXCoords, int32_t aYCoords, const char16_t *aTipText) 1.2697 +{ 1.2698 + nsString str(aTipText); 1.2699 + SendShowTooltip(aXCoords, aYCoords, str); 1.2700 + return NS_OK; 1.2701 +} 1.2702 + 1.2703 +NS_IMETHODIMP 1.2704 +TabChild::OnHideTooltip() 1.2705 +{ 1.2706 + SendHideTooltip(); 1.2707 + return NS_OK; 1.2708 +} 1.2709 + 1.2710 +TabChildGlobal::TabChildGlobal(TabChildBase* aTabChild) 1.2711 +: mTabChild(aTabChild) 1.2712 +{ 1.2713 +} 1.2714 + 1.2715 +void 1.2716 +TabChildGlobal::Init() 1.2717 +{ 1.2718 + NS_ASSERTION(!mMessageManager, "Re-initializing?!?"); 1.2719 + mMessageManager = new nsFrameMessageManager(mTabChild, 1.2720 + nullptr, 1.2721 + MM_CHILD); 1.2722 +} 1.2723 + 1.2724 +NS_IMPL_CYCLE_COLLECTION_INHERITED(TabChildGlobal, DOMEventTargetHelper, 1.2725 + mMessageManager, mTabChild) 1.2726 + 1.2727 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TabChildGlobal) 1.2728 + NS_INTERFACE_MAP_ENTRY(nsIMessageListenerManager) 1.2729 + NS_INTERFACE_MAP_ENTRY(nsIMessageSender) 1.2730 + NS_INTERFACE_MAP_ENTRY(nsISyncMessageSender) 1.2731 + NS_INTERFACE_MAP_ENTRY(nsIContentFrameMessageManager) 1.2732 + NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal) 1.2733 + NS_INTERFACE_MAP_ENTRY(nsIGlobalObject) 1.2734 + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ContentFrameMessageManager) 1.2735 +NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper) 1.2736 + 1.2737 +NS_IMPL_ADDREF_INHERITED(TabChildGlobal, DOMEventTargetHelper) 1.2738 +NS_IMPL_RELEASE_INHERITED(TabChildGlobal, DOMEventTargetHelper) 1.2739 + 1.2740 +/* [notxpcom] boolean markForCC (); */ 1.2741 +// This method isn't automatically forwarded safely because it's notxpcom, so 1.2742 +// the IDL binding doesn't know what value to return. 1.2743 +NS_IMETHODIMP_(bool) 1.2744 +TabChildGlobal::MarkForCC() 1.2745 +{ 1.2746 + return mMessageManager ? mMessageManager->MarkForCC() : false; 1.2747 +} 1.2748 + 1.2749 +NS_IMETHODIMP 1.2750 +TabChildGlobal::GetContent(nsIDOMWindow** aContent) 1.2751 +{ 1.2752 + *aContent = nullptr; 1.2753 + if (!mTabChild) 1.2754 + return NS_ERROR_NULL_POINTER; 1.2755 + nsCOMPtr<nsIDOMWindow> window = do_GetInterface(mTabChild->WebNavigation()); 1.2756 + window.swap(*aContent); 1.2757 + return NS_OK; 1.2758 +} 1.2759 + 1.2760 +NS_IMETHODIMP 1.2761 +TabChildGlobal::PrivateNoteIntentionalCrash() 1.2762 +{ 1.2763 + mozilla::NoteIntentionalCrash("tab"); 1.2764 + return NS_OK; 1.2765 +} 1.2766 + 1.2767 +NS_IMETHODIMP 1.2768 +TabChildGlobal::GetDocShell(nsIDocShell** aDocShell) 1.2769 +{ 1.2770 + *aDocShell = nullptr; 1.2771 + if (!mTabChild) 1.2772 + return NS_ERROR_NULL_POINTER; 1.2773 + nsCOMPtr<nsIDocShell> docShell = do_GetInterface(mTabChild->WebNavigation()); 1.2774 + docShell.swap(*aDocShell); 1.2775 + return NS_OK; 1.2776 +} 1.2777 + 1.2778 +NS_IMETHODIMP 1.2779 +TabChildGlobal::Btoa(const nsAString& aBinaryData, 1.2780 + nsAString& aAsciiBase64String) 1.2781 +{ 1.2782 + return nsContentUtils::Btoa(aBinaryData, aAsciiBase64String); 1.2783 +} 1.2784 + 1.2785 +NS_IMETHODIMP 1.2786 +TabChildGlobal::Atob(const nsAString& aAsciiString, 1.2787 + nsAString& aBinaryData) 1.2788 +{ 1.2789 + return nsContentUtils::Atob(aAsciiString, aBinaryData); 1.2790 +} 1.2791 + 1.2792 +JSContext* 1.2793 +TabChildGlobal::GetJSContextForEventHandlers() 1.2794 +{ 1.2795 + return nsContentUtils::GetSafeJSContext(); 1.2796 +} 1.2797 + 1.2798 +nsIPrincipal* 1.2799 +TabChildGlobal::GetPrincipal() 1.2800 +{ 1.2801 + if (!mTabChild) 1.2802 + return nullptr; 1.2803 + return mTabChild->GetPrincipal(); 1.2804 +} 1.2805 + 1.2806 +JSObject* 1.2807 +TabChildGlobal::GetGlobalJSObject() 1.2808 +{ 1.2809 + NS_ENSURE_TRUE(mTabChild, nullptr); 1.2810 + nsCOMPtr<nsIXPConnectJSObjectHolder> ref = mTabChild->GetGlobal(); 1.2811 + NS_ENSURE_TRUE(ref, nullptr); 1.2812 + return ref->GetJSObject(); 1.2813 +} 1.2814 +