Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef TabGroup_h
8 : #define TabGroup_h
9 :
10 : #include "nsISupportsImpl.h"
11 : #include "nsIPrincipal.h"
12 : #include "nsTHashtable.h"
13 : #include "nsString.h"
14 :
15 : #include "mozilla/Atomics.h"
16 : #include "mozilla/SchedulerGroup.h"
17 : #include "mozilla/RefPtr.h"
18 :
19 : class mozIDOMWindowProxy;
20 : class nsIDocShellTreeItem;
21 : class nsIDocument;
22 : class nsPIDOMWindowOuter;
23 :
24 : namespace mozilla {
25 : class AbstractThread;
26 : class ThrottledEventQueue;
27 : namespace dom {
28 :
29 : // Two browsing contexts are considered "related" if they are reachable from one
30 : // another through window.opener, window.parent, or window.frames. This is the
31 : // spec concept of a "unit of related browsing contexts"
32 : //
33 : // Two browsing contexts are considered "similar-origin" if they can be made to
34 : // have the same origin by setting document.domain. This is the spec concept of
35 : // a "unit of similar-origin related browsing contexts"
36 : //
37 : // A TabGroup is a set of browsing contexts which are all "related". Within a
38 : // TabGroup, browsing contexts are broken into "similar-origin" DocGroups. In
39 : // more detail, a DocGroup is actually a collection of documents, and a
40 : // TabGroup is a collection of DocGroups. A TabGroup typically will contain
41 : // (through its DocGroups) the documents from one or more tabs related by
42 : // window.opener. A DocGroup is a member of exactly one TabGroup.
43 :
44 : class DocGroup;
45 :
46 : class TabGroup final : public SchedulerGroup
47 : {
48 : private:
49 0 : class HashEntry : public nsCStringHashKey
50 : {
51 : public:
52 : // NOTE: Weak reference. The DocGroup destructor removes itself from its
53 : // owning TabGroup.
54 : DocGroup* mDocGroup;
55 : explicit HashEntry(const nsACString* aKey);
56 : };
57 :
58 : typedef nsTHashtable<HashEntry> DocGroupMap;
59 :
60 : public:
61 : typedef DocGroupMap::Iterator Iterator;
62 :
63 : friend class DocGroup;
64 :
65 281 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(TabGroup, override)
66 :
67 : static TabGroup*
68 : GetChromeTabGroup();
69 :
70 : // Checks if the TabChild already has a TabGroup assigned to it in
71 : // IPDL. Returns this TabGroup if it does. This could happen if the parent
72 : // process created the PBrowser and we needed to assign a TabGroup immediately
73 : // upon receiving the IPDL message. This method is main thread only.
74 : static TabGroup* GetFromActor(TabChild* aTabChild);
75 :
76 : static TabGroup* GetFromWindow(mozIDOMWindowProxy* aWindow);
77 :
78 : explicit TabGroup(bool aIsChrome = false);
79 :
80 : // Get the docgroup for the corresponding doc group key.
81 : // Returns null if the given key hasn't been seen yet.
82 : already_AddRefed<DocGroup>
83 : GetDocGroup(const nsACString& aKey);
84 :
85 : already_AddRefed<DocGroup>
86 : AddDocument(const nsACString& aKey, nsIDocument* aDocument);
87 :
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>
91 : Join(nsPIDOMWindowOuter* aWindow, TabGroup* aTabGroup);
92 :
93 : void Leave(nsPIDOMWindowOuter* aWindow);
94 :
95 : Iterator Iter()
96 : {
97 : return mDocGroups.Iter();
98 : }
99 :
100 :
101 : // Returns the nsIDocShellTreeItem with the given name, searching each of the
102 : // docShell trees which are within this TabGroup. It will pass itself as
103 : // aRequestor to each docShellTreeItem which it asks to search for the name,
104 : // and will not search the docShellTreeItem which is passed as aRequestor.
105 : //
106 : // This method is used in order to correctly namespace named windows based on
107 : // their unit of related browsing contexts.
108 : //
109 : // It is illegal to pass in the special case-insensitive names "_blank",
110 : // "_self", "_parent" or "_top", as those should be handled elsewhere.
111 : nsresult
112 : FindItemWithName(const nsAString& aName,
113 : nsIDocShellTreeItem* aRequestor,
114 : nsIDocShellTreeItem* aOriginalRequestor,
115 : nsIDocShellTreeItem** aFoundItem);
116 :
117 : nsTArray<nsPIDOMWindowOuter*> GetTopLevelWindows() const;
118 1 : const nsTArray<nsPIDOMWindowOuter*>& GetWindows() { return mWindows; }
119 :
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;
123 :
124 : void WindowChangedBackgroundStatus(bool aIsNowBackground);
125 :
126 : // Returns true if all of the TabGroup's top-level windows are in
127 : // the background.
128 : bool IsBackground() const override;
129 :
130 : // Increase/Decrease the number of IndexedDB transactions/databases for the
131 : // decision making of the preemption in the scheduler.
132 0 : Atomic<uint32_t>& IndexedDBTransactionCounter()
133 : {
134 0 : return mNumOfIndexedDBTransactions;
135 : }
136 :
137 0 : Atomic<uint32_t>& IndexedDBDatabaseCounter()
138 : {
139 0 : return mNumOfIndexedDBDatabases;
140 : }
141 :
142 : private:
143 : virtual AbstractThread*
144 : AbstractMainThreadForImpl(TaskCategory aCategory) override;
145 :
146 1 : TabGroup* AsTabGroup() override { return this; }
147 :
148 : void EnsureThrottledEventQueues();
149 :
150 : ~TabGroup();
151 :
152 : // Thread-safe members
153 : Atomic<bool> mLastWindowLeft;
154 : Atomic<bool> mThrottledQueuesInitialized;
155 : Atomic<uint32_t> mNumOfIndexedDBTransactions;
156 : Atomic<uint32_t> mNumOfIndexedDBDatabases;
157 : const bool mIsChrome;
158 :
159 : // Main thread only
160 : DocGroupMap mDocGroups;
161 : nsTArray<nsPIDOMWindowOuter*> mWindows;
162 : uint32_t mForegroundCount;
163 : };
164 :
165 : } // namespace dom
166 : } // namespace mozilla
167 :
168 : #endif // defined(TabGroup_h)
|