Coverage Report

Created: 2018-09-25 14:53

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