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/. */
7 #ifndef nsContentPermissionHelper_h
8 #define nsContentPermissionHelper_h
10 #include "nsIContentPermissionPrompt.h"
12 #include "nsIMutableArray.h"
13 #include "mozilla/dom/PContentPermissionRequestChild.h"
14 #include "mozilla/dom/ipc/IdType.h"
15 #include "mozilla/PermissionDelegateHandler.h"
17 // Microsoft's API Name hackery sucks
18 // XXXbz Doing this in a header is a gigantic footgun. See
19 // https://bugzilla.mozilla.org/show_bug.cgi?id=932421#c3 for why.
22 class nsPIDOMWindowInner
;
23 class nsContentPermissionRequestProxy
;
25 namespace mozilla::dom
{
28 class PermissionRequest
;
29 class ContentPermissionRequestParent
;
30 class PContentPermissionRequestParent
;
32 class ContentPermissionType
: public nsIContentPermissionType
{
35 NS_DECL_NSICONTENTPERMISSIONTYPE
37 ContentPermissionType(const nsACString
& aType
,
38 const nsTArray
<nsString
>& aOptions
);
41 virtual ~ContentPermissionType();
44 nsTArray
<nsString
> mOptions
;
47 class nsContentPermissionUtils
{
49 static uint32_t ConvertPermissionRequestToArray(
50 nsTArray
<PermissionRequest
>& aSrcArray
, nsIMutableArray
* aDesArray
);
52 // Converts blindly, that is, strings are not matched against any list.
54 // @param aSrcArray needs to contain elements of type
55 // `nsIContentPermissionType`.
56 static void ConvertArrayToPermissionRequest(
57 nsIArray
* aSrcArray
, nsTArray
<PermissionRequest
>& aDesArray
);
59 static nsresult
CreatePermissionArray(const nsACString
& aType
,
60 const nsTArray
<nsString
>& aOptions
,
61 nsIArray
** aTypesArray
);
63 // @param aIsRequestDelegatedToUnsafeThirdParty see
64 // ContentPermissionRequestParent.
65 static PContentPermissionRequestParent
* CreateContentPermissionRequestParent(
66 const nsTArray
<PermissionRequest
>& aRequests
, Element
* aElement
,
67 nsIPrincipal
* aPrincipal
, nsIPrincipal
* aTopLevelPrincipal
,
68 const bool aHasValidTransientUserGestureActivation
,
69 const bool aIsRequestDelegatedToUnsafeThirdParty
, const TabId
& aTabId
);
71 static nsresult
AskPermission(nsIContentPermissionRequest
* aRequest
,
72 nsPIDOMWindowInner
* aWindow
);
74 static nsTArray
<PContentPermissionRequestParent
*>
75 GetContentPermissionRequestParentById(const TabId
& aTabId
);
77 static void NotifyRemoveContentPermissionRequestParent(
78 PContentPermissionRequestParent
* aParent
);
80 static nsTArray
<PContentPermissionRequestChild
*>
81 GetContentPermissionRequestChildById(const TabId
& aTabId
);
83 static void NotifyRemoveContentPermissionRequestChild(
84 PContentPermissionRequestChild
* aChild
);
87 nsresult
TranslateChoices(
88 JS::Handle
<JS::Value
> aChoices
,
89 const nsTArray
<PermissionRequest
>& aPermissionRequests
,
90 nsTArray
<PermissionChoice
>& aTranslatedChoices
);
92 class ContentPermissionRequestBase
: public nsIContentPermissionRequest
{
94 NS_DECL_CYCLE_COLLECTING_ISUPPORTS
95 NS_DECL_CYCLE_COLLECTION_CLASS(ContentPermissionRequestBase
)
97 NS_IMETHOD
GetTypes(nsIArray
** aTypes
) override
;
98 NS_IMETHOD
GetPrincipal(nsIPrincipal
** aPrincipal
) override
;
99 NS_IMETHOD
GetDelegatePrincipal(const nsACString
& aType
,
100 nsIPrincipal
** aPrincipal
) override
;
101 NS_IMETHOD
GetTopLevelPrincipal(nsIPrincipal
** aTopLevelPrincipal
) override
;
102 NS_IMETHOD
GetWindow(mozIDOMWindow
** aWindow
) override
;
103 NS_IMETHOD
GetElement(mozilla::dom::Element
** aElement
) override
;
104 NS_IMETHOD
GetHasValidTransientUserGestureActivation(
105 bool* aHasValidTransientUserGestureActivation
) override
;
106 NS_IMETHOD
GetIsRequestDelegatedToUnsafeThirdParty(
107 bool* aIsRequestDelegatedToUnsafeThirdParty
) override
;
108 // Overrides for Allow() and Cancel() aren't provided by this class.
109 // That is the responsibility of the subclasses.
111 enum class PromptResult
{
116 nsresult
ShowPrompt(PromptResult
& aResult
);
118 PromptResult
CheckPromptPrefs() const;
120 // Check if the permission has an opportunity to request.
121 bool CheckPermissionDelegate() const;
123 enum class DelayedTaskType
{
128 void RequestDelayedTask(nsIEventTarget
* aTarget
, DelayedTaskType aType
);
131 // @param aPrefName see `mPrefName`.
132 // @param aType see `mType`.
133 ContentPermissionRequestBase(nsIPrincipal
* aPrincipal
,
134 nsPIDOMWindowInner
* aWindow
,
135 const nsACString
& aPrefName
,
136 const nsACString
& aType
);
137 virtual ~ContentPermissionRequestBase() = default;
139 nsCOMPtr
<nsIPrincipal
> mPrincipal
;
140 nsCOMPtr
<nsIPrincipal
> mTopLevelPrincipal
;
141 nsCOMPtr
<nsPIDOMWindowInner
> mWindow
;
142 RefPtr
<PermissionDelegateHandler
> mPermissionHandler
;
144 // The prefix of a pref which allows tests to bypass showing the prompt.
145 // Tests will have to set both of
146 // ${mPrefName}.prompt.testing and
147 // ${mPrefName}.prompt.testing.allow
148 // to either true or false. If no such testing is required, mPrefName may be
150 const nsCString mPrefName
;
152 // The type of the request, such as "autoplay-media-audible".
153 const nsCString mType
;
155 bool mHasValidTransientUserGestureActivation
;
157 // See nsIPermissionDelegateHandler.maybeUnsafePermissionDelegate`.
158 bool mIsRequestDelegatedToUnsafeThirdParty
;
161 } // namespace mozilla::dom
163 using mozilla::dom::ContentPermissionRequestParent
;
165 class nsContentPermissionRequestProxy
: public nsIContentPermissionRequest
{
168 NS_DECL_NSICONTENTPERMISSIONREQUEST
170 explicit nsContentPermissionRequestProxy(
171 ContentPermissionRequestParent
* parent
);
173 nsresult
Init(const nsTArray
<mozilla::dom::PermissionRequest
>& requests
);
175 void OnParentDestroyed();
178 virtual ~nsContentPermissionRequestProxy();
180 // Non-owning pointer to the ContentPermissionRequestParent object which owns
182 ContentPermissionRequestParent
* mParent
;
183 nsTArray
<mozilla::dom::PermissionRequest
> mPermissionRequests
;
187 * RemotePermissionRequest will send a prompt ipdl request to the chrome process
188 * (https://wiki.mozilla.org/Security/Sandbox/Process_model#Chrome_process_.28Parent.29).
190 class RemotePermissionRequest final
191 : public mozilla::dom::PContentPermissionRequestChild
{
193 NS_INLINE_DECL_REFCOUNTING(RemotePermissionRequest
)
195 RemotePermissionRequest(nsIContentPermissionRequest
* aRequest
,
196 nsPIDOMWindowInner
* aWindow
);
198 // It will be called when prompt dismissed. MOZ_CAN_RUN_SCRIPT_BOUNDARY
199 // because we don't have MOZ_CAN_RUN_SCRIPT bits in IPC code yet.
200 MOZ_CAN_RUN_SCRIPT_BOUNDARY
201 mozilla::ipc::IPCResult
RecvNotifyResult(
202 const bool& aAllow
, nsTArray
<PermissionChoice
>&& aChoices
);
216 bool IPCOpen() const { return mIPCOpen
&& !mDestroyed
; }
219 virtual ~RemotePermissionRequest();
222 void DoAllow(JS::Handle
<JS::Value
> aChoices
);
226 nsCOMPtr
<nsIContentPermissionRequest
> mRequest
;
227 nsCOMPtr
<nsPIDOMWindowInner
> mWindow
;
232 #endif // nsContentPermissionHelper_h