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