Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "base/basictypes.h"
8 :
9 : #include "TabParent.h"
10 :
11 : #ifdef ACCESSIBILITY
12 : #include "mozilla/a11y/DocAccessibleParent.h"
13 : #include "nsAccessibilityService.h"
14 : #endif
15 : #include "mozilla/BrowserElementParent.h"
16 : #include "mozilla/dom/ContentBridgeParent.h"
17 : #include "mozilla/dom/ContentParent.h"
18 : #include "mozilla/dom/DataTransfer.h"
19 : #include "mozilla/dom/Event.h"
20 : #include "mozilla/dom/indexedDB/ActorsParent.h"
21 : #include "mozilla/dom/IPCBlobUtils.h"
22 : #include "mozilla/dom/PaymentRequestParent.h"
23 : #include "mozilla/EventStateManager.h"
24 : #include "mozilla/gfx/2D.h"
25 : #include "mozilla/gfx/DataSurfaceHelpers.h"
26 : #include "mozilla/gfx/GPUProcessManager.h"
27 : #include "mozilla/Hal.h"
28 : #include "mozilla/IMEStateManager.h"
29 : #include "mozilla/ipc/DocumentRendererParent.h"
30 : #include "mozilla/jsipc/CrossProcessObjectWrappers.h"
31 : #include "mozilla/layers/AsyncDragMetrics.h"
32 : #include "mozilla/layers/InputAPZContext.h"
33 : #include "mozilla/layout/RenderFrameParent.h"
34 : #include "mozilla/plugins/PPluginWidgetParent.h"
35 : #include "mozilla/LookAndFeel.h"
36 : #include "mozilla/MouseEvents.h"
37 : #include "mozilla/net/NeckoChild.h"
38 : #include "mozilla/Preferences.h"
39 : #include "mozilla/PresShell.h"
40 : #include "mozilla/TextEvents.h"
41 : #include "mozilla/TouchEvents.h"
42 : #include "mozilla/UniquePtr.h"
43 : #include "mozilla/Unused.h"
44 : #include "nsCOMPtr.h"
45 : #include "nsContentAreaDragDrop.h"
46 : #include "nsContentUtils.h"
47 : #include "nsDebug.h"
48 : #include "nsFocusManager.h"
49 : #include "nsFrameLoader.h"
50 : #include "nsIBaseWindow.h"
51 : #include "nsIBrowser.h"
52 : #include "nsIContent.h"
53 : #include "nsIDocShell.h"
54 : #include "nsIDocShellTreeOwner.h"
55 : #include "nsIDOMElement.h"
56 : #include "nsIDOMEvent.h"
57 : #include "nsIDOMWindow.h"
58 : #include "nsIDOMWindowUtils.h"
59 : #include "nsIInterfaceRequestorUtils.h"
60 : #include "nsILoadInfo.h"
61 : #include "nsIPromptFactory.h"
62 : #include "nsIURI.h"
63 : #include "nsIWindowWatcher.h"
64 : #include "nsIWebBrowserChrome.h"
65 : #include "nsIXULBrowserWindow.h"
66 : #include "nsIXULWindow.h"
67 : #include "nsIRemoteBrowser.h"
68 : #include "nsViewManager.h"
69 : #include "nsVariant.h"
70 : #include "nsIWidget.h"
71 : #include "nsNetUtil.h"
72 : #ifndef XP_WIN
73 : #include "nsJARProtocolHandler.h"
74 : #endif
75 : #include "nsPIDOMWindow.h"
76 : #include "nsPrintfCString.h"
77 : #include "nsServiceManagerUtils.h"
78 : #include "nsThreadUtils.h"
79 : #include "PermissionMessageUtils.h"
80 : #include "StructuredCloneData.h"
81 : #include "ColorPickerParent.h"
82 : #include "FilePickerParent.h"
83 : #include "TabChild.h"
84 : #include "LoadContext.h"
85 : #include "nsNetCID.h"
86 : #include "nsIAuthInformation.h"
87 : #include "nsIAuthPromptCallback.h"
88 : #include "nsAuthInformationHolder.h"
89 : #include "nsICancelable.h"
90 : #include "gfxPrefs.h"
91 : #include "nsILoginManagerPrompter.h"
92 : #include "nsPIWindowRoot.h"
93 : #include "nsIAuthPrompt2.h"
94 : #include "gfxDrawable.h"
95 : #include "ImageOps.h"
96 : #include "UnitTransforms.h"
97 : #include <algorithm>
98 : #include "mozilla/WebBrowserPersistDocumentParent.h"
99 : #include "nsIGroupedSHistory.h"
100 : #include "PartialSHistory.h"
101 : #include "ProcessPriorityManager.h"
102 : #include "nsString.h"
103 :
104 : #ifdef XP_WIN
105 : #include "mozilla/plugins/PluginWidgetParent.h"
106 : #endif
107 :
108 : #if defined(XP_WIN) && defined(ACCESSIBILITY)
109 : #include "mozilla/a11y/AccessibleWrap.h"
110 : #include "mozilla/a11y/nsWinUtils.h"
111 : #endif
112 :
113 : using namespace mozilla::dom;
114 : using namespace mozilla::ipc;
115 : using namespace mozilla::layers;
116 : using namespace mozilla::layout;
117 : using namespace mozilla::services;
118 : using namespace mozilla::widget;
119 : using namespace mozilla::jsipc;
120 : using namespace mozilla::gfx;
121 :
122 : using mozilla::Unused;
123 :
124 : // The flags passed by the webProgress notifications are 16 bits shifted
125 : // from the ones registered by webProgressListeners.
126 : #define NOTIFY_FLAG_SHIFT 16
127 :
128 : namespace mozilla {
129 : namespace dom {
130 :
131 : TabParent::LayerToTabParentTable* TabParent::sLayerToTabParentTable = nullptr;
132 :
133 95 : NS_IMPL_ISUPPORTS(TabParent,
134 : nsITabParent,
135 : nsIAuthPromptProvider,
136 : nsISecureBrowserUI,
137 : nsISupportsWeakReference,
138 : nsIWebBrowserPersistable)
139 :
140 1 : TabParent::TabParent(nsIContentParent* aManager,
141 : const TabId& aTabId,
142 : const TabContext& aContext,
143 1 : uint32_t aChromeFlags)
144 : : TabContext(aContext)
145 : , mFrameElement(nullptr)
146 : , mContentCache(*this)
147 : , mRect(0, 0, 0, 0)
148 : , mDimensions(0, 0)
149 : , mOrientation(0)
150 : , mDPI(0)
151 : , mRounding(0)
152 : , mDefaultScale(0)
153 : , mUpdatedDimensions(false)
154 : , mSizeMode(nsSizeMode_Normal)
155 : , mManager(aManager)
156 : , mDocShellIsActive(false)
157 : , mMarkedDestroying(false)
158 : , mIsDestroyed(false)
159 : , mChromeFlags(aChromeFlags)
160 : , mDragValid(false)
161 : , mInitedByParent(false)
162 : , mTabId(aTabId)
163 : , mCreatingWindow(false)
164 : , mCursor(nsCursor(-1))
165 : , mTabSetsCursor(false)
166 : , mHasContentOpener(false)
167 : #ifdef DEBUG
168 : , mActiveSupressDisplayportCount(0)
169 : #endif
170 : , mLayerTreeEpoch(0)
171 : , mPreserveLayers(false)
172 : , mHasPresented(false)
173 1 : , mHasBeforeUnload(false)
174 : {
175 1 : MOZ_ASSERT(aManager);
176 1 : }
177 :
178 0 : TabParent::~TabParent()
179 : {
180 0 : }
181 :
182 : TabParent*
183 1 : TabParent::GetTabParentFromLayersId(uint64_t aLayersId)
184 : {
185 1 : if (!sLayerToTabParentTable) {
186 0 : return nullptr;
187 : }
188 1 : return sLayerToTabParentTable->Get(aLayersId);
189 : }
190 :
191 : void
192 1 : TabParent::AddTabParentToTable(uint64_t aLayersId, TabParent* aTabParent)
193 : {
194 1 : if (!sLayerToTabParentTable) {
195 1 : sLayerToTabParentTable = new LayerToTabParentTable();
196 : }
197 1 : sLayerToTabParentTable->Put(aLayersId, aTabParent);
198 1 : }
199 :
200 : void
201 0 : TabParent::RemoveTabParentFromTable(uint64_t aLayersId)
202 : {
203 0 : if (!sLayerToTabParentTable) {
204 0 : return;
205 : }
206 0 : sLayerToTabParentTable->Remove(aLayersId);
207 0 : if (sLayerToTabParentTable->Count() == 0) {
208 0 : delete sLayerToTabParentTable;
209 0 : sLayerToTabParentTable = nullptr;
210 : }
211 : }
212 :
213 : void
214 0 : TabParent::CacheFrameLoader(nsFrameLoader* aFrameLoader)
215 : {
216 0 : mFrameLoader = aFrameLoader;
217 0 : }
218 :
219 : /**
220 : * Will return nullptr if there is no outer window available for the
221 : * document hosting the owner element of this TabParent. Also will return
222 : * nullptr if that outer window is in the process of closing.
223 : */
224 : already_AddRefed<nsPIDOMWindowOuter>
225 0 : TabParent::GetParentWindowOuter()
226 : {
227 0 : nsCOMPtr<nsIContent> frame = do_QueryInterface(GetOwnerElement());
228 0 : if (!frame) {
229 0 : return nullptr;
230 : }
231 :
232 0 : nsCOMPtr<nsPIDOMWindowOuter> parent = frame->OwnerDoc()->GetWindow();
233 0 : if (!parent || parent->Closed()) {
234 0 : return nullptr;
235 : }
236 :
237 0 : return parent.forget();
238 : }
239 :
240 : void
241 1 : TabParent::SetOwnerElement(Element* aElement)
242 : {
243 : // If we held previous content then unregister for its events.
244 1 : RemoveWindowListeners();
245 :
246 : // If we change top-level documents then we need to change our
247 : // registration with them.
248 2 : RefPtr<nsPIWindowRoot> curTopLevelWin, newTopLevelWin;
249 1 : if (mFrameElement) {
250 0 : curTopLevelWin = nsContentUtils::GetWindowRoot(mFrameElement->OwnerDoc());
251 : }
252 1 : if (aElement) {
253 1 : newTopLevelWin = nsContentUtils::GetWindowRoot(aElement->OwnerDoc());
254 : }
255 1 : bool isSameTopLevelWin = curTopLevelWin == newTopLevelWin;
256 1 : if (curTopLevelWin && !isSameTopLevelWin) {
257 0 : curTopLevelWin->RemoveBrowser(this);
258 : }
259 :
260 : // Update to the new content, and register to listen for events from it.
261 1 : mFrameElement = aElement;
262 :
263 1 : if (newTopLevelWin && !isSameTopLevelWin) {
264 1 : newTopLevelWin->AddBrowser(this);
265 : }
266 :
267 1 : if (mFrameElement) {
268 : bool useGlobalHistory =
269 1 : !mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::disableglobalhistory);
270 1 : Unused << SendSetUseGlobalHistory(useGlobalHistory);
271 : }
272 :
273 : #if defined(XP_WIN) && defined(ACCESSIBILITY)
274 : if (!mIsDestroyed) {
275 : uintptr_t newWindowHandle = 0;
276 : if (nsCOMPtr<nsIWidget> widget = GetWidget()) {
277 : newWindowHandle =
278 : reinterpret_cast<uintptr_t>(widget->GetNativeData(NS_NATIVE_WINDOW));
279 : }
280 : Unused << SendUpdateNativeWindowHandle(newWindowHandle);
281 : a11y::DocAccessibleParent* doc = GetTopLevelDocAccessible();
282 : if (doc) {
283 : HWND hWnd = reinterpret_cast<HWND>(doc->GetEmulatedWindowHandle());
284 : if (hWnd) {
285 : HWND parentHwnd = reinterpret_cast<HWND>(newWindowHandle);
286 : if (parentHwnd != ::GetParent(hWnd)) {
287 : ::SetParent(hWnd, parentHwnd);
288 : }
289 : }
290 : }
291 : }
292 : #endif
293 :
294 1 : AddWindowListeners();
295 1 : TryCacheDPIAndScale();
296 :
297 : // Try to send down WidgetNativeData, now that this TabParent is associated
298 : // with a widget.
299 2 : nsCOMPtr<nsIWidget> widget = GetTopLevelWidget();
300 1 : if (widget) {
301 : WindowsHandle widgetNativeData = reinterpret_cast<WindowsHandle>(
302 1 : widget->GetNativeData(NS_NATIVE_SHAREABLE_WINDOW));
303 1 : if (widgetNativeData) {
304 1 : Unused << SendSetWidgetNativeData(widgetNativeData);
305 : }
306 : }
307 1 : }
308 :
309 : void
310 1 : TabParent::AddWindowListeners()
311 : {
312 1 : if (mFrameElement && mFrameElement->OwnerDoc()) {
313 2 : if (nsCOMPtr<nsPIDOMWindowOuter> window = mFrameElement->OwnerDoc()->GetWindow()) {
314 2 : nsCOMPtr<EventTarget> eventTarget = window->GetTopWindowRoot();
315 1 : if (eventTarget) {
316 3 : eventTarget->AddEventListener(NS_LITERAL_STRING("MozUpdateWindowPos"),
317 2 : this, false, false);
318 : }
319 : }
320 : }
321 1 : }
322 :
323 : void
324 1 : TabParent::RemoveWindowListeners()
325 : {
326 1 : if (mFrameElement && mFrameElement->OwnerDoc()->GetWindow()) {
327 0 : nsCOMPtr<nsPIDOMWindowOuter> window = mFrameElement->OwnerDoc()->GetWindow();
328 0 : nsCOMPtr<EventTarget> eventTarget = window->GetTopWindowRoot();
329 0 : if (eventTarget) {
330 0 : eventTarget->RemoveEventListener(NS_LITERAL_STRING("MozUpdateWindowPos"),
331 0 : this, false);
332 : }
333 : }
334 1 : }
335 :
336 : void
337 0 : TabParent::DestroyInternal()
338 : {
339 0 : IMEStateManager::OnTabParentDestroying(this);
340 :
341 0 : RemoveWindowListeners();
342 :
343 : #ifdef ACCESSIBILITY
344 0 : if (a11y::DocAccessibleParent* tabDoc = GetTopLevelDocAccessible()) {
345 0 : tabDoc->Destroy();
346 : }
347 : #endif
348 :
349 : // If this fails, it's most likely due to a content-process crash,
350 : // and auto-cleanup will kick in. Otherwise, the child side will
351 : // destroy itself and send back __delete__().
352 0 : Unused << SendDestroy();
353 :
354 0 : if (RenderFrameParent* frame = GetRenderFrame()) {
355 0 : RemoveTabParentFromTable(frame->GetLayersId());
356 0 : frame->Destroy();
357 : }
358 :
359 : #ifdef XP_WIN
360 : // Let all PluginWidgets know we are tearing down. Prevents
361 : // these objects from sending async events after the child side
362 : // is shut down.
363 : const ManagedContainer<PPluginWidgetParent>& kids =
364 : ManagedPPluginWidgetParent();
365 : for (auto iter = kids.ConstIter(); !iter.Done(); iter.Next()) {
366 : static_cast<mozilla::plugins::PluginWidgetParent*>(
367 : iter.Get()->GetKey())->ParentDestroy();
368 : }
369 : #endif
370 0 : }
371 :
372 : void
373 0 : TabParent::Destroy()
374 : {
375 : // Aggressively release the window to avoid leaking the world in shutdown
376 : // corner cases.
377 0 : mBrowserDOMWindow = nullptr;
378 :
379 0 : if (mIsDestroyed) {
380 0 : return;
381 : }
382 :
383 0 : DestroyInternal();
384 :
385 0 : mIsDestroyed = true;
386 :
387 0 : if (XRE_IsParentProcess()) {
388 0 : ContentParent::NotifyTabDestroying(this->GetTabId(), Manager()->AsContentParent()->ChildID());
389 : } else {
390 0 : ContentParent::NotifyTabDestroying(this->GetTabId(), Manager()->ChildID());
391 : }
392 :
393 0 : mMarkedDestroying = true;
394 : }
395 :
396 : mozilla::ipc::IPCResult
397 0 : TabParent::RecvEnsureLayersConnected(CompositorOptions* aCompositorOptions)
398 : {
399 0 : if (RenderFrameParent* frame = GetRenderFrame()) {
400 0 : frame->EnsureLayersConnected(aCompositorOptions);
401 : }
402 0 : return IPC_OK();
403 : }
404 :
405 : mozilla::ipc::IPCResult
406 0 : TabParent::Recv__delete__()
407 : {
408 0 : if (XRE_IsParentProcess()) {
409 0 : ContentParent::UnregisterRemoteFrame(mTabId,
410 0 : Manager()->AsContentParent()->ChildID(),
411 0 : mMarkedDestroying);
412 : }
413 : else {
414 0 : Manager()->AsContentBridgeParent()->NotifyTabDestroyed();
415 0 : ContentParent::UnregisterRemoteFrame(mTabId,
416 0 : Manager()->ChildID(),
417 0 : mMarkedDestroying);
418 : }
419 :
420 0 : return IPC_OK();
421 : }
422 :
423 : void
424 0 : TabParent::ActorDestroy(ActorDestroyReason why)
425 : {
426 : // Even though TabParent::Destroy calls this, we need to do it here too in
427 : // case of a crash.
428 0 : IMEStateManager::OnTabParentDestroying(this);
429 :
430 : // Prevent executing ContentParent::NotifyTabDestroying in
431 : // TabParent::Destroy() called by frameLoader->DestroyComplete() below
432 : // when tab crashes in contentprocess because ContentParent::ActorDestroy()
433 : // in main process will be triggered before this function
434 : // and remove the process information that
435 : // ContentParent::NotifyTabDestroying need from mContentParentMap.
436 :
437 : // When tab crashes in content process,
438 : // there is no need to call ContentParent::NotifyTabDestroying
439 : // because the jobs in ContentParent::NotifyTabDestroying
440 : // will be done by ContentParent::ActorDestroy.
441 0 : if (XRE_IsContentProcess() && why == AbnormalShutdown && !mIsDestroyed) {
442 0 : DestroyInternal();
443 0 : mIsDestroyed = true;
444 : }
445 :
446 0 : RefPtr<nsFrameLoader> frameLoader = GetFrameLoader(true);
447 0 : nsCOMPtr<nsIObserverService> os = services::GetObserverService();
448 0 : if (frameLoader) {
449 0 : nsCOMPtr<Element> frameElement(mFrameElement);
450 0 : ReceiveMessage(CHILD_PROCESS_SHUTDOWN_MESSAGE, false, nullptr, nullptr,
451 0 : nullptr);
452 0 : frameLoader->DestroyComplete();
453 :
454 0 : if (why == AbnormalShutdown && os) {
455 0 : os->NotifyObservers(NS_ISUPPORTS_CAST(nsIFrameLoader*, frameLoader),
456 0 : "oop-frameloader-crashed", nullptr);
457 0 : nsCOMPtr<nsIFrameLoaderOwner> owner = do_QueryInterface(frameElement);
458 0 : if (owner) {
459 0 : RefPtr<nsFrameLoader> currentFrameLoader = owner->GetFrameLoader();
460 : // It's possible that the frameloader owner has already moved on
461 : // and created a new frameloader. If so, we don't fire the event,
462 : // since the frameloader owner has clearly moved on.
463 0 : if (currentFrameLoader == frameLoader) {
464 0 : nsContentUtils::DispatchTrustedEvent(frameElement->OwnerDoc(), frameElement,
465 0 : NS_LITERAL_STRING("oop-browser-crashed"),
466 0 : true, true);
467 :
468 : }
469 : }
470 : }
471 :
472 0 : mFrameLoader = nullptr;
473 : }
474 :
475 0 : if (os) {
476 0 : os->NotifyObservers(NS_ISUPPORTS_CAST(nsITabParent*, this), "ipc:browser-destroyed", nullptr);
477 : }
478 0 : }
479 :
480 : mozilla::ipc::IPCResult
481 0 : TabParent::RecvMoveFocus(const bool& aForward, const bool& aForDocumentNavigation)
482 : {
483 0 : nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
484 0 : if (fm) {
485 0 : nsCOMPtr<nsIDOMElement> dummy;
486 :
487 0 : uint32_t type = aForward ?
488 0 : (aForDocumentNavigation ? static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_FORWARDDOC) :
489 : static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_FORWARD)) :
490 0 : (aForDocumentNavigation ? static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_BACKWARDDOC) :
491 0 : static_cast<uint32_t>(nsIFocusManager::MOVEFOCUS_BACKWARD));
492 0 : nsCOMPtr<nsIDOMElement> frame = do_QueryInterface(mFrameElement);
493 0 : fm->MoveFocus(nullptr, frame, type, nsIFocusManager::FLAG_BYKEY,
494 0 : getter_AddRefs(dummy));
495 : }
496 0 : return IPC_OK();
497 : }
498 :
499 : mozilla::ipc::IPCResult
500 0 : TabParent::RecvSizeShellTo(const uint32_t& aFlags, const int32_t& aWidth, const int32_t& aHeight,
501 : const int32_t& aShellItemWidth, const int32_t& aShellItemHeight)
502 : {
503 0 : NS_ENSURE_TRUE(mFrameElement, IPC_OK());
504 :
505 0 : nsCOMPtr<nsIDocShell> docShell = mFrameElement->OwnerDoc()->GetDocShell();
506 0 : NS_ENSURE_TRUE(docShell, IPC_OK());
507 :
508 0 : nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
509 0 : nsresult rv = docShell->GetTreeOwner(getter_AddRefs(treeOwner));
510 0 : NS_ENSURE_SUCCESS(rv, IPC_OK());
511 :
512 0 : int32_t width = aWidth;
513 0 : int32_t height = aHeight;
514 :
515 0 : if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_CX) {
516 0 : width = mDimensions.width;
517 : }
518 :
519 0 : if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_CY) {
520 0 : height = mDimensions.height;
521 : }
522 :
523 0 : nsCOMPtr<nsIXULWindow> xulWin(do_GetInterface(treeOwner));
524 0 : NS_ENSURE_TRUE(xulWin, IPC_OK());
525 0 : xulWin->SizeShellToWithLimit(width, height, aShellItemWidth, aShellItemHeight);
526 :
527 0 : return IPC_OK();
528 : }
529 :
530 : mozilla::ipc::IPCResult
531 0 : TabParent::RecvDropLinks(nsTArray<nsString>&& aLinks)
532 : {
533 0 : nsCOMPtr<nsIBrowser> browser = do_QueryInterface(mFrameElement);
534 0 : if (browser) {
535 0 : UniquePtr<const char16_t*[]> links;
536 0 : links = MakeUnique<const char16_t*[]>(aLinks.Length());
537 0 : for (uint32_t i = 0; i < aLinks.Length(); i++) {
538 0 : links[i] = aLinks[i].get();
539 : }
540 0 : browser->DropLinks(aLinks.Length(), links.get());
541 : }
542 0 : return IPC_OK();
543 : }
544 :
545 : mozilla::ipc::IPCResult
546 0 : TabParent::RecvEvent(const RemoteDOMEvent& aEvent)
547 : {
548 0 : nsCOMPtr<nsIDOMEvent> event = do_QueryInterface(aEvent.mEvent);
549 0 : NS_ENSURE_TRUE(event, IPC_OK());
550 :
551 0 : nsCOMPtr<mozilla::dom::EventTarget> target = do_QueryInterface(mFrameElement);
552 0 : NS_ENSURE_TRUE(target, IPC_OK());
553 :
554 0 : event->SetOwner(target);
555 :
556 : bool dummy;
557 0 : target->DispatchEvent(event, &dummy);
558 0 : return IPC_OK();
559 : }
560 :
561 : bool
562 12 : TabParent::SendLoadRemoteScript(const nsString& aURL,
563 : const bool& aRunInGlobalScope)
564 : {
565 12 : if (mCreatingWindow) {
566 0 : mDelayedFrameScripts.AppendElement(FrameScriptInfo(aURL, aRunInGlobalScope));
567 0 : return true;
568 : }
569 :
570 12 : MOZ_ASSERT(mDelayedFrameScripts.IsEmpty());
571 12 : return PBrowserParent::SendLoadRemoteScript(aURL, aRunInGlobalScope);
572 : }
573 :
574 : void
575 1 : TabParent::LoadURL(nsIURI* aURI)
576 : {
577 1 : MOZ_ASSERT(aURI);
578 :
579 1 : if (mIsDestroyed) {
580 0 : return;
581 : }
582 :
583 2 : nsCString spec;
584 1 : aURI->GetSpec(spec);
585 :
586 1 : if (mCreatingWindow) {
587 : // Don't send the message if the child wants to load its own URL.
588 0 : MOZ_ASSERT(mDelayedURL.IsEmpty());
589 0 : mDelayedURL = spec;
590 0 : return;
591 : }
592 :
593 1 : Unused << SendLoadURL(spec, GetShowInfo());
594 : }
595 :
596 : void
597 1 : TabParent::InitRenderFrame()
598 : {
599 1 : if (IsInitedByParent()) {
600 : // If TabParent is initialized by parent side then the RenderFrame must also
601 : // be created here. If TabParent is initialized by child side,
602 : // child side will create RenderFrame.
603 1 : MOZ_ASSERT(!GetRenderFrame());
604 2 : RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
605 1 : MOZ_ASSERT(frameLoader);
606 1 : if (frameLoader) {
607 2 : RenderFrameParent* renderFrame = new RenderFrameParent(frameLoader);
608 1 : MOZ_ASSERT(renderFrame->IsInitted());
609 1 : uint64_t layersId = renderFrame->GetLayersId();
610 1 : AddTabParentToTable(layersId, this);
611 1 : if (!SendPRenderFrameConstructor(renderFrame)) {
612 0 : return;
613 : }
614 :
615 1 : TextureFactoryIdentifier textureFactoryIdentifier;
616 1 : renderFrame->GetTextureFactoryIdentifier(&textureFactoryIdentifier);
617 1 : Unused << SendInitRendering(textureFactoryIdentifier, layersId,
618 2 : renderFrame->GetCompositorOptions(),
619 2 : renderFrame->IsLayersConnected(), renderFrame);
620 : }
621 : } else {
622 : // Otherwise, the child should have constructed the RenderFrame,
623 : // and we should already know about it.
624 0 : MOZ_ASSERT(GetRenderFrame());
625 : }
626 : }
627 :
628 : void
629 1 : TabParent::Show(const ScreenIntSize& size, bool aParentIsActive)
630 : {
631 1 : mDimensions = size;
632 1 : if (mIsDestroyed) {
633 0 : return;
634 : }
635 :
636 1 : MOZ_ASSERT(GetRenderFrame());
637 :
638 2 : nsCOMPtr<nsISupports> container = mFrameElement->OwnerDoc()->GetContainer();
639 2 : nsCOMPtr<nsIBaseWindow> baseWindow = do_QueryInterface(container);
640 2 : nsCOMPtr<nsIWidget> mainWidget;
641 1 : baseWindow->GetMainWidget(getter_AddRefs(mainWidget));
642 1 : mSizeMode = mainWidget ? mainWidget->SizeMode() : nsSizeMode_Normal;
643 :
644 1 : Unused << SendShow(size, GetShowInfo(), aParentIsActive, mSizeMode);
645 : }
646 :
647 : mozilla::ipc::IPCResult
648 0 : TabParent::RecvSetDimensions(const uint32_t& aFlags,
649 : const int32_t& aX, const int32_t& aY,
650 : const int32_t& aCx, const int32_t& aCy)
651 : {
652 0 : MOZ_ASSERT(!(aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_INNER),
653 : "We should never see DIM_FLAGS_SIZE_INNER here!");
654 :
655 0 : NS_ENSURE_TRUE(mFrameElement, IPC_OK());
656 0 : nsCOMPtr<nsIDocShell> docShell = mFrameElement->OwnerDoc()->GetDocShell();
657 0 : NS_ENSURE_TRUE(docShell, IPC_OK());
658 0 : nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
659 0 : docShell->GetTreeOwner(getter_AddRefs(treeOwner));
660 0 : nsCOMPtr<nsIBaseWindow> treeOwnerAsWin = do_QueryInterface(treeOwner);
661 0 : NS_ENSURE_TRUE(treeOwnerAsWin, IPC_OK());
662 :
663 : // We only care about the parameters that actually changed, see more
664 : // details in TabChild::SetDimensions.
665 : int32_t unused;
666 0 : int32_t x = aX;
667 0 : if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_X) {
668 0 : treeOwnerAsWin->GetPosition(&x, &unused);
669 : }
670 :
671 0 : int32_t y = aY;
672 0 : if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_Y) {
673 0 : treeOwnerAsWin->GetPosition(&unused, &y);
674 : }
675 :
676 0 : int32_t cx = aCx;
677 0 : if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_CX) {
678 0 : treeOwnerAsWin->GetSize(&cx, &unused);
679 : }
680 :
681 0 : int32_t cy = aCy;
682 0 : if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_IGNORE_CY) {
683 0 : treeOwnerAsWin->GetSize(&unused, &cy);
684 : }
685 :
686 0 : if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION &&
687 0 : aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER) {
688 0 : treeOwnerAsWin->SetPositionAndSize(x, y, cx, cy,
689 0 : nsIBaseWindow::eRepaint);
690 0 : return IPC_OK();
691 : }
692 :
693 0 : if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_POSITION) {
694 0 : treeOwnerAsWin->SetPosition(x, y);
695 0 : mUpdatedDimensions = false;
696 0 : UpdatePosition();
697 0 : return IPC_OK();
698 : }
699 :
700 0 : if (aFlags & nsIEmbeddingSiteWindow::DIM_FLAGS_SIZE_OUTER) {
701 0 : treeOwnerAsWin->SetSize(cx, cy, true);
702 0 : return IPC_OK();
703 : }
704 :
705 0 : MOZ_ASSERT(false, "Unknown flags!");
706 : return IPC_FAIL_NO_REASON(this);
707 : }
708 :
709 : nsresult
710 5 : TabParent::UpdatePosition()
711 : {
712 10 : RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
713 5 : if (!frameLoader) {
714 0 : return NS_OK;
715 : }
716 5 : nsIntRect windowDims;
717 5 : NS_ENSURE_SUCCESS(frameLoader->GetWindowDimensions(windowDims), NS_ERROR_FAILURE);
718 5 : UpdateDimensions(windowDims, mDimensions);
719 5 : return NS_OK;
720 : }
721 :
722 : void
723 8 : TabParent::UpdateDimensions(const nsIntRect& rect, const ScreenIntSize& size)
724 : {
725 8 : if (mIsDestroyed) {
726 0 : return;
727 : }
728 16 : nsCOMPtr<nsIWidget> widget = GetWidget();
729 8 : if (!widget) {
730 0 : NS_WARNING("No widget found in TabParent::UpdateDimensions");
731 0 : return;
732 : }
733 :
734 16 : hal::ScreenConfiguration config;
735 8 : hal::GetCurrentScreenConfiguration(&config);
736 8 : ScreenOrientationInternal orientation = config.orientation();
737 8 : LayoutDeviceIntPoint clientOffset = widget->GetClientOffset();
738 8 : LayoutDeviceIntPoint chromeOffset = -GetChildProcessOffset();
739 :
740 30 : if (!mUpdatedDimensions || mOrientation != orientation ||
741 16 : mDimensions != size || !mRect.IsEqualEdges(rect) ||
742 16 : clientOffset != mClientOffset ||
743 4 : chromeOffset != mChromeOffset) {
744 :
745 4 : mUpdatedDimensions = true;
746 4 : mRect = rect;
747 4 : mDimensions = size;
748 4 : mOrientation = orientation;
749 4 : mClientOffset = clientOffset;
750 4 : mChromeOffset = chromeOffset;
751 :
752 4 : Unused << SendUpdateDimensions(GetDimensionInfo());
753 : }
754 : }
755 :
756 : DimensionInfo
757 4 : TabParent::GetDimensionInfo()
758 : {
759 8 : nsCOMPtr<nsIWidget> widget = GetWidget();
760 4 : MOZ_ASSERT(widget);
761 4 : CSSToLayoutDeviceScale widgetScale = widget->GetDefaultScale();
762 :
763 : LayoutDeviceIntRect devicePixelRect =
764 : ViewAs<LayoutDevicePixel>(mRect,
765 4 : PixelCastJustification::LayoutDeviceIsScreenForTabDims);
766 : LayoutDeviceIntSize devicePixelSize =
767 : ViewAs<LayoutDevicePixel>(mDimensions,
768 4 : PixelCastJustification::LayoutDeviceIsScreenForTabDims);
769 :
770 4 : CSSRect unscaledRect = devicePixelRect / widgetScale;
771 4 : CSSSize unscaledSize = devicePixelSize / widgetScale;
772 : DimensionInfo di(unscaledRect, unscaledSize, mOrientation,
773 4 : mClientOffset, mChromeOffset);
774 8 : return di;
775 : }
776 :
777 : void
778 1 : TabParent::SizeModeChanged(const nsSizeMode& aSizeMode)
779 : {
780 1 : if (!mIsDestroyed && aSizeMode != mSizeMode) {
781 1 : mSizeMode = aSizeMode;
782 1 : Unused << SendSizeModeChanged(aSizeMode);
783 : }
784 1 : }
785 :
786 : void
787 0 : TabParent::UIResolutionChanged()
788 : {
789 0 : if (!mIsDestroyed) {
790 : // TryCacheDPIAndScale()'s cache is keyed off of
791 : // mDPI being greater than 0, so this invalidates it.
792 0 : mDPI = -1;
793 0 : TryCacheDPIAndScale();
794 : // If mDPI was set to -1 to invalidate it and then TryCacheDPIAndScale
795 : // fails to cache the values, then mDefaultScale.scale might be invalid.
796 : // We don't want to send that value to content. Just send -1 for it too in
797 : // that case.
798 0 : Unused << SendUIResolutionChanged(mDPI, mRounding,
799 0 : mDPI < 0 ? -1.0 : mDefaultScale.scale);
800 : }
801 0 : }
802 :
803 : void
804 0 : TabParent::ThemeChanged()
805 : {
806 0 : if (!mIsDestroyed) {
807 : // The theme has changed, and any cached values we had sent down
808 : // to the child have been invalidated. When this method is called,
809 : // LookAndFeel should have the up-to-date values, which we now
810 : // send down to the child. We do this for every remote tab for now,
811 : // but bug 1156934 has been filed to do it once per content process.
812 0 : Unused << SendThemeChanged(LookAndFeel::GetIntCache());
813 : }
814 0 : }
815 :
816 : void
817 0 : TabParent::HandleAccessKey(const WidgetKeyboardEvent& aEvent,
818 : nsTArray<uint32_t>& aCharCodes,
819 : const int32_t& aModifierMask)
820 : {
821 0 : if (!mIsDestroyed) {
822 : // Note that we don't need to mark aEvent is posted to a remote process
823 : // because the event may be dispatched to it as normal keyboard event.
824 : // Therefore, we should use local copy to send it.
825 0 : WidgetKeyboardEvent localEvent(aEvent);
826 0 : Unused << SendHandleAccessKey(localEvent, aCharCodes, aModifierMask);
827 : }
828 0 : }
829 :
830 : void
831 1 : TabParent::Activate()
832 : {
833 1 : if (!mIsDestroyed) {
834 1 : Unused << Manager()->SendActivate(this);
835 : }
836 1 : }
837 :
838 : void
839 0 : TabParent::Deactivate()
840 : {
841 0 : if (!mIsDestroyed) {
842 0 : Unused << Manager()->SendDeactivate(this);
843 : }
844 0 : }
845 :
846 : NS_IMETHODIMP
847 0 : TabParent::Init(mozIDOMWindowProxy *window)
848 : {
849 0 : return NS_OK;
850 : }
851 :
852 : NS_IMETHODIMP
853 0 : TabParent::GetState(uint32_t *aState)
854 : {
855 0 : NS_ENSURE_ARG(aState);
856 0 : NS_WARNING("SecurityState not valid here");
857 0 : *aState = 0;
858 0 : return NS_OK;
859 : }
860 :
861 : NS_IMETHODIMP
862 0 : TabParent::SetDocShell(nsIDocShell *aDocShell)
863 : {
864 0 : NS_ENSURE_ARG(aDocShell);
865 0 : NS_WARNING("No mDocShell member in TabParent so there is no docShell to set");
866 0 : return NS_OK;
867 : }
868 :
869 : a11y::PDocAccessibleParent*
870 0 : TabParent::AllocPDocAccessibleParent(PDocAccessibleParent* aParent,
871 : const uint64_t&, const uint32_t&,
872 : const IAccessibleHolder&)
873 : {
874 : #ifdef ACCESSIBILITY
875 0 : return new a11y::DocAccessibleParent();
876 : #else
877 : return nullptr;
878 : #endif
879 : }
880 :
881 : bool
882 0 : TabParent::DeallocPDocAccessibleParent(PDocAccessibleParent* aParent)
883 : {
884 : #ifdef ACCESSIBILITY
885 0 : delete static_cast<a11y::DocAccessibleParent*>(aParent);
886 : #endif
887 0 : return true;
888 : }
889 :
890 : mozilla::ipc::IPCResult
891 0 : TabParent::RecvPDocAccessibleConstructor(PDocAccessibleParent* aDoc,
892 : PDocAccessibleParent* aParentDoc,
893 : const uint64_t& aParentID,
894 : const uint32_t& aMsaaID,
895 : const IAccessibleHolder& aDocCOMProxy)
896 : {
897 : #ifdef ACCESSIBILITY
898 0 : auto doc = static_cast<a11y::DocAccessibleParent*>(aDoc);
899 :
900 : // If this tab is already shutting down just mark the new actor as shutdown
901 : // and ignore it. When the tab actor is destroyed it will be too.
902 0 : if (mIsDestroyed) {
903 0 : doc->MarkAsShutdown();
904 0 : return IPC_OK();
905 : }
906 :
907 0 : if (aParentDoc) {
908 : // A document should never directly be the parent of another document.
909 : // There should always be an outer doc accessible child of the outer
910 : // document containing the child.
911 0 : MOZ_ASSERT(aParentID);
912 0 : if (!aParentID) {
913 0 : return IPC_FAIL_NO_REASON(this);
914 : }
915 :
916 0 : auto parentDoc = static_cast<a11y::DocAccessibleParent*>(aParentDoc);
917 0 : mozilla::ipc::IPCResult added = parentDoc->AddChildDoc(doc, aParentID);
918 0 : if (!added) {
919 : #ifdef DEBUG
920 0 : return added;
921 : #else
922 : return IPC_OK();
923 : #endif
924 : }
925 :
926 : #ifdef XP_WIN
927 : MOZ_ASSERT(aDocCOMProxy.IsNull());
928 : a11y::WrapperFor(doc)->SetID(aMsaaID);
929 : if (a11y::nsWinUtils::IsWindowEmulationStarted()) {
930 : doc->SetEmulatedWindowHandle(parentDoc->GetEmulatedWindowHandle());
931 : }
932 : #endif
933 :
934 0 : return IPC_OK();
935 : } else {
936 : // null aParentDoc means this document is at the top level in the child
937 : // process. That means it makes no sense to get an id for an accessible
938 : // that is its parent.
939 0 : MOZ_ASSERT(!aParentID);
940 0 : if (aParentID) {
941 0 : return IPC_FAIL_NO_REASON(this);
942 : }
943 :
944 0 : doc->SetTopLevel();
945 0 : a11y::DocManager::RemoteDocAdded(doc);
946 : #ifdef XP_WIN
947 : a11y::WrapperFor(doc)->SetID(aMsaaID);
948 : MOZ_ASSERT(!aDocCOMProxy.IsNull());
949 : if (aDocCOMProxy.IsNull()) {
950 : return IPC_FAIL(this, "Constructing a top-level PDocAccessible with null COM proxy");
951 : }
952 :
953 : RefPtr<IAccessible> proxy(aDocCOMProxy.Get());
954 : doc->SetCOMInterface(proxy);
955 : doc->MaybeInitWindowEmulation();
956 : doc->SendParentCOMProxy();
957 : #endif
958 : }
959 : #endif
960 0 : return IPC_OK();
961 : }
962 :
963 : a11y::DocAccessibleParent*
964 0 : TabParent::GetTopLevelDocAccessible() const
965 : {
966 : #ifdef ACCESSIBILITY
967 : // XXX Consider managing non top level PDocAccessibles with their parent
968 : // document accessible.
969 0 : const ManagedContainer<PDocAccessibleParent>& docs = ManagedPDocAccessibleParent();
970 0 : for (auto iter = docs.ConstIter(); !iter.Done(); iter.Next()) {
971 0 : auto doc = static_cast<a11y::DocAccessibleParent*>(iter.Get()->GetKey());
972 0 : if (doc->IsTopLevel()) {
973 0 : return doc;
974 : }
975 : }
976 :
977 0 : MOZ_ASSERT(docs.Count() == 0, "If there isn't a top level accessible doc "
978 : "there shouldn't be an accessible doc at all!");
979 : #endif
980 0 : return nullptr;
981 : }
982 :
983 : PDocumentRendererParent*
984 0 : TabParent::AllocPDocumentRendererParent(const nsRect& documentRect,
985 : const gfx::Matrix& transform,
986 : const nsString& bgcolor,
987 : const uint32_t& renderFlags,
988 : const bool& flushLayout,
989 : const nsIntSize& renderSize)
990 : {
991 0 : return new DocumentRendererParent();
992 : }
993 :
994 : bool
995 0 : TabParent::DeallocPDocumentRendererParent(PDocumentRendererParent* actor)
996 : {
997 0 : delete actor;
998 0 : return true;
999 : }
1000 :
1001 : PFilePickerParent*
1002 0 : TabParent::AllocPFilePickerParent(const nsString& aTitle, const int16_t& aMode)
1003 : {
1004 0 : return new FilePickerParent(aTitle, aMode);
1005 : }
1006 :
1007 : bool
1008 0 : TabParent::DeallocPFilePickerParent(PFilePickerParent* actor)
1009 : {
1010 0 : delete actor;
1011 0 : return true;
1012 : }
1013 :
1014 : auto
1015 0 : TabParent::AllocPIndexedDBPermissionRequestParent(const Principal& aPrincipal)
1016 : -> PIndexedDBPermissionRequestParent*
1017 : {
1018 0 : MOZ_ASSERT(NS_IsMainThread());
1019 :
1020 0 : nsCOMPtr<nsIPrincipal> principal(aPrincipal);
1021 0 : if (!principal) {
1022 0 : return nullptr;
1023 : }
1024 :
1025 0 : nsCOMPtr<nsIContentParent> manager = Manager();
1026 0 : if (!manager->IsContentParent()) {
1027 0 : MOZ_CRASH("Figure out security checks for bridged content!");
1028 : }
1029 :
1030 0 : if (NS_WARN_IF(!mFrameElement)) {
1031 0 : return nullptr;
1032 : }
1033 :
1034 : return
1035 0 : mozilla::dom::indexedDB::AllocPIndexedDBPermissionRequestParent(mFrameElement,
1036 0 : principal);
1037 : }
1038 :
1039 : mozilla::ipc::IPCResult
1040 0 : TabParent::RecvPIndexedDBPermissionRequestConstructor(
1041 : PIndexedDBPermissionRequestParent* aActor,
1042 : const Principal& aPrincipal)
1043 : {
1044 0 : MOZ_ASSERT(NS_IsMainThread());
1045 0 : MOZ_ASSERT(aActor);
1046 :
1047 0 : if (!mozilla::dom::indexedDB::RecvPIndexedDBPermissionRequestConstructor(aActor)) {
1048 0 : return IPC_FAIL_NO_REASON(this);
1049 : }
1050 0 : return IPC_OK();
1051 : }
1052 :
1053 : bool
1054 0 : TabParent::DeallocPIndexedDBPermissionRequestParent(
1055 : PIndexedDBPermissionRequestParent* aActor)
1056 : {
1057 0 : MOZ_ASSERT(NS_IsMainThread());
1058 0 : MOZ_ASSERT(aActor);
1059 :
1060 : return
1061 0 : mozilla::dom::indexedDB::DeallocPIndexedDBPermissionRequestParent(aActor);
1062 : }
1063 :
1064 : void
1065 0 : TabParent::SendMouseEvent(const nsAString& aType, float aX, float aY,
1066 : int32_t aButton, int32_t aClickCount,
1067 : int32_t aModifiers, bool aIgnoreRootScrollFrame)
1068 : {
1069 0 : if (!mIsDestroyed) {
1070 0 : Unused << PBrowserParent::SendMouseEvent(nsString(aType), aX, aY,
1071 : aButton, aClickCount,
1072 : aModifiers,
1073 : aIgnoreRootScrollFrame);
1074 : }
1075 0 : }
1076 :
1077 : void
1078 0 : TabParent::SendKeyEvent(const nsAString& aType,
1079 : int32_t aKeyCode,
1080 : int32_t aCharCode,
1081 : int32_t aModifiers,
1082 : bool aPreventDefault)
1083 : {
1084 0 : if (mIsDestroyed) {
1085 0 : return;
1086 : }
1087 0 : Unused << PBrowserParent::SendKeyEvent(nsString(aType), aKeyCode, aCharCode,
1088 : aModifiers, aPreventDefault);
1089 : }
1090 :
1091 : void
1092 6 : TabParent::SendRealMouseEvent(WidgetMouseEvent& aEvent)
1093 : {
1094 6 : if (mIsDestroyed) {
1095 4 : return;
1096 : }
1097 6 : aEvent.mRefPoint += GetChildProcessOffset();
1098 :
1099 8 : nsCOMPtr<nsIWidget> widget = GetWidget();
1100 6 : if (widget) {
1101 : // When we mouseenter the tab, the tab's cursor should
1102 : // become the current cursor. When we mouseexit, we stop.
1103 6 : if (eMouseEnterIntoWidget == aEvent.mMessage) {
1104 1 : mTabSetsCursor = true;
1105 1 : if (mCustomCursor) {
1106 0 : widget->SetCursor(mCustomCursor,
1107 0 : mCustomCursorHotspotX, mCustomCursorHotspotY);
1108 1 : } else if (mCursor != nsCursor(-1)) {
1109 0 : widget->SetCursor(mCursor);
1110 : }
1111 5 : } else if (eMouseExitFromWidget == aEvent.mMessage) {
1112 1 : mTabSetsCursor = false;
1113 : }
1114 : }
1115 :
1116 8 : ScrollableLayerGuid guid;
1117 : uint64_t blockId;
1118 6 : ApzAwareEventRoutingToChild(&guid, &blockId, nullptr);
1119 :
1120 6 : if (eMouseMove == aEvent.mMessage) {
1121 4 : if (aEvent.mReason == WidgetMouseEvent::eSynthesized) {
1122 0 : DebugOnly<bool> ret = SendSynthMouseMoveEvent(aEvent, guid, blockId);
1123 0 : NS_WARNING_ASSERTION(ret, "SendSynthMouseMoveEvent() failed");
1124 0 : MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
1125 0 : return;
1126 : }
1127 8 : DebugOnly<bool> ret = SendRealMouseMoveEvent(aEvent, guid, blockId);
1128 4 : NS_WARNING_ASSERTION(ret, "SendRealMouseMoveEvent() failed");
1129 4 : MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
1130 4 : return;
1131 : }
1132 :
1133 4 : DebugOnly<bool> ret = SendRealMouseButtonEvent(aEvent, guid, blockId);
1134 2 : NS_WARNING_ASSERTION(ret, "SendRealMouseButtonEvent() failed");
1135 2 : MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
1136 : }
1137 :
1138 : LayoutDeviceToCSSScale
1139 0 : TabParent::GetLayoutDeviceToCSSScale()
1140 : {
1141 0 : nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
1142 0 : nsIDocument* doc = (content ? content->OwnerDoc() : nullptr);
1143 0 : nsIPresShell* shell = (doc ? doc->GetShell() : nullptr);
1144 0 : nsPresContext* ctx = (shell ? shell->GetPresContext() : nullptr);
1145 : return LayoutDeviceToCSSScale(ctx
1146 0 : ? (float)ctx->AppUnitsPerDevPixel() / nsPresContext::AppUnitsPerCSSPixel()
1147 0 : : 0.0f);
1148 : }
1149 :
1150 : void
1151 0 : TabParent::SendRealDragEvent(WidgetDragEvent& aEvent, uint32_t aDragAction,
1152 : uint32_t aDropEffect)
1153 : {
1154 0 : if (mIsDestroyed) {
1155 0 : return;
1156 : }
1157 0 : aEvent.mRefPoint += GetChildProcessOffset();
1158 : DebugOnly<bool> ret =
1159 0 : PBrowserParent::SendRealDragEvent(aEvent, aDragAction, aDropEffect);
1160 0 : NS_WARNING_ASSERTION(ret, "PBrowserParent::SendRealDragEvent() failed");
1161 0 : MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
1162 : }
1163 :
1164 : LayoutDevicePoint
1165 0 : TabParent::AdjustTapToChildWidget(const LayoutDevicePoint& aPoint)
1166 : {
1167 0 : return aPoint + LayoutDevicePoint(GetChildProcessOffset());
1168 : }
1169 :
1170 : void
1171 0 : TabParent::SendMouseWheelEvent(WidgetWheelEvent& aEvent)
1172 : {
1173 0 : if (mIsDestroyed) {
1174 0 : return;
1175 : }
1176 :
1177 0 : ScrollableLayerGuid guid;
1178 : uint64_t blockId;
1179 0 : ApzAwareEventRoutingToChild(&guid, &blockId, nullptr);
1180 0 : aEvent.mRefPoint += GetChildProcessOffset();
1181 : DebugOnly<bool> ret =
1182 0 : PBrowserParent::SendMouseWheelEvent(aEvent, guid, blockId);
1183 0 : NS_WARNING_ASSERTION(ret, "PBrowserParent::SendMouseWheelEvent() failed");
1184 0 : MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
1185 : }
1186 :
1187 : mozilla::ipc::IPCResult
1188 0 : TabParent::RecvDispatchWheelEvent(const mozilla::WidgetWheelEvent& aEvent)
1189 : {
1190 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1191 0 : if (!widget) {
1192 0 : return IPC_OK();
1193 : }
1194 :
1195 0 : WidgetWheelEvent localEvent(aEvent);
1196 0 : localEvent.mWidget = widget;
1197 0 : localEvent.mRefPoint -= GetChildProcessOffset();
1198 :
1199 0 : widget->DispatchInputEvent(&localEvent);
1200 0 : return IPC_OK();
1201 : }
1202 :
1203 : mozilla::ipc::IPCResult
1204 0 : TabParent::RecvDispatchMouseEvent(const mozilla::WidgetMouseEvent& aEvent)
1205 : {
1206 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1207 0 : if (!widget) {
1208 0 : return IPC_OK();
1209 : }
1210 :
1211 0 : WidgetMouseEvent localEvent(aEvent);
1212 0 : localEvent.mWidget = widget;
1213 0 : localEvent.mRefPoint -= GetChildProcessOffset();
1214 :
1215 0 : widget->DispatchInputEvent(&localEvent);
1216 0 : return IPC_OK();
1217 : }
1218 :
1219 : mozilla::ipc::IPCResult
1220 0 : TabParent::RecvDispatchKeyboardEvent(const mozilla::WidgetKeyboardEvent& aEvent)
1221 : {
1222 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1223 0 : if (!widget) {
1224 0 : return IPC_OK();
1225 : }
1226 :
1227 0 : WidgetKeyboardEvent localEvent(aEvent);
1228 0 : localEvent.mWidget = widget;
1229 0 : localEvent.mRefPoint -= GetChildProcessOffset();
1230 :
1231 0 : widget->DispatchInputEvent(&localEvent);
1232 0 : return IPC_OK();
1233 : }
1234 :
1235 : mozilla::ipc::IPCResult
1236 0 : TabParent::RecvRequestNativeKeyBindings(const uint32_t& aType,
1237 : const WidgetKeyboardEvent& aEvent,
1238 : nsTArray<CommandInt>* aCommands)
1239 : {
1240 0 : MOZ_ASSERT(aCommands);
1241 0 : MOZ_ASSERT(aCommands->IsEmpty());
1242 :
1243 : nsIWidget::NativeKeyBindingsType keyBindingsType =
1244 0 : static_cast<nsIWidget::NativeKeyBindingsType>(aType);
1245 0 : switch (keyBindingsType) {
1246 : case nsIWidget::NativeKeyBindingsForSingleLineEditor:
1247 : case nsIWidget::NativeKeyBindingsForMultiLineEditor:
1248 : case nsIWidget::NativeKeyBindingsForRichTextEditor:
1249 0 : break;
1250 : default:
1251 0 : return IPC_FAIL(this, "Invalid aType value");
1252 : }
1253 :
1254 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1255 0 : if (!widget) {
1256 0 : return IPC_OK();
1257 : }
1258 :
1259 0 : WidgetKeyboardEvent localEvent(aEvent);
1260 0 : localEvent.mWidget = widget;
1261 :
1262 0 : if (NS_FAILED(widget->AttachNativeKeyEvent(localEvent))) {
1263 0 : return IPC_OK();
1264 : }
1265 :
1266 0 : localEvent.InitEditCommandsFor(keyBindingsType);
1267 0 : *aCommands = localEvent.EditCommandsConstRef(keyBindingsType);
1268 :
1269 0 : return IPC_OK();
1270 : }
1271 :
1272 : class SynthesizedEventObserver : public nsIObserver
1273 : {
1274 : NS_DECL_ISUPPORTS
1275 :
1276 : public:
1277 0 : SynthesizedEventObserver(TabParent* aTabParent, const uint64_t& aObserverId)
1278 0 : : mTabParent(aTabParent)
1279 0 : , mObserverId(aObserverId)
1280 : {
1281 0 : MOZ_ASSERT(mTabParent);
1282 0 : }
1283 :
1284 0 : NS_IMETHOD Observe(nsISupports* aSubject,
1285 : const char* aTopic,
1286 : const char16_t* aData) override
1287 : {
1288 0 : if (!mTabParent || !mObserverId) {
1289 : // We already sent the notification, or we don't actually need to
1290 : // send any notification at all.
1291 0 : return NS_OK;
1292 : }
1293 :
1294 0 : if (!mTabParent->SendNativeSynthesisResponse(mObserverId,
1295 0 : nsCString(aTopic))) {
1296 0 : NS_WARNING("Unable to send native event synthesization response!");
1297 : }
1298 : // Null out tabparent to indicate we already sent the response
1299 0 : mTabParent = nullptr;
1300 0 : return NS_OK;
1301 : }
1302 :
1303 : private:
1304 0 : virtual ~SynthesizedEventObserver() { }
1305 :
1306 : RefPtr<TabParent> mTabParent;
1307 : uint64_t mObserverId;
1308 : };
1309 :
1310 0 : NS_IMPL_ISUPPORTS(SynthesizedEventObserver, nsIObserver)
1311 :
1312 : class MOZ_STACK_CLASS AutoSynthesizedEventResponder
1313 : {
1314 : public:
1315 0 : AutoSynthesizedEventResponder(TabParent* aTabParent,
1316 : const uint64_t& aObserverId,
1317 : const char* aTopic)
1318 0 : : mObserver(new SynthesizedEventObserver(aTabParent, aObserverId))
1319 0 : , mTopic(aTopic)
1320 0 : { }
1321 :
1322 0 : ~AutoSynthesizedEventResponder()
1323 0 : {
1324 : // This may be a no-op if the observer already sent a response.
1325 0 : mObserver->Observe(nullptr, mTopic, nullptr);
1326 0 : }
1327 :
1328 0 : nsIObserver* GetObserver()
1329 : {
1330 0 : return mObserver;
1331 : }
1332 :
1333 : private:
1334 : nsCOMPtr<nsIObserver> mObserver;
1335 : const char* mTopic;
1336 : };
1337 :
1338 : mozilla::ipc::IPCResult
1339 0 : TabParent::RecvSynthesizeNativeKeyEvent(const int32_t& aNativeKeyboardLayout,
1340 : const int32_t& aNativeKeyCode,
1341 : const uint32_t& aModifierFlags,
1342 : const nsString& aCharacters,
1343 : const nsString& aUnmodifiedCharacters,
1344 : const uint64_t& aObserverId)
1345 : {
1346 0 : AutoSynthesizedEventResponder responder(this, aObserverId, "keyevent");
1347 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1348 0 : if (widget) {
1349 0 : widget->SynthesizeNativeKeyEvent(aNativeKeyboardLayout, aNativeKeyCode,
1350 : aModifierFlags, aCharacters,
1351 : aUnmodifiedCharacters,
1352 0 : responder.GetObserver());
1353 : }
1354 0 : return IPC_OK();
1355 : }
1356 :
1357 : mozilla::ipc::IPCResult
1358 0 : TabParent::RecvSynthesizeNativeMouseEvent(const LayoutDeviceIntPoint& aPoint,
1359 : const uint32_t& aNativeMessage,
1360 : const uint32_t& aModifierFlags,
1361 : const uint64_t& aObserverId)
1362 : {
1363 0 : AutoSynthesizedEventResponder responder(this, aObserverId, "mouseevent");
1364 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1365 0 : if (widget) {
1366 0 : widget->SynthesizeNativeMouseEvent(aPoint, aNativeMessage, aModifierFlags,
1367 0 : responder.GetObserver());
1368 : }
1369 0 : return IPC_OK();
1370 : }
1371 :
1372 : mozilla::ipc::IPCResult
1373 0 : TabParent::RecvSynthesizeNativeMouseMove(const LayoutDeviceIntPoint& aPoint,
1374 : const uint64_t& aObserverId)
1375 : {
1376 0 : AutoSynthesizedEventResponder responder(this, aObserverId, "mousemove");
1377 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1378 0 : if (widget) {
1379 0 : widget->SynthesizeNativeMouseMove(aPoint, responder.GetObserver());
1380 : }
1381 0 : return IPC_OK();
1382 : }
1383 :
1384 : mozilla::ipc::IPCResult
1385 0 : TabParent::RecvSynthesizeNativeMouseScrollEvent(
1386 : const LayoutDeviceIntPoint& aPoint,
1387 : const uint32_t& aNativeMessage,
1388 : const double& aDeltaX,
1389 : const double& aDeltaY,
1390 : const double& aDeltaZ,
1391 : const uint32_t& aModifierFlags,
1392 : const uint32_t& aAdditionalFlags,
1393 : const uint64_t& aObserverId)
1394 : {
1395 0 : AutoSynthesizedEventResponder responder(this, aObserverId, "mousescrollevent");
1396 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1397 0 : if (widget) {
1398 0 : widget->SynthesizeNativeMouseScrollEvent(aPoint, aNativeMessage,
1399 : aDeltaX, aDeltaY, aDeltaZ,
1400 : aModifierFlags, aAdditionalFlags,
1401 0 : responder.GetObserver());
1402 : }
1403 0 : return IPC_OK();
1404 : }
1405 :
1406 : mozilla::ipc::IPCResult
1407 0 : TabParent::RecvSynthesizeNativeTouchPoint(
1408 : const uint32_t& aPointerId,
1409 : const TouchPointerState& aPointerState,
1410 : const LayoutDeviceIntPoint& aPoint,
1411 : const double& aPointerPressure,
1412 : const uint32_t& aPointerOrientation,
1413 : const uint64_t& aObserverId)
1414 : {
1415 0 : AutoSynthesizedEventResponder responder(this, aObserverId, "touchpoint");
1416 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1417 0 : if (widget) {
1418 0 : widget->SynthesizeNativeTouchPoint(aPointerId, aPointerState, aPoint,
1419 : aPointerPressure, aPointerOrientation,
1420 0 : responder.GetObserver());
1421 : }
1422 0 : return IPC_OK();
1423 : }
1424 :
1425 : mozilla::ipc::IPCResult
1426 0 : TabParent::RecvSynthesizeNativeTouchTap(const LayoutDeviceIntPoint& aPoint,
1427 : const bool& aLongTap,
1428 : const uint64_t& aObserverId)
1429 : {
1430 0 : AutoSynthesizedEventResponder responder(this, aObserverId, "touchtap");
1431 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1432 0 : if (widget) {
1433 0 : widget->SynthesizeNativeTouchTap(aPoint, aLongTap, responder.GetObserver());
1434 : }
1435 0 : return IPC_OK();
1436 : }
1437 :
1438 : mozilla::ipc::IPCResult
1439 0 : TabParent::RecvClearNativeTouchSequence(const uint64_t& aObserverId)
1440 : {
1441 0 : AutoSynthesizedEventResponder responder(this, aObserverId, "cleartouch");
1442 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1443 0 : if (widget) {
1444 0 : widget->ClearNativeTouchSequence(responder.GetObserver());
1445 : }
1446 0 : return IPC_OK();
1447 : }
1448 :
1449 : void
1450 0 : TabParent::SendRealKeyEvent(WidgetKeyboardEvent& aEvent)
1451 : {
1452 0 : if (mIsDestroyed) {
1453 0 : return;
1454 : }
1455 0 : aEvent.mRefPoint += GetChildProcessOffset();
1456 :
1457 0 : if (aEvent.mMessage == eKeyPress) {
1458 : // XXX Should we do this only when input context indicates an editor having
1459 : // focus and the key event won't cause inputting text?
1460 0 : aEvent.InitAllEditCommands();
1461 : } else {
1462 0 : aEvent.PreventNativeKeyBindings();
1463 : }
1464 :
1465 0 : DebugOnly<bool> ret = PBrowserParent::SendRealKeyEvent(aEvent);
1466 0 : NS_WARNING_ASSERTION(ret, "PBrowserParent::SendRealKeyEvent() failed");
1467 0 : MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
1468 : }
1469 :
1470 : void
1471 0 : TabParent::SendRealTouchEvent(WidgetTouchEvent& aEvent)
1472 : {
1473 0 : if (mIsDestroyed) {
1474 0 : return;
1475 : }
1476 :
1477 : // PresShell::HandleEventInternal adds touches on touch end/cancel. This
1478 : // confuses remote content and the panning and zooming logic into thinking
1479 : // that the added touches are part of the touchend/cancel, when actually
1480 : // they're not.
1481 0 : if (aEvent.mMessage == eTouchEnd || aEvent.mMessage == eTouchCancel) {
1482 0 : for (int i = aEvent.mTouches.Length() - 1; i >= 0; i--) {
1483 0 : if (!aEvent.mTouches[i]->mChanged) {
1484 0 : aEvent.mTouches.RemoveElementAt(i);
1485 : }
1486 : }
1487 : }
1488 :
1489 0 : ScrollableLayerGuid guid;
1490 : uint64_t blockId;
1491 : nsEventStatus apzResponse;
1492 0 : ApzAwareEventRoutingToChild(&guid, &blockId, &apzResponse);
1493 :
1494 0 : if (mIsDestroyed) {
1495 0 : return;
1496 : }
1497 :
1498 0 : LayoutDeviceIntPoint offset = GetChildProcessOffset();
1499 0 : for (uint32_t i = 0; i < aEvent.mTouches.Length(); i++) {
1500 0 : aEvent.mTouches[i]->mRefPoint += offset;
1501 : }
1502 :
1503 0 : if (aEvent.mMessage == eTouchMove) {
1504 : DebugOnly<bool> ret =
1505 0 : PBrowserParent::SendRealTouchMoveEvent(aEvent, guid, blockId,
1506 0 : apzResponse);
1507 0 : NS_WARNING_ASSERTION(ret,
1508 : "PBrowserParent::SendRealTouchMoveEvent() failed");
1509 0 : MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
1510 0 : return;
1511 : }
1512 :
1513 : DebugOnly<bool> ret =
1514 0 : PBrowserParent::SendRealTouchEvent(aEvent, guid, blockId, apzResponse);
1515 0 : NS_WARNING_ASSERTION(ret, "PBrowserParent::SendRealTouchEvent() failed");
1516 0 : MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
1517 : }
1518 :
1519 : void
1520 0 : TabParent::SendPluginEvent(WidgetPluginEvent& aEvent)
1521 : {
1522 0 : DebugOnly<bool> ret = PBrowserParent::SendPluginEvent(aEvent);
1523 0 : NS_WARNING_ASSERTION(ret, "PBrowserParent::SendPluginEvent() failed");
1524 0 : MOZ_ASSERT(!ret || aEvent.HasBeenPostedToRemoteProcess());
1525 0 : }
1526 :
1527 : bool
1528 0 : TabParent::SendHandleTap(TapType aType,
1529 : const LayoutDevicePoint& aPoint,
1530 : Modifiers aModifiers,
1531 : const ScrollableLayerGuid& aGuid,
1532 : uint64_t aInputBlockId)
1533 : {
1534 0 : if (mIsDestroyed) {
1535 0 : return false;
1536 : }
1537 0 : if ((aType == TapType::eSingleTap || aType == TapType::eSecondTap) &&
1538 0 : GetRenderFrame()) {
1539 0 : GetRenderFrame()->TakeFocusForClickFromTap();
1540 : }
1541 0 : LayoutDeviceIntPoint offset = GetChildProcessOffset();
1542 0 : return PBrowserParent::SendHandleTap(aType, aPoint + offset, aModifiers,
1543 0 : aGuid, aInputBlockId);
1544 : }
1545 :
1546 : mozilla::ipc::IPCResult
1547 0 : TabParent::RecvSyncMessage(const nsString& aMessage,
1548 : const ClonedMessageData& aData,
1549 : InfallibleTArray<CpowEntry>&& aCpows,
1550 : const IPC::Principal& aPrincipal,
1551 : nsTArray<StructuredCloneData>* aRetVal)
1552 : {
1553 0 : NS_LossyConvertUTF16toASCII messageNameCStr(aMessage);
1554 0 : AUTO_PROFILER_LABEL_DYNAMIC("TabParent::RecvSyncMessage", EVENTS,
1555 : messageNameCStr.get());
1556 :
1557 0 : StructuredCloneData data;
1558 0 : ipc::UnpackClonedMessageDataForParent(aData, data);
1559 :
1560 0 : CrossProcessCpowHolder cpows(Manager(), aCpows);
1561 0 : if (!ReceiveMessage(aMessage, true, &data, &cpows, aPrincipal, aRetVal)) {
1562 0 : return IPC_FAIL_NO_REASON(this);
1563 : }
1564 0 : return IPC_OK();
1565 : }
1566 :
1567 : mozilla::ipc::IPCResult
1568 0 : TabParent::RecvRpcMessage(const nsString& aMessage,
1569 : const ClonedMessageData& aData,
1570 : InfallibleTArray<CpowEntry>&& aCpows,
1571 : const IPC::Principal& aPrincipal,
1572 : nsTArray<StructuredCloneData>* aRetVal)
1573 : {
1574 0 : NS_LossyConvertUTF16toASCII messageNameCStr(aMessage);
1575 0 : AUTO_PROFILER_LABEL_DYNAMIC("TabParent::RecvRpcMessage", EVENTS,
1576 : messageNameCStr.get());
1577 :
1578 0 : StructuredCloneData data;
1579 0 : ipc::UnpackClonedMessageDataForParent(aData, data);
1580 :
1581 0 : CrossProcessCpowHolder cpows(Manager(), aCpows);
1582 0 : if (!ReceiveMessage(aMessage, true, &data, &cpows, aPrincipal, aRetVal)) {
1583 0 : return IPC_FAIL_NO_REASON(this);
1584 : }
1585 0 : return IPC_OK();
1586 : }
1587 :
1588 : mozilla::ipc::IPCResult
1589 29 : TabParent::RecvAsyncMessage(const nsString& aMessage,
1590 : InfallibleTArray<CpowEntry>&& aCpows,
1591 : const IPC::Principal& aPrincipal,
1592 : const ClonedMessageData& aData)
1593 : {
1594 57 : NS_LossyConvertUTF16toASCII messageNameCStr(aMessage);
1595 57 : AUTO_PROFILER_LABEL_DYNAMIC("TabParent::RecvAsyncMessage", EVENTS,
1596 : messageNameCStr.get());
1597 :
1598 57 : StructuredCloneData data;
1599 29 : ipc::UnpackClonedMessageDataForParent(aData, data);
1600 :
1601 57 : CrossProcessCpowHolder cpows(Manager(), aCpows);
1602 29 : if (!ReceiveMessage(aMessage, false, &data, &cpows, aPrincipal, nullptr)) {
1603 0 : return IPC_FAIL_NO_REASON(this);
1604 : }
1605 28 : return IPC_OK();
1606 : }
1607 :
1608 : mozilla::ipc::IPCResult
1609 0 : TabParent::RecvSetCursor(const uint32_t& aCursor, const bool& aForce)
1610 : {
1611 0 : mCursor = static_cast<nsCursor>(aCursor);
1612 0 : mCustomCursor = nullptr;
1613 :
1614 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1615 0 : if (widget) {
1616 0 : if (aForce) {
1617 0 : widget->ClearCachedCursor();
1618 : }
1619 0 : if (mTabSetsCursor) {
1620 0 : widget->SetCursor(mCursor);
1621 : }
1622 : }
1623 0 : return IPC_OK();
1624 : }
1625 :
1626 : mozilla::ipc::IPCResult
1627 0 : TabParent::RecvSetCustomCursor(const nsCString& aCursorData,
1628 : const uint32_t& aWidth,
1629 : const uint32_t& aHeight,
1630 : const uint32_t& aStride,
1631 : const uint8_t& aFormat,
1632 : const uint32_t& aHotspotX,
1633 : const uint32_t& aHotspotY,
1634 : const bool& aForce)
1635 : {
1636 0 : mCursor = nsCursor(-1);
1637 :
1638 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1639 0 : if (widget) {
1640 0 : if (aForce) {
1641 0 : widget->ClearCachedCursor();
1642 : }
1643 :
1644 0 : if (mTabSetsCursor) {
1645 0 : const gfx::IntSize size(aWidth, aHeight);
1646 :
1647 : RefPtr<gfx::DataSourceSurface> customCursor =
1648 0 : gfx::CreateDataSourceSurfaceFromData(size,
1649 0 : static_cast<gfx::SurfaceFormat>(aFormat),
1650 0 : reinterpret_cast<const uint8_t*>(aCursorData.BeginReading()),
1651 0 : aStride);
1652 :
1653 0 : RefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(customCursor, size);
1654 0 : nsCOMPtr<imgIContainer> cursorImage(image::ImageOps::CreateFromDrawable(drawable));
1655 0 : widget->SetCursor(cursorImage, aHotspotX, aHotspotY);
1656 0 : mCustomCursor = cursorImage;
1657 0 : mCustomCursorHotspotX = aHotspotX;
1658 0 : mCustomCursorHotspotY = aHotspotY;
1659 : }
1660 : }
1661 :
1662 0 : return IPC_OK();
1663 : }
1664 :
1665 : nsIXULBrowserWindow*
1666 2 : TabParent::GetXULBrowserWindow()
1667 : {
1668 2 : if (!mFrameElement) {
1669 0 : return nullptr;
1670 : }
1671 :
1672 4 : nsCOMPtr<nsIDocShell> docShell = mFrameElement->OwnerDoc()->GetDocShell();
1673 2 : if (!docShell) {
1674 0 : return nullptr;
1675 : }
1676 :
1677 4 : nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
1678 2 : docShell->GetTreeOwner(getter_AddRefs(treeOwner));
1679 2 : if (!treeOwner) {
1680 0 : return nullptr;
1681 : }
1682 :
1683 4 : nsCOMPtr<nsIXULWindow> window = do_GetInterface(treeOwner);
1684 2 : if (!window) {
1685 0 : return nullptr;
1686 : }
1687 :
1688 4 : nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow;
1689 2 : window->GetXULBrowserWindow(getter_AddRefs(xulBrowserWindow));
1690 2 : return xulBrowserWindow;
1691 : }
1692 :
1693 : mozilla::ipc::IPCResult
1694 2 : TabParent::RecvSetStatus(const uint32_t& aType, const nsString& aStatus)
1695 : {
1696 4 : nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow = GetXULBrowserWindow();
1697 2 : if (!xulBrowserWindow) {
1698 0 : return IPC_OK();
1699 : }
1700 :
1701 2 : switch (aType) {
1702 : case nsIWebBrowserChrome::STATUS_SCRIPT:
1703 2 : xulBrowserWindow->SetJSStatus(aStatus);
1704 2 : break;
1705 : case nsIWebBrowserChrome::STATUS_LINK:
1706 0 : xulBrowserWindow->SetOverLink(aStatus, nullptr);
1707 0 : break;
1708 : }
1709 2 : return IPC_OK();
1710 : }
1711 :
1712 : mozilla::ipc::IPCResult
1713 0 : TabParent::RecvShowTooltip(const uint32_t& aX, const uint32_t& aY, const nsString& aTooltip,
1714 : const nsString& aDirection)
1715 : {
1716 0 : nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow = GetXULBrowserWindow();
1717 0 : if (!xulBrowserWindow) {
1718 0 : return IPC_OK();
1719 : }
1720 :
1721 0 : xulBrowserWindow->ShowTooltip(aX, aY, aTooltip, aDirection);
1722 0 : return IPC_OK();
1723 : }
1724 :
1725 : mozilla::ipc::IPCResult
1726 0 : TabParent::RecvHideTooltip()
1727 : {
1728 0 : nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow = GetXULBrowserWindow();
1729 0 : if (!xulBrowserWindow) {
1730 0 : return IPC_OK();
1731 : }
1732 :
1733 0 : xulBrowserWindow->HideTooltip();
1734 0 : return IPC_OK();
1735 : }
1736 :
1737 : mozilla::ipc::IPCResult
1738 0 : TabParent::RecvNotifyIMEFocus(const ContentCache& aContentCache,
1739 : const IMENotification& aIMENotification,
1740 : IMENotificationRequests* aRequests)
1741 : {
1742 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1743 0 : if (!widget) {
1744 0 : *aRequests = IMENotificationRequests();
1745 0 : return IPC_OK();
1746 : }
1747 :
1748 0 : mContentCache.AssignContent(aContentCache, widget, &aIMENotification);
1749 0 : IMEStateManager::NotifyIME(aIMENotification, widget, this);
1750 :
1751 0 : if (aIMENotification.mMessage == NOTIFY_IME_OF_FOCUS) {
1752 0 : *aRequests = widget->IMENotificationRequestsRef();
1753 : }
1754 0 : return IPC_OK();
1755 : }
1756 :
1757 : mozilla::ipc::IPCResult
1758 0 : TabParent::RecvNotifyIMETextChange(const ContentCache& aContentCache,
1759 : const IMENotification& aIMENotification)
1760 : {
1761 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1762 0 : if (!widget) {
1763 0 : return IPC_OK();
1764 : }
1765 :
1766 : #ifdef DEBUG
1767 : const IMENotificationRequests& requests =
1768 0 : widget->IMENotificationRequestsRef();
1769 0 : NS_ASSERTION(requests.WantTextChange(),
1770 : "Don't call Send/RecvNotifyIMETextChange without NOTIFY_TEXT_CHANGE");
1771 : #endif
1772 :
1773 0 : mContentCache.AssignContent(aContentCache, widget, &aIMENotification);
1774 0 : mContentCache.MaybeNotifyIME(widget, aIMENotification);
1775 0 : return IPC_OK();
1776 : }
1777 :
1778 : mozilla::ipc::IPCResult
1779 0 : TabParent::RecvNotifyIMECompositionUpdate(
1780 : const ContentCache& aContentCache,
1781 : const IMENotification& aIMENotification)
1782 : {
1783 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1784 0 : if (!widget) {
1785 0 : return IPC_OK();
1786 : }
1787 0 : mContentCache.AssignContent(aContentCache, widget, &aIMENotification);
1788 0 : mContentCache.MaybeNotifyIME(widget, aIMENotification);
1789 0 : return IPC_OK();
1790 : }
1791 :
1792 : mozilla::ipc::IPCResult
1793 0 : TabParent::RecvNotifyIMESelection(const ContentCache& aContentCache,
1794 : const IMENotification& aIMENotification)
1795 : {
1796 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1797 0 : if (!widget) {
1798 0 : return IPC_OK();
1799 : }
1800 0 : mContentCache.AssignContent(aContentCache, widget, &aIMENotification);
1801 0 : mContentCache.MaybeNotifyIME(widget, aIMENotification);
1802 0 : return IPC_OK();
1803 : }
1804 :
1805 : mozilla::ipc::IPCResult
1806 1 : TabParent::RecvUpdateContentCache(const ContentCache& aContentCache)
1807 : {
1808 2 : nsCOMPtr<nsIWidget> widget = GetWidget();
1809 1 : if (!widget) {
1810 0 : return IPC_OK();
1811 : }
1812 :
1813 1 : mContentCache.AssignContent(aContentCache, widget);
1814 1 : return IPC_OK();
1815 : }
1816 :
1817 : mozilla::ipc::IPCResult
1818 0 : TabParent::RecvNotifyIMEMouseButtonEvent(
1819 : const IMENotification& aIMENotification,
1820 : bool* aConsumedByIME)
1821 : {
1822 :
1823 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1824 0 : if (!widget) {
1825 0 : *aConsumedByIME = false;
1826 0 : return IPC_OK();
1827 : }
1828 0 : nsresult rv = IMEStateManager::NotifyIME(aIMENotification, widget, this);
1829 0 : *aConsumedByIME = rv == NS_SUCCESS_EVENT_CONSUMED;
1830 0 : return IPC_OK();
1831 : }
1832 :
1833 : mozilla::ipc::IPCResult
1834 0 : TabParent::RecvNotifyIMEPositionChange(const ContentCache& aContentCache,
1835 : const IMENotification& aIMENotification)
1836 : {
1837 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1838 0 : if (!widget) {
1839 0 : return IPC_OK();
1840 : }
1841 0 : mContentCache.AssignContent(aContentCache, widget, &aIMENotification);
1842 0 : mContentCache.MaybeNotifyIME(widget, aIMENotification);
1843 0 : return IPC_OK();
1844 : }
1845 :
1846 : mozilla::ipc::IPCResult
1847 0 : TabParent::RecvOnEventNeedingAckHandled(const EventMessage& aMessage)
1848 : {
1849 : // This is called when the child process receives WidgetCompositionEvent or
1850 : // WidgetSelectionEvent.
1851 : // FYI: Don't check if widget is nullptr here because it's more important to
1852 : // notify mContentCahce of this than handling something in it.
1853 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1854 :
1855 : // While calling OnEventNeedingAckHandled(), TabParent *might* be destroyed
1856 : // since it may send notifications to IME.
1857 0 : RefPtr<TabParent> kungFuDeathGrip(this);
1858 0 : mContentCache.OnEventNeedingAckHandled(widget, aMessage);
1859 0 : return IPC_OK();
1860 : }
1861 :
1862 : void
1863 0 : TabParent::HandledWindowedPluginKeyEvent(const NativeEventData& aKeyEventData,
1864 : bool aIsConsumed)
1865 : {
1866 : DebugOnly<bool> ok =
1867 0 : SendHandledWindowedPluginKeyEvent(aKeyEventData, aIsConsumed);
1868 0 : NS_WARNING_ASSERTION(ok, "SendHandledWindowedPluginKeyEvent failed");
1869 0 : }
1870 :
1871 : mozilla::ipc::IPCResult
1872 0 : TabParent::RecvOnWindowedPluginKeyEvent(const NativeEventData& aKeyEventData)
1873 : {
1874 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
1875 0 : if (NS_WARN_IF(!widget)) {
1876 : // Notifies the plugin process of the key event being not consumed by us.
1877 0 : HandledWindowedPluginKeyEvent(aKeyEventData, false);
1878 0 : return IPC_OK();
1879 : }
1880 0 : nsresult rv = widget->OnWindowedPluginKeyEvent(aKeyEventData, this);
1881 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
1882 : // Notifies the plugin process of the key event being not consumed by us.
1883 0 : HandledWindowedPluginKeyEvent(aKeyEventData, false);
1884 0 : return IPC_OK();
1885 : }
1886 :
1887 : // If the key event is posted to another process, we need to wait a call
1888 : // of HandledWindowedPluginKeyEvent(). So, nothing to do here in this case.
1889 0 : if (rv == NS_SUCCESS_EVENT_HANDLED_ASYNCHRONOUSLY) {
1890 0 : return IPC_OK();
1891 : }
1892 :
1893 : // Otherwise, the key event is handled synchronously. Let's notify the
1894 : // plugin process of the key event's result.
1895 0 : bool consumed = (rv == NS_SUCCESS_EVENT_CONSUMED);
1896 0 : HandledWindowedPluginKeyEvent(aKeyEventData, consumed);
1897 :
1898 0 : return IPC_OK();
1899 : }
1900 :
1901 : mozilla::ipc::IPCResult
1902 0 : TabParent::RecvRequestFocus(const bool& aCanRaise)
1903 : {
1904 0 : nsCOMPtr<nsIFocusManager> fm = nsFocusManager::GetFocusManager();
1905 0 : if (!fm) {
1906 0 : return IPC_OK();
1907 : }
1908 :
1909 0 : nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
1910 0 : if (!content || !content->OwnerDoc()) {
1911 0 : return IPC_OK();
1912 : }
1913 :
1914 0 : uint32_t flags = nsIFocusManager::FLAG_NOSCROLL;
1915 0 : if (aCanRaise)
1916 0 : flags |= nsIFocusManager::FLAG_RAISE;
1917 :
1918 0 : nsCOMPtr<nsIDOMElement> node = do_QueryInterface(mFrameElement);
1919 0 : fm->SetFocus(node, flags);
1920 0 : return IPC_OK();
1921 : }
1922 :
1923 : mozilla::ipc::IPCResult
1924 2 : TabParent::RecvEnableDisableCommands(const nsString& aAction,
1925 : nsTArray<nsCString>&& aEnabledCommands,
1926 : nsTArray<nsCString>&& aDisabledCommands)
1927 : {
1928 4 : nsCOMPtr<nsIRemoteBrowser> remoteBrowser = do_QueryInterface(mFrameElement);
1929 2 : if (remoteBrowser) {
1930 4 : UniquePtr<const char*[]> enabledCommands, disabledCommands;
1931 :
1932 2 : if (aEnabledCommands.Length()) {
1933 2 : enabledCommands = MakeUnique<const char*[]>(aEnabledCommands.Length());
1934 114 : for (uint32_t c = 0; c < aEnabledCommands.Length(); c++) {
1935 112 : enabledCommands[c] = aEnabledCommands[c].get();
1936 : }
1937 : }
1938 :
1939 2 : if (aDisabledCommands.Length()) {
1940 2 : disabledCommands = MakeUnique<const char*[]>(aDisabledCommands.Length());
1941 12 : for (uint32_t c = 0; c < aDisabledCommands.Length(); c++) {
1942 10 : disabledCommands[c] = aDisabledCommands[c].get();
1943 : }
1944 : }
1945 :
1946 8 : remoteBrowser->EnableDisableCommands(aAction,
1947 2 : aEnabledCommands.Length(), enabledCommands.get(),
1948 6 : aDisabledCommands.Length(), disabledCommands.get());
1949 : }
1950 :
1951 4 : return IPC_OK();
1952 : }
1953 :
1954 : NS_IMETHODIMP
1955 0 : TabParent::GetChildProcessOffset(int32_t* aOutCssX, int32_t* aOutCssY)
1956 : {
1957 0 : NS_ENSURE_ARG(aOutCssX);
1958 0 : NS_ENSURE_ARG(aOutCssY);
1959 0 : CSSPoint offset = LayoutDevicePoint(GetChildProcessOffset())
1960 0 : * GetLayoutDeviceToCSSScale();
1961 0 : *aOutCssX = offset.x;
1962 0 : *aOutCssY = offset.y;
1963 0 : return NS_OK;
1964 : }
1965 :
1966 : LayoutDeviceIntPoint
1967 14 : TabParent::GetChildProcessOffset()
1968 : {
1969 : // The "toplevel widget" in child processes is always at position
1970 : // 0,0. Map the event coordinates to match that.
1971 :
1972 14 : LayoutDeviceIntPoint offset(0, 0);
1973 28 : RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
1974 14 : if (!frameLoader) {
1975 0 : return offset;
1976 : }
1977 14 : nsIFrame* targetFrame = frameLoader->GetPrimaryFrameOfOwningContent();
1978 14 : if (!targetFrame) {
1979 0 : return offset;
1980 : }
1981 :
1982 : // Find out how far we're offset from the nearest widget.
1983 28 : nsCOMPtr<nsIWidget> widget = GetWidget();
1984 14 : if (!widget) {
1985 0 : return offset;
1986 : }
1987 : nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(widget,
1988 28 : LayoutDeviceIntPoint(0, 0),
1989 28 : targetFrame);
1990 :
1991 : return LayoutDeviceIntPoint::FromAppUnitsToNearest(
1992 14 : pt, targetFrame->PresContext()->AppUnitsPerDevPixel());
1993 : }
1994 :
1995 : mozilla::ipc::IPCResult
1996 0 : TabParent::RecvReplyKeyEvent(const WidgetKeyboardEvent& aEvent)
1997 : {
1998 0 : NS_ENSURE_TRUE(mFrameElement, IPC_OK());
1999 :
2000 0 : WidgetKeyboardEvent localEvent(aEvent);
2001 0 : localEvent.MarkAsHandledInRemoteProcess();
2002 :
2003 : // Here we convert the WidgetEvent that we received to an nsIDOMEvent
2004 : // to be able to dispatch it to the <browser> element as the target element.
2005 0 : nsIDocument* doc = mFrameElement->OwnerDoc();
2006 0 : nsIPresShell* presShell = doc->GetShell();
2007 0 : NS_ENSURE_TRUE(presShell, IPC_OK());
2008 0 : nsPresContext* presContext = presShell->GetPresContext();
2009 0 : NS_ENSURE_TRUE(presContext, IPC_OK());
2010 :
2011 0 : AutoHandlingUserInputStatePusher userInpStatePusher(localEvent.IsTrusted(),
2012 0 : &localEvent, doc);
2013 :
2014 0 : EventDispatcher::Dispatch(mFrameElement, presContext, &localEvent);
2015 :
2016 0 : if (!localEvent.DefaultPrevented() &&
2017 0 : !localEvent.mFlags.mIsSynthesizedForTests) {
2018 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
2019 0 : if (widget) {
2020 0 : widget->PostHandleKeyEvent(&localEvent);
2021 0 : localEvent.StopPropagation();
2022 : }
2023 : }
2024 :
2025 0 : return IPC_OK();
2026 : }
2027 :
2028 : mozilla::ipc::IPCResult
2029 0 : TabParent::RecvAccessKeyNotHandled(const WidgetKeyboardEvent& aEvent)
2030 : {
2031 0 : NS_ENSURE_TRUE(mFrameElement, IPC_OK());
2032 :
2033 0 : WidgetKeyboardEvent localEvent(aEvent);
2034 0 : localEvent.MarkAsHandledInRemoteProcess();
2035 0 : localEvent.mMessage = eAccessKeyNotFound;
2036 0 : localEvent.mAccessKeyForwardedToChild = false;
2037 :
2038 : // Here we convert the WidgetEvent that we received to an nsIDOMEvent
2039 : // to be able to dispatch it to the <browser> element as the target element.
2040 0 : nsIDocument* doc = mFrameElement->OwnerDoc();
2041 0 : nsIPresShell* presShell = doc->GetShell();
2042 0 : NS_ENSURE_TRUE(presShell, IPC_OK());
2043 :
2044 0 : if (presShell->CanDispatchEvent()) {
2045 0 : nsPresContext* presContext = presShell->GetPresContext();
2046 0 : NS_ENSURE_TRUE(presContext, IPC_OK());
2047 :
2048 0 : EventDispatcher::Dispatch(mFrameElement, presContext, &localEvent);
2049 : }
2050 :
2051 0 : return IPC_OK();
2052 : }
2053 :
2054 : mozilla::ipc::IPCResult
2055 0 : TabParent::RecvSetHasBeforeUnload(const bool& aHasBeforeUnload)
2056 : {
2057 0 : mHasBeforeUnload = aHasBeforeUnload;
2058 0 : return IPC_OK();
2059 : }
2060 :
2061 : bool
2062 0 : TabParent::HandleQueryContentEvent(WidgetQueryContentEvent& aEvent)
2063 : {
2064 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
2065 0 : if (!widget) {
2066 0 : return true;
2067 : }
2068 0 : if (NS_WARN_IF(!mContentCache.HandleQueryContentEvent(aEvent, widget)) ||
2069 0 : NS_WARN_IF(!aEvent.mSucceeded)) {
2070 0 : return true;
2071 : }
2072 0 : switch (aEvent.mMessage) {
2073 : case eQueryTextRect:
2074 : case eQueryCaretRect:
2075 : case eQueryEditorRect:
2076 0 : aEvent.mReply.mRect -= GetChildProcessOffset();
2077 0 : break;
2078 : default:
2079 0 : break;
2080 : }
2081 0 : return true;
2082 : }
2083 :
2084 : bool
2085 0 : TabParent::SendCompositionEvent(WidgetCompositionEvent& aEvent)
2086 : {
2087 0 : if (mIsDestroyed) {
2088 0 : return false;
2089 : }
2090 :
2091 0 : if (!mContentCache.OnCompositionEvent(aEvent)) {
2092 0 : return true;
2093 : }
2094 0 : if (NS_WARN_IF(!PBrowserParent::SendCompositionEvent(aEvent))) {
2095 0 : return false;
2096 : }
2097 0 : MOZ_ASSERT(aEvent.HasBeenPostedToRemoteProcess());
2098 0 : return true;
2099 : }
2100 :
2101 : bool
2102 0 : TabParent::SendSelectionEvent(WidgetSelectionEvent& aEvent)
2103 : {
2104 0 : if (mIsDestroyed) {
2105 0 : return false;
2106 : }
2107 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
2108 0 : if (!widget) {
2109 0 : return true;
2110 : }
2111 0 : mContentCache.OnSelectionEvent(aEvent);
2112 0 : if (NS_WARN_IF(!PBrowserParent::SendSelectionEvent(aEvent))) {
2113 0 : return false;
2114 : }
2115 0 : MOZ_ASSERT(aEvent.HasBeenPostedToRemoteProcess());
2116 0 : aEvent.mSucceeded = true;
2117 0 : return true;
2118 : }
2119 :
2120 : bool
2121 0 : TabParent::SendPasteTransferable(const IPCDataTransfer& aDataTransfer,
2122 : const bool& aIsPrivateData,
2123 : const IPC::Principal& aRequestingPrincipal)
2124 : {
2125 0 : return PBrowserParent::SendPasteTransferable(aDataTransfer,
2126 : aIsPrivateData,
2127 0 : aRequestingPrincipal);
2128 : }
2129 :
2130 : /*static*/ TabParent*
2131 29 : TabParent::GetFrom(nsFrameLoader* aFrameLoader)
2132 : {
2133 29 : if (!aFrameLoader) {
2134 0 : return nullptr;
2135 : }
2136 29 : PBrowserParent* remoteBrowser = aFrameLoader->GetRemoteBrowser();
2137 29 : return static_cast<TabParent*>(remoteBrowser);
2138 : }
2139 :
2140 : /*static*/ TabParent*
2141 0 : TabParent::GetFrom(nsIFrameLoader* aFrameLoader)
2142 : {
2143 0 : if (!aFrameLoader)
2144 0 : return nullptr;
2145 0 : return GetFrom(static_cast<nsFrameLoader*>(aFrameLoader));
2146 : }
2147 :
2148 : /*static*/ TabParent*
2149 1 : TabParent::GetFrom(nsITabParent* aTabParent)
2150 : {
2151 1 : return static_cast<TabParent*>(aTabParent);
2152 : }
2153 :
2154 : /*static*/ TabParent*
2155 22 : TabParent::GetFrom(PBrowserParent* aTabParent)
2156 : {
2157 22 : return static_cast<TabParent*>(aTabParent);
2158 : }
2159 :
2160 : /*static*/ TabParent*
2161 23 : TabParent::GetFrom(nsIContent* aContent)
2162 : {
2163 46 : nsCOMPtr<nsIFrameLoaderOwner> loaderOwner = do_QueryInterface(aContent);
2164 23 : if (!loaderOwner) {
2165 3 : return nullptr;
2166 : }
2167 40 : RefPtr<nsFrameLoader> frameLoader = loaderOwner->GetFrameLoader();
2168 20 : return GetFrom(frameLoader);
2169 : }
2170 :
2171 : /*static*/ TabId
2172 1 : TabParent::GetTabIdFrom(nsIDocShell *docShell)
2173 : {
2174 2 : nsCOMPtr<nsITabChild> tabChild(TabChild::GetFrom(docShell));
2175 1 : if (tabChild) {
2176 0 : return static_cast<TabChild*>(tabChild.get())->GetTabId();
2177 : }
2178 1 : return TabId(0);
2179 : }
2180 :
2181 : RenderFrameParent*
2182 42 : TabParent::GetRenderFrame()
2183 : {
2184 42 : PRenderFrameParent* p = LoneManagedOrNullAsserts(ManagedPRenderFrameParent());
2185 42 : RenderFrameParent* frame = static_cast<RenderFrameParent*>(p);
2186 :
2187 42 : return frame;
2188 : }
2189 :
2190 : mozilla::ipc::IPCResult
2191 0 : TabParent::RecvRequestIMEToCommitComposition(const bool& aCancel,
2192 : bool* aIsCommitted,
2193 : nsString* aCommittedString)
2194 : {
2195 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
2196 0 : if (!widget) {
2197 0 : *aIsCommitted = false;
2198 0 : return IPC_OK();
2199 : }
2200 :
2201 0 : *aIsCommitted =
2202 0 : mContentCache.RequestIMEToCommitComposition(widget, aCancel,
2203 : *aCommittedString);
2204 0 : return IPC_OK();
2205 : }
2206 :
2207 : mozilla::ipc::IPCResult
2208 0 : TabParent::RecvStartPluginIME(const WidgetKeyboardEvent& aKeyboardEvent,
2209 : const int32_t& aPanelX, const int32_t& aPanelY,
2210 : nsString* aCommitted)
2211 : {
2212 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
2213 0 : if (!widget) {
2214 0 : return IPC_OK();
2215 : }
2216 0 : Unused << widget->StartPluginIME(aKeyboardEvent,
2217 : (int32_t&)aPanelX,
2218 : (int32_t&)aPanelY,
2219 0 : *aCommitted);
2220 0 : return IPC_OK();
2221 : }
2222 :
2223 : mozilla::ipc::IPCResult
2224 0 : TabParent::RecvSetPluginFocused(const bool& aFocused)
2225 : {
2226 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
2227 0 : if (!widget) {
2228 0 : return IPC_OK();
2229 : }
2230 0 : widget->SetPluginFocused((bool&)aFocused);
2231 0 : return IPC_OK();
2232 : }
2233 :
2234 : mozilla::ipc::IPCResult
2235 0 : TabParent::RecvSetCandidateWindowForPlugin(
2236 : const CandidateWindowPosition& aPosition)
2237 : {
2238 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
2239 0 : if (!widget) {
2240 0 : return IPC_OK();
2241 : }
2242 :
2243 0 : widget->SetCandidateWindowForPlugin(aPosition);
2244 0 : return IPC_OK();
2245 : }
2246 :
2247 : mozilla::ipc::IPCResult
2248 0 : TabParent::RecvDefaultProcOfPluginEvent(const WidgetPluginEvent& aEvent)
2249 : {
2250 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
2251 0 : if (!widget) {
2252 0 : return IPC_OK();
2253 : }
2254 :
2255 0 : widget->DefaultProcOfPluginEvent(aEvent);
2256 0 : return IPC_OK();
2257 : }
2258 :
2259 : mozilla::ipc::IPCResult
2260 0 : TabParent::RecvGetInputContext(int32_t* aIMEEnabled,
2261 : int32_t* aIMEOpen)
2262 : {
2263 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
2264 0 : if (!widget) {
2265 0 : *aIMEEnabled = IMEState::DISABLED;
2266 0 : *aIMEOpen = IMEState::OPEN_STATE_NOT_SUPPORTED;
2267 0 : return IPC_OK();
2268 : }
2269 :
2270 0 : InputContext context = widget->GetInputContext();
2271 0 : *aIMEEnabled = static_cast<int32_t>(context.mIMEState.mEnabled);
2272 0 : *aIMEOpen = static_cast<int32_t>(context.mIMEState.mOpen);
2273 0 : return IPC_OK();
2274 : }
2275 :
2276 : mozilla::ipc::IPCResult
2277 3 : TabParent::RecvSetInputContext(const int32_t& aIMEEnabled,
2278 : const int32_t& aIMEOpen,
2279 : const nsString& aType,
2280 : const nsString& aInputmode,
2281 : const nsString& aActionHint,
2282 : const int32_t& aCause,
2283 : const int32_t& aFocusChange)
2284 : {
2285 6 : InputContext context;
2286 3 : context.mIMEState.mEnabled = static_cast<IMEState::Enabled>(aIMEEnabled);
2287 3 : context.mIMEState.mOpen = static_cast<IMEState::Open>(aIMEOpen);
2288 3 : context.mHTMLInputType.Assign(aType);
2289 3 : context.mHTMLInputInputmode.Assign(aInputmode);
2290 3 : context.mActionHint.Assign(aActionHint);
2291 3 : context.mOrigin = InputContext::ORIGIN_CONTENT;
2292 :
2293 : InputContextAction action(
2294 3 : static_cast<InputContextAction::Cause>(aCause),
2295 6 : static_cast<InputContextAction::FocusChange>(aFocusChange));
2296 :
2297 3 : IMEStateManager::SetInputContextForChildProcess(this, context, action);
2298 :
2299 6 : return IPC_OK();
2300 : }
2301 :
2302 : mozilla::ipc::IPCResult
2303 0 : TabParent::RecvIsParentWindowMainWidgetVisible(bool* aIsVisible)
2304 : {
2305 0 : nsCOMPtr<nsIContent> frame = do_QueryInterface(mFrameElement);
2306 0 : if (!frame)
2307 0 : return IPC_OK();
2308 : nsCOMPtr<nsIDOMWindowUtils> windowUtils =
2309 0 : do_QueryInterface(frame->OwnerDoc()->GetWindow());
2310 0 : nsresult rv = windowUtils->GetIsParentWindowMainWidgetVisible(aIsVisible);
2311 0 : if (NS_FAILED(rv)) {
2312 0 : return IPC_FAIL_NO_REASON(this);
2313 : }
2314 0 : return IPC_OK();
2315 : }
2316 :
2317 : mozilla::ipc::IPCResult
2318 0 : TabParent::RecvGetDPI(float* aValue)
2319 : {
2320 0 : TryCacheDPIAndScale();
2321 :
2322 0 : MOZ_ASSERT(mDPI > 0 || mFrameElement,
2323 : "Must not ask for DPI before OwnerElement is received!");
2324 0 : *aValue = mDPI;
2325 0 : return IPC_OK();
2326 : }
2327 :
2328 : mozilla::ipc::IPCResult
2329 0 : TabParent::RecvGetDefaultScale(double* aValue)
2330 : {
2331 0 : TryCacheDPIAndScale();
2332 :
2333 0 : MOZ_ASSERT(mDefaultScale.scale > 0 || mFrameElement,
2334 : "Must not ask for scale before OwnerElement is received!");
2335 0 : *aValue = mDefaultScale.scale;
2336 0 : return IPC_OK();
2337 : }
2338 :
2339 : mozilla::ipc::IPCResult
2340 0 : TabParent::RecvGetWidgetRounding(int32_t* aValue)
2341 : {
2342 0 : TryCacheDPIAndScale();
2343 :
2344 0 : MOZ_ASSERT(mRounding > 0 || mFrameElement,
2345 : "Must not ask for rounding before OwnerElement is received!");
2346 0 : *aValue = mRounding;
2347 0 : return IPC_OK();
2348 : }
2349 :
2350 : already_AddRefed<nsIWidget>
2351 1 : TabParent::GetTopLevelWidget()
2352 : {
2353 2 : nsCOMPtr<nsIContent> content = do_QueryInterface(mFrameElement);
2354 1 : if (content) {
2355 1 : nsIPresShell* shell = content->OwnerDoc()->GetShell();
2356 1 : if (shell) {
2357 1 : nsViewManager* vm = shell->GetViewManager();
2358 2 : nsCOMPtr<nsIWidget> widget;
2359 1 : vm->GetRootWidget(getter_AddRefs(widget));
2360 1 : return widget.forget();
2361 : }
2362 : }
2363 0 : return nullptr;
2364 : }
2365 :
2366 : mozilla::ipc::IPCResult
2367 0 : TabParent::RecvSetNativeChildOfShareableWindow(const uintptr_t& aChildWindow)
2368 : {
2369 : #if defined(XP_WIN)
2370 : nsCOMPtr<nsIWidget> widget = GetTopLevelWidget();
2371 : if (widget) {
2372 : // Note that this call will probably cause a sync native message to the
2373 : // process that owns the child window.
2374 : widget->SetNativeData(NS_NATIVE_CHILD_OF_SHAREABLE_WINDOW, aChildWindow);
2375 : }
2376 : return IPC_OK();
2377 : #else
2378 0 : NS_NOTREACHED(
2379 : "TabParent::RecvSetNativeChildOfShareableWindow not implemented!");
2380 0 : return IPC_FAIL_NO_REASON(this);
2381 : #endif
2382 : }
2383 :
2384 : mozilla::ipc::IPCResult
2385 0 : TabParent::RecvDispatchFocusToTopLevelWindow()
2386 : {
2387 0 : nsCOMPtr<nsIWidget> widget = GetTopLevelWidget();
2388 0 : if (widget) {
2389 0 : widget->SetFocus(false);
2390 : }
2391 0 : return IPC_OK();
2392 : }
2393 :
2394 : bool
2395 29 : TabParent::ReceiveMessage(const nsString& aMessage,
2396 : bool aSync,
2397 : StructuredCloneData* aData,
2398 : CpowHolder* aCpows,
2399 : nsIPrincipal* aPrincipal,
2400 : nsTArray<StructuredCloneData>* aRetVal)
2401 : {
2402 57 : RefPtr<nsFrameLoader> frameLoader = GetFrameLoader(true);
2403 29 : if (frameLoader && frameLoader->GetFrameMessageManager()) {
2404 : RefPtr<nsFrameMessageManager> manager =
2405 57 : frameLoader->GetFrameMessageManager();
2406 :
2407 58 : manager->ReceiveMessage(mFrameElement,
2408 : frameLoader,
2409 : aMessage,
2410 : aSync,
2411 : aData,
2412 : aCpows,
2413 : aPrincipal,
2414 58 : aRetVal);
2415 : }
2416 56 : return true;
2417 : }
2418 :
2419 : // nsIAuthPromptProvider
2420 :
2421 : // This method is largely copied from nsDocShell::GetAuthPrompt
2422 : NS_IMETHODIMP
2423 0 : TabParent::GetAuthPrompt(uint32_t aPromptReason, const nsIID& iid,
2424 : void** aResult)
2425 : {
2426 : // we're either allowing auth, or it's a proxy request
2427 : nsresult rv;
2428 : nsCOMPtr<nsIPromptFactory> wwatch =
2429 0 : do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
2430 0 : NS_ENSURE_SUCCESS(rv, rv);
2431 :
2432 0 : nsCOMPtr<nsPIDOMWindowOuter> window;
2433 0 : nsCOMPtr<nsIContent> frame = do_QueryInterface(mFrameElement);
2434 0 : if (frame)
2435 0 : window = frame->OwnerDoc()->GetWindow();
2436 :
2437 : // Get an auth prompter for our window so that the parenting
2438 : // of the dialogs works as it should when using tabs.
2439 0 : nsCOMPtr<nsISupports> prompt;
2440 0 : rv = wwatch->GetPrompt(window, iid, getter_AddRefs(prompt));
2441 0 : NS_ENSURE_SUCCESS(rv, rv);
2442 :
2443 0 : nsCOMPtr<nsILoginManagerPrompter> prompter = do_QueryInterface(prompt);
2444 0 : if (prompter) {
2445 0 : nsCOMPtr<nsIDOMElement> browser = do_QueryInterface(mFrameElement);
2446 0 : prompter->SetBrowser(browser);
2447 : }
2448 :
2449 0 : *aResult = prompt.forget().take();
2450 0 : return NS_OK;
2451 : }
2452 :
2453 : PColorPickerParent*
2454 0 : TabParent::AllocPColorPickerParent(const nsString& aTitle,
2455 : const nsString& aInitialColor)
2456 : {
2457 0 : return new ColorPickerParent(aTitle, aInitialColor);
2458 : }
2459 :
2460 : bool
2461 0 : TabParent::DeallocPColorPickerParent(PColorPickerParent* actor)
2462 : {
2463 0 : delete actor;
2464 0 : return true;
2465 : }
2466 :
2467 : PRenderFrameParent*
2468 0 : TabParent::AllocPRenderFrameParent()
2469 : {
2470 0 : MOZ_ASSERT(ManagedPRenderFrameParent().IsEmpty());
2471 0 : RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
2472 :
2473 0 : RenderFrameParent* rfp = new RenderFrameParent(frameLoader);
2474 0 : if (rfp->IsInitted()) {
2475 0 : uint64_t layersId = rfp->GetLayersId();
2476 0 : AddTabParentToTable(layersId, this);
2477 : }
2478 0 : return rfp;
2479 : }
2480 :
2481 : bool
2482 0 : TabParent::DeallocPRenderFrameParent(PRenderFrameParent* aFrame)
2483 : {
2484 0 : delete aFrame;
2485 0 : return true;
2486 : }
2487 :
2488 : bool
2489 0 : TabParent::SetRenderFrame(PRenderFrameParent* aRFParent)
2490 : {
2491 0 : if (IsInitedByParent()) {
2492 0 : return false;
2493 : }
2494 :
2495 0 : RefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
2496 :
2497 0 : if (!frameLoader) {
2498 0 : return false;
2499 : }
2500 :
2501 0 : RenderFrameParent* renderFrame = static_cast<RenderFrameParent*>(aRFParent);
2502 0 : bool success = renderFrame->Init(frameLoader);
2503 0 : if (!success) {
2504 0 : return false;
2505 : }
2506 :
2507 0 : uint64_t layersId = renderFrame->GetLayersId();
2508 0 : AddTabParentToTable(layersId, this);
2509 :
2510 0 : return true;
2511 : }
2512 :
2513 : bool
2514 0 : TabParent::GetRenderFrameInfo(TextureFactoryIdentifier* aTextureFactoryIdentifier,
2515 : uint64_t* aLayersId)
2516 : {
2517 0 : RenderFrameParent* rfp = GetRenderFrame();
2518 0 : if (!rfp) {
2519 0 : return false;
2520 : }
2521 :
2522 0 : *aLayersId = rfp->GetLayersId();
2523 0 : rfp->GetTextureFactoryIdentifier(aTextureFactoryIdentifier);
2524 0 : return true;
2525 : }
2526 :
2527 : already_AddRefed<nsFrameLoader>
2528 49 : TabParent::GetFrameLoader(bool aUseCachedFrameLoaderAfterDestroy) const
2529 : {
2530 49 : if (mIsDestroyed && !aUseCachedFrameLoaderAfterDestroy) {
2531 0 : return nullptr;
2532 : }
2533 :
2534 49 : if (mFrameLoader) {
2535 0 : RefPtr<nsFrameLoader> fl = mFrameLoader;
2536 0 : return fl.forget();
2537 : }
2538 98 : nsCOMPtr<nsIFrameLoaderOwner> frameLoaderOwner = do_QueryInterface(mFrameElement);
2539 49 : return frameLoaderOwner ? frameLoaderOwner->GetFrameLoader() : nullptr;
2540 : }
2541 :
2542 : void
2543 3 : TabParent::TryCacheDPIAndScale()
2544 : {
2545 3 : if (mDPI > 0) {
2546 2 : return;
2547 : }
2548 :
2549 2 : nsCOMPtr<nsIWidget> widget = GetWidget();
2550 :
2551 1 : if (widget) {
2552 1 : mDPI = widget->GetDPI();
2553 1 : mRounding = widget->RoundsWidgetCoordinatesTo();
2554 1 : mDefaultScale = widget->GetDefaultScale();
2555 : }
2556 : }
2557 :
2558 : already_AddRefed<nsIWidget>
2559 40 : TabParent::GetWidget() const
2560 : {
2561 40 : if (!mFrameElement) {
2562 0 : return nullptr;
2563 : }
2564 80 : nsCOMPtr<nsIWidget> widget = nsContentUtils::WidgetForContent(mFrameElement);
2565 40 : if (!widget) {
2566 0 : widget = nsContentUtils::WidgetForDocument(mFrameElement->OwnerDoc());
2567 : }
2568 40 : return widget.forget();
2569 : }
2570 :
2571 : void
2572 6 : TabParent::ApzAwareEventRoutingToChild(ScrollableLayerGuid* aOutTargetGuid,
2573 : uint64_t* aOutInputBlockId,
2574 : nsEventStatus* aOutApzResponse)
2575 : {
2576 : // Let the widget know that the event will be sent to the child process,
2577 : // which will (hopefully) send a confirmation notice back to APZ.
2578 : // Do this even if APZ is off since we need it for swipe gesture support on
2579 : // OS X without APZ.
2580 6 : InputAPZContext::SetRoutedToChildProcess();
2581 :
2582 6 : if (AsyncPanZoomEnabled()) {
2583 6 : if (aOutTargetGuid) {
2584 6 : *aOutTargetGuid = InputAPZContext::GetTargetLayerGuid();
2585 :
2586 : // There may be cases where the APZ hit-testing code came to a different
2587 : // conclusion than the main-thread hit-testing code as to where the event
2588 : // is destined. In such cases the layersId of the APZ result may not match
2589 : // the layersId of this renderframe. In such cases the main-thread hit-
2590 : // testing code "wins" so we need to update the guid to reflect this.
2591 6 : if (RenderFrameParent* rfp = GetRenderFrame()) {
2592 6 : if (aOutTargetGuid->mLayersId != rfp->GetLayersId()) {
2593 6 : *aOutTargetGuid = ScrollableLayerGuid(rfp->GetLayersId(), 0, FrameMetrics::NULL_SCROLL_ID);
2594 : }
2595 : }
2596 : }
2597 6 : if (aOutInputBlockId) {
2598 6 : *aOutInputBlockId = InputAPZContext::GetInputBlockId();
2599 : }
2600 6 : if (aOutApzResponse) {
2601 0 : *aOutApzResponse = InputAPZContext::GetApzResponse();
2602 : }
2603 : } else {
2604 0 : if (aOutInputBlockId) {
2605 0 : *aOutInputBlockId = 0;
2606 : }
2607 0 : if (aOutApzResponse) {
2608 0 : *aOutApzResponse = nsEventStatus_eIgnore;
2609 : }
2610 : }
2611 6 : }
2612 :
2613 : mozilla::ipc::IPCResult
2614 0 : TabParent::RecvBrowserFrameOpenWindow(PBrowserParent* aOpener,
2615 : PRenderFrameParent* aRenderFrame,
2616 : const nsString& aURL,
2617 : const nsString& aName,
2618 : const nsString& aFeatures,
2619 : BrowserFrameOpenWindowResolver&& aResolve)
2620 : {
2621 0 : CreatedWindowInfo cwi;
2622 0 : cwi.rv() = NS_OK;
2623 0 : cwi.layersId() = 0;
2624 0 : cwi.maxTouchPoints() = 0;
2625 :
2626 : BrowserElementParent::OpenWindowResult opened =
2627 0 : BrowserElementParent::OpenWindowOOP(TabParent::GetFrom(aOpener),
2628 : this, aRenderFrame, aURL, aName, aFeatures,
2629 0 : &cwi.textureFactoryIdentifier(),
2630 0 : &cwi.layersId());
2631 0 : cwi.compositorOptions() =
2632 0 : static_cast<RenderFrameParent*>(aRenderFrame)->GetCompositorOptions();
2633 0 : cwi.windowOpened() = (opened == BrowserElementParent::OPEN_WINDOW_ADDED);
2634 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
2635 0 : if (widget) {
2636 0 : cwi.maxTouchPoints() = widget->GetMaxTouchPoints();
2637 0 : cwi.dimensions() = GetDimensionInfo();
2638 : }
2639 :
2640 : // Resolve the request with the information we collected.
2641 0 : aResolve(cwi);
2642 :
2643 0 : if (!cwi.windowOpened()) {
2644 0 : Destroy();
2645 : }
2646 0 : return IPC_OK();
2647 : }
2648 :
2649 : mozilla::ipc::IPCResult
2650 0 : TabParent::RecvRespondStartSwipeEvent(const uint64_t& aInputBlockId,
2651 : const bool& aStartSwipe)
2652 : {
2653 0 : if (nsCOMPtr<nsIWidget> widget = GetWidget()) {
2654 0 : widget->ReportSwipeStarted(aInputBlockId, aStartSwipe);
2655 : }
2656 0 : return IPC_OK();
2657 : }
2658 :
2659 : already_AddRefed<nsILoadContext>
2660 1 : TabParent::GetLoadContext()
2661 : {
2662 2 : nsCOMPtr<nsILoadContext> loadContext;
2663 1 : if (mLoadContext) {
2664 0 : loadContext = mLoadContext;
2665 : } else {
2666 1 : bool isPrivate = mChromeFlags & nsIWebBrowserChrome::CHROME_PRIVATE_WINDOW;
2667 1 : SetPrivateBrowsingAttributes(isPrivate);
2668 1 : bool useTrackingProtection = false;
2669 2 : nsCOMPtr<nsIDocShell> docShell = mFrameElement->OwnerDoc()->GetDocShell();
2670 1 : if (docShell) {
2671 1 : docShell->GetUseTrackingProtection(&useTrackingProtection);
2672 : }
2673 1 : loadContext = new LoadContext(GetOwnerElement(),
2674 : true /* aIsContent */,
2675 : isPrivate,
2676 1 : mChromeFlags & nsIWebBrowserChrome::CHROME_REMOTE_WINDOW,
2677 : useTrackingProtection,
2678 3 : OriginAttributesRef());
2679 1 : mLoadContext = loadContext;
2680 : }
2681 2 : return loadContext.forget();
2682 : }
2683 :
2684 : NS_IMETHODIMP
2685 0 : TabParent::GetUseAsyncPanZoom(bool* useAsyncPanZoom)
2686 : {
2687 0 : *useAsyncPanZoom = AsyncPanZoomEnabled();
2688 0 : return NS_OK;
2689 : }
2690 :
2691 : // defined in nsITabParent
2692 : NS_IMETHODIMP
2693 2 : TabParent::SetDocShellIsActive(bool isActive)
2694 : {
2695 : // Increment the epoch so that layer tree updates from previous
2696 : // SetDocShellIsActive requests are ignored.
2697 2 : mLayerTreeEpoch++;
2698 :
2699 : // docshell is consider prerendered only if not active yet
2700 2 : mIsPrerendered &= !isActive;
2701 2 : mDocShellIsActive = isActive;
2702 2 : Unused << SendSetDocShellIsActive(isActive, mPreserveLayers, mLayerTreeEpoch);
2703 :
2704 : // Let's inform the priority manager. This operation can end up with the
2705 : // changing of the process priority.
2706 2 : ProcessPriorityManager::TabActivityChanged(this, isActive);
2707 :
2708 : // Ask the child to repaint using the PHangMonitor channel/thread (which may
2709 : // be less congested).
2710 2 : if (isActive) {
2711 2 : ContentParent* cp = Manager()->AsContentParent();
2712 2 : cp->ForceTabPaint(this, mLayerTreeEpoch);
2713 : }
2714 :
2715 2 : return NS_OK;
2716 : }
2717 :
2718 : NS_IMETHODIMP
2719 0 : TabParent::GetDocShellIsActive(bool* aIsActive)
2720 : {
2721 0 : *aIsActive = mDocShellIsActive;
2722 0 : return NS_OK;
2723 : }
2724 :
2725 : NS_IMETHODIMP
2726 0 : TabParent::GetIsPrerendered(bool* aIsPrerendered)
2727 : {
2728 0 : *aIsPrerendered = mIsPrerendered;
2729 0 : return NS_OK;
2730 : }
2731 :
2732 : NS_IMETHODIMP
2733 1 : TabParent::PreserveLayers(bool aPreserveLayers)
2734 : {
2735 1 : mPreserveLayers = aPreserveLayers;
2736 1 : return NS_OK;
2737 : }
2738 :
2739 : NS_IMETHODIMP
2740 0 : TabParent::SuppressDisplayport(bool aEnabled)
2741 : {
2742 0 : if (IsDestroyed()) {
2743 0 : return NS_OK;
2744 : }
2745 :
2746 : #ifdef DEBUG
2747 0 : if (aEnabled) {
2748 0 : mActiveSupressDisplayportCount++;
2749 : } else {
2750 0 : mActiveSupressDisplayportCount--;
2751 : }
2752 0 : MOZ_ASSERT(mActiveSupressDisplayportCount >= 0);
2753 : #endif
2754 :
2755 0 : Unused << SendSuppressDisplayport(aEnabled);
2756 0 : return NS_OK;
2757 : }
2758 :
2759 : NS_IMETHODIMP
2760 0 : TabParent::GetTabId(uint64_t* aId)
2761 : {
2762 0 : *aId = GetTabId();
2763 0 : return NS_OK;
2764 : }
2765 :
2766 : NS_IMETHODIMP
2767 0 : TabParent::GetOsPid(int32_t* aId)
2768 : {
2769 0 : *aId = Manager()->Pid();
2770 0 : return NS_OK;
2771 : }
2772 :
2773 : NS_IMETHODIMP
2774 1 : TabParent::GetHasContentOpener(bool* aResult)
2775 : {
2776 1 : *aResult = mHasContentOpener;
2777 1 : return NS_OK;
2778 : }
2779 :
2780 : void
2781 0 : TabParent::SetHasContentOpener(bool aHasContentOpener)
2782 : {
2783 0 : mHasContentOpener = aHasContentOpener;
2784 0 : }
2785 :
2786 : NS_IMETHODIMP
2787 0 : TabParent::GetHasPresented(bool* aResult)
2788 : {
2789 0 : *aResult = mHasPresented;
2790 0 : return NS_OK;
2791 : }
2792 :
2793 : NS_IMETHODIMP
2794 0 : TabParent::NavigateByKey(bool aForward, bool aForDocumentNavigation)
2795 : {
2796 0 : Unused << SendNavigateByKey(aForward, aForDocumentNavigation);
2797 0 : return NS_OK;
2798 : }
2799 :
2800 : NS_IMETHODIMP
2801 0 : TabParent::TransmitPermissionsForPrincipal(nsIPrincipal* aPrincipal)
2802 : {
2803 0 : nsCOMPtr<nsIContentParent> manager = Manager();
2804 0 : if (!manager->IsContentParent()) {
2805 0 : return NS_ERROR_UNEXPECTED;
2806 : }
2807 :
2808 : return manager->AsContentParent()
2809 0 : ->TransmitPermissionsForPrincipal(aPrincipal);
2810 : }
2811 :
2812 : NS_IMETHODIMP
2813 0 : TabParent::GetHasBeforeUnload(bool* aResult)
2814 : {
2815 0 : *aResult = mHasBeforeUnload;
2816 0 : return NS_OK;
2817 : }
2818 :
2819 : class LayerTreeUpdateRunnable final
2820 : : public mozilla::Runnable
2821 : {
2822 : uint64_t mLayersId;
2823 : uint64_t mEpoch;
2824 : bool mActive;
2825 :
2826 : public:
2827 : explicit LayerTreeUpdateRunnable(uint64_t aLayersId,
2828 : uint64_t aEpoch,
2829 : bool aActive)
2830 : : Runnable("dom::LayerTreeUpdateRunnable")
2831 : , mLayersId(aLayersId)
2832 : , mEpoch(aEpoch)
2833 : , mActive(aActive)
2834 : {
2835 : MOZ_ASSERT(!NS_IsMainThread());
2836 : }
2837 :
2838 : private:
2839 : NS_IMETHOD Run() override {
2840 : MOZ_ASSERT(NS_IsMainThread());
2841 : if (RefPtr<TabParent> tabParent = TabParent::GetTabParentFromLayersId(mLayersId)) {
2842 : tabParent->LayerTreeUpdate(mEpoch, mActive);
2843 : }
2844 : return NS_OK;
2845 : }
2846 : };
2847 :
2848 : void
2849 3 : TabParent::LayerTreeUpdate(uint64_t aEpoch, bool aActive)
2850 : {
2851 : // Ignore updates from old epochs. They might tell us that layers are
2852 : // available when we've already sent a message to clear them. We can't trust
2853 : // the update in that case since layers could disappear anytime after that.
2854 3 : if (aEpoch != mLayerTreeEpoch || mIsDestroyed) {
2855 2 : return;
2856 : }
2857 :
2858 4 : nsCOMPtr<mozilla::dom::EventTarget> target = do_QueryInterface(mFrameElement);
2859 2 : if (!target) {
2860 0 : NS_WARNING("Could not locate target for layer tree message.");
2861 0 : return;
2862 : }
2863 :
2864 4 : RefPtr<Event> event = NS_NewDOMEvent(mFrameElement, nullptr, nullptr);
2865 2 : if (aActive) {
2866 2 : mHasPresented = true;
2867 2 : event->InitEvent(NS_LITERAL_STRING("MozLayerTreeReady"), true, false);
2868 : } else {
2869 0 : event->InitEvent(NS_LITERAL_STRING("MozLayerTreeCleared"), true, false);
2870 : }
2871 2 : event->SetTrusted(true);
2872 2 : event->WidgetEventPtr()->mFlags.mOnlyChromeDispatch = true;
2873 : bool dummy;
2874 2 : mFrameElement->DispatchEvent(event, &dummy);
2875 : }
2876 :
2877 : mozilla::ipc::IPCResult
2878 2 : TabParent::RecvForcePaintNoOp(const uint64_t& aLayerObserverEpoch)
2879 : {
2880 : // We sent a ForcePaint message when layers were already visible. In this
2881 : // case, we should act as if an update occurred even though we already have
2882 : // the layers.
2883 2 : LayerTreeUpdate(aLayerObserverEpoch, true);
2884 2 : return IPC_OK();
2885 : }
2886 :
2887 : mozilla::ipc::IPCResult
2888 0 : TabParent::RecvRemotePaintIsReady()
2889 : {
2890 0 : nsCOMPtr<mozilla::dom::EventTarget> target = do_QueryInterface(mFrameElement);
2891 0 : if (!target) {
2892 0 : NS_WARNING("Could not locate target for MozAfterRemotePaint message.");
2893 0 : return IPC_OK();
2894 : }
2895 :
2896 0 : RefPtr<Event> event = NS_NewDOMEvent(mFrameElement, nullptr, nullptr);
2897 0 : event->InitEvent(NS_LITERAL_STRING("MozAfterRemotePaint"), false, false);
2898 0 : event->SetTrusted(true);
2899 0 : event->WidgetEventPtr()->mFlags.mOnlyChromeDispatch = true;
2900 : bool dummy;
2901 0 : mFrameElement->DispatchEvent(event, &dummy);
2902 0 : return IPC_OK();
2903 : }
2904 :
2905 : mozilla::plugins::PPluginWidgetParent*
2906 0 : TabParent::AllocPPluginWidgetParent()
2907 : {
2908 : #ifdef XP_WIN
2909 : return new mozilla::plugins::PluginWidgetParent();
2910 : #else
2911 0 : MOZ_ASSERT_UNREACHABLE();
2912 : return nullptr;
2913 : #endif
2914 : }
2915 :
2916 : bool
2917 0 : TabParent::DeallocPPluginWidgetParent(mozilla::plugins::PPluginWidgetParent* aActor)
2918 : {
2919 0 : delete aActor;
2920 0 : return true;
2921 : }
2922 :
2923 : PPaymentRequestParent*
2924 0 : TabParent::AllocPPaymentRequestParent()
2925 : {
2926 0 : RefPtr<PaymentRequestParent> actor = new PaymentRequestParent(GetTabId());
2927 0 : return actor.forget().take();
2928 : }
2929 :
2930 : bool
2931 0 : TabParent::DeallocPPaymentRequestParent(PPaymentRequestParent* aActor)
2932 : {
2933 : RefPtr<PaymentRequestParent> actor =
2934 0 : dont_AddRef(static_cast<PaymentRequestParent*>(aActor));
2935 0 : return true;
2936 : }
2937 :
2938 : nsresult
2939 5 : TabParent::HandleEvent(nsIDOMEvent* aEvent)
2940 : {
2941 10 : nsAutoString eventType;
2942 5 : aEvent->GetType(eventType);
2943 :
2944 5 : if (eventType.EqualsLiteral("MozUpdateWindowPos") && !mIsDestroyed) {
2945 : // This event is sent when the widget moved. Therefore we only update
2946 : // the position.
2947 5 : return UpdatePosition();
2948 : }
2949 0 : return NS_OK;
2950 : }
2951 :
2952 : class FakeChannel final : public nsIChannel,
2953 : public nsIAuthPromptCallback,
2954 : public nsIInterfaceRequestor,
2955 : public nsILoadContext
2956 : {
2957 : public:
2958 0 : FakeChannel(const nsCString& aUri, uint64_t aCallbackId, Element* aElement)
2959 0 : : mCallbackId(aCallbackId)
2960 0 : , mElement(aElement)
2961 : {
2962 0 : NS_NewURI(getter_AddRefs(mUri), aUri);
2963 0 : }
2964 :
2965 : NS_DECL_ISUPPORTS
2966 : #define NO_IMPL override { return NS_ERROR_NOT_IMPLEMENTED; }
2967 0 : NS_IMETHOD GetName(nsACString&) NO_IMPL
2968 0 : NS_IMETHOD IsPending(bool*) NO_IMPL
2969 0 : NS_IMETHOD GetStatus(nsresult*) NO_IMPL
2970 0 : NS_IMETHOD Cancel(nsresult) NO_IMPL
2971 0 : NS_IMETHOD Suspend() NO_IMPL
2972 0 : NS_IMETHOD Resume() NO_IMPL
2973 0 : NS_IMETHOD GetLoadGroup(nsILoadGroup**) NO_IMPL
2974 0 : NS_IMETHOD SetLoadGroup(nsILoadGroup*) NO_IMPL
2975 0 : NS_IMETHOD SetLoadFlags(nsLoadFlags) NO_IMPL
2976 0 : NS_IMETHOD GetLoadFlags(nsLoadFlags*) NO_IMPL
2977 0 : NS_IMETHOD GetIsDocument(bool *) NO_IMPL
2978 0 : NS_IMETHOD GetOriginalURI(nsIURI**) NO_IMPL
2979 0 : NS_IMETHOD SetOriginalURI(nsIURI*) NO_IMPL
2980 0 : NS_IMETHOD GetURI(nsIURI** aUri) override
2981 : {
2982 0 : nsCOMPtr<nsIURI> copy = mUri;
2983 0 : copy.forget(aUri);
2984 0 : return NS_OK;
2985 : }
2986 0 : NS_IMETHOD GetOwner(nsISupports**) NO_IMPL
2987 0 : NS_IMETHOD SetOwner(nsISupports*) NO_IMPL
2988 0 : NS_IMETHOD GetLoadInfo(nsILoadInfo** aLoadInfo) override
2989 : {
2990 0 : nsCOMPtr<nsILoadInfo> copy = mLoadInfo;
2991 0 : copy.forget(aLoadInfo);
2992 0 : return NS_OK;
2993 : }
2994 0 : NS_IMETHOD SetLoadInfo(nsILoadInfo* aLoadInfo) override
2995 : {
2996 0 : mLoadInfo = aLoadInfo;
2997 0 : return NS_OK;
2998 : }
2999 0 : NS_IMETHOD GetNotificationCallbacks(nsIInterfaceRequestor** aRequestor) override
3000 : {
3001 0 : NS_ADDREF(*aRequestor = this);
3002 0 : return NS_OK;
3003 : }
3004 0 : NS_IMETHOD SetNotificationCallbacks(nsIInterfaceRequestor*) NO_IMPL
3005 0 : NS_IMETHOD GetSecurityInfo(nsISupports**) NO_IMPL
3006 0 : NS_IMETHOD GetContentType(nsACString&) NO_IMPL
3007 0 : NS_IMETHOD SetContentType(const nsACString&) NO_IMPL
3008 0 : NS_IMETHOD GetContentCharset(nsACString&) NO_IMPL
3009 0 : NS_IMETHOD SetContentCharset(const nsACString&) NO_IMPL
3010 0 : NS_IMETHOD GetContentLength(int64_t*) NO_IMPL
3011 0 : NS_IMETHOD SetContentLength(int64_t) NO_IMPL
3012 0 : NS_IMETHOD Open(nsIInputStream**) NO_IMPL
3013 0 : NS_IMETHOD Open2(nsIInputStream**) NO_IMPL
3014 0 : NS_IMETHOD AsyncOpen(nsIStreamListener*, nsISupports*) NO_IMPL
3015 0 : NS_IMETHOD AsyncOpen2(nsIStreamListener*) NO_IMPL
3016 0 : NS_IMETHOD GetContentDisposition(uint32_t*) NO_IMPL
3017 0 : NS_IMETHOD SetContentDisposition(uint32_t) NO_IMPL
3018 0 : NS_IMETHOD GetContentDispositionFilename(nsAString&) NO_IMPL
3019 0 : NS_IMETHOD SetContentDispositionFilename(const nsAString&) NO_IMPL
3020 0 : NS_IMETHOD GetContentDispositionHeader(nsACString&) NO_IMPL
3021 : NS_IMETHOD OnAuthAvailable(nsISupports *aContext, nsIAuthInformation *aAuthInfo) override;
3022 : NS_IMETHOD OnAuthCancelled(nsISupports *aContext, bool userCancel) override;
3023 0 : NS_IMETHOD GetInterface(const nsIID & uuid, void **result) override
3024 : {
3025 0 : return QueryInterface(uuid, result);
3026 : }
3027 0 : NS_IMETHOD GetAssociatedWindow(mozIDOMWindowProxy**) NO_IMPL
3028 0 : NS_IMETHOD GetTopWindow(mozIDOMWindowProxy**) NO_IMPL
3029 0 : NS_IMETHOD GetTopFrameElement(nsIDOMElement** aElement) override
3030 : {
3031 0 : nsCOMPtr<nsIDOMElement> elem = do_QueryInterface(mElement);
3032 0 : elem.forget(aElement);
3033 0 : return NS_OK;
3034 : }
3035 0 : NS_IMETHOD GetNestedFrameId(uint64_t*) NO_IMPL
3036 0 : NS_IMETHOD GetIsContent(bool*) NO_IMPL
3037 0 : NS_IMETHOD GetUsePrivateBrowsing(bool*) NO_IMPL
3038 0 : NS_IMETHOD SetUsePrivateBrowsing(bool) NO_IMPL
3039 0 : NS_IMETHOD SetPrivateBrowsing(bool) NO_IMPL
3040 0 : NS_IMETHOD GetIsInIsolatedMozBrowserElement(bool*) NO_IMPL
3041 0 : NS_IMETHOD GetScriptableOriginAttributes(JS::MutableHandleValue) NO_IMPL
3042 0 : NS_IMETHOD_(void) GetOriginAttributes(mozilla::OriginAttributes& aAttrs) override {}
3043 0 : NS_IMETHOD GetUseRemoteTabs(bool*) NO_IMPL
3044 0 : NS_IMETHOD SetRemoteTabs(bool) NO_IMPL
3045 0 : NS_IMETHOD GetUseTrackingProtection(bool*) NO_IMPL
3046 0 : NS_IMETHOD SetUseTrackingProtection(bool) NO_IMPL
3047 : #undef NO_IMPL
3048 :
3049 : protected:
3050 0 : ~FakeChannel() {}
3051 :
3052 : nsCOMPtr<nsIURI> mUri;
3053 : uint64_t mCallbackId;
3054 : nsCOMPtr<Element> mElement;
3055 : nsCOMPtr<nsILoadInfo> mLoadInfo;
3056 : };
3057 :
3058 0 : NS_IMPL_ISUPPORTS(FakeChannel, nsIChannel, nsIAuthPromptCallback,
3059 : nsIRequest, nsIInterfaceRequestor, nsILoadContext);
3060 :
3061 : mozilla::ipc::IPCResult
3062 0 : TabParent::RecvAsyncAuthPrompt(const nsCString& aUri,
3063 : const nsString& aRealm,
3064 : const uint64_t& aCallbackId)
3065 : {
3066 0 : nsCOMPtr<nsIAuthPrompt2> authPrompt;
3067 0 : GetAuthPrompt(nsIAuthPromptProvider::PROMPT_NORMAL,
3068 : NS_GET_IID(nsIAuthPrompt2),
3069 0 : getter_AddRefs(authPrompt));
3070 0 : RefPtr<FakeChannel> channel = new FakeChannel(aUri, aCallbackId, mFrameElement);
3071 0 : uint32_t promptFlags = nsIAuthInformation::AUTH_HOST;
3072 :
3073 : RefPtr<nsAuthInformationHolder> holder =
3074 : new nsAuthInformationHolder(promptFlags, aRealm,
3075 0 : EmptyCString());
3076 :
3077 0 : uint32_t level = nsIAuthPrompt2::LEVEL_NONE;
3078 0 : nsCOMPtr<nsICancelable> dummy;
3079 : nsresult rv =
3080 0 : authPrompt->AsyncPromptAuth(channel, channel, nullptr,
3081 0 : level, holder, getter_AddRefs(dummy));
3082 :
3083 0 : if (NS_FAILED(rv)) {
3084 0 : return IPC_FAIL_NO_REASON(this);
3085 : }
3086 0 : return IPC_OK();
3087 : }
3088 :
3089 : mozilla::ipc::IPCResult
3090 0 : TabParent::RecvInvokeDragSession(nsTArray<IPCDataTransfer>&& aTransfers,
3091 : const uint32_t& aAction,
3092 : const OptionalShmem& aVisualDnDData,
3093 : const uint32_t& aStride, const uint8_t& aFormat,
3094 : const LayoutDeviceIntRect& aDragRect)
3095 : {
3096 0 : mInitialDataTransferItems.Clear();
3097 0 : nsIPresShell* shell = mFrameElement->OwnerDoc()->GetShell();
3098 0 : if (!shell) {
3099 0 : if (Manager()->IsContentParent()) {
3100 0 : Unused << Manager()->AsContentParent()->SendEndDragSession(true, true,
3101 0 : LayoutDeviceIntPoint(),
3102 0 : 0);
3103 : }
3104 0 : return IPC_OK();
3105 : }
3106 :
3107 0 : EventStateManager* esm = shell->GetPresContext()->EventStateManager();
3108 0 : for (uint32_t i = 0; i < aTransfers.Length(); ++i) {
3109 0 : mInitialDataTransferItems.AppendElement(mozilla::Move(aTransfers[i].items()));
3110 : }
3111 0 : if (Manager()->IsContentParent()) {
3112 : nsCOMPtr<nsIDragService> dragService =
3113 0 : do_GetService("@mozilla.org/widget/dragservice;1");
3114 0 : if (dragService) {
3115 0 : dragService->MaybeAddChildProcess(Manager()->AsContentParent());
3116 : }
3117 : }
3118 :
3119 0 : if (aVisualDnDData.type() == OptionalShmem::Tvoid_t ||
3120 0 : !aVisualDnDData.get_Shmem().IsReadable() ||
3121 0 : aVisualDnDData.get_Shmem().Size<char>() < aDragRect.height * aStride) {
3122 0 : mDnDVisualization = nullptr;
3123 : } else {
3124 : mDnDVisualization =
3125 0 : gfx::CreateDataSourceSurfaceFromData(gfx::IntSize(aDragRect.width, aDragRect.height),
3126 0 : static_cast<gfx::SurfaceFormat>(aFormat),
3127 0 : aVisualDnDData.get_Shmem().get<uint8_t>(),
3128 0 : aStride);
3129 : }
3130 :
3131 0 : mDragValid = true;
3132 0 : mDragRect = aDragRect;
3133 :
3134 0 : esm->BeginTrackingRemoteDragGesture(mFrameElement);
3135 :
3136 0 : if (aVisualDnDData.type() == OptionalShmem::TShmem) {
3137 0 : Unused << DeallocShmem(aVisualDnDData);
3138 : }
3139 :
3140 0 : return IPC_OK();
3141 : }
3142 :
3143 : void
3144 0 : TabParent::AddInitialDnDDataTo(DataTransfer* aDataTransfer)
3145 : {
3146 0 : for (uint32_t i = 0; i < mInitialDataTransferItems.Length(); ++i) {
3147 0 : nsTArray<IPCDataTransferItem>& itemArray = mInitialDataTransferItems[i];
3148 0 : for (auto& item : itemArray) {
3149 0 : RefPtr<nsVariantCC> variant = new nsVariantCC();
3150 : // Special case kFilePromiseMime so that we get the right
3151 : // nsIFlavorDataProvider for it.
3152 0 : if (item.flavor().EqualsLiteral(kFilePromiseMime)) {
3153 : RefPtr<nsISupports> flavorDataProvider =
3154 0 : new nsContentAreaDragDropDataProvider();
3155 0 : variant->SetAsISupports(flavorDataProvider);
3156 0 : } else if (item.data().type() == IPCDataTransferData::TnsString) {
3157 0 : variant->SetAsAString(item.data().get_nsString());
3158 0 : } else if (item.data().type() == IPCDataTransferData::TIPCBlob) {
3159 : RefPtr<BlobImpl> impl =
3160 0 : IPCBlobUtils::Deserialize(item.data().get_IPCBlob());
3161 0 : variant->SetAsISupports(impl);
3162 0 : } else if (item.data().type() == IPCDataTransferData::TShmem) {
3163 0 : if (nsContentUtils::IsFlavorImage(item.flavor())) {
3164 : // An image! Get the imgIContainer for it and set it in the variant.
3165 0 : nsCOMPtr<imgIContainer> imageContainer;
3166 : nsresult rv =
3167 0 : nsContentUtils::DataTransferItemToImage(item,
3168 0 : getter_AddRefs(imageContainer));
3169 0 : if (NS_FAILED(rv)) {
3170 0 : continue;
3171 : }
3172 0 : variant->SetAsISupports(imageContainer);
3173 : } else {
3174 0 : Shmem data = item.data().get_Shmem();
3175 0 : variant->SetAsACString(nsDependentCString(data.get<char>(), data.Size<char>()));
3176 : }
3177 :
3178 0 : mozilla::Unused << DeallocShmem(item.data().get_Shmem());
3179 : }
3180 :
3181 : // Using system principal here, since once the data is on parent process
3182 : // side, it can be handled as being from browser chrome or OS.
3183 :
3184 : // We set aHidden to false, as we don't need to worry about hiding data
3185 : // from content in the parent process where there is no content.
3186 : // XXX: Nested Content Processes may change this
3187 0 : aDataTransfer->SetDataWithPrincipalFromOtherProcess(NS_ConvertUTF8toUTF16(item.flavor()),
3188 : variant, i,
3189 : nsContentUtils::GetSystemPrincipal(),
3190 0 : /* aHidden = */ false);
3191 : }
3192 : }
3193 0 : mInitialDataTransferItems.Clear();
3194 0 : }
3195 :
3196 : bool
3197 0 : TabParent::TakeDragVisualization(RefPtr<mozilla::gfx::SourceSurface>& aSurface,
3198 : LayoutDeviceIntRect* aDragRect)
3199 : {
3200 0 : if (!mDragValid)
3201 0 : return false;
3202 :
3203 0 : aSurface = mDnDVisualization.forget();
3204 0 : *aDragRect = mDragRect;
3205 0 : mDragValid = false;
3206 0 : return true;
3207 : }
3208 :
3209 : bool
3210 6 : TabParent::AsyncPanZoomEnabled() const
3211 : {
3212 12 : nsCOMPtr<nsIWidget> widget = GetWidget();
3213 12 : return widget && widget->AsyncPanZoomEnabled();
3214 : }
3215 :
3216 : NS_IMETHODIMP
3217 0 : TabParent::StartPersistence(uint64_t aOuterWindowID,
3218 : nsIWebBrowserPersistDocumentReceiver* aRecv)
3219 : {
3220 0 : nsCOMPtr<nsIContentParent> manager = Manager();
3221 0 : if (!manager->IsContentParent()) {
3222 0 : return NS_ERROR_UNEXPECTED;
3223 : }
3224 0 : auto* actor = new WebBrowserPersistDocumentParent();
3225 0 : actor->SetOnReady(aRecv);
3226 0 : return manager->AsContentParent()
3227 0 : ->SendPWebBrowserPersistDocumentConstructor(actor, this, aOuterWindowID)
3228 0 : ? NS_OK : NS_ERROR_FAILURE;
3229 : // (The actor will be destroyed on constructor failure.)
3230 : }
3231 :
3232 : ShowInfo
3233 2 : TabParent::GetShowInfo()
3234 : {
3235 2 : TryCacheDPIAndScale();
3236 2 : if (mFrameElement) {
3237 4 : nsAutoString name;
3238 2 : mFrameElement->GetAttr(kNameSpaceID_None, nsGkAtoms::name, name);
3239 : bool allowFullscreen =
3240 4 : mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) ||
3241 4 : mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::mozallowfullscreen);
3242 2 : bool isPrivate = mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::mozprivatebrowsing);
3243 : bool isTransparent =
3244 4 : nsContentUtils::IsChromeDoc(mFrameElement->OwnerDoc()) &&
3245 4 : mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::transparent);
3246 : return ShowInfo(name, allowFullscreen, isPrivate, false,
3247 2 : isTransparent, mDPI, mRounding, mDefaultScale.scale);
3248 : }
3249 :
3250 : return ShowInfo(EmptyString(), false, false, false,
3251 0 : false, mDPI, mRounding, mDefaultScale.scale);
3252 : }
3253 :
3254 : mozilla::ipc::IPCResult
3255 0 : TabParent::RecvGetTabCount(uint32_t* aValue)
3256 : {
3257 0 : *aValue = 0;
3258 :
3259 0 : nsCOMPtr<nsIXULBrowserWindow> xulBrowserWindow = GetXULBrowserWindow();
3260 0 : NS_ENSURE_TRUE(xulBrowserWindow, IPC_OK());
3261 :
3262 : uint32_t tabCount;
3263 0 : nsresult rv = xulBrowserWindow->GetTabCount(&tabCount);
3264 0 : NS_ENSURE_SUCCESS(rv, IPC_OK());
3265 :
3266 0 : *aValue = tabCount;
3267 0 : return IPC_OK();
3268 : }
3269 :
3270 : mozilla::ipc::IPCResult
3271 0 : TabParent::RecvLookUpDictionary(const nsString& aText,
3272 : nsTArray<FontRange>&& aFontRangeArray,
3273 : const bool& aIsVertical,
3274 : const LayoutDeviceIntPoint& aPoint)
3275 : {
3276 0 : nsCOMPtr<nsIWidget> widget = GetWidget();
3277 0 : if (!widget) {
3278 0 : return IPC_OK();
3279 : }
3280 :
3281 0 : widget->LookUpDictionary(aText, aFontRangeArray, aIsVertical,
3282 0 : aPoint - GetChildProcessOffset());
3283 0 : return IPC_OK();
3284 : }
3285 :
3286 : mozilla::ipc::IPCResult
3287 0 : TabParent::RecvSHistoryUpdate(const uint32_t& aCount, const uint32_t& aLocalIndex, const bool& aTruncate)
3288 : {
3289 0 : RefPtr<nsFrameLoader> frameLoader(GetFrameLoader());
3290 0 : if (!frameLoader) {
3291 : // FrameLoader can be nullptr if the it is destroying.
3292 : // In this case session history change can simply be ignored.
3293 0 : return IPC_OK();
3294 : }
3295 :
3296 0 : nsCOMPtr<nsIPartialSHistory> partialHistory;
3297 0 : frameLoader->GetPartialSHistory(getter_AddRefs(partialHistory));
3298 0 : if (!partialHistory) {
3299 : // PartialSHistory is not enabled
3300 0 : return IPC_OK();
3301 : }
3302 :
3303 0 : partialHistory->HandleSHistoryUpdate(aCount, aLocalIndex, aTruncate);
3304 0 : return IPC_OK();
3305 : }
3306 :
3307 : mozilla::ipc::IPCResult
3308 0 : TabParent::RecvRequestCrossBrowserNavigation(const uint32_t& aGlobalIndex)
3309 : {
3310 0 : RefPtr<nsFrameLoader> frameLoader(GetFrameLoader());
3311 0 : if (!frameLoader) {
3312 : // FrameLoader can be nullptr if the it is destroying.
3313 : // In this case we can ignore the request.
3314 0 : return IPC_OK();
3315 : }
3316 :
3317 0 : nsCOMPtr<nsISupports> promise;
3318 0 : if (NS_FAILED(frameLoader->RequestGroupedHistoryNavigation(aGlobalIndex,
3319 : getter_AddRefs(promise)))) {
3320 0 : return IPC_FAIL_NO_REASON(this);
3321 : }
3322 0 : return IPC_OK();
3323 : }
3324 :
3325 : void
3326 0 : TabParent::LiveResizeStarted()
3327 : {
3328 0 : SuppressDisplayport(true);
3329 0 : }
3330 :
3331 : void
3332 0 : TabParent::LiveResizeStopped()
3333 : {
3334 0 : SuppressDisplayport(false);
3335 0 : }
3336 :
3337 : NS_IMETHODIMP
3338 0 : FakeChannel::OnAuthAvailable(nsISupports *aContext, nsIAuthInformation *aAuthInfo)
3339 : {
3340 : nsAuthInformationHolder* holder =
3341 0 : static_cast<nsAuthInformationHolder*>(aAuthInfo);
3342 :
3343 0 : if (!net::gNeckoChild->SendOnAuthAvailable(mCallbackId,
3344 : holder->User(),
3345 : holder->Password(),
3346 : holder->Domain())) {
3347 0 : return NS_ERROR_FAILURE;
3348 : }
3349 0 : return NS_OK;
3350 : }
3351 :
3352 : NS_IMETHODIMP
3353 0 : FakeChannel::OnAuthCancelled(nsISupports *aContext, bool userCancel)
3354 : {
3355 0 : if (!net::gNeckoChild->SendOnAuthCancelled(mCallbackId, userCancel)) {
3356 0 : return NS_ERROR_FAILURE;
3357 : }
3358 0 : return NS_OK;
3359 : }
3360 :
3361 :
3362 : } // namespace dom
3363 : } // namespace mozilla
|