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 "mozilla/PermissionDelegateHandler.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 25 // Forward declare IPC::Principal here which is defined in 26 // PermissionMessageUtils.h. Include this file will transitively includes 27 // "windows.h" and it defines 28 // #define CreateEvent CreateEventW 29 // #define LoadImage LoadImageW 30 // That will mess up windows build. 31 namespace IPC { 32 class Principal; 33 } // namespace IPC 34 35 namespace mozilla { 36 namespace dom { 37 38 class Element; 39 class PermissionRequest; 40 class ContentPermissionRequestParent; 41 class PContentPermissionRequestParent; 42 43 class ContentPermissionType : public nsIContentPermissionType { 44 public: 45 NS_DECL_ISUPPORTS 46 NS_DECL_NSICONTENTPERMISSIONTYPE 47 48 ContentPermissionType(const nsACString& aType, 49 const nsTArray<nsString>& aOptions); 50 51 protected: 52 virtual ~ContentPermissionType(); 53 54 nsCString mType; 55 nsTArray<nsString> mOptions; 56 }; 57 58 class nsContentPermissionUtils { 59 public: 60 static uint32_t ConvertPermissionRequestToArray( 61 nsTArray<PermissionRequest>& aSrcArray, nsIMutableArray* aDesArray); 62 63 static uint32_t ConvertArrayToPermissionRequest( 64 nsIArray* aSrcArray, nsTArray<PermissionRequest>& aDesArray); 65 66 static nsresult CreatePermissionArray(const nsACString& aType, 67 const nsTArray<nsString>& aOptions, 68 nsIArray** aTypesArray); 69 70 static PContentPermissionRequestParent* CreateContentPermissionRequestParent( 71 const nsTArray<PermissionRequest>& aRequests, Element* aElement, 72 nsIPrincipal* aPrincipal, nsIPrincipal* aTopLevelPrincipal, 73 const bool aIsHandlingUserInput, 74 const bool aMaybeUnsafePermissionDelegate, const TabId& aTabId); 75 76 static nsresult AskPermission(nsIContentPermissionRequest* aRequest, 77 nsPIDOMWindowInner* aWindow); 78 79 static nsTArray<PContentPermissionRequestParent*> 80 GetContentPermissionRequestParentById(const TabId& aTabId); 81 82 static void NotifyRemoveContentPermissionRequestParent( 83 PContentPermissionRequestParent* aParent); 84 85 static nsTArray<PContentPermissionRequestChild*> 86 GetContentPermissionRequestChildById(const TabId& aTabId); 87 88 static void NotifyRemoveContentPermissionRequestChild( 89 PContentPermissionRequestChild* aChild); 90 }; 91 92 nsresult TranslateChoices( 93 JS::HandleValue aChoices, 94 const nsTArray<PermissionRequest>& aPermissionRequests, 95 nsTArray<PermissionChoice>& aTranslatedChoices); 96 97 class ContentPermissionRequestBase : public nsIContentPermissionRequest { 98 public: 99 NS_DECL_CYCLE_COLLECTING_ISUPPORTS 100 NS_DECL_CYCLE_COLLECTION_CLASS(ContentPermissionRequestBase) 101 102 NS_IMETHOD GetTypes(nsIArray** aTypes) override; 103 NS_IMETHOD GetPrincipal(nsIPrincipal** aPrincipal) override; 104 NS_IMETHOD GetDelegatePrincipal(const nsACString& aType, 105 nsIPrincipal** aPrincipal) override; 106 NS_IMETHOD GetTopLevelPrincipal(nsIPrincipal** aTopLevelPrincipal) override; 107 NS_IMETHOD GetWindow(mozIDOMWindow** aWindow) override; 108 NS_IMETHOD GetElement(mozilla::dom::Element** aElement) override; 109 NS_IMETHOD GetIsHandlingUserInput(bool* aIsHandlingUserInput) override; 110 NS_IMETHOD GetMaybeUnsafePermissionDelegate( 111 bool* aMaybeUnsafePermissionDelegate) override; 112 // Overrides for Allow() and Cancel() aren't provided by this class. 113 // That is the responsibility of the subclasses. 114 115 enum class PromptResult { 116 Granted, 117 Denied, 118 Pending, 119 }; 120 nsresult ShowPrompt(PromptResult& aResult); 121 122 PromptResult CheckPromptPrefs(); 123 124 // Check if the permission has an opportunity to request. 125 bool CheckPermissionDelegate(); 126 127 enum class DelayedTaskType { 128 Allow, 129 Deny, 130 Request, 131 }; 132 void RequestDelayedTask(nsIEventTarget* aTarget, DelayedTaskType aType); 133 134 protected: 135 ContentPermissionRequestBase(nsIPrincipal* aPrincipal, 136 nsPIDOMWindowInner* aWindow, 137 const nsACString& aPrefName, 138 const nsACString& aType); 139 virtual ~ContentPermissionRequestBase() = default; 140 141 nsCOMPtr<nsIPrincipal> mPrincipal; 142 nsCOMPtr<nsIPrincipal> mTopLevelPrincipal; 143 nsCOMPtr<nsPIDOMWindowInner> mWindow; 144 RefPtr<PermissionDelegateHandler> mPermissionHandler; 145 nsCString mPrefName; 146 nsCString mType; 147 bool mIsHandlingUserInput; 148 bool mMaybeUnsafePermissionDelegate; 149 }; 150 151 } // namespace dom 152 } // namespace mozilla 153 154 using mozilla::dom::ContentPermissionRequestParent; 155 156 class nsContentPermissionRequestProxy : public nsIContentPermissionRequest { 157 public: 158 NS_DECL_ISUPPORTS 159 NS_DECL_NSICONTENTPERMISSIONREQUEST 160 161 explicit nsContentPermissionRequestProxy( 162 ContentPermissionRequestParent* parent); 163 164 nsresult Init(const nsTArray<mozilla::dom::PermissionRequest>& requests); 165 166 void OnParentDestroyed(); 167 168 private: 169 virtual ~nsContentPermissionRequestProxy(); 170 171 // Non-owning pointer to the ContentPermissionRequestParent object which owns 172 // this proxy. 173 ContentPermissionRequestParent* mParent; 174 nsTArray<mozilla::dom::PermissionRequest> mPermissionRequests; 175 }; 176 177 /** 178 * RemotePermissionRequest will send a prompt ipdl request to b2g process. 179 */ 180 class RemotePermissionRequest final 181 : public mozilla::dom::PContentPermissionRequestChild { 182 public: 183 NS_INLINE_DECL_REFCOUNTING(RemotePermissionRequest) 184 185 RemotePermissionRequest(nsIContentPermissionRequest* aRequest, 186 nsPIDOMWindowInner* aWindow); 187 188 // It will be called when prompt dismissed. MOZ_CAN_RUN_SCRIPT_BOUNDARY 189 // because we don't have MOZ_CAN_RUN_SCRIPT bits in IPC code yet. 190 MOZ_CAN_RUN_SCRIPT_BOUNDARY 191 mozilla::ipc::IPCResult RecvNotifyResult( 192 const bool& aAllow, nsTArray<PermissionChoice>&& aChoices); 193 IPDLAddRef()194 void IPDLAddRef() { 195 mIPCOpen = true; 196 AddRef(); 197 } 198 IPDLRelease()199 void IPDLRelease() { 200 mIPCOpen = false; 201 Release(); 202 } 203 204 void Destroy(); 205 IPCOpen()206 bool IPCOpen() const { return mIPCOpen && !mDestroyed; } 207 208 private: 209 virtual ~RemotePermissionRequest(); 210 211 MOZ_CAN_RUN_SCRIPT 212 void DoAllow(JS::HandleValue aChoices); 213 MOZ_CAN_RUN_SCRIPT 214 void DoCancel(); 215 216 nsCOMPtr<nsIContentPermissionRequest> mRequest; 217 nsCOMPtr<nsPIDOMWindowInner> mWindow; 218 bool mIPCOpen; 219 bool mDestroyed; 220 }; 221 222 #endif // nsContentPermissionHelper_h 223