DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Implementation

Mercurial (1aeaa33a64f9)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef TabGroup_h
#define TabGroup_h

#include "nsHashKeys.h"
#include "nsISupportsImpl.h"
#include "nsIPrincipal.h"
#include "nsTHashtable.h"
#include "nsString.h"

#include "mozilla/Atomics.h"
#include "mozilla/SchedulerGroup.h"
#include "mozilla/RefPtr.h"

class mozIDOMWindowProxy;
class nsIDocShellTreeItem;
class nsIDocument;
class nsPIDOMWindowOuter;

namespace mozilla {
class AbstractThread;
class ThrottledEventQueue;
namespace dom {
class TabChild;

// Two browsing contexts are considered "related" if they are reachable from one
// another through window.opener, window.parent, or window.frames. This is the
// spec concept of a "unit of related browsing contexts"
//
// Two browsing contexts are considered "similar-origin" if they can be made to
// have the same origin by setting document.domain. This is the spec concept of
// a "unit of similar-origin related browsing contexts"
//
// A TabGroup is a set of browsing contexts which are all "related". Within a
// TabGroup, browsing contexts are broken into "similar-origin" DocGroups. In
// more detail, a DocGroup is actually a collection of documents, and a
// TabGroup is a collection of DocGroups. A TabGroup typically will contain
// (through its DocGroups) the documents from one or more tabs related by
// window.opener. A DocGroup is a member of exactly one TabGroup.

class DocGroup;
class TabChild;

class TabGroup final : public SchedulerGroup {
 private:
  class HashEntry : public nsCStringHashKey {
   public:
    // NOTE: Weak reference. The DocGroup destructor removes itself from its
    // owning TabGroup.
    DocGroup* mDocGroup;
    explicit HashEntry(const nsACString* aKey);
  };

  typedef nsTHashtable<HashEntry> DocGroupMap;

 public:
  typedef DocGroupMap::Iterator Iterator;

  friend class DocGroup;

  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TabGroup, override)

  static TabGroup* GetChromeTabGroup();

  // Checks if the TabChild already has a TabGroup assigned to it in
  // IPDL. Returns this TabGroup if it does. This could happen if the parent
  // process created the PBrowser and we needed to assign a TabGroup immediately
  // upon receiving the IPDL message. This method is main thread only.
  static TabGroup* GetFromActor(TabChild* aTabChild);

  static TabGroup* GetFromWindow(mozIDOMWindowProxy* aWindow);

  explicit TabGroup(bool aIsChrome = false);

  // Get the docgroup for the corresponding doc group key.
  // Returns null if the given key hasn't been seen yet.
  already_AddRefed<DocGroup> GetDocGroup(const nsACString& aKey);

  already_AddRefed<DocGroup> AddDocument(const nsACString& aKey,
                                         nsIDocument* aDocument);

  // Join the specified TabGroup, returning a reference to it. If aTabGroup is
  // nullptr, create a new tabgroup to join.
  static already_AddRefed<TabGroup> Join(nsPIDOMWindowOuter* aWindow,
                                         TabGroup* aTabGroup);

  void Leave(nsPIDOMWindowOuter* aWindow);

  Iterator Iter() { return mDocGroups.Iter(); }

  // Returns the nsIDocShellTreeItem with the given name, searching each of the
  // docShell trees which are within this TabGroup. It will pass itself as
  // aRequestor to each docShellTreeItem which it asks to search for the name,
  // and will not search the docShellTreeItem which is passed as aRequestor.
  //
  // This method is used in order to correctly namespace named windows based on
  // their unit of related browsing contexts.
  //
  // It is illegal to pass in the special case-insensitive names "_blank",
  // "_self", "_parent" or "_top", as those should be handled elsewhere.
  nsresult FindItemWithName(const nsAString& aName,
                            nsIDocShellTreeItem* aRequestor,
                            nsIDocShellTreeItem* aOriginalRequestor,
                            nsIDocShellTreeItem** aFoundItem);

  nsTArray<nsPIDOMWindowOuter*> GetTopLevelWindows() const;
  const nsTArray<nsPIDOMWindowOuter*>& GetWindows() { return mWindows; }

  // This method is always safe to call off the main thread. The nsIEventTarget
  // can always be used off the main thread.
  nsISerialEventTarget* EventTargetFor(TaskCategory aCategory) const override;

  void WindowChangedBackgroundStatus(bool aIsNowBackground);

  // Returns true if all of the TabGroup's top-level windows are in
  // the background.
  bool IsBackground() const override;

  // Increase/Decrease the number of IndexedDB transactions/databases for the
  // decision making of the preemption in the scheduler.
  Atomic<uint32_t>& IndexedDBTransactionCounter() {
    return mNumOfIndexedDBTransactions;
  }

  Atomic<uint32_t>& IndexedDBDatabaseCounter() {
    return mNumOfIndexedDBDatabases;
  }

 private:
  virtual AbstractThread* AbstractMainThreadForImpl(
      TaskCategory aCategory) override;

  TabGroup* AsTabGroup() override { return this; }

  void EnsureThrottledEventQueues();

  ~TabGroup();

  // Thread-safe members
  Atomic<bool> mLastWindowLeft;
  Atomic<bool> mThrottledQueuesInitialized;
  Atomic<uint32_t> mNumOfIndexedDBTransactions;
  Atomic<uint32_t> mNumOfIndexedDBDatabases;
  const bool mIsChrome;

  // Main thread only
  DocGroupMap mDocGroups;
  nsTArray<nsPIDOMWindowOuter*> mWindows;
  uint32_t mForegroundCount;
};

}  // namespace dom
}  // namespace mozilla

#endif  // defined(TabGroup_h)