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 #ifndef _mozilla_dom_ClientManagerService_h
7 #define _mozilla_dom_ClientManagerService_h
9 #include "ClientHandleParent.h"
10 #include "ClientOpPromise.h"
11 #include "mozilla/AlreadyAddRefed.h"
12 #include "mozilla/Assertions.h"
13 #include "mozilla/Maybe.h"
14 #include "mozilla/MozPromise.h"
15 #include "mozilla/RefPtr.h"
16 #include "mozilla/Variant.h"
17 #include "mozilla/dom/ClientIPCTypes.h"
18 #include "mozilla/dom/ipc/IdType.h"
19 #include "nsTHashMap.h"
20 #include "nsHashKeys.h"
21 #include "nsISupports.h"
36 class ClientManagerParent
;
37 class ClientSourceParent
;
38 class ClientHandleParent
;
39 class ThreadsafeContentParentHandle
;
41 // Define a singleton service to manage client activity throughout the
42 // browser. This service runs on the PBackground thread. To interact
43 // it with it please use the ClientManager and ClientHandle classes.
44 class ClientManagerService final
{
45 // Placeholder type that represents a ClientSourceParent that may be created
46 // in the future (e.g. while a redirect chain is being resolved).
48 // Each FutureClientSourceParent has a promise that callbacks may be chained
49 // to; the promise will be resolved when the associated ClientSourceParent is
50 // created or rejected when it's known that it'll never be created.
51 class FutureClientSourceParent
{
53 explicit FutureClientSourceParent(const IPCClientInfo
& aClientInfo
);
55 const mozilla::ipc::PrincipalInfo
& PrincipalInfo() const {
56 return mPrincipalInfo
;
59 already_AddRefed
<SourcePromise
> Promise() {
60 return mPromiseHolder
.Ensure(__func__
);
63 void ResolvePromiseIfExists() {
64 mPromiseHolder
.ResolveIfExists(true, __func__
);
67 void RejectPromiseIfExists(const CopyableErrorResult
& aRv
) {
68 MOZ_ASSERT(aRv
.Failed());
69 mPromiseHolder
.RejectIfExists(aRv
, __func__
);
72 void SetAsAssociated() { mAssociated
= true; }
74 bool IsAssociated() const { return mAssociated
; }
77 const mozilla::ipc::PrincipalInfo mPrincipalInfo
;
78 MozPromiseHolder
<SourcePromise
> mPromiseHolder
;
79 RefPtr
<ClientManagerService
> mService
= ClientManagerService::GetInstance();
83 using SourceTableEntry
=
84 Variant
<FutureClientSourceParent
, ClientSourceParent
*>;
86 // Store the possible ClientSourceParent objects in a hash table. We want to
87 // optimize for insertion, removal, and lookup by UUID.
88 nsTHashMap
<nsIDHashKey
, SourceTableEntry
> mSourceTable
;
90 nsTArray
<ClientManagerParent
*> mManagerList
;
94 ClientManagerService();
95 ~ClientManagerService();
99 // Returns nullptr if aEntry isn't a ClientSourceParent (i.e. it's a
100 // FutureClientSourceParent).
101 ClientSourceParent
* MaybeUnwrapAsExistingSource(
102 const SourceTableEntry
& aEntry
) const;
105 static already_AddRefed
<ClientManagerService
> GetOrCreateInstance();
107 // Returns nullptr if the service is not already created.
108 static already_AddRefed
<ClientManagerService
> GetInstance();
110 bool AddSource(ClientSourceParent
* aSource
);
112 bool RemoveSource(ClientSourceParent
* aSource
);
114 // Returns true when a FutureClientSourceParent is successfully added.
115 bool ExpectFutureSource(const IPCClientInfo
& aClientInfo
);
117 // May still be called if it's possible that the FutureClientSourceParent
119 void ForgetFutureSource(const IPCClientInfo
& aClientInfo
);
121 // Returns a promise that resolves if/when the ClientSourceParent exists and
122 // rejects if/when it's known that the ClientSourceParent will never exist or
123 // if it's frozen. Note that the ClientSourceParent may not exist anymore
124 // by the time promise callbacks run.
125 RefPtr
<SourcePromise
> FindSource(
126 const nsID
& aID
, const mozilla::ipc::PrincipalInfo
& aPrincipalInfo
);
128 // Returns nullptr if the ClientSourceParent doesn't exist yet (i.e. it's a
129 // FutureClientSourceParent or has already been destroyed) or is frozen.
130 ClientSourceParent
* FindExistingSource(
131 const nsID
& aID
, const mozilla::ipc::PrincipalInfo
& aPrincipalInfo
) const;
133 void AddManager(ClientManagerParent
* aManager
);
135 void RemoveManager(ClientManagerParent
* aManager
);
137 RefPtr
<ClientOpPromise
> Navigate(
138 ThreadsafeContentParentHandle
* aOriginContent
,
139 const ClientNavigateArgs
& aArgs
);
141 RefPtr
<ClientOpPromise
> MatchAll(
142 ThreadsafeContentParentHandle
* aOriginContent
,
143 const ClientMatchAllArgs
& aArgs
);
145 RefPtr
<ClientOpPromise
> Claim(ThreadsafeContentParentHandle
* aOriginContent
,
146 const ClientClaimArgs
& aArgs
);
148 RefPtr
<ClientOpPromise
> GetInfoAndState(
149 ThreadsafeContentParentHandle
* aOriginContent
,
150 const ClientGetInfoAndStateArgs
& aArgs
);
152 RefPtr
<ClientOpPromise
> OpenWindow(
153 ThreadsafeContentParentHandle
* aOriginContent
,
154 const ClientOpenWindowArgs
& aArgs
);
156 bool HasWindow(const Maybe
<ContentParentId
>& aContentParentId
,
157 const mozilla::ipc::PrincipalInfo
& aPrincipalInfo
,
158 const nsID
& aClientId
);
160 NS_INLINE_DECL_REFCOUNTING(mozilla::dom::ClientManagerService
)
164 } // namespace mozilla
166 #endif // _mozilla_dom_ClientManagerService_h