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 file,
5 * You can obtain one at http://mozilla.org/MPL/2.0/. */
10 #include "nsHashKeys.h"
11 #include "nsISupportsImpl.h"
12 #include "nsIPrincipal.h"
13 #include "nsTHashtable.h"
16 #include "mozilla/Atomics.h"
17 #include "mozilla/SchedulerGroup.h"
18 #include "mozilla/RefPtr.h"
20 class mozIDOMWindowProxy
;
21 class nsIDocShellTreeItem
;
22 class nsPIDOMWindowOuter
;
26 class ThrottledEventQueue
;
31 // Two browsing contexts are considered "related" if they are reachable from one
32 // another through window.opener, window.parent, or window.frames. This is the
33 // spec concept of a "unit of related browsing contexts"
35 // Two browsing contexts are considered "similar-origin" if they can be made to
36 // have the same origin by setting document.domain. This is the spec concept of
37 // a "unit of similar-origin related browsing contexts"
39 // A TabGroup is a set of browsing contexts which are all "related". Within a
40 // TabGroup, browsing contexts are broken into "similar-origin" DocGroups. In
41 // more detail, a DocGroup is actually a collection of documents, and a
42 // TabGroup is a collection of DocGroups. A TabGroup typically will contain
43 // (through its DocGroups) the documents from one or more tabs related by
44 // window.opener. A DocGroup is a member of exactly one TabGroup.
49 class TabGroup final
: public SchedulerGroup
,
50 public LinkedListElement
<TabGroup
> {
52 class HashEntry
: public nsCStringHashKey
{
54 // NOTE: Weak reference. The DocGroup destructor removes itself from its
57 explicit HashEntry(const nsACString
* aKey
);
60 typedef nsTHashtable
<HashEntry
> DocGroupMap
;
63 typedef DocGroupMap::Iterator Iterator
;
65 friend class DocGroup
;
67 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TabGroup
, override
)
69 static TabGroup
* GetChromeTabGroup();
71 // Checks if the BrowserChild already has a TabGroup assigned to it in
72 // IPDL. Returns this TabGroup if it does. This could happen if the parent
73 // process created the PBrowser and we needed to assign a TabGroup immediately
74 // upon receiving the IPDL message. This method is main thread only.
75 static TabGroup
* GetFromActor(BrowserChild
* aBrowserChild
);
77 static TabGroup
* GetFromWindow(mozIDOMWindowProxy
* aWindow
);
79 explicit TabGroup(bool aIsChrome
= false);
81 // Get the docgroup for the corresponding doc group key.
82 // Returns null if the given key hasn't been seen yet.
83 already_AddRefed
<DocGroup
> GetDocGroup(const nsACString
& aKey
);
85 already_AddRefed
<DocGroup
> AddDocument(const nsACString
& aKey
,
88 // Join the specified TabGroup, returning a reference to it. If aTabGroup is
89 // nullptr, create a new tabgroup to join.
90 static already_AddRefed
<TabGroup
> Join(nsPIDOMWindowOuter
* aWindow
,
93 void Leave(nsPIDOMWindowOuter
* aWindow
);
95 Iterator
Iter() { return mDocGroups
.Iter(); }
97 // Returns the size of the set of "similar-origin" DocGroups. To
98 // only consider DocGroups with at least one active document, call
99 // Count with 'aActiveOnly' = true
100 uint32_t Count(bool aActiveOnly
= false) const;
102 // Returns the nsIDocShellTreeItem with the given name, searching each of the
103 // docShell trees which are within this TabGroup. It will pass itself as
104 // aRequestor to each docShellTreeItem which it asks to search for the name,
105 // and will not search the docShellTreeItem which is passed as aRequestor.
107 // This method is used in order to correctly namespace named windows based on
108 // their unit of related browsing contexts.
110 // It is illegal to pass in the special case-insensitive names "_blank",
111 // "_self", "_parent" or "_top", as those should be handled elsewhere.
112 nsresult
FindItemWithName(const nsAString
& aName
,
113 nsIDocShellTreeItem
* aRequestor
,
114 nsIDocShellTreeItem
* aOriginalRequestor
,
115 nsIDocShellTreeItem
** aFoundItem
);
117 nsTArray
<nsPIDOMWindowOuter
*> GetTopLevelWindows() const;
118 const nsTArray
<nsPIDOMWindowOuter
*>& GetWindows() { return mWindows
; }
120 // This method is always safe to call off the main thread. The nsIEventTarget
121 // can always be used off the main thread.
122 nsISerialEventTarget
* EventTargetFor(TaskCategory aCategory
) const override
;
124 void WindowChangedBackgroundStatus(bool aIsNowBackground
);
126 // Returns true if all of the TabGroup's top-level windows are in
128 bool IsBackground() const override
;
130 // Increase/Decrease the number of IndexedDB transactions/databases for the
131 // decision making of the preemption in the scheduler.
132 Atomic
<uint32_t>& IndexedDBTransactionCounter() {
133 return mNumOfIndexedDBTransactions
;
136 Atomic
<uint32_t>& IndexedDBDatabaseCounter() {
137 return mNumOfIndexedDBDatabases
;
140 static LinkedList
<TabGroup
>* GetTabGroupList() { return sTabGroups
; }
142 // This returns true if all the window objects in all the TabGroups are
143 // either inactive (for example in bfcache) or are in background tabs which
145 static bool HasOnlyThrottableTabs();
147 nsresult
QueuePostMessageEvent(already_AddRefed
<nsIRunnable
>&& aRunnable
);
149 void FlushPostMessageEvents();
152 virtual AbstractThread
* AbstractMainThreadForImpl(
153 TaskCategory aCategory
) override
;
155 TabGroup
* AsTabGroup() override
{ return this; }
157 void EnsureThrottledEventQueues();
161 // Thread-safe members
162 Atomic
<bool> mLastWindowLeft
;
163 Atomic
<bool> mThrottledQueuesInitialized
;
164 Atomic
<uint32_t> mNumOfIndexedDBTransactions
;
165 Atomic
<uint32_t> mNumOfIndexedDBDatabases
;
166 const bool mIsChrome
;
169 DocGroupMap mDocGroups
;
170 nsTArray
<nsPIDOMWindowOuter
*> mWindows
;
171 uint32_t mForegroundCount
;
173 static LinkedList
<TabGroup
>* sTabGroups
;
175 // A queue to store postMessage events during page load, the queue will be
176 // flushed once the page is loaded
177 RefPtr
<mozilla::ThrottledEventQueue
> mPostMessageEventQueue
;
181 } // namespace mozilla
183 #endif // defined(TabGroup_h)