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 
7 #ifndef nsContentPermissionHelper_h
8 #define nsContentPermissionHelper_h
9 
10 #include "nsIContentPermissionPrompt.h"
11 #include "nsTArray.h"
12 #include "nsIMutableArray.h"
13 #include "mozilla/dom/PContentPermissionRequestChild.h"
14 #include "mozilla/dom/ipc/IdType.h"
15 #include "nsIDOMEventListener.h"
16 
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.
20 #undef LoadImage
21 
22 class nsPIDOMWindowInner;
23 class nsContentPermissionRequestProxy;
24 class VisibilityChangeListener;
25 
26 // Forward declare IPC::Principal here which is defined in
27 // PermissionMessageUtils.h. Include this file will transitively includes
28 // "windows.h" and it defines
29 //   #define CreateEvent CreateEventW
30 //   #define LoadImage LoadImageW
31 // That will mess up windows build.
32 namespace IPC {
33 class Principal;
34 }  // namespace IPC
35 
36 namespace mozilla {
37 namespace dom {
38 
39 class Element;
40 class PermissionRequest;
41 class ContentPermissionRequestParent;
42 class PContentPermissionRequestParent;
43 
44 class ContentPermissionType : public nsIContentPermissionType {
45  public:
46   NS_DECL_ISUPPORTS
47   NS_DECL_NSICONTENTPERMISSIONTYPE
48 
49   ContentPermissionType(const nsACString& aType, const nsACString& aAccess,
50                         const nsTArray<nsString>& aOptions);
51 
52  protected:
53   virtual ~ContentPermissionType();
54 
55   nsCString mType;
56   nsCString mAccess;
57   nsTArray<nsString> mOptions;
58 };
59 
60 class nsContentPermissionUtils {
61  public:
62   static uint32_t ConvertPermissionRequestToArray(
63       nsTArray<PermissionRequest>& aSrcArray, nsIMutableArray* aDesArray);
64 
65   static uint32_t ConvertArrayToPermissionRequest(
66       nsIArray* aSrcArray, nsTArray<PermissionRequest>& aDesArray);
67 
68   static nsresult CreatePermissionArray(const nsACString& aType,
69                                         const nsACString& aAccess,
70                                         const nsTArray<nsString>& aOptions,
71                                         nsIArray** aTypesArray);
72 
73   static PContentPermissionRequestParent* CreateContentPermissionRequestParent(
74       const nsTArray<PermissionRequest>& aRequests, Element* aElement,
75       const IPC::Principal& aPrincipal, const bool aIsHandlingUserInput,
76       const TabId& aTabId);
77 
78   static nsresult AskPermission(nsIContentPermissionRequest* aRequest,
79                                 nsPIDOMWindowInner* aWindow);
80 
81   static nsTArray<PContentPermissionRequestParent*>
82   GetContentPermissionRequestParentById(const TabId& aTabId);
83 
84   static void NotifyRemoveContentPermissionRequestParent(
85       PContentPermissionRequestParent* aParent);
86 
87   static nsTArray<PContentPermissionRequestChild*>
88   GetContentPermissionRequestChildById(const TabId& aTabId);
89 
90   static void NotifyRemoveContentPermissionRequestChild(
91       PContentPermissionRequestChild* aChild);
92 };
93 
94 class nsContentPermissionRequester final
95     : public nsIContentPermissionRequester {
96  public:
97   NS_DECL_ISUPPORTS
98   NS_DECL_NSICONTENTPERMISSIONREQUESTER
99 
100   explicit nsContentPermissionRequester(nsPIDOMWindowInner* aWindow);
101 
102  private:
103   virtual ~nsContentPermissionRequester();
104 
105   nsWeakPtr mWindow;
106   RefPtr<VisibilityChangeListener> mListener;
107 };
108 
109 }  // namespace dom
110 }  // namespace mozilla
111 
112 using mozilla::dom::ContentPermissionRequestParent;
113 
114 class nsContentPermissionRequestProxy : public nsIContentPermissionRequest {
115  public:
116   NS_DECL_ISUPPORTS
117   NS_DECL_NSICONTENTPERMISSIONREQUEST
118 
119   nsContentPermissionRequestProxy();
120 
121   nsresult Init(const nsTArray<mozilla::dom::PermissionRequest>& requests,
122                 ContentPermissionRequestParent* parent);
123 
124   void OnParentDestroyed();
125 
126   void NotifyVisibility(const bool& aIsVisible);
127 
128  private:
129   class nsContentPermissionRequesterProxy final
130       : public nsIContentPermissionRequester {
131    public:
132     NS_DECL_ISUPPORTS
133     NS_DECL_NSICONTENTPERMISSIONREQUESTER
134 
nsContentPermissionRequesterProxy(ContentPermissionRequestParent * aParent)135     explicit nsContentPermissionRequesterProxy(
136         ContentPermissionRequestParent* aParent)
137         : mParent(aParent), mWaitGettingResult(false) {}
138 
139     void NotifyVisibilityResult(const bool& aIsVisible);
140 
141    private:
~nsContentPermissionRequesterProxy()142     virtual ~nsContentPermissionRequesterProxy() {}
143 
144     ContentPermissionRequestParent* mParent;
145     bool mWaitGettingResult;
146     nsCOMPtr<nsIContentPermissionRequestCallback> mGetCallback;
147     nsCOMPtr<nsIContentPermissionRequestCallback> mOnChangeCallback;
148   };
149 
150   virtual ~nsContentPermissionRequestProxy();
151 
152   // Non-owning pointer to the ContentPermissionRequestParent object which owns
153   // this proxy.
154   ContentPermissionRequestParent* mParent;
155   nsTArray<mozilla::dom::PermissionRequest> mPermissionRequests;
156   RefPtr<nsContentPermissionRequesterProxy> mRequester;
157 };
158 
159 /**
160  * RemotePermissionRequest will send a prompt ipdl request to b2g process.
161  */
162 class RemotePermissionRequest final
163     : public nsIContentPermissionRequestCallback,
164       public mozilla::dom::PContentPermissionRequestChild {
165  public:
166   NS_DECL_ISUPPORTS
167   NS_DECL_NSICONTENTPERMISSIONREQUESTCALLBACK
168 
169   RemotePermissionRequest(nsIContentPermissionRequest* aRequest,
170                           nsPIDOMWindowInner* aWindow);
171 
172   // It will be called when prompt dismissed.
173   virtual mozilla::ipc::IPCResult RecvNotifyResult(
174       const bool& aAllow,
175       InfallibleTArray<PermissionChoice>&& aChoices) override;
176 
177   virtual mozilla::ipc::IPCResult RecvGetVisibility() override;
178 
IPDLAddRef()179   void IPDLAddRef() {
180     mIPCOpen = true;
181     AddRef();
182   }
183 
IPDLRelease()184   void IPDLRelease() {
185     mIPCOpen = false;
186     Release();
187   }
188 
189   void Destroy();
190 
IPCOpen()191   bool IPCOpen() const { return mIPCOpen && !mDestroyed; }
192 
193  private:
194   virtual ~RemotePermissionRequest();
195 
196   void DoAllow(JS::HandleValue aChoices);
197   void DoCancel();
198 
199   nsCOMPtr<nsIContentPermissionRequest> mRequest;
200   nsCOMPtr<nsPIDOMWindowInner> mWindow;
201   bool mIPCOpen;
202   bool mDestroyed;
203   RefPtr<VisibilityChangeListener> mListener;
204 };
205 
206 #endif  // nsContentPermissionHelper_h
207